SPB Git
3.5 KB · 86 lines typescript
1/** Provider-neutral types used by the chat engine, router and UI. */23export type Provider = "openai" | "anthropic" | "local";45export type Capability = "text" | "vision" | "audioInput" | "audioOutput" | "imageGeneration" | "reasoning" | "tools" | "structuredOutput" | "streaming" | "longContext";6export type CapValue = boolean | "unknown";78export interface AIModel {9  id: string;10  provider: Provider;11  displayName: string;12  kind: string;13  api?: "responses" | "chat" | "messages" | null;14  status: "verified" | "unavailable" | "unsupported" | "untested";15  available: boolean;16  tested: boolean;17  unavailableReason?: string | null;18  capabilities: Partial<Record<Capability, CapValue>>;19  contextWindow?: number | null;20  maxOutputTokens?: number | null;21  pricing?: { input?: number; cachedInput?: number; output?: number; notes?: string; [k: string]: unknown } | null;22  benchmark?: {23    tests: number; passed: number; qualityScore: number | null; p50LatencyMs: number | null; p50TtftMs: number | null;24    totalCostUsd: number; avgOutputTokens: number | null; perTest: Record<string, "pass" | "fail" | "error">; errors: string[];25  } | null;26  hidden: boolean;27  favorite: boolean;28  lastVerifiedAt?: string | null;29}3031// ---------------------------------------------------------------- message parts (stored in messages.parts)32export type Part =33  | { type: "text"; text: string }34  | { type: "reasoning"; text: string; summarized?: boolean }35  | { type: "image"; attachmentId: string; mime: string; name?: string; url?: string }36  | { type: "file"; attachmentId: string; mime: string; name: string; size?: number; pages?: number }37  | { type: "tool_call"; id: string; name: string; input: unknown; status: "pending_approval" | "running" | "ok" | "error" | "denied"; output?: unknown; durationMs?: number; error?: string }38  | { type: "artifact"; artifactId: string; title: string; artifactType: string; language?: string }39  | { type: "citation"; url: string; title?: string; snippet?: string }40  | { type: "generated_image"; attachmentId: string; prompt: string; model: string };4142export type Role = "user" | "assistant" | "system" | "tool";4344export interface UnifiedMessage { role: Role; parts: Part[]; id?: string }4546export interface ToolDef {47  name: string;48  description: string;49  inputSchema: Record<string, unknown>; // JSON schema object50}5152export interface ChatSettings {53  effort?: "low" | "medium" | "high" | "xhigh" | "max";54  maxOutputTokens?: number;55  temperature?: number; // only honoured where the provider still accepts it56  reasoningSummary?: boolean;57  toolsEnabled?: string[];58}5960export interface ChatRequest {61  model: AIModel;62  system?: string;63  messages: UnifiedMessage[];64  tools?: ToolDef[];65  settings?: ChatSettings;66  signal?: AbortSignal;67  /** resolver for attachments referenced in parts → {bytes, mime} */68  loadAttachment: (id: string) => Promise<{ data: Buffer; mime: string; name: string; text?: string | null } | null>;69}7071export interface Usage { input: number; output: number; cached?: number; reasoning?: number }7273export type StreamEvent =74  | { type: "text"; delta: string }75  | { type: "reasoning"; delta: string }76  | { type: "tool_call"; id: string; name: string; input: unknown }77  | { type: "usage"; usage: Usage }78  | { type: "stop"; reason: string; details?: unknown }79  | { type: "error"; message: string; status?: number; retryable?: boolean }80  | { type: "meta"; data: Record<string, unknown> };8182export interface ProviderAdapter {83  provider: Provider;84  stream(req: ChatRequest): AsyncGenerator<StreamEvent, void, void>;85}86
Files · e271e75196f58c092c7f0be7ddb52ff27d11b54f
Menu

Theme