@deepstrike/sdk 0.2.69 → 0.2.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/index.d.ts +6 -1
  2. package/dist/index.js +2 -0
  3. package/dist/kernel.d.ts +7 -4
  4. package/dist/memory/protocols.d.ts +2 -2
  5. package/dist/providers/anthropic-adapter.d.ts +2 -2
  6. package/dist/providers/anthropic.d.ts +9 -5
  7. package/dist/providers/anthropic.js +20 -5
  8. package/dist/providers/base.d.ts +5 -5
  9. package/dist/providers/content-normalization.d.ts +4 -4
  10. package/dist/providers/gemini-adapter.d.ts +2 -2
  11. package/dist/providers/gemini.d.ts +8 -4
  12. package/dist/providers/gemini.js +20 -7
  13. package/dist/providers/ollama-adapter.d.ts +2 -2
  14. package/dist/providers/ollama.d.ts +6 -3
  15. package/dist/providers/ollama.js +14 -3
  16. package/dist/providers/openai-chat.d.ts +4 -4
  17. package/dist/providers/openai-responses-adapter.d.ts +2 -2
  18. package/dist/providers/openai-responses-adapter.js +1 -1
  19. package/dist/providers/openai-responses.d.ts +7 -3
  20. package/dist/providers/openai-responses.js +19 -6
  21. package/dist/providers/openai.d.ts +8 -5
  22. package/dist/providers/openai.js +14 -3
  23. package/dist/providers/prepared-request.d.ts +4 -0
  24. package/dist/providers/prepared-request.js +78 -0
  25. package/dist/providers/protocol-adapter.d.ts +2 -2
  26. package/dist/providers/replay-validator.d.ts +3 -3
  27. package/dist/providers/request-plan.d.ts +8 -1
  28. package/dist/providers/request-plan.js +4 -3
  29. package/dist/runtime/archive.d.ts +7 -7
  30. package/dist/runtime/canonical-kernel-step.d.ts +4 -3
  31. package/dist/runtime/canonical-kernel-step.js +17 -8
  32. package/dist/runtime/context.d.ts +28 -0
  33. package/dist/runtime/context.js +16 -0
  34. package/dist/runtime/eval.d.ts +2 -2
  35. package/dist/runtime/evolution.d.ts +195 -0
  36. package/dist/runtime/evolution.js +34 -0
  37. package/dist/runtime/execution-plane.d.ts +1 -1
  38. package/dist/runtime/kernel-step.d.ts +7 -6
  39. package/dist/runtime/provider-replay.d.ts +2 -2
  40. package/dist/runtime/provider-replay.js +1 -1
  41. package/dist/runtime/replay-fixture.d.ts +5 -5
  42. package/dist/runtime/replay-fixture.js +3 -3
  43. package/dist/runtime/replay-provider.d.ts +4 -4
  44. package/dist/runtime/replay-provider.js +1 -1
  45. package/dist/runtime/runner.d.ts +8 -6
  46. package/dist/runtime/runner.js +23 -6
  47. package/dist/runtime/session-log.d.ts +9 -4
  48. package/dist/runtime/session-log.js +3 -2
  49. package/dist/runtime/session-repair.d.ts +3 -4
  50. package/dist/runtime/session-repair.js +1 -4
  51. package/dist/runtime/verifiable-report.d.ts +2 -2
  52. package/dist/runtime/verifiable-report.js +2 -2
  53. package/dist/skills/loader.d.ts +1 -1
  54. package/dist/tools/index.d.ts +2 -2
  55. package/dist/types/agent.d.ts +5 -5
  56. package/dist/types.d.ts +20 -11
  57. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -51,6 +51,8 @@ export { FULL_FOOTPRINT_USAGE_ACCOUNTING_POLICY, providerAttemptToRecord } from
51
51
  export type { InvocationOutcome, ModelInvocation, ProviderAttempt, ProviderAttemptRecord, ProviderAttemptStatus, UsageAccountingPolicy, ModelUsageSettlement } from "./runtime/execution-evidence.js";
52
52
  export { VERIFIABLE_REPORT_SCHEMA, VERIFIABLE_FORK_SCHEMA, assertVerifiableReportSchema, createVerifiableRuntimeAdapter, createNativeVerifiableRuntimeAdapter, VerifiableOperation, } from "./runtime/verifiable-report.js";
53
53
  export type { VerifiableCommand, CheckVerdict, VerifiableForkManifest, ForkPlan, VerifiableEvidence, VerifyOptions, ReplayOptions, VerifiableRuntimeAdapter, VerifiableReport, VerifiableOperationJson, } from "./runtime/verifiable-report.js";
54
+ export { createEvolutionRuntimeAdapter, createNativeEvolutionRuntimeAdapter, EvolutionRuntime } from "./runtime/evolution.js";
55
+ export type { ActivationBinding, ArtifactKind, ArtifactManifest, ArtifactRef, ArtifactSet, ArtifactVersion, ContextEntryRef, ContextEntrySource, ContextExecutionInput, ContextPreparationRequest, ContextPlan, ContextPlanAction, ContextSelection, ContextState, EvaluationContextBinding, EvaluationFact, EvaluationGate, EvaluationMetric, EvaluationRun, EvolutionBundle, EvolutionProposal, EvolutionReport, EvolutionVerdict, EvolutionViolation, PromotionDecision, PromotionOutcome, EvolutionStore, } from "./runtime/evolution.js";
54
56
  export type { GovernancePolicy, GovernanceConstraint } from "./governance.js";
55
57
  export { AgentPool } from "./collaboration/pool.js";
56
58
  export { Agent } from "./agent.js";
@@ -63,7 +65,10 @@ export type { Knowledge, KnowledgeSourceRef } from "./knowledge/public.js";
63
65
  export type { AgentRef, Handoff } from "./handoff-target.js";
64
66
  export type { Session } from "./session.js";
65
67
  export type { RuntimeSignal, SignalClaim, SignalDeliveryReceipt, SignalSource, } from "./signals/types.js";
