@opencow-ai/opencow-agent-sdk 0.4.13 → 0.4.14

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.
@@ -112,8 +112,10 @@ export interface SdkDiagnosticEvent {
112
112
  * across all providers).
113
113
  *
114
114
  * `source` mirrors the `source` argument that `buildFetch` already
115
- * accepts (e.g. `'main_loop'`, `'token_count'`) — lets the host
116
- * distinguish main-loop API calls from auxiliary ones.
115
+ * accepts (e.g. `'main_loop'`, `'count_tokens'`, `'agent:custom'`) —
116
+ * lets the host distinguish main-loop API calls from auxiliary and
117
+ * subagent ones. `endpoint` is a normalized route family such as
118
+ * `'messages'`, `'count_tokens'`, or `'responses'`.
117
119
  *
118
120
  * @stable
119
121
  */
@@ -123,18 +125,47 @@ export type SdkHttpEvent = {
123
125
  readonly method: string;
124
126
  readonly url: string;
125
127
  readonly source: string | undefined;
128
+ readonly endpoint?: string;
129
+ readonly attempt?: number;
130
+ readonly maxAttempts?: number;
126
131
  readonly timestamp: number;
127
132
  } | {
128
133
  readonly type: 'response_start';
129
134
  readonly requestId: string;
130
135
  readonly status: number;
131
136
  readonly durationMs: number;
137
+ readonly source?: string;
138
+ readonly endpoint?: string;
139
+ readonly attempt?: number;
140
+ readonly maxAttempts?: number;
141
+ readonly willRetry?: boolean;
142
+ readonly retryDelayMs?: number;
143
+ readonly failureReason?: string;
132
144
  readonly timestamp: number;
133
145
  } | {
134
146
  readonly type: 'error';
135
147
  readonly requestId: string;
136
148
  readonly error: Error;
137
149
  readonly durationMs: number;
150
+ readonly source?: string;
151
+ readonly endpoint?: string;
152
+ readonly attempt?: number;
153
+ readonly maxAttempts?: number;
154
+ readonly willRetry?: boolean;
155
+ readonly retryDelayMs?: number;
156
+ readonly failureReason?: string;
157
+ readonly status?: number;
158
+ readonly timestamp: number;
159
+ } | {
160
+ readonly type: 'retry';
161
+ readonly requestId?: string;
162
+ readonly source?: string;
163
+ readonly endpoint?: string;
164
+ readonly attempt: number;
165
+ readonly maxAttempts?: number;
166
+ readonly retryDelayMs: number;
167
+ readonly status?: number;
168
+ readonly failureReason: string;
138
169
  readonly timestamp: number;
139
170
  };
140
171
  /**
@@ -6,6 +6,7 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
6
  import type { CallToolResult, ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';
7
7
  import type { z } from 'zod/v4';
8
8
  import type { ExitReason, HookEvent, HookInput, SDKMessage, SDKResultMessage, SDKSessionInfo, SDKUserMessage, SyncHookJSONOutput } from './coreTypes.js';
9
+ export type { SDKMessage, SDKUserMessage } from './coreTypes.js';
9
10
  export type EffortLevel = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
10
11
  export type AnyZodRawShape = z.ZodRawShape;
11
12
  export type InferShape<Shape extends AnyZodRawShape = AnyZodRawShape> = z.infer<z.ZodObject<Shape>>;
@@ -170,10 +171,9 @@ export type Options = {
170
171
  contextWindow?: number;
171
172
  /**
172
173
  * Host-provided default reasoning effort for the selected model. This is
173
- * protocol-neutral: OpenAI Chat Completions serializes it as
174
- * `reasoning_effort`, while OpenAI Responses serializes it as
175
- * `reasoning.effort` and can still merge protocol-specific fields such as
176
- * `reasoning.summary`.
174
+ * protocol-neutral: providers serialize it into their native request shape,
175
+ * such as OpenAI Chat Completions `reasoning_effort` or OpenAI Responses
176
+ * `reasoning.effort`.
177
177
  *
178
178
  * Leave unset to preserve SDK/model defaults. Pass `null` on a per-turn
179
179
  * override to clear inherited or descriptor defaults. Hosts with an
@@ -182,6 +182,13 @@ export type Options = {
182
182
  * the SDK.
183
183
  */
184
184
  reasoningEffort?: ReasoningEffort | null;
