Collapse model adapter package boundary

This commit is contained in:
Meta Vens 2026-08-25 01:44:59 +02:00
commit a721b76372
14 changed files with 224 additions and 251 deletions

12
Cargo.lock generated
View file

@ -543,7 +543,6 @@ dependencies = [
"cultnet-rs",
"ed25519-dalek",
"epiphany-model-adapter",
"epiphany-openai-adapter",
"epiphany-release-construction",
"epiphany-tool-adapter",
"ghostlight-persona-projection",
@ -562,19 +561,10 @@ dependencies = [
[[package]]
name = "epiphany-model-adapter"
version = "0.1.0"
dependencies = [
"cultcache-rs",
"serde",
]
[[package]]
name = "epiphany-openai-adapter"
version = "0.1.0"
dependencies = [
"anyhow",
"codex-connector",
"cultcache-rs",
"epiphany-model-adapter",
"serde",
"serde_json",
"sha2",
@ -589,7 +579,6 @@ dependencies = [
"cultcache-rs",
"epiphany-core",
"epiphany-model-adapter",
"epiphany-openai-adapter",
"epiphany-tool-adapter",
"rmp-serde",
"serde",
@ -612,7 +601,6 @@ dependencies = [
"cultnet-rs",
"epiphany-core",
"epiphany-model-adapter",
"epiphany-openai-adapter",
"epiphany-openai-runtime",
"epiphany-tool-adapter",
"epiphany-tool-mcp-runtime",

View file

@ -2,7 +2,6 @@
members = [
"epiphany-core",
"epiphany-model-adapter",
"epiphany-openai-adapter",
"epiphany-openai-runtime",
"epiphany-release-construction",
"epiphany-tool-adapter",
@ -27,7 +26,6 @@ cultcache-rs = { path = "vendor/cultcache-rs" }
cultnet-rs = { path = "vendor/cultnet-rs" }
epiphany-core = { path = "epiphany-core" }
epiphany-model-adapter = { path = "epiphany-model-adapter" }
epiphany-openai-adapter = { path = "epiphany-openai-adapter" }
epiphany-openai-runtime = { path = "epiphany-openai-runtime", optional = true }
codex-connector = { git = "https://github.com/GameCult/CodexConnector", rev = "6dc80f6d266db4d82566d2434adcc55a48e8ecad", default-features = false, features = ["client"], optional = true }
epiphany-tool-adapter = { path = "epiphany-tool-adapter" }

View file

@ -17,7 +17,6 @@ ctrlc = { version = "3.5.1", features = ["termination"] }
cultcache-rs = { path = "../vendor/cultcache-rs" }
cultmesh-rs = { path = "../vendor/cultmesh-rs" }
cultnet-rs = { path = "../vendor/cultnet-rs" }
epiphany-openai-adapter = { path = "../epiphany-openai-adapter" }
epiphany-release-construction = { path = "../epiphany-release-construction" }
epiphany-model-adapter = { path = "../epiphany-model-adapter" }
epiphany-tool-adapter = { path = "../epiphany-tool-adapter" }

View file

@ -6,10 +6,9 @@ use crate::{
};
use anyhow::{Result, anyhow};
use cultcache_rs::{CacheBackingStore, CultCache, CultCacheEnvelope, DatabaseEntry};
use epiphany_model_adapter::EpiphanyModelRequest;
use epiphany_openai_adapter::EpiphanyProviderRequest;
#[cfg(test)]
use epiphany_openai_adapter::EpiphanyProviderRequestPayload;
use epiphany_model_adapter::EpiphanyProviderRequestPayload;
use epiphany_model_adapter::{EpiphanyModelRequest, EpiphanyProviderRequest};
use epiphany_tool_adapter::{
EpiphanyToolInvocationIntent, EpiphanyToolInvocationReceipt, receipt_output_for_model,
tool_invocation_intent_key, tool_invocation_receipt_key,
@ -371,7 +370,7 @@ impl EpiphanyDecisionContext {
tool_observations: Vec<EpiphanyDecisionToolObservation>,
) -> Result<Self> {
basis.validate()?;
let provider_request = epiphany_openai_adapter::request_from_native(&native_request)?;
let provider_request = epiphany_model_adapter::request_from_native(&native_request)?;
validate_request_pair(basis, &native_request, &provider_request)?;
validate_tool_observations(&native_request, &tool_observations)?;
let mut context = Self {
@ -1699,7 +1698,7 @@ fn validate_request_pair(
if native.reasoning_basis_id.as_deref() != Some(basis.basis_id.as_str()) {
return Err(anyhow!("model request does not bind its reasoning basis"));
}
if provider != &epiphany_openai_adapter::request_from_native(native)? {
if provider != &epiphany_model_adapter::request_from_native(native)? {
return Err(anyhow!("native and provider terminal requests diverge"));
}
Ok(())
@ -1995,7 +1994,7 @@ mod tests {
native.input.push(EpiphanyModelInputItem::UserText {
text: "projection".into(),
});
let provider = epiphany_openai_adapter::request_from_native(&native).unwrap();
let provider = epiphany_model_adapter::request_from_native(&native).unwrap();
(native, provider)
}
@ -2072,7 +2071,7 @@ mod tests {
)?;
assert_eq!(
tool_context.provider_request()?,
epiphany_openai_adapter::request_from_native(&native_with_substituted_tools)?,
epiphany_model_adapter::request_from_native(&native_with_substituted_tools)?,
"provider request must be derived from the complete native request"
);
@ -2172,7 +2171,7 @@ mod tests {
));
assert_eq!(
provider,
epiphany_openai_adapter::request_from_native(&native)?
epiphany_model_adapter::request_from_native(&native)?
);
Ok(())
}

View file

@ -34,7 +34,7 @@ use epiphany_model_adapter::EpiphanyModelReceipt;
use epiphany_model_adapter::EpiphanyModelRequest;
use epiphany_model_adapter::EpiphanyModelStreamEvent;
use epiphany_model_adapter::EpiphanyModelStreamPayload;
use epiphany_openai_adapter::EpiphanyProviderRequest;
use epiphany_model_adapter::EpiphanyProviderRequest;
use epiphany_tool_adapter::EpiphanyToolInvocationIntent;
use epiphany_tool_adapter::EpiphanyToolInvocationReceipt;
use epiphany_tool_adapter::TOOL_ADAPTER_INVOCATION_INTENT_SCHEMA_ID;
@ -1078,7 +1078,7 @@ pub fn open_runtime_model_execution(
validate_non_empty(&job_options.job_id, "model execution job id")?;
validate_non_empty(&model_request.request_id, "model execution request id")?;
validate_non_empty(&model_request.provider, "model execution provider")?;
let provider_request = epiphany_openai_adapter::request_from_native(model_request)?;
let provider_request = epiphany_model_adapter::request_from_native(model_request)?;
let store_path = store_path.as_ref();
let mut cache = runtime_spine_cache(store_path)?;
@ -1399,7 +1399,7 @@ pub(crate) fn validate_runtime_model_execution_binding(
.get::<EpiphanyRuntimeJob>(&binding.job_id)?
.ok_or_else(|| anyhow!("model execution binding {request_id:?} lost its job"))?;
if binding.request_id != request_id
|| provider != epiphany_openai_adapter::request_from_native(&native)?
|| provider != epiphany_model_adapter::request_from_native(&native)?
{
return Err(anyhow!(
"model execution binding {request_id:?} is not one exact request family"
@ -1737,7 +1737,7 @@ fn archive_completed_model_session(
.get::<EpiphanyProviderRequest>(request_id)?
.ok_or_else(|| anyhow!("archived model execution lost provider request"))?;
if provider_request.request_id() != request_id
|| provider_request != epiphany_openai_adapter::request_from_native(native_request)?
|| provider_request != epiphany_model_adapter::request_from_native(native_request)?
{
return Err(anyhow!(
"archived model execution request family is inconsistent"

View file

@ -10,5 +10,9 @@ name = "epiphany_model_adapter"
path = "src/lib.rs"
[dependencies]
anyhow = "1"
codex-connector = { git = "https://github.com/GameCult/CodexConnector", rev = "6dc80f6d266db4d82566d2434adcc55a48e8ecad", default-features = false }
cultcache-rs = { path = "../vendor/cultcache-rs" }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sha2 = "0.10"

View file

@ -1,192 +1,5 @@
use cultcache_rs::DatabaseEntry;
use serde::Deserialize;
use serde::Serialize;
mod native;
mod provider;
pub const MODEL_ADAPTER_REQUEST_SCHEMA_ID: &str = "epiphany.model_request.v0";
pub const MODEL_ADAPTER_EVENT_SCHEMA_ID: &str = "epiphany.model_stream_event.v0";
pub const MODEL_ADAPTER_RECEIPT_SCHEMA_ID: &str = "epiphany.model_receipt.v1";
#[derive(Debug, Clone, PartialEq, DatabaseEntry)]
#[cultcache(type = "epiphany.model_request.v0", schema = "EpiphanyModelRequest")]
pub struct EpiphanyModelRequest {
#[cultcache(key = 0)]
pub schema_id: String,
#[cultcache(key = 1)]
pub request_id: String,
#[cultcache(key = 2)]
pub conversation_id: String,
#[cultcache(key = 3)]
pub provider: String,
#[cultcache(key = 4)]
pub model: String,
#[cultcache(key = 5)]
pub instructions: String,
#[cultcache(key = 6, default)]
pub input: Vec<EpiphanyModelInputItem>,
#[cultcache(key = 7, default)]
pub reasoning_effort: Option<String>,
#[cultcache(key = 8, default)]
pub reasoning_summary: Option<String>,
#[cultcache(key = 9, default)]
pub service_tier: Option<String>,
#[cultcache(key = 10, default)]
pub output_contract_id: Option<String>,
#[cultcache(key = 11, default)]
pub previous_response_id: Option<String>,
#[cultcache(key = 12, default)]
pub tools: Vec<EpiphanyModelToolDefinition>,
#[cultcache(key = 13, default)]
pub output_schema_json: Option<String>,
#[cultcache(key = 14, default)]
pub source_worker_job_id: Option<String>,
#[cultcache(key = 15, default)]
pub reasoning_basis_id: Option<String>,
}
impl EpiphanyModelRequest {
pub fn new(
request_id: impl Into<String>,
conversation_id: impl Into<String>,
provider: impl Into<String>,
model: impl Into<String>,
instructions: impl Into<String>,
) -> Self {
Self {
schema_id: MODEL_ADAPTER_REQUEST_SCHEMA_ID.to_string(),
request_id: request_id.into(),
conversation_id: conversation_id.into(),
provider: provider.into(),
model: model.into(),
instructions: instructions.into(),
input: Vec::new(),
reasoning_effort: None,
reasoning_summary: None,
service_tier: None,
output_contract_id: None,
previous_response_id: None,
tools: Vec::new(),
output_schema_json: None,
source_worker_job_id: None,
reasoning_basis_id: None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EpiphanyModelToolDefinition {
pub name: String,
pub description: String,
pub parameters_json: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum EpiphanyModelInputItem {
UserText {
text: String,
},
AssistantText {
text: String,
},
ToolCall {
call_id: String,
name: String,
arguments: String,
},
ToolResult {
call_id: String,
output: String,
},
}
#[derive(Debug, Clone, PartialEq, DatabaseEntry)]
#[cultcache(
type = "epiphany.model_stream_event.v0",
schema = "EpiphanyModelStreamEvent"
)]
pub struct EpiphanyModelStreamEvent {
#[cultcache(key = 0)]
pub schema_id: String,
#[cultcache(key = 1)]
pub request_id: String,
#[cultcache(key = 2)]
pub provider: String,
#[cultcache(key = 3)]
pub sequence: u64,
#[cultcache(key = 4)]
pub payload: EpiphanyModelStreamPayload,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum EpiphanyModelStreamPayload {
TextDelta {
text: String,
},
ReasoningDelta {
text: String,
},
ToolCall {
call_id: String,
name: String,
arguments: String,
},
Completed {
receipt: Box<EpiphanyModelReceipt>,
},
Failed {
message: String,
},
}
#[derive(Debug, Clone, PartialEq, Eq, DatabaseEntry)]
#[cultcache(type = "epiphany.model_receipt.v1", schema = "EpiphanyModelReceipt")]
pub struct EpiphanyModelReceipt {
#[cultcache(key = 0)]
pub schema_id: String,
#[cultcache(key = 1)]
pub request_id: String,
#[cultcache(key = 2)]
pub provider: String,
#[cultcache(key = 3)]
pub model: String,
#[cultcache(key = 4, default)]
pub provider_response_id: Option<String>,
#[cultcache(key = 5, default)]
pub input_tokens: Option<u64>,
#[cultcache(key = 6, default)]
pub output_tokens: Option<u64>,
#[cultcache(key = 7, default)]
pub reasoning_output_tokens: Option<u64>,
#[cultcache(key = 8, default)]
pub transport: Option<String>,
#[cultcache(key = 9, default)]
pub caller_runtime_id: Option<String>,
#[cultcache(key = 10, default)]
pub native_request_sha256: Option<String>,
#[cultcache(key = 11, default)]
pub provider_request_sha256: Option<String>,
#[cultcache(key = 12, default)]
pub cached_input_tokens: Option<u64>,
}
impl EpiphanyModelReceipt {
pub fn new(
request_id: impl Into<String>,
provider: impl Into<String>,
model: impl Into<String>,
) -> Self {
Self {
schema_id: MODEL_ADAPTER_RECEIPT_SCHEMA_ID.to_string(),
request_id: request_id.into(),
provider: provider.into(),
model: model.into(),
provider_response_id: None,
input_tokens: None,
output_tokens: None,
reasoning_output_tokens: None,
transport: None,
caller_runtime_id: None,
native_request_sha256: None,
provider_request_sha256: None,
cached_input_tokens: None,
}
}
}
pub use native::*;
pub use provider::*;

View file

@ -0,0 +1,192 @@
use cultcache_rs::DatabaseEntry;
use serde::Deserialize;
use serde::Serialize;
pub const MODEL_ADAPTER_REQUEST_SCHEMA_ID: &str = "epiphany.model_request.v0";
pub const MODEL_ADAPTER_EVENT_SCHEMA_ID: &str = "epiphany.model_stream_event.v0";
pub const MODEL_ADAPTER_RECEIPT_SCHEMA_ID: &str = "epiphany.model_receipt.v1";
#[derive(Debug, Clone, PartialEq, DatabaseEntry)]
#[cultcache(type = "epiphany.model_request.v0", schema = "EpiphanyModelRequest")]
pub struct EpiphanyModelRequest {
#[cultcache(key = 0)]
pub schema_id: String,
#[cultcache(key = 1)]
pub request_id: String,
#[cultcache(key = 2)]
pub conversation_id: String,
#[cultcache(key = 3)]
pub provider: String,
#[cultcache(key = 4)]
pub model: String,
#[cultcache(key = 5)]
pub instructions: String,
#[cultcache(key = 6, default)]
pub input: Vec<EpiphanyModelInputItem>,
#[cultcache(key = 7, default)]
pub reasoning_effort: Option<String>,
#[cultcache(key = 8, default)]
pub reasoning_summary: Option<String>,
#[cultcache(key = 9, default)]
pub service_tier: Option<String>,
#[cultcache(key = 10, default)]
pub output_contract_id: Option<String>,
#[cultcache(key = 11, default)]
pub previous_response_id: Option<String>,
#[cultcache(key = 12, default)]
pub tools: Vec<EpiphanyModelToolDefinition>,
#[cultcache(key = 13, default)]
pub output_schema_json: Option<String>,
#[cultcache(key = 14, default)]
pub source_worker_job_id: Option<String>,
#[cultcache(key = 15, default)]
pub reasoning_basis_id: Option<String>,
}
impl EpiphanyModelRequest {
pub fn new(
request_id: impl Into<String>,
conversation_id: impl Into<String>,
provider: impl Into<String>,
model: impl Into<String>,
instructions: impl Into<String>,
) -> Self {
Self {
schema_id: MODEL_ADAPTER_REQUEST_SCHEMA_ID.to_string(),
request_id: request_id.into(),
conversation_id: conversation_id.into(),
provider: provider.into(),
model: model.into(),
instructions: instructions.into(),
input: Vec::new(),
reasoning_effort: None,
reasoning_summary: None,
service_tier: None,
output_contract_id: None,
previous_response_id: None,
tools: Vec::new(),
output_schema_json: None,
source_worker_job_id: None,
reasoning_basis_id: None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EpiphanyModelToolDefinition {
pub name: String,
pub description: String,
pub parameters_json: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum EpiphanyModelInputItem {
UserText {
text: String,
},
AssistantText {
text: String,
},
ToolCall {
call_id: String,
name: String,
arguments: String,
},
ToolResult {
call_id: String,
output: String,
},
}
#[derive(Debug, Clone, PartialEq, DatabaseEntry)]
#[cultcache(
type = "epiphany.model_stream_event.v0",
schema = "EpiphanyModelStreamEvent"
)]
pub struct EpiphanyModelStreamEvent {
#[cultcache(key = 0)]
pub schema_id: String,
#[cultcache(key = 1)]
pub request_id: String,
#[cultcache(key = 2)]
pub provider: String,
#[cultcache(key = 3)]
pub sequence: u64,
#[cultcache(key = 4)]
pub payload: EpiphanyModelStreamPayload,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum EpiphanyModelStreamPayload {
TextDelta {
text: String,
},
ReasoningDelta {
text: String,
},
ToolCall {
call_id: String,
name: String,
arguments: String,
},
Completed {
receipt: Box<EpiphanyModelReceipt>,
},
Failed {
message: String,
},
}
#[derive(Debug, Clone, PartialEq, Eq, DatabaseEntry)]
#[cultcache(type = "epiphany.model_receipt.v1", schema = "EpiphanyModelReceipt")]
pub struct EpiphanyModelReceipt {
#[cultcache(key = 0)]
pub schema_id: String,
#[cultcache(key = 1)]
pub request_id: String,
#[cultcache(key = 2)]
pub provider: String,
#[cultcache(key = 3)]
pub model: String,
#[cultcache(key = 4, default)]
pub provider_response_id: Option<String>,
#[cultcache(key = 5, default)]
pub input_tokens: Option<u64>,
#[cultcache(key = 6, default)]
pub output_tokens: Option<u64>,
#[cultcache(key = 7, default)]
pub reasoning_output_tokens: Option<u64>,
#[cultcache(key = 8, default)]
pub transport: Option<String>,
#[cultcache(key = 9, default)]
pub caller_runtime_id: Option<String>,
#[cultcache(key = 10, default)]
pub native_request_sha256: Option<String>,
#[cultcache(key = 11, default)]
pub provider_request_sha256: Option<String>,
#[cultcache(key = 12, default)]
pub cached_input_tokens: Option<u64>,
}
impl EpiphanyModelReceipt {
pub fn new(
request_id: impl Into<String>,
provider: impl Into<String>,
model: impl Into<String>,
) -> Self {
Self {
schema_id: MODEL_ADAPTER_RECEIPT_SCHEMA_ID.to_string(),
request_id: request_id.into(),
provider: provider.into(),
model: model.into(),
provider_response_id: None,
input_tokens: None,
output_tokens: None,
reasoning_output_tokens: None,
transport: None,
caller_runtime_id: None,
native_request_sha256: None,
provider_request_sha256: None,
cached_input_tokens: None,
}
}
}

View file

@ -1,10 +1,10 @@
use anyhow::{Result, anyhow};
use codex_connector::{CodexInputItem, CodexProviderRequest, CodexToolChoice, CodexToolDefinition};
use cultcache_rs::DatabaseEntry;
use epiphany_model_adapter::{
use crate::{
EpiphanyModelInputItem, EpiphanyModelReceipt, EpiphanyModelRequest, EpiphanyModelStreamEvent,
EpiphanyModelStreamPayload, EpiphanyModelToolDefinition, MODEL_ADAPTER_EVENT_SCHEMA_ID,
};
use anyhow::{Result, anyhow};
use codex_connector::{CodexInputItem, CodexProviderRequest, CodexToolChoice, CodexToolDefinition};
use cultcache_rs::DatabaseEntry;
use serde::Deserialize;
use serde::Serialize;
use sha2::{Digest, Sha256};

View file

@ -1,19 +0,0 @@
[package]
name = "epiphany-openai-adapter"
version = "0.1.0"
edition = "2024"
publish = false
license-file = "../LICENSE"
[lib]
name = "epiphany_openai_adapter"
path = "src/lib.rs"
[dependencies]
anyhow = "1"
codex-connector = { git = "https://github.com/GameCult/CodexConnector", rev = "6dc80f6d266db4d82566d2434adcc55a48e8ecad", default-features = false }
cultcache-rs = { path = "../vendor/cultcache-rs" }
epiphany-model-adapter = { path = "../epiphany-model-adapter" }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sha2 = "0.10"

View file

@ -16,7 +16,6 @@ chrono = "0.4.44"
cultcache-rs = { path = "../vendor/cultcache-rs" }
epiphany-core = { path = "../epiphany-core" }
epiphany-model-adapter = { path = "../epiphany-model-adapter" }
epiphany-openai-adapter = { path = "../epiphany-openai-adapter" }
epiphany-tool-adapter = { path = "../epiphany-tool-adapter" }
rmp-serde = "1"
serde = { version = "1", features = ["derive"] }

View file

@ -22,7 +22,7 @@ use epiphany_model_adapter::{
MODEL_ADAPTER_EVENT_SCHEMA_ID,
};
#[cfg(test)]
use epiphany_openai_adapter::{EpiphanyOpenRouterRequest, EpiphanyProviderRequestPayload};
use epiphany_model_adapter::{EpiphanyOpenRouterRequest, EpiphanyProviderRequestPayload};
use epiphany_openai_runtime::DEFAULT_CODEX_CONNECTOR_ENDPOINT;
use epiphany_openai_runtime::DEFAULT_PROVIDER_REQUEST_TIMEOUT;
use epiphany_openai_runtime::EpiphanyOpenAiRuntimeOptions;
@ -934,7 +934,7 @@ mod tests {
output: r#"{"ok":true}"#.into(),
});
let projected = epiphany_openai_adapter::request_from_native(&request)?;
let projected = epiphany_model_adapter::request_from_native(&request)?;
let EpiphanyProviderRequestPayload::Codex(projected) = projected.payload else {
panic!("Codex provider must lower to the connector contract")
};
@ -1048,7 +1048,7 @@ mod tests {
);
request.output_contract_id = Some(format!("worker-schema-{index}"));
request.output_schema_json = Some(serde_json::to_string(&schema)?);
let projected = epiphany_openai_adapter::strict_provider_schema(
let projected = epiphany_model_adapter::strict_provider_schema(
request.output_schema_json.as_deref().unwrap(),
)?;
assert_eq!(projected["additionalProperties"], false);
@ -1072,7 +1072,7 @@ mod tests {
),
)?);
let projected = epiphany_openai_adapter::strict_provider_schema(
let projected = epiphany_model_adapter::strict_provider_schema(
request.output_schema_json.as_deref().unwrap(),
)?;
let decision = &projected["properties"]["researchDecision"];

View file

@ -28,7 +28,7 @@ use epiphany_model_adapter::EpiphanyModelRequest;
use epiphany_model_adapter::EpiphanyModelStreamEvent;
use epiphany_model_adapter::EpiphanyModelStreamPayload;
use epiphany_model_adapter::EpiphanyModelToolDefinition;
use epiphany_openai_adapter::EpiphanyProviderRequest;
use epiphany_model_adapter::EpiphanyProviderRequest;
use epiphany_tool_adapter::EPIPHANY_TOOL_RUNTIME_ADAPTER_ID;
use epiphany_tool_adapter::EpiphanyToolInvocationIntent;
use epiphany_tool_adapter::EpiphanyToolInvocationReceipt;
@ -765,7 +765,7 @@ pub fn model_receipt_key(request_id: &str) -> String {
pub fn provider_request_from_model_request(
request: &EpiphanyModelRequest,
) -> Result<EpiphanyProviderRequest> {
epiphany_openai_adapter::request_from_native(request)
epiphany_model_adapter::request_from_native(request)
}
fn repository_source_tools() -> Vec<EpiphanyModelToolDefinition> {
@ -2772,7 +2772,7 @@ mod tests {
"gpt-5.4",
"Answer plainly.",
);
let request = epiphany_openai_adapter::request_from_native(&native_request)?;
let request = epiphany_model_adapter::request_from_native(&native_request)?;
let options = default_options(store.clone(), &request);
ensure_openai_runtime_ready(&options)?;
open_runtime_model_execution(
@ -3220,7 +3220,7 @@ mod tests {
r#"{"type":"object","properties":{"researchDecision":{"type":"string"}},"required":["researchDecision"]}"#
.to_string(),
);
let request = epiphany_openai_adapter::request_from_native(&native_request)?;
let request = epiphany_model_adapter::request_from_native(&native_request)?;
let options = default_options(store.clone(), &request);
ensure_openai_runtime_ready(&options)?;
open_runtime_model_execution(

View file

@ -11,7 +11,7 @@ use epiphany_model_adapter::{
EpiphanyModelReceipt, EpiphanyModelRequest, EpiphanyModelStreamEvent,
EpiphanyModelStreamPayload, MODEL_ADAPTER_EVENT_SCHEMA_ID,
};
use epiphany_openai_adapter::{
use epiphany_model_adapter::{
EpiphanyOpenRouterRequest, EpiphanyProviderRequestPayload, openrouter_events_from_response,
openrouter_request_body,
};