66
- export type { Message, ToolCall, ToolResult, ToolSchema, ContentPart, TextPart, ImagePart, AudioPart, MediaSource, ContentBlockText, ContentBlockImage, ContentBlockAudio, ContentBlockVideo, ContentBlockFile, StreamEvent, TextDelta, ThinkingDelta, ToolCallEvent, ToolChunk, ToolDeltaEvent, ToolSuspendEvent, ToolResultEvent, ToolAuditFailedEvent, DoneEvent, ErrorEvent, PermissionRequestEvent, PermissionResolvedEvent, PermissionResponse, EntropySample, EntropySampleEvent, EntropyAlertEvent, EntropyWatchOptions, LLMProvider, RetryConfig, TokenUsage, ProviderWireEvidence, ProviderTransportTelemetry, } from "./types.js";
68
+ export type { ProviderMessage, ToolCall, ToolExecutionResult, ToolSchema, ContentPart, TextPart, ImagePart, AudioPart, MediaSource, ContentBlockText, ContentBlockImage, ContentBlockAudio, ContentBlockVideo, ContentBlockFile, StreamEvent, TextDelta, ThinkingDelta, ToolCallEvent, ToolChunk, ToolDeltaEvent, ToolSuspendEvent, ToolResultEvent, ToolAuditFailedEvent, DoneEvent, ErrorEvent, PermissionRequestEvent, PermissionResolvedEvent, PermissionResponse, EntropySample, EntropySampleEvent, EntropyAlertEvent, EntropyWatchOptions, LLMProvider, RetryConfig, TokenUsage, ProviderWireEvidence, ProviderTransportTelemetry, } from "./types.js";
67
69
  export { DurableContentError, decodeDurableContent, decodeDurableToolResult, encodeDurableContent, encodeDurableToolResult, toolOutputBlocksToDurable, durableBlocksToToolOutput, } from "./runtime/durable-content.js";
68
70
  export type { DurableContent, DurableContentBlock, DurableSource, DurableToolResult } from "./runtime/durable-content.js";
69
71
  export type { WorkflowSpec, WorkflowNodeSpec, SchedulingFactors, WorkflowDependencyPolicy, WorkflowNodeStatus, WorkflowNodeOutcome, WorkflowOutcome, } from "./types/agent.js";
72
+ export { createContextPreparationAdapter, createNativeContextPreparationAdapter } from "./runtime/context.js";
73
+ export type { ContextPrepareJson, ContextVerifyJson, ContextPrepared, ContextProviderPreparationRequest } from "./runtime/context.js";
74
+ export type { PreparedProviderRequest } from "./types.js";
package/dist/index.js CHANGED
@@ -47,6 +47,7 @@ export { UnsupportedModalityError } from "./providers/base.js";
47
47
  export { createProviderRequestPlan, createProviderRequestPlanForProvider, estimateProviderPromptTokens, measurementForPlan, normalizeProviderUsage, priceProviderUsage, recordPromptMeasurement, resolveProviderRoute } from "./providers/request-plan.js";
48
48
  export { FULL_FOOTPRINT_USAGE_ACCOUNTING_POLICY, providerAttemptToRecord } from "./runtime/execution-evidence.js";
49
49
  export { VERIFIABLE_REPORT_SCHEMA, VERIFIABLE_FORK_SCHEMA, assertVerifiableReportSchema, createVerifiableRuntimeAdapter, createNativeVerifiableRuntimeAdapter, VerifiableOperation, } from "./runtime/verifiable-report.js";
50
+ export { createEvolutionRuntimeAdapter, createNativeEvolutionRuntimeAdapter, EvolutionRuntime } from "./runtime/evolution.js";
50
51
  // ── Multi-agent primitive ───────────────────────────────────────────────────
51
52
  // Parallel fan-out / sub-agent delegation. The full orchestration layer is in `@deepstrike/sdk/workflow`.
52
53
  export { AgentPool } from "./collaboration/pool.js";
@@ -54,3 +55,4 @@ export { AgentPool } from "./collaboration/pool.js";
54
55
  export { Agent } from "./agent.js";
55
56
  export { lowerAgent, normalizeAgent } from "./agent-ir.js";
56
57
  export { DurableContentError, decodeDurableContent, decodeDurableToolResult, encodeDurableContent, encodeDurableToolResult, toolOutputBlocksToDurable, durableBlocksToToolOutput, } from "./runtime/durable-content.js";
58
+ export { createContextPreparationAdapter, createNativeContextPreparationAdapter } from "./runtime/context.js";
package/dist/kernel.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Message } from "./types.js";
1
+ import type { ProviderMessage } from "./types.js";
2
2
  /**
3
3
  * M2 资源配额 — declarative resource limits enforced at the kernel's single syscall trap.
4
4
  *
@@ -141,8 +141,8 @@ export interface CanonicalKernelInstance {
141
141
  restore(checkpointBytes: Buffer | undefined, recordBytes: Buffer[]): CanonicalRestoreCost;
142
142
  lifecycle(): "created" | "configured" | "running" | "suspended" | "completed" | "cancelled" | "failed";
143
143
  pendingEffectsJson(): string;
144
- /** Canonical core projection; additive during the 0.2.62 migration. */
145
- currentProjectionJson(): string;
144
+ /** Canonical host projection selected by the core transaction. */
145
+ projectionJson(): string;
146
146
  projectPlannedStepJson(plannedStepJson: string): string;
147
147
  publishedEffectsManifestJson(plannedStepJson: string): string;
148
148
  terminalJson(): string | undefined;