185
+ /**
186
+ * Low-level request-body extension. Snake-case mirrors OpenAI-style clients
187
+ * that expose an `extra_body` escape hatch. Provider shims decide how to
188
+ * merge it into their wire body; the SDK does not validate provider-specific
189
+ * nested schemas here.
190
+ */
191
+ extra_body?: ExtraBody;
185
192
  /**
186
193
  * 本回合手动压缩上下文(对应 host 的 /compact)。设置后 SDK 复用 auto-compact
187
194
  * 机制(isAutoCompact=false + 这些指令)压缩当前消息、发出 system/compact_boundary,
@@ -323,10 +330,9 @@ export type Options = {
323
330
  * Explicit wire-level transport selection. When provided, overrides the
324
331
  * default base-URL / model-alias sniff in `resolveProviderTransport`.
325
332
  *
326
- * Hosts that proxy upstream providers through their own backend (e.g.
327
- * desktop-evose proxies api.openai.com via {host}/sdk/v1/responses)
328
- * MUST set this explicitly because the proxy URL does not match the
329
- * SDK's built-in Codex base URL detector.
333
+ * Hosts that proxy upstream providers through their own backend MUST set
334
+ * this explicitly because the proxy URL usually does not match the SDK's
335
+ * built-in provider detectors.
330
336
  *
331
337
  * - `'auto'` (default) — sniff baseUrl then model alias (legacy behavior)
332
338
  * - `'chat_completions'` — POST {baseUrl}/chat/completions (OpenAI Chat
@@ -341,12 +347,9 @@ export type Options = {
341
347
  /**
342
348
  * Host model → provider-route catalog, keyed by model id. Consulted AFTER
343
349
  * subagent model resolution (tier aliases / Agent tool `model` param), so
344
- * a subagent whose model lives on a different wire or endpoint than the
345
- * main session routes to its own baseURL/key/transport instead of
346
- * inheriting the session's (which 404s for cross-protocol tier models).
347
- * Models absent from the catalog use the session provider config as
348
- * before. Entries may carry `providerSpecific.openaiResponses` extras
349
- * applied when that model's request uses the openai_responses wire.
350
+ * a host can override a subagent model's baseURL/key/transport/reasoning
351
+ * defaults without changing the main session provider. Models absent from
352
+ * the catalog use the session provider config as before.
350
353
  */
351
354
  modelProviders?: ModelProviders;
352
355
  /**
@@ -474,6 +477,7 @@ export type InternalOptions = Options;
474
477
  export type SessionMutationOptions = {
475
478
  dir?: string;
476
479
  };
480
+ export type ExtraBody = Record<string, unknown>;
477
481
  export type GetSessionInfoOptions = SessionMutationOptions;
478
482
  export type ListSessionsOptions = SessionMutationOptions & {
479
483
  limit?: number;
@@ -62,7 +62,9 @@ export declare function convertMessages(messages: Array<{
62
62
  content?: unknown;
63
63
  };
64
64
  content?: unknown;
65
- }>, system: unknown): OpenAIMessage[];
65
+ }>, system: unknown, options?: {
66
+ replayReasoningContent?: boolean;
67
+ }): OpenAIMessage[];
66
68
  export declare function convertTools(tools: Array<{
67
69
  name: string;
68
70
  description?: string;
@@ -200,5 +202,6 @@ export declare function createOpenAIShimClient(options: {
200
202
  timeout?: number;
201
203
  reasoningEffort?: ReasoningEffort;
202
204
  providerOverride?: ProviderOverride;
205
+ source?: string;
203
206
  }): unknown;
204
207
  export {};
@@ -86,7 +86,7 @@ export interface Provider {
86
86
  /**
87
87
  * Construct the HTTP-level client that `services/api/claude.ts`
88
88
  * drives in its request pipeline. The returned object exposes the
89
- * Anthropic SDK's `beta.messages.create(...)` surface so
89
+ * Anthropic SDK's `messages.create(...)` surface so
90
90
  * `withRetry` and the main agent loop consume a uniform shape
91
91
  * regardless of Provider family.
92
92
  *
@@ -16,6 +16,7 @@ export type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | '
16
16
  * wire format. Renamed from `'codex_responses'` in 0.2.0 (alias retained
17
17
  * one version). ChatGPT-Codex vendor identity (isCodexBaseUrl /
18
18
  * CODEX_ALIAS_MODELS / DEFAULT_CODEX_BASE_URL) is orthogonal and preserved.
19
+ *
19
20
  */
20
21
  export type ProviderTransport = 'chat_completions' | 'openai_responses';
