Stage 1 of the candle-native pivot. Replaces the external-process harness model (mistralrs over HTTP, llamacpp placeholder) with an in-process Harness trait whose sole implementation is candle. The trait keeps its shape so future engines slot in additively, but start/stop default to no-ops and HarnessConfig drops endpoint and systemd_unit since no harness needs external supervision. Behaviour is unchanged on the wire: load_model returns a "not implemented yet (Stage 2)" error and list_models is empty. The gateway-side proxy, poller, and router are untouched. CLAUDE.md Phase 11 (llama.cpp) and Phase 12 (mistral.rs COPR) are marked superseded; the staged plan lives in ~/.claude/plans/create-a-more-aggressive-calm-naur.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
88 lines
2.6 KiB
Rust
88 lines
2.6 KiB
Rust
//! Anthropic Messages API request and response types.
|
|
//!
|
|
//! These mirror the `/v1/messages` format used by the Anthropic API.
|
|
//! The gateway accepts these, translates to OpenAI format, proxies to
|
|
//! the inference backend (neuron), then translates the response back.
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_json::Value;
|
|
|
|
// ── Messages request ─────────────────────────────────────────────────
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct MessagesRequest {
|
|
pub model: String,
|
|
pub messages: Vec<AnthropicMessage>,
|
|
pub max_tokens: u64,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub system: Option<SystemPrompt>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub temperature: Option<f64>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub top_p: Option<f64>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub stream: Option<bool>,
|
|
#[serde(flatten)]
|
|
pub extra: Value,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(untagged)]
|
|
pub enum SystemPrompt {
|
|
Text(String),
|
|
Blocks(Vec<Value>),
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct AnthropicMessage {
|
|
pub role: String,
|
|
pub content: AnthropicContent,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(untagged)]
|
|
pub enum AnthropicContent {
|
|
Text(String),
|
|
Blocks(Vec<ContentBlock>),
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ContentBlock {
|
|
#[serde(rename = "type")]
|
|
pub block_type: String,
|
|
#[serde(flatten)]
|
|
pub data: Value,
|
|
}
|
|
|
|
// ── Messages response ────────────────────────────────────────────────
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct MessagesResponse {
|
|
pub id: String,
|
|
#[serde(rename = "type")]
|
|
pub response_type: String,
|
|
pub role: String,
|
|
pub content: Vec<ContentBlock>,
|
|
pub model: String,
|
|
pub stop_reason: Option<String>,
|
|
pub usage: AnthropicUsage,
|
|
#[serde(flatten)]
|
|
pub extra: Value,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct AnthropicUsage {
|
|
pub input_tokens: u64,
|
|
pub output_tokens: u64,
|
|
}
|
|
|
|
// ── Streaming events ─────────────────────────────────────────────────
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct StreamEvent {
|
|
#[serde(rename = "type")]
|
|
pub event_type: String,
|
|
#[serde(flatten)]
|
|
pub data: Value,
|
|
}
|