@@ -150,10 +150,13 @@ export interface CanonicalKernelInstance {
150
150
  interface KernelModule {
151
151
  CanonicalKernel: new () => CanonicalKernelInstance;
152
152
  SignalRouter: new (maxQueueSize: number) => SignalRouterInstance;
153
- buildEvalMessages(goal: string, criteria: NativeCriterion[], result: string, attempt: number, extractSkillOnPass: boolean): Message[];
153
+ buildEvalMessages(goal: string, criteria: NativeCriterion[], result: string, attempt: number, extractSkillOnPass: boolean): ProviderMessage[];
154
154
  parseVerdict(content: string): Verdict;
155
155
  verdictOutputSchema(extractSkillOnPass: boolean): string;
156
156
  verifiableOperationJson(request: string): string;
157
+ evolutionValidateJson(request: string): string;
158
+ contextPrepareJson(request: string): string;
159
+ contextVerifyJson(request: string): string;
157
160
  }
158
161
  export declare function getKernel(): KernelModule;
159
162
  export {};
@@ -1,6 +1,6 @@
1
- import type { Message, ContentPart } from "../types.js";
1
+ import type { ProviderMessage, ContentPart } from "../types.js";
2
2
  export interface SessionMessage {
3
- role: Message["role"];
3
+ role: ProviderMessage["role"];
4
4
  content: string;
5
5
  /** Structured multimodal parts. Preserved for round-trip fidelity (e.g. tool result messages). */
6
6
  contentParts?: ContentPart[];
@@ -1,4 +1,4 @@
1
- import type { Message, ProviderReplay, ProviderUsage, ToolCall } from "../types.js";
1
+ import type { ProviderMessage, ProviderReplay, ProviderUsage, ToolCall } from "../types.js";
2
2
  import type { CanonicalAdapterInput } from "./content-normalization.js";
3
3
  import { type AdapterDecodeInput, type AdapterOutput, type AdapterStreamInput, type CanonicalStopReason, type ProtocolAdapter } from "./protocol-adapter.js";
4
4
  export declare const ANTHROPIC_TEXTUAL_TOOL_CALL_START_MARKER = "<\uFF5C\uFF5CDSML\uFF5C\uFF5Ctool_calls>";
@@ -47,7 +47,7 @@ export declare class AnthropicMessagesAdapter implements ProtocolAdapter<Anthrop
47
47
  readonly protocolCapabilities: import("./protocol-capabilities.js").ProtocolRuntimeCapabilities;
48
48
  buildRequest(input: CanonicalAdapterInput): AnthropicRequestPlan;
49
49
  decodeComplete(raw: Record<string, any>, decodeInput: AdapterDecodeInput): {
50
- message: Message;
50
+ message: ProviderMessage;
51
51
  replay?: ProviderReplay;
52
52
  };
53
53
  createStreamState(input: AdapterStreamInput): AnthropicStreamState;
@@ -1,4 +1,5 @@
1
- import type { LLMProvider, Message, PromptMeasurement, ProviderDescriptor, ProviderReplay, ProviderRunState, ProviderTransportTelemetry, RenderedContext, RuntimePolicy, StreamEvent, ToolSchema } from "../types.js";
1
+ import type { PreparedProviderRequest, ProviderRunState as PreparedRunState } from "../types.js";
2
+ import type { LLMProvider, ProviderMessage, PromptMeasurement, ProviderDescriptor, ProviderReplay, ProviderTransportTelemetry, RenderedContext, RuntimePolicy, StreamEvent, ToolSchema } from "../types.js";
2
3
  import { type CanonicalAdapterInput } from "./content-normalization.js";
3
4
  export interface AnthropicProviderConfig {
4
5
  apiKey: string;
@@ -34,14 +35,17 @@ export declare class AnthropicProvider implements LLMProvider {
34
35
  private lastTelemetry;
35
36
  peekTransportTelemetry(): ProviderTransportTelemetry | undefined;
36
37
  bindResolvedRuntime(resolved: ResolvedAnthropicRuntime): void;
37
- peekProviderReplay(message: Pick<Message, "content" | "toolCalls">): ProviderReplay | undefined;
38
- seedProviderReplay(message: Pick<Message, "content" | "toolCalls">, replay: ProviderReplay): void;
38
+ peekProviderReplay(message: Pick<ProviderMessage, "content" | "toolCalls">): ProviderReplay | undefined;
39
+ seedProviderReplay(message: Pick<ProviderMessage, "content" | "toolCalls">, replay: ProviderReplay): void;
39
40
  private adapterInput;
40
41
  private buildPlan;
41
- complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<Message>;
42
+ complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<ProviderMessage>;
42
43
  /** Native measurement belongs to the verified official endpoint, not the wire protocol. */
43
44
  countTokens(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<PromptMeasurement>;
44
- stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, _state?: ProviderRunState, signal?: AbortSignal): AsyncIterable<StreamEvent>;
45
+ private countPlan;
46
+ prepareRequest(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: PreparedRunState): PreparedProviderRequest;
47
+ stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: PreparedRunState, signal?: AbortSignal): AsyncIterable<StreamEvent>;
48
+ private streamPlan;
45
49
  private createMessage;
46
50
  private streamMessage;
47
51
  private buildSystem;
@@ -1,3 +1,4 @@
1
+ import { requestSnapshot } from "./prepared-request.js";
1
2
  import Anthropic from "@anthropic-ai/sdk";
2
3
  import { assistantReplayKey } from "../runtime/provider-replay.js";
3
4
  import { withServerRuntimeGuard } from "../runtime/server.js";
@@ -167,30 +168,44 @@ export class AnthropicProvider {
167
168
  }
168
169
  /** Native measurement belongs to the verified official endpoint, not the wire protocol. */
169
170
  async countTokens(context, tools, extensions) {
171
+ return this.countPlan(this.buildPlan(context, tools, extensions).plan);
172
+ }
173
+ async countPlan(plan) {
170
174
  const enabled = this.resolvedRuntime
171
175
  ? this.resolvedRuntime.effectiveCapabilities.nativeTokenCounting.state === "supported"
172
176
  : this.providerName() === "anthropic" && this.directNativeTokenCounting;
173
177
  if (!enabled) {
174
178
  throw new Error(`Native token counting is unavailable on ${this.providerName()} Anthropic-compatible endpoint`);
175
179
  }
176
- const { plan } = this.buildPlan(context, tools, extensions);
177
180
  const { model, system, messages, tools: requestTools } = plan.params;
178
- const response = await this.client.messages.countTokens({
181
+ const response = await this.client.messages.countTokens(requestSnapshot({
179
182
  model,
180
183
  ...(system ? { system } : {}),
181
184
  messages,
182
185
  ...(requestTools ? { tools: requestTools } : {}),
183
- });
186
+ }));
184
187
  return {
185
188
  inputTokens: response.input_tokens,
186
189
  source: { kind: "native", provider: "anthropic" },
187
190
  confidence: "exact",
188
191
  };
189
192
  }
190
- async *stream(context, tools, extensions, _state, signal) {
193
+ prepareRequest(context, tools, extensions, state) {
194
+ const { input, plan: built } = this.buildPlan(context, tools, extensions);
195
+ const plan = requestSnapshot(built);
196
+ plan.params.stream = true;
197
+ return {
198
+ scope: "encoded_body", request: requestSnapshot({ body: plan.params, transport: plan.transport }), state: requestSnapshot(state ?? null),
199
+ stream: signal => this.streamPlan(input, plan, signal),
200
+ countTokens: () => this.countPlan(plan),
201
+ };
202
+ }
203
+ async *stream(context, tools, extensions, state, signal) {
204
+ yield* this.prepareRequest(context, tools, extensions, state).stream(signal);
205
+ }
206
+ async *streamPlan(input, plan, signal) {
191
207
  const provider = this.providerName();
192
208
  try {
193
- const { input, plan } = this.buildPlan(context, tools, extensions);
194
209
  const state = this.adapter.createStreamState({ input });
195
210
  this.lastTelemetry = { rungs: 1 };
196
211
  for await (const chunk of this.streamMessage(plan.params, plan.transport, signal)) {
@@ -1,4 +1,4 @@
1
- import type { Message, RenderedContext } from "../types.js";
1
+ import type { ProviderMessage, RenderedContext } from "../types.js";
2
2
  export declare class CircuitBreaker {
3
3
  private readonly openAfter;
4
4
  private readonly resetAfter;
@@ -53,7 +53,7 @@ export declare class UnsupportedModalityError extends Error {
53
53
  readonly provider: string;
54
54
  constructor(modality: string, provider: string);
55
55
  }
56
- export declare function toAnthropicContent(msg: Message): string | Array<Record<string, unknown>>;
56
+ export declare function toAnthropicContent(msg: ProviderMessage): string | Array<Record<string, unknown>>;
57
57
  /**
58
58
  * History turns with the volatile State turn appended as the latest turn, for
59
59
  * providers that render it inline (OpenAI-family, Gemini, Ollama). Appending
@@ -64,14 +64,14 @@ export declare function toAnthropicContent(msg: Message): string | Array<Record<
64
64
  * AnthropicProvider.buildMessages). When `stateTurn` is absent (un-rebuilt
65
65
  * binding) the State turn is still inside `turns`, so this returns `turns` as-is.
66
66
  */
67
- export declare function turnsWithStateAppended(context: RenderedContext): Message[];
67
+ export declare function turnsWithStateAppended(context: RenderedContext): ProviderMessage[];
68
68
  /** Convert RenderedContext.turns to Anthropic messages array.
69
69
  * `turns` contains only user / assistant / tool roles — no system filtering needed. */
70
- export declare function toAnthropicMessages(turns: Message[], nativeReplay?: (message: Message) => Array<Record<string, unknown>> | undefined): Array<Record<string, unknown>>;
70
+ export declare function toAnthropicMessages(turns: ProviderMessage[], nativeReplay?: (message: ProviderMessage) => Array<Record<string, unknown>> | undefined): Array<Record<string, unknown>>;
71
71
  /** Map an audio MIME type to OpenAI's `input_audio.format` (accepts "mp3" | "wav").
72
72
  * `audio/mpeg` must become "mp3", not the raw "mpeg" subtype. */
73
73
  export declare function openaiAudioFormat(mediaType: string | undefined): string;
74
- export declare function toOpenAIContent(msg: Message): string | Array<Record<string, unknown>>;
74
+ export declare function toOpenAIContent(msg: ProviderMessage): string | Array<Record<string, unknown>>;
75
75
  /** Build the full OpenAI messages array from a RenderedContext.
76
76
  * Prepends systemText as the first system message, then converts turns. */
77
77
  export declare function toOpenAIMessageParams(context: RenderedContext): Array<Record<string, unknown>>;
@@ -1,4 +1,4 @@
1
- import type { Message, RenderedContext, ToolOutputBlock, ToolResultPart, ToolSchema, ToolCall, ProviderReplay } from "../types.js";
1
+ import type { ProviderMessage, RenderedContext, ToolOutputBlock, ToolResultPart, ToolSchema, ToolCall, ProviderReplay } from "../types.js";
2
2
  import type { ResolvedProviderRuntime } from "./model-registry.js";
3
3
  export declare class ContentValidationError extends Error {
4
4
  constructor(message: string);
@@ -16,7 +16,7 @@ export interface CanonicalToolResult {
16
16
  }
17
17
  export type CanonicalMessageBlock = ToolOutputBlock | CanonicalToolResult;
18
18
  export interface CanonicalMessage {
19
- readonly role: Message["role"];
19
+ readonly role: ProviderMessage["role"];
20
20
  readonly blocks: readonly CanonicalMessageBlock[];
21
21
  /** `blocks` remains authoritative; this only preserves an observable wire-shape distinction. */
22
22
  readonly contentForm?: "text" | "blocks";
@@ -43,7 +43,7 @@ export declare function projectToolOutputToText(blocks: readonly ToolOutputBlock
43
43
  export declare function normalizeToolResultPart(part: ToolResultPart): CanonicalToolResult;
44
44
  /** Attach process-local blocks only within the operation that produced them. */
45
45
  export declare function attachToolOutputOverlay(context: RenderedContext, overlay: ReadonlyMap<string, readonly ToolOutputBlock[]>): RenderedContext;
46
- export declare function normalizeCanonicalContext(context: RenderedContext, replayForMessage?: (message: Message) => ProviderReplay | undefined): CanonicalRenderedContext;
46
+ export declare function normalizeCanonicalContext(context: RenderedContext, replayForMessage?: (message: ProviderMessage) => ProviderReplay | undefined): CanonicalRenderedContext;
47
47
  /** Full-tree validation uses the resolved operation capabilities. Unknown stays unknown/fail-open. */
48
48
  export declare function validateCanonicalAdapterInput(input: CanonicalAdapterInput): void;
49
49
  export declare function normalizeCanonicalAdapterInput(input: {
@@ -51,6 +51,6 @@ export declare function normalizeCanonicalAdapterInput(input: {
51
51
  tools: readonly ToolSchema[];
52
52
  resolved: ResolvedProviderRuntime<unknown>;
53
53
  extensions?: Readonly<Record<string, unknown>>;
54
- replayForMessage?: (message: Message) => ProviderReplay | undefined;
54
+ replayForMessage?: (message: ProviderMessage) => ProviderReplay | undefined;
55
55
  }): CanonicalAdapterInput;
56
56
  export declare function normalizeToolResultContent(callId: string, output: string, isError: boolean, contentParts: readonly ToolOutputBlock[] | undefined): CanonicalToolResult;
@@ -1,5 +1,5 @@
1
1
  import type { Content, GenerateContentRequest, GenerateContentResponse, ModelParams, Tool } from "@google/generative-ai";
2
- import type { Message, ProviderUsage } from "../types.js";
2
+ import type { ProviderMessage, ProviderUsage } from "../types.js";
3
3
  import type { CanonicalAdapterInput } from "./content-normalization.js";
4
4
  import { type AdapterDecodeInput, type AdapterOutput, type AdapterStreamInput, type CanonicalStopReason, type ProtocolAdapter } from "./protocol-adapter.js";
5
5
  export interface GeminiRequestPlan {
@@ -23,7 +23,7 @@ export declare class GeminiAdapter implements ProtocolAdapter<GeminiRequestPlan,
23
23
  readonly protocolCapabilities: import("./protocol-capabilities.js").ProtocolRuntimeCapabilities;
24
24
  buildRequest(input: CanonicalAdapterInput): GeminiRequestPlan;
25
25
  decodeComplete(raw: GenerateContentResponse, _input: AdapterDecodeInput): {
26
- message: Message;
26
+ message: ProviderMessage;
27
27
  };
28
28
  createStreamState(input: AdapterStreamInput): GeminiStreamState;
29
29
  pushStreamChunk(chunk: GenerateContentResponse, state: GeminiStreamState): AdapterOutput;
@@ -1,8 +1,9 @@
1
+ import type { PreparedProviderRequest, ProviderRunState as PreparedRunState } from "../types.js";
1
2
  import { type Content } from "@google/generative-ai";
2
- import type { Message, RenderedContext, ToolSchema, StreamEvent, LLMProvider, RuntimePolicy, PromptMeasurement, ProviderTransportTelemetry } from "../types.js";
3
+ import type { ProviderMessage, RenderedContext, ToolSchema, StreamEvent, LLMProvider, RuntimePolicy, PromptMeasurement, ProviderTransportTelemetry } from "../types.js";
3
4
  import { type CanonicalAdapterInput } from "./content-normalization.js";
4
5
  type ResolvedGeminiRuntime = CanonicalAdapterInput["resolved"];
5
- export declare function buildContents(turns: Message[]): Content[];
6
+ export declare function buildContents(turns: ProviderMessage[]): Content[];
6
7
  export declare class GeminiProvider implements LLMProvider {
7
8
  private readonly model;
8
9
  private resolvedRuntime?;
@@ -23,14 +24,17 @@ export declare class GeminiProvider implements LLMProvider {
23
24
  runtimePolicy(): RuntimePolicy;
24
25
  bindResolvedRuntime(resolved: ResolvedGeminiRuntime): void;
25
26
  private adapterInput;
26
- complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<Message>;
27
- stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): AsyncIterable<StreamEvent>;
27
+ complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<ProviderMessage>;
28
+ prepareRequest(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: PreparedRunState): PreparedProviderRequest;
29
+ stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: PreparedRunState, signal?: AbortSignal): AsyncIterable<StreamEvent>;
30
+ private streamPlan;
28
31
  /**
29
32
  * spc_011-C-05: preflight native token count via `GenerativeModel.countTokens` — reuses the
30
33
  * same contents/tools/vendorConfig construction `complete()` uses so the counted request and
31
34
  * the sent request never diverge.
32
35
  */
33
36
  countTokens(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<PromptMeasurement>;
37
+ private countPlan;
34
38
  /**
35
39
  * Gemini vendor features from extensions, mapped to the Node SDK shape (mirrors the Python provider's
36
40
  * extension keys for a consistent cross-SDK API):
@@ -1,3 +1,4 @@
1
+ import { requestSnapshot } from "./prepared-request.js";
1
2
  import { GoogleGenerativeAI } from "@google/generative-ai";
2
3
  import { withServerRuntimeGuard } from "../runtime/server.js";
3
4
  import { CircuitBreaker } from "./base.js";
@@ -46,8 +47,8 @@ export class GeminiProvider {
46
47
  }
47
48
  adapterInput(context, tools, extensions) {
48
49
  if (!this.resolvedRuntime) {
49
- // Direct class construction is a published compatibility path. A-07 replaces it with
50
- // injected runtime profiles; until then this local descriptor contains no Registry lookup.
50
+ // Direct construction uses a local resolved profile when no registry binding was injected;
51
+ // this descriptor intentionally performs no Registry lookup.
51
52
  const resolved = {
52
53
  identity: {
53
54
  providerId: "gemini",
@@ -112,10 +113,20 @@ export class GeminiProvider {
112
113
  }
113
114
  throw classifyProviderError("gemini", lastErr);
114
115
  }
115
- async *stream(context, tools, extensions) {
116
+ prepareRequest(context, tools, extensions, state) {
117
+ const input = this.adapterInput(context, tools, extensions);
118
+ const plan = requestSnapshot(this.adapter.buildRequest(input));
119
+ return {
120
+ scope: "encoded_body", request: requestSnapshot(plan), state: requestSnapshot(state ?? null),
121
+ stream: signal => this.streamPlan(input, plan),
122
+ countTokens: () => this.countPlan(plan),
123
+ };
124
+ }
125
+ async *stream(context, tools, extensions, state, signal) {
126
+ yield* this.prepareRequest(context, tools, extensions, state).stream(signal);
127
+ }
128
+ async *streamPlan(input, plan) {
116
129
  try {
117
- const input = this.adapterInput(context, tools, extensions);
118
- const plan = this.adapter.buildRequest(input);
119
130
  const m = this.genAI.getGenerativeModel(plan.modelParams, this.requestOptions);
120
131
  const result = await m.generateContentStream(plan.request);
121
132
  const state = this.adapter.createStreamState({ input });
@@ -141,9 +152,11 @@ export class GeminiProvider {
141
152
  * the sent request never diverge.
142
153
  */
143
154
  async countTokens(context, tools, extensions) {
144
- const plan = this.adapter.buildRequest(this.adapterInput(context, tools, extensions));
155
+ return this.countPlan(this.adapter.buildRequest(this.adapterInput(context, tools, extensions)));
156
+ }
157
+ async countPlan(plan) {
145
158
  const m = this.genAI.getGenerativeModel(plan.modelParams, this.requestOptions);
146
- const resp = await m.countTokens(plan.request);
159
+ const resp = await m.countTokens(requestSnapshot(plan.request));
147
160
  return {
148
161
  inputTokens: resp.totalTokens,
149
162
  source: { kind: "native", provider: "gemini" },
@@ -1,4 +1,4 @@
1
- import type { Message, ProviderUsage } from "../types.js";
1
+ import type { ProviderMessage, ProviderUsage } from "../types.js";
2
2
  import type { CanonicalAdapterInput } from "./content-normalization.js";
3
3
  import { type AdapterDecodeInput, type AdapterOutput, type AdapterStreamInput, type CanonicalStopReason, type ProtocolAdapter } from "./protocol-adapter.js";
4
4
  export interface OllamaMessage {
@@ -54,7 +54,7 @@ export declare class OllamaAdapter implements ProtocolAdapter<OllamaRequest, Oll
54
54
  readonly protocolCapabilities: import("./protocol-capabilities.js").ProtocolRuntimeCapabilities;
55
55
  buildRequest(input: CanonicalAdapterInput): OllamaRequest;
56
56
  decodeComplete(raw: OllamaChunk, _input: AdapterDecodeInput): {
57
- message: Message;
57
+ message: ProviderMessage;
58
58
  };
59
59
  createStreamState(input: AdapterStreamInput): OllamaStreamState;
60
60
  pushStreamChunk(chunk: OllamaChunk, state: OllamaStreamState): AdapterOutput;
@@ -1,4 +1,5 @@
1
- import type { Message, RenderedContext, ToolSchema, StreamEvent, LLMProvider, RuntimePolicy, ProviderTransportTelemetry } from "../types.js";
1
+ import type { PreparedProviderRequest, ProviderRunState as PreparedRunState } from "../types.js";
2
+ import type { ProviderMessage, RenderedContext, ToolSchema, StreamEvent, LLMProvider, RuntimePolicy, ProviderTransportTelemetry } from "../types.js";
2
3
  import { type CanonicalAdapterInput } from "./content-normalization.js";
3
4
  type ResolvedOllamaRuntime = CanonicalAdapterInput["resolved"];
4
5
  export declare class OllamaProvider implements LLMProvider {
@@ -14,7 +15,9 @@ export declare class OllamaProvider implements LLMProvider {
14
15
  runtimePolicy(): RuntimePolicy;
15
16
  bindResolvedRuntime(resolved: ResolvedOllamaRuntime): void;
16
17
  private adapterInput;
17
- complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<Message>;
18
- stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): AsyncIterable<StreamEvent>;
18
+ complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<ProviderMessage>;
19
+ prepareRequest(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: PreparedRunState): PreparedProviderRequest;
20
+ stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: PreparedRunState, signal?: AbortSignal): AsyncIterable<StreamEvent>;
21
+ private streamPlan;
19
22
  }
20
23
  export {};
@@ -1,3 +1,4 @@
1
+ import { requestSnapshot } from "./prepared-request.js";
1
2
  import { normalizeCanonicalAdapterInput, } from "./content-normalization.js";
2
3
  import { endpointProfiles } from "./endpoints.js";
3
4
  import { OllamaAdapter } from "./ollama-adapter.js";
@@ -73,10 +74,20 @@ export class OllamaProvider {
73
74
  throw classifyProviderError("ollama", error);
74
75
  }
75
76
  }
76
- async *stream(context, tools, extensions) {
77
+ prepareRequest(context, tools, extensions, state) {
78
+ const input = this.adapterInput(context, tools, extensions);
79
+ const plan = requestSnapshot({ ...this.adapter.buildRequest(input), stream: true });
80
+ return {
81
+ scope: "encoded_body", request: requestSnapshot(plan), state: requestSnapshot(state ?? null),
82
+ stream: signal => this.streamPlan(input, plan),
83
+ };
84
+ }
85
+ async *stream(context, tools, extensions, state, signal) {
86
+ yield* this.prepareRequest(context, tools, extensions, state).stream(signal);
87
+ }
88
+ async *streamPlan(input, plan) {
77
89
  try {
78
- const input = this.adapterInput(context, tools, extensions);
79
- const body = { ...this.adapter.buildRequest(input), stream: true };
90
+ const body = plan;
80
91
  this.lastTelemetry = { rungs: 1 };
81
92
  const resp = await fetch(`${this.baseUrl}/api/chat`, {
82
93
  method: "POST",
@@ -1,5 +1,5 @@
1
1
  import type OpenAI from "openai";
2
- import type { Message, ProviderDescriptor, ProviderReplay, ProviderUsage, RenderedContext, ToolCall, ToolSchema } from "../types.js";
2
+ import type { ProviderMessage, ProviderDescriptor, ProviderReplay, ProviderUsage, RenderedContext, ToolCall, ToolSchema } from "../types.js";
3
3
  import { ThinkingTagStreamExtractor } from "./base.js";
4
4
  import type { CanonicalAdapterInput } from "./content-normalization.js";
5
5
  import { type ReplayabilityAssessment } from "./replay-validator.js";
@@ -41,7 +41,7 @@ export declare class OpenAIChatAdapter implements ProtocolAdapter<OpenAIChatRequ
41
41
  readonly protocolCapabilities: import("./protocol-capabilities.js").ProtocolRuntimeCapabilities;
42
42
  buildRequest(input: CanonicalAdapterInput, dialect?: OpenAIChatWireDialect): OpenAIChatRequestPlan;
43
43
  decodeComplete(raw: Record<string, any>, input: AdapterDecodeInput, dialect?: OpenAIChatWireDialect): {
44
- message: Message;
44
+ message: ProviderMessage;
45
45
  replay?: ProviderReplay;
46
46
  };
47
47
  createStreamState(input: AdapterStreamInput, dialect?: OpenAIChatWireDialect): OpenAIChatStreamState;
@@ -60,6 +60,6 @@ export declare class OpenAIChatAdapter implements ProtocolAdapter<OpenAIChatRequ
60
60
  buildMessages(context: RenderedContext, options?: OpenAIChatBuildMessageOptions): OpenAI.ChatCompletionMessageParam[];
61
61
  assessReasoning(context: RenderedContext): ReplayabilityAssessment;
62
62
  normalizeToolCalls(toolCalls?: OpenAI.ChatCompletionMessageToolCall[]): ToolCall[];
63
- rememberReplayFields(message: Pick<Message, "content" | "toolCalls">, fields: Record<string, unknown>): void;
64
- peekReplayFields(message: Pick<Message, "content" | "toolCalls">): Record<string, unknown> | undefined;
63
+ rememberReplayFields(message: Pick<ProviderMessage, "content" | "toolCalls">, fields: Record<string, unknown>): void;
64
+ peekReplayFields(message: Pick<ProviderMessage, "content" | "toolCalls">): Record<string, unknown> | undefined;
65
65
  }
@@ -1,4 +1,4 @@
1
- import type { Message, ProviderUsage, RenderedContext, ToolCall, ToolSchema } from "../types.js";
1
+ import type { ProviderMessage, ProviderUsage, RenderedContext, ToolCall, ToolSchema } from "../types.js";
2
2
  import type { CanonicalAdapterInput } from "./content-normalization.js";
3
3
  import { type AdapterDecodeInput, type AdapterOutput, type AdapterStreamInput, type CanonicalStopReason, type ProtocolAdapter } from "./protocol-adapter.js";
4
4
  export interface OpenAIResponsesRunState {
@@ -23,7 +23,7 @@ export declare class OpenAIResponsesAdapter implements ProtocolAdapter<OpenAIRes
23
23
  readonly protocolCapabilities: import("./protocol-capabilities.js").ProtocolRuntimeCapabilities;
24
24
  buildRequest(input: CanonicalAdapterInput, state?: OpenAIResponsesRunState): OpenAIResponsesRequestPlan;
25
25
  decodeComplete(raw: Record<string, any>, _input: AdapterDecodeInput): {
26
- message: Message;
26
+ message: ProviderMessage;
27
27
  };
28
28
  createStreamState(input: AdapterStreamInput, _state?: OpenAIResponsesRunState): OpenAIResponsesStreamState;
29
29
  pushStreamChunk(chunk: OpenAIResponsesStreamChunk, state: OpenAIResponsesStreamState): AdapterOutput;
@@ -312,7 +312,7 @@ export class OpenAIResponsesAdapter {
312
312
  return "content_filter";
313
313
  return "other";
314
314
  }
315
- // Published compatibility helpers retained while internally routing through canonical input.
315
+ // Framework adapter primitives used by the canonical request path.
316
316
  buildTools(tools) {
317
317
  return tools.map(tool => ({
318
318
  type: "function",
@@ -1,5 +1,6 @@
1
+ import type { PreparedProviderRequest, ProviderRunState as PreparedRunState } from "../types.js";
1
2
  import OpenAI from "openai";
2
- import type { LLMProvider, Message, PromptMeasurement, ProviderRunState, ProviderTransportTelemetry, RenderedContext, RuntimePolicy, StreamEvent, ToolSchema } from "../types.js";
3
+ import type { LLMProvider, ProviderMessage, PromptMeasurement, ProviderRunState, ProviderTransportTelemetry, RenderedContext, RuntimePolicy, StreamEvent, ToolSchema } from "../types.js";
3
4
  import { CircuitBreaker } from "./base.js";
4
5
  import { type CanonicalAdapterInput } from "./content-normalization.js";
5
6
  import { OpenAIResponsesAdapter, type OpenAIResponsesRunState } from "./openai-responses-adapter.js";
@@ -24,12 +25,15 @@ export declare class OpenAIResponsesProvider implements LLMProvider {
24
25
  bindResolvedRuntime(resolved: ResolvedOpenAIResponsesRuntime): void;
25
26
  createRunState(): OpenAIResponsesRunState;
26
27
  private adapterInput;
27
- complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<Message>;
28
+ complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<ProviderMessage>;
28
29
  /** spc_024-05: native preflight via the official Responses input-token count endpoint. Counts
29
30
  * the exact create request plan (stateful `previous_response_id` continuation included) —
30
31
  * native measurement belongs to the verified official endpoint, not the wire protocol. */
31
32
  countTokens(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: ProviderRunState): Promise<PromptMeasurement>;
32
- stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: ProviderRunState, signal?: AbortSignal): AsyncIterable<StreamEvent>;
33
+ private countPlan;
34
+ prepareRequest(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: PreparedRunState): PreparedProviderRequest;
35
+ stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: PreparedRunState, signal?: AbortSignal): AsyncIterable<StreamEvent>;
36
+ private streamPlan;
33
37
  private builtinTools;
34
38
  private requestExtensions;
35
39
  /** P4-S1: transport facts of the most recent execution. Host evidence only (B7). */
@@ -1,3 +1,4 @@
1
+ import { requestSnapshot } from "./prepared-request.js";
1
2
  import OpenAI from "openai";
2
3
  import { withServerRuntimeGuard } from "../runtime/server.js";
3
4
  import { CircuitBreaker } from "./base.js";
@@ -108,6 +109,9 @@ export class OpenAIResponsesProvider {
108
109
  * the exact create request plan (stateful `previous_response_id` continuation included) —
109
110
  * native measurement belongs to the verified official endpoint, not the wire protocol. */
110
111
  async countTokens(context, tools, extensions, state) {
112
+ return this.countPlan(this.responses.buildRequest(this.adapterInput(context, tools, extensions), this.asRunState(state)));
113
+ }
114
+ async countPlan(plan) {
111
115
  const enabled = this.resolvedRuntime
112
116
  ? this.resolvedRuntime.effectiveCapabilities.nativeTokenCounting.state === "supported"
113
117
  : this.directNativeTokenCounting;
@@ -115,23 +119,32 @@ export class OpenAIResponsesProvider {
115
119
  if (!enabled || typeof inputTokens?.count !== "function") {
116
120
  throw new Error("Native token counting is unavailable on this OpenAI-compatible endpoint");
117
121
  }
118
- const input = this.adapterInput(context, tools, extensions);
119
- const plan = this.responses.buildRequest(input, this.asRunState(state));
120
122
  const body = Object.fromEntries(INPUT_TOKEN_COUNT_PARAM_KEYS
121
123
  .filter(key => key in plan.params)
122
124
  .map(key => [key, plan.params[key]]));
123
- const response = await inputTokens.count(body);
125
+ const response = await inputTokens.count(requestSnapshot(body));
124
126
  return {
125
127
  inputTokens: response.input_tokens,
126
128
  source: { kind: "native", provider: "openai" },
127
129
  confidence: "exact",
128
130
  };
129
131
  }
132
+ prepareRequest(context, tools, extensions, state) {
133
+ const runState = requestSnapshot(this.asRunState(state));
134
+ const input = this.adapterInput(context, tools, extensions);
135
+ const plan = requestSnapshot(this.responses.buildRequest(input, runState));
136
+ plan.params.stream = true;
137
+ return {
138
+ scope: "encoded_body", request: requestSnapshot(plan.params), state: requestSnapshot(state ?? null),
139
+ stream: signal => this.streamPlan(input, plan, runState, state, signal),
140
+ countTokens: () => this.countPlan(plan),
141
+ };
142
+ }
130
143
  async *stream(context, tools, extensions, state, signal) {
144
+ yield* this.prepareRequest(context, tools, extensions, state).stream(signal);
145
+ }
146
+ async *streamPlan(input, plan, runState, state, signal) {
131
147
  try {
132
- const runState = this.asRunState(state);
133
- const input = this.adapterInput(context, tools, extensions);
134
- const plan = this.responses.buildRequest(input, runState);
135
148
  const streamState = this.responses.createStreamState({ input }, runState);
136
149
  const stream = await this.client.responses.create({ ...plan.params, stream: true }, signal ? { signal } : undefined);
137
150
  this.lastTelemetry = { rungs: 1 };
@@ -1,5 +1,6 @@
1
+ import type { PreparedProviderRequest, ProviderRunState as PreparedRunState } from "../types.js";
1
2
  import OpenAI from "openai";
2
- import type { LLMProvider, Message, ProviderDescriptor, ProviderReplay, ProviderRunState, ProviderTransportTelemetry, RenderedContext, ReplayabilityAssessment, RuntimePolicy, StreamEvent, ToolSchema } from "../types.js";
3
+ import type { LLMProvider, ProviderMessage, ProviderDescriptor, ProviderReplay, ProviderTransportTelemetry, RenderedContext, ReplayabilityAssessment, RuntimePolicy, StreamEvent, ToolSchema } from "../types.js";
3
4
  import { CircuitBreaker } from "./base.js";
4
5
  import { type CanonicalAdapterInput } from "./content-normalization.js";
5
6
  import { OpenAIChatAdapter } from "./openai-chat.js";
@@ -38,12 +39,14 @@ export declare class OpenAIChatProvider implements LLMProvider {
38
39
  /** P4-S1: transport facts of the most recent execution. Host evidence only (B7). */
39
40
  private lastTelemetry;
40
41
  peekTransportTelemetry(): ProviderTransportTelemetry | undefined;
41
- peekProviderReplay(message: Pick<Message, "content" | "toolCalls">): ProviderReplay | undefined;
42
- seedProviderReplay(message: Pick<Message, "content" | "toolCalls">, replay: ProviderReplay): void;
42
+ peekProviderReplay(message: Pick<ProviderMessage, "content" | "toolCalls">): ProviderReplay | undefined;
43
+ seedProviderReplay(message: Pick<ProviderMessage, "content" | "toolCalls">, replay: ProviderReplay): void;
43
44
  private rememberReplay;
44
45
  private adapterInput;
45
- complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<Message>;
46
- stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, _state?: ProviderRunState, signal?: AbortSignal): AsyncIterable<StreamEvent>;
46
+ complete(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>): Promise<ProviderMessage>;
47
+ prepareRequest(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: PreparedRunState): PreparedProviderRequest;
48
+ stream(context: RenderedContext, tools: ToolSchema[], extensions?: Record<string, unknown>, state?: PreparedRunState, signal?: AbortSignal): AsyncIterable<StreamEvent>;
49
+ private streamPlan;
47
50
  protected prepareExtensions(extensions?: Record<string, unknown>): Record<string, unknown>;
48
51
  protected requestBodyExtras(extensions?: Record<string, unknown>): Record<string, unknown>;
49
52
  protected serverTools(extensions?: Record<string, unknown>): unknown[];
@@ -1,3 +1,4 @@
1
+ import { requestSnapshot } from "./prepared-request.js";
1
2
  import OpenAI from "openai";
2
3
  import { assistantReplayKey } from "../runtime/provider-replay.js";
3
4
  import { withServerRuntimeGuard } from "../runtime/server.js";
@@ -164,11 +165,21 @@ export class OpenAIChatProvider {
164
165
  }
165
166
  throw classifyProviderError(provider, lastError);
166
167
  }
167
- async *stream(context, tools, extensions, _state, signal) {
168
+ prepareRequest(context, tools, extensions, state) {
169
+ const input = this.adapterInput(context, tools, extensions);
170
+ const plan = requestSnapshot(this.chat.buildRequest(input, this.dialect));
171
+ Object.assign(plan.params, { stream: true, stream_options: { include_usage: true } });
172
+ return {
173
+ scope: "encoded_body", request: requestSnapshot(plan.params), state: requestSnapshot(state ?? null),
174
+ stream: signal => this.streamPlan(input, plan, signal),
175
+ };
176
+ }
177
+ async *stream(context, tools, extensions, state, signal) {
178
+ yield* this.prepareRequest(context, tools, extensions, state).stream(signal);
179
+ }
180
+ async *streamPlan(input, plan, signal) {
168
181
  const provider = this.dialect.providerId;
169
182
  try {
170
- const input = this.adapterInput(context, tools, extensions);
171
- const plan = this.chat.buildRequest(input, this.dialect);
172
183
  const state = this.chat.createStreamState({ input }, this.dialect);
173
184
  const stream = await this.client.chat.completions.create({
174
185
  ...plan.params,
@@ -0,0 +1,4 @@
1
+ import type { LLMProvider, PreparedProviderRequest, ProviderRunState, RenderedContext, ToolSchema } from "../types.js";
2
+ /** JSON value snapshots sever aliases to mutable provider replay and continuation state. */
3
+ export declare function requestSnapshot<T>(value: T): T;
4
+ export declare function prepareProviderRequest(provider: LLMProvider, context: RenderedContext, tools: ToolSchema[], options?: Record<string, unknown>, state?: ProviderRunState): PreparedProviderRequest;