21
22
  /**
@@ -25,15 +26,15 @@ export type ProviderTransport = 'chat_completions' | 'openai_responses';
25
26
  export type DeprecatedProviderTransportName = 'codex_responses';
26
27
  /**
27
28
  * ALS-scoped env-var keys used to forward public `Options.transport` /
28
- * `Options.providerSpecific.openaiResponses` from `runSdkQueryRuntime` to
29
- * provider-side resolvers (`resolveProviderRequest`, `performCodexRequest`)
30
- * without threading new parameters through the deep call chain.
29
+ * `Options.providerSpecific.openaiResponses` / `Options.extra_body` from
30
+ * `runSdkQueryRuntime` to provider-side resolvers/shims without threading new
31
+ * parameters through the deep call chain.
31
32
  *
32
33
  * Pattern: identical to how `OPENAI_BASE_URL` is consumed via
33
34
  * `getQueryEnvVar` from inside `resolveProviderTransport`. The double
34
35
  * underscore prefix marks them as SDK-internal — hosts MUST NOT set these
35
36
  * directly in `Options.env`; use the typed `Options.transport` /
36
- * `Options.providerSpecific` fields instead.
37
+ * `Options.providerSpecific` / `Options.extra_body` fields instead.
37
38
  *
38
39
  * Why env-injection (vs signature plumbing): the call chain
39
40
  * `runSdkQueryRuntime` → `QueryEngine.ask` → `getNormalizedClient` →
@@ -48,6 +49,7 @@ export declare const QUERY_ENV_KEY_TRANSPORT_OVERRIDE = "__OPENCOW_TRANSPORT_OVE
48
49
  export declare const QUERY_ENV_KEY_REASONING_EFFORT_OVERRIDE = "__OPENCOW_REASONING_EFFORT_OVERRIDE";
49
50
  export declare const QUERY_ENV_VALUE_REASONING_EFFORT_CLEAR = "__OPENCOW_CLEAR_REASONING_EFFORT__";
50
51
  export declare const QUERY_ENV_KEY_PROVIDER_SPECIFIC_OPENAI_RESPONSES = "__OPENCOW_PROVIDER_SPECIFIC_OPENAI_RESPONSES";
52
+ export declare const QUERY_ENV_KEY_EXTRA_BODY = "__OPENCOW_EXTRA_BODY";
51
53
  export type ResolvedProviderRequest = {
52
54
  transport: ProviderTransport;
53
55
  requestedModel: string;
@@ -0,0 +1,5 @@
1
+ import type { SdkHttpEvent } from '../../entrypoints/sdk/logTypes.js';
2
+ export declare function classifyModelHttpEndpoint(url: string): string;
3
+ export declare function errorToFailureReason(error: unknown): string;
4
+ export declare function responseBodyToFailureReason(status: number, body: string): string;
5
+ export declare function emitSdkHttp(event: SdkHttpEvent): void;
@@ -0,0 +1 @@
1
+ export declare function mergeOpenAICompatibleExtraBodyParams(body: Record<string, unknown>, params: Record<string, unknown>): void;
@@ -8,17 +8,14 @@ import type { ProviderTransport, ReasoningEffort } from './config.js';
8
8
  export interface ProviderOverride {
9
9
  /** Model name to send to the API (e.g. "deepseek-chat", "gpt-4o") */
10
10
  model: string;
11
- /** Base URL. Optional — falls back to the session's OPENAI_BASE_URL env. */
11
+ /** Base URL. Optional — falls back to the session's provider env. */
12
12
  baseURL?: string;
13
13
  /** API key. Optional — falls back to the session's env credential chain. */
14
14
  apiKey?: string;
15
15
  /**
16
16
  * Wire transport for this override. Without it the session-level
17
- * transport/sniff applies which is exactly the cross-protocol subagent
18
- * bug: a tier model living on a different wire (e.g. openai_responses)
19
- * than the main session (chat_completions) hits the wrong endpoint and
20
- * 404s. 'anthropic' routes to the native Anthropic client instead of the
21
- * OpenAI shim.
17
+ * transport/sniff applies. 'anthropic' routes to the native Anthropic
18
+ * client; other values route to their matching shim.
22
19
  */
23
20
  transport?: ProviderTransport | 'anthropic';
24
21
  /** Default reasoning effort for this model route; null clears session default. */
@@ -32,9 +29,9 @@ export interface ProviderOverride {
32
29
  * Host-supplied model → provider-route catalog (`Options.modelProviders`).
33
30
  * Key is the model id as it appears after subagent model resolution (tier
34
31
  * env values / Agent tool `model` param). The host owns the model catalog
35
- * (which channel/protocol each model lives on); the SDK consults this AFTER
36
- * resolving a subagent's model so any resolution path — tier alias, explicit
37
- * model param, inherit — lands on the right wire.
32
+ * (which endpoint/defaults each model should use); the SDK consults this
33
+ * AFTER resolving a subagent's model so any resolution path — tier alias,
34
+ * explicit model param, inherit — can land on the right provider config.
38
35
  */
39
36
  export type ModelProviderConfig = Omit<ProviderOverride, 'model'>;
40
37
  export type ModelProviders = Record<string, ModelProviderConfig>;