@f5-sales-demo/pi-ai 19.51.2

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 (128) hide show
  1. package/CHANGELOG.md +1997 -0
  2. package/README.md +1160 -0
  3. package/package.json +135 -0
  4. package/src/api-registry.ts +95 -0
  5. package/src/auth-storage.ts +2694 -0
  6. package/src/cli.ts +493 -0
  7. package/src/index.ts +42 -0
  8. package/src/model-cache.ts +97 -0
  9. package/src/model-manager.ts +349 -0
  10. package/src/model-thinking.ts +561 -0
  11. package/src/models.json +49439 -0
  12. package/src/models.json.d.ts +9 -0
  13. package/src/models.ts +56 -0
  14. package/src/prompts/turn-aborted-guidance.md +4 -0
  15. package/src/provider-details.ts +81 -0
  16. package/src/provider-models/descriptors.ts +285 -0
  17. package/src/provider-models/google.ts +90 -0
  18. package/src/provider-models/index.ts +4 -0
  19. package/src/provider-models/openai-compat.ts +2074 -0
  20. package/src/provider-models/special.ts +106 -0
  21. package/src/providers/amazon-bedrock.ts +706 -0
  22. package/src/providers/anthropic.ts +1682 -0
  23. package/src/providers/azure-openai-responses.ts +391 -0
  24. package/src/providers/cursor/gen/agent_pb.ts +15274 -0
  25. package/src/providers/cursor/proto/agent.proto +3526 -0
  26. package/src/providers/cursor/proto/buf.gen.yaml +6 -0
  27. package/src/providers/cursor/proto/buf.yaml +17 -0
  28. package/src/providers/cursor.ts +2218 -0
  29. package/src/providers/github-copilot-headers.ts +140 -0
  30. package/src/providers/gitlab-duo.ts +381 -0
  31. package/src/providers/google-gemini-cli.ts +1133 -0
  32. package/src/providers/google-shared.ts +354 -0
  33. package/src/providers/google-vertex.ts +436 -0
  34. package/src/providers/google.ts +381 -0
  35. package/src/providers/kimi.ts +151 -0
  36. package/src/providers/openai-codex/constants.ts +43 -0
  37. package/src/providers/openai-codex/request-transformer.ts +158 -0
  38. package/src/providers/openai-codex/response-handler.ts +81 -0
  39. package/src/providers/openai-codex-responses.ts +2345 -0
  40. package/src/providers/openai-completions-compat.ts +159 -0
  41. package/src/providers/openai-completions.ts +1290 -0
  42. package/src/providers/openai-responses-shared.ts +452 -0
  43. package/src/providers/openai-responses.ts +519 -0
  44. package/src/providers/register-builtins.ts +329 -0
  45. package/src/providers/synthetic.ts +154 -0
  46. package/src/providers/transform-messages.ts +234 -0
  47. package/src/rate-limit-utils.ts +84 -0
  48. package/src/stream.ts +728 -0
  49. package/src/types.ts +546 -0
  50. package/src/usage/claude.ts +337 -0
  51. package/src/usage/gemini.ts +248 -0
  52. package/src/usage/github-copilot.ts +421 -0
  53. package/src/usage/google-antigravity.ts +200 -0
  54. package/src/usage/kimi.ts +286 -0
  55. package/src/usage/minimax-code.ts +31 -0
  56. package/src/usage/openai-codex.ts +387 -0
  57. package/src/usage/zai.ts +247 -0
  58. package/src/usage.ts +130 -0
  59. package/src/utils/abort.ts +36 -0
  60. package/src/utils/anthropic-auth.ts +293 -0
  61. package/src/utils/discovery/antigravity.ts +261 -0
  62. package/src/utils/discovery/codex.ts +371 -0
  63. package/src/utils/discovery/cursor.ts +306 -0
  64. package/src/utils/discovery/gemini.ts +248 -0
  65. package/src/utils/discovery/index.ts +5 -0
  66. package/src/utils/discovery/openai-compatible.ts +224 -0
  67. package/src/utils/event-stream.ts +209 -0
  68. package/src/utils/http-inspector.ts +165 -0
  69. package/src/utils/idle-iterator.ts +176 -0
  70. package/src/utils/json-parse.ts +28 -0
  71. package/src/utils/oauth/alibaba-coding-plan.ts +59 -0
  72. package/src/utils/oauth/anthropic.ts +134 -0
  73. package/src/utils/oauth/api-key-validation.ts +92 -0
  74. package/src/utils/oauth/callback-server.ts +276 -0
  75. package/src/utils/oauth/cerebras.ts +59 -0
  76. package/src/utils/oauth/cloudflare-ai-gateway.ts +48 -0
  77. package/src/utils/oauth/cursor.ts +157 -0
  78. package/src/utils/oauth/github-copilot.ts +358 -0
  79. package/src/utils/oauth/gitlab-duo.ts +123 -0
  80. package/src/utils/oauth/google-antigravity.ts +275 -0
  81. package/src/utils/oauth/google-gemini-cli.ts +334 -0
  82. package/src/utils/oauth/huggingface.ts +62 -0
  83. package/src/utils/oauth/index.ts +512 -0
  84. package/src/utils/oauth/kagi.ts +47 -0
  85. package/src/utils/oauth/kilo.ts +87 -0
  86. package/src/utils/oauth/kimi.ts +251 -0
  87. package/src/utils/oauth/litellm.ts +81 -0
  88. package/src/utils/oauth/lm-studio.ts +40 -0
  89. package/src/utils/oauth/minimax-code.ts +78 -0
  90. package/src/utils/oauth/moonshot.ts +59 -0
  91. package/src/utils/oauth/nanogpt.ts +51 -0
  92. package/src/utils/oauth/nvidia.ts +70 -0
  93. package/src/utils/oauth/oauth.html +199 -0
  94. package/src/utils/oauth/ollama.ts +47 -0
  95. package/src/utils/oauth/openai-codex.ts +190 -0
  96. package/src/utils/oauth/opencode.ts +49 -0
  97. package/src/utils/oauth/parallel.ts +46 -0
  98. package/src/utils/oauth/perplexity.ts +200 -0
  99. package/src/utils/oauth/pkce.ts +18 -0
  100. package/src/utils/oauth/qianfan.ts +58 -0
  101. package/src/utils/oauth/qwen-portal.ts +60 -0
  102. package/src/utils/oauth/synthetic.ts +60 -0
  103. package/src/utils/oauth/tavily.ts +46 -0
  104. package/src/utils/oauth/together.ts +59 -0
  105. package/src/utils/oauth/types.ts +89 -0
  106. package/src/utils/oauth/venice.ts +59 -0
  107. package/src/utils/oauth/vercel-ai-gateway.ts +47 -0
  108. package/src/utils/oauth/vllm.ts +40 -0
  109. package/src/utils/oauth/xiaomi.ts +88 -0
  110. package/src/utils/oauth/zai.ts +60 -0
  111. package/src/utils/oauth/zenmux.ts +51 -0
  112. package/src/utils/overflow.ts +134 -0
  113. package/src/utils/retry-after.ts +110 -0
  114. package/src/utils/retry.ts +93 -0
  115. package/src/utils/schema/CONSTRAINTS.md +160 -0
  116. package/src/utils/schema/adapt.ts +20 -0
  117. package/src/utils/schema/compatibility.ts +397 -0
  118. package/src/utils/schema/dereference.ts +93 -0
  119. package/src/utils/schema/equality.ts +93 -0
  120. package/src/utils/schema/fields.ts +147 -0
  121. package/src/utils/schema/index.ts +9 -0
  122. package/src/utils/schema/normalize-cca.ts +479 -0
  123. package/src/utils/schema/sanitize-google.ts +212 -0
  124. package/src/utils/schema/strict-mode.ts +385 -0
  125. package/src/utils/schema/types.ts +5 -0
  126. package/src/utils/tool-choice.ts +81 -0
  127. package/src/utils/validation.ts +664 -0
  128. package/src/utils.ts +147 -0
package/src/types.ts ADDED
@@ -0,0 +1,546 @@
1
+ import type { TSchema } from "@sinclair/typebox";
2
+ import type { BedrockOptions } from "./providers/amazon-bedrock";
3
+ import type { AnthropicOptions } from "./providers/anthropic";
4
+ import type { AzureOpenAIResponsesOptions } from "./providers/azure-openai-responses";
5
+ import type { CursorOptions } from "./providers/cursor";
6
+ import type {
7
+ DeleteArgs,
8
+ DeleteResult,
9
+ DiagnosticsArgs,
10
+ DiagnosticsResult,
11
+ GrepArgs,
12
+ GrepResult,
13
+ LsArgs,
14
+ LsResult,
15
+ McpResult,
16
+ ReadArgs,
17
+ ReadResult,
18
+ ShellArgs,
19
+ ShellResult,
20
+ WriteArgs,
21
+ WriteResult,
22
+ } from "./providers/cursor/gen/agent_pb";
23
+ import type { GoogleOptions } from "./providers/google";
24
+ import type { GoogleGeminiCliOptions } from "./providers/google-gemini-cli";
25
+ import type { GoogleVertexOptions } from "./providers/google-vertex";
26
+ import type { OpenAICodexResponsesOptions } from "./providers/openai-codex-responses";
27
+ import type { OpenAICompletionsOptions } from "./providers/openai-completions";
28
+ import type { OpenAIResponsesOptions } from "./providers/openai-responses";
29
+ import type { AssistantMessageEventStream } from "./utils/event-stream";
30
+
31
+ export type { AssistantMessageEventStream } from "./utils/event-stream";
32
+
33
+ export type KnownApi =
34
+ | "openai-completions"
35
+ | "openai-responses"
36
+ | "openai-codex-responses"
37
+ | "azure-openai-responses"
38
+ | "anthropic-messages"
39
+ | "bedrock-converse-stream"
40
+ | "google-generative-ai"
41
+ | "google-gemini-cli"
42
+ | "google-vertex"
43
+ | "cursor-agent";
44
+ export type Api = KnownApi | (string & {});
45
+ export interface ApiOptionsMap {
46
+ "anthropic-messages": AnthropicOptions;
47
+ "bedrock-converse-stream": BedrockOptions;
48
+ "openai-completions": OpenAICompletionsOptions;
49
+ "openai-responses": OpenAIResponsesOptions;
50
+ "openai-codex-responses": OpenAICodexResponsesOptions;
51
+ "azure-openai-responses": AzureOpenAIResponsesOptions;
52
+ "google-generative-ai": GoogleOptions;
53
+ "google-gemini-cli": GoogleGeminiCliOptions;
54
+ "google-vertex": GoogleVertexOptions;
55
+ "cursor-agent": CursorOptions;
56
+ }
57
+ // Compile-time exhaustiveness check - this will fail if ApiOptionsMap doesn't have all KnownApi keys
58
+ type _CheckExhaustive =
59
+ ApiOptionsMap extends Record<KnownApi, StreamOptions>
60
+ ? Record<KnownApi, StreamOptions> extends ApiOptionsMap
61
+ ? true
62
+ : ["ApiOptionsMap is missing some KnownApi values", Exclude<KnownApi, keyof ApiOptionsMap>]
63
+ : ["ApiOptionsMap doesn't extend Record<KnownApi, StreamOptions>"];
64
+ const _exhaustive: _CheckExhaustive = true;
65
+ export type OptionsForApi<TApi extends Api> =
66
+ | StreamOptions
67
+ | (TApi extends keyof ApiOptionsMap ? ApiOptionsMap[TApi] : never);
68
+
69
+ /** Canonical thinking transport used by a model. */
70
+ export type ThinkingControlMode =
71
+ | "effort"
72
+ | "budget"
73
+ | "google-level"
74
+ | "anthropic-adaptive"
75
+ | "anthropic-budget-effort";
76
+
77
+ /** Per-model thinking capabilities used to clamp and map user-facing effort levels. */
78
+ export interface ThinkingConfig {
79
+ /** Least intensive supported user-facing effort level. */
80
+ minLevel: Effort;
81
+ /** Most intensive supported user-facing effort level. */
82
+ maxLevel: Effort;
83
+ /** Provider-specific transport used to encode the selected effort. */
84
+ mode: ThinkingControlMode;
85
+ }
86
+
87
+ export type KnownProvider =
88
+ | "alibaba-coding-plan"
89
+ | "amazon-bedrock"
90
+ | "anthropic"
91
+ | "google"
92
+ | "google-gemini-cli"
93
+ | "google-antigravity"
94
+ | "google-vertex"
95
+ | "openai"
96
+ | "openai-codex"
97
+ | "kimi-code"
98
+ | "minimax-code"
99
+ | "minimax-code-cn"
100
+ | "github-copilot"
101
+ | "gitlab-duo"
102
+ | "cursor"
103
+ | "xai"
104
+ | "groq"
105
+ | "cerebras"
106
+ | "openrouter"
107
+ | "kilo"
108
+ | "vercel-ai-gateway"
109
+ | "zai"
110
+ | "mistral"
111
+ | "minimax"
112
+ | "opencode-go"
113
+ | "opencode-zen"
114
+ | "synthetic"
115
+ | "cloudflare-ai-gateway"
116
+ | "huggingface"
117
+ | "litellm"
118
+ | "moonshot"
119
+ | "nvidia"
120
+ | "nanogpt"
121
+ | "ollama"
122
+ | "qianfan"
123
+ | "qwen-portal"
124
+ | "together"
125
+ | "venice"
126
+ | "vllm"
127
+ | "xiaomi"
128
+ | "zenmux"
129
+ | "lm-studio";
130
+ export type Provider = KnownProvider | string;
131
+
132
+ import type { Effort } from "./model-thinking";
133
+
134
+ /** Token budgets for each thinking level (token-based providers only) */
135
+ export type ThinkingBudgets = { [key in Effort]?: number };
136
+
137
+ export type MessageAttribution = "user" | "agent";
138
+
139
+ export type ToolChoice =
140
+ | "auto"
141
+ | "none"
142
+ | "any"
143
+ | "required"
144
+ | { type: "function"; name: string }
145
+ | { type: "function"; function: { name: string } }
146
+ | { type: "tool"; name: string };
147
+
148
+ // Base options all providers share
149
+ export type CacheRetention = "none" | "short" | "long";
150
+
151
+ /** OpenAI service tier for processing priority. Only applies to OpenAI-compatible APIs. */
152
+ export type ServiceTier = "auto" | "default" | "flex" | "scale" | "priority";
153
+
154
+ export function isSpecialServiceTier(serviceTier?: ServiceTier | null): serviceTier is "flex" | "scale" | "priority" {
155
+ return serviceTier === "flex" || serviceTier === "scale" || serviceTier === "priority";
156
+ }
157
+
158
+ export interface ProviderSessionState {
159
+ close(): void;
160
+ }
161
+
162
+ export interface StreamOptions {
163
+ temperature?: number;
164
+ topP?: number;
165
+ topK?: number;
166
+ minP?: number;
167
+ presencePenalty?: number;
168
+ repetitionPenalty?: number;
169
+ maxTokens?: number;
170
+ signal?: AbortSignal;
171
+ apiKey?: string;
172
+ cacheRetention?: CacheRetention;
173
+ /**
174
+ * Additional headers to include in provider requests.
175
+ * These are merged on top of model-defined headers.
176
+ */
177
+ headers?: Record<string, string>;
178
+ /**
179
+ * Optional explicit request attribution override for providers that support it.
180
+ */
181
+ initiatorOverride?: MessageAttribution;
182
+ /**
183
+ * Maximum delay in milliseconds to wait for a retry when the server requests a long wait.
184
+ * If the server's requested delay exceeds this value, the request fails immediately
185
+ * with an error containing the requested delay, allowing higher-level retry logic
186
+ * to handle it with user visibility.
187
+ * Default: 60000 (60 seconds). Set to 0 to disable the cap.
188
+ */
189
+ maxRetryDelayMs?: number;
190
+ /**
191
+ * Optional metadata to include in API requests.
192
+ * Providers extract the fields they understand and ignore the rest.
193
+ * For example, Anthropic uses `user_id` for abuse tracking and rate limiting.
194
+ */
195
+ metadata?: Record<string, unknown>;
196
+ /**
197
+ * Optional session identifier for providers that support session-based caching.
198
+ * Providers can use this to enable prompt caching, request routing, or other
199
+ * session-aware features. Ignored by providers that don't support it.
200
+ */
201
+ sessionId?: string;
202
+ /**
203
+ * Provider-scoped mutable state store for this agent session.
204
+ * Providers can use this to persist transport/session state between turns.
205
+ */
206
+ providerSessionState?: Map<string, ProviderSessionState>;
207
+ /**
208
+ * Optional callback for inspecting or replacing provider payloads before sending.
209
+ * Return undefined to keep the payload unchanged.
210
+ */
211
+ onPayload?: (payload: unknown, model?: Model<Api>) => unknown | undefined | Promise<unknown | undefined>;
212
+ /**
213
+ * Optional override for the first streamed event watchdog in milliseconds.
214
+ * Set to 0 to disable the first-event watchdog for this request.
215
+ */
216
+ streamFirstEventTimeoutMs?: number;
217
+ /** Cursor exec/MCP tool handlers (cursor-agent only). */
218
+ execHandlers?: CursorExecHandlers;
219
+ }
220
+
221
+ // Unified options with reasoning passed to streamSimple() and completeSimple()
222
+ export interface SimpleStreamOptions extends StreamOptions {
223
+ reasoning?: Effort;
224
+ /** Custom token budgets for thinking levels (token-based providers only) */
225
+ thinkingBudgets?: ThinkingBudgets;
226
+ /** Cursor exec handlers for local tool execution */
227
+ cursorExecHandlers?: CursorExecHandlers;
228
+ /** Hook to handle tool results from Cursor exec */
229
+ cursorOnToolResult?: CursorToolResultHandler;
230
+ /** Optional tool choice override for compatible providers */
231
+ toolChoice?: ToolChoice;
232
+ /** OpenAI service tier for processing priority/cost control. Ignored by non-OpenAI providers. */
233
+ serviceTier?: ServiceTier;
234
+ /** API format for Kimi Code provider: "openai" or "anthropic" (default: "anthropic") */
235
+ kimiApiFormat?: "openai" | "anthropic";
236
+ /** API format for Synthetic provider: "openai" or "anthropic" (default: "openai") */
237
+ syntheticApiFormat?: "openai" | "anthropic";
238
+ /** Hint that websocket transport should be preferred when supported by the provider implementation. */
239
+ preferWebsockets?: boolean;
240
+ }
241
+
242
+ // Generic StreamFunction with typed options
243
+ export type StreamFunction<TApi extends Api> = (
244
+ model: Model<TApi>,
245
+ context: Context,
246
+ options: OptionsForApi<TApi>,
247
+ ) => AssistantMessageEventStream;
248
+
249
+ export interface TextSignatureV1 {
250
+ v: 1;
251
+ id: string;
252
+ phase?: "commentary" | "final_answer";
253
+ }
254
+
255
+ export interface TextContent {
256
+ type: "text";
257
+ text: string;
258
+ textSignature?: string; // e.g., for OpenAI responses, message metadata (legacy id string or TextSignatureV1 JSON)
259
+ }
260
+
261
+ export interface ThinkingContent {
262
+ type: "thinking";
263
+ thinking: string;
264
+ thinkingSignature?: string; // e.g., for OpenAI responses, the reasoning item ID
265
+ }
266
+
267
+ export interface RedactedThinkingContent {
268
+ type: "redactedThinking";
269
+ data: string;
270
+ }
271
+
272
+ export interface ImageContent {
273
+ type: "image";
274
+ data: string; // base64 encoded image data
275
+ mimeType: string; // e.g., "image/jpeg", "image/png"
276
+ }
277
+
278
+ export interface ToolCall {
279
+ type: "toolCall";
280
+ id: string;
281
+ name: string;
282
+ arguments: Record<string, any>;
283
+ thoughtSignature?: string; // Google-specific: opaque signature for reusing thought context
284
+ intent?: string; // Harness-level intent metadata extracted from traced tool arguments
285
+ }
286
+
287
+ export interface Usage {
288
+ input: number;
289
+ output: number;
290
+ cacheRead: number;
291
+ cacheWrite: number;
292
+ totalTokens: number;
293
+ premiumRequests?: number;
294
+ cost: {
295
+ input: number;
296
+ output: number;
297
+ cacheRead: number;
298
+ cacheWrite: number;
299
+ total: number;
300
+ };
301
+ }
302
+
303
+ export type StopReason = "stop" | "length" | "toolUse" | "error" | "aborted";
304
+
305
+ export interface OpenAIResponsesHistoryPayload {
306
+ type: "openaiResponsesHistory";
307
+ provider?: string;
308
+ dt?: boolean;
309
+ items: Array<Record<string, unknown>>;
310
+ }
311
+
312
+ export type ProviderPayload = OpenAIResponsesHistoryPayload;
313
+
314
+ export interface UserMessage {
315
+ role: "user";
316
+ content: string | (TextContent | ImageContent)[];
317
+ /** True if the message was injected by the system (e.g., auto-continue). */
318
+ synthetic?: boolean;
319
+ /** Who initiated this message for billing/attribution semantics. */
320
+ attribution?: MessageAttribution;
321
+ /** Provider-specific opaque payload used to reconstruct transport-native history. */
322
+ providerPayload?: ProviderPayload;
323
+ timestamp: number; // Unix timestamp in milliseconds
324
+ }
325
+
326
+ export interface DeveloperMessage {
327
+ role: "developer";
328
+ content: string | (TextContent | ImageContent)[];
329
+ /** Who initiated this message for billing/attribution semantics. */
330
+ attribution?: MessageAttribution;
331
+ /** Provider-specific opaque payload used to reconstruct transport-native history. */
332
+ providerPayload?: ProviderPayload;
333
+ timestamp: number; // Unix timestamp in milliseconds
334
+ }
335
+
336
+ export interface AssistantMessage {
337
+ role: "assistant";
338
+ content: (TextContent | ThinkingContent | RedactedThinkingContent | ToolCall)[];
339
+ api: Api;
340
+ provider: Provider;
341
+ model: string;
342
+ responseId?: string; // Provider-specific response/message identifier when the upstream API exposes one
343
+ usage: Usage;
344
+ stopReason: StopReason;
345
+ errorMessage?: string;
346
+ /** Provider-specific opaque payload used to reconstruct transport-native history. */
347
+ providerPayload?: ProviderPayload;
348
+ timestamp: number; // Unix timestamp in milliseconds
349
+ duration?: number; // Request duration in milliseconds
350
+ ttft?: number; // Time to first token in milliseconds
351
+ }
352
+
353
+ export interface ToolResultMessage<TDetails = any> {
354
+ role: "toolResult";
355
+ toolCallId: string;
356
+ toolName: string;
357
+ content: (TextContent | ImageContent)[]; // Supports text and images
358
+ details?: TDetails;
359
+ isError: boolean;
360
+ /** Set when the tool completed normally but produced a degraded or empty result. */
361
+ isWarning?: boolean;
362
+ /** Who initiated this message for billing/attribution semantics. */
363
+ attribution?: MessageAttribution;
364
+ /** Timestamp when output was pruned (ms since epoch). Undefined if unpruned. */
365
+ prunedAt?: number;
366
+ timestamp: number; // Unix timestamp in milliseconds
367
+ }
368
+
369
+ export type Message = UserMessage | DeveloperMessage | AssistantMessage | ToolResultMessage;
370
+
371
+ export type CursorExecHandlerResult<T> = { result: T; toolResult?: ToolResultMessage } | T | ToolResultMessage;
372
+
373
+ export type CursorToolResultHandler = (
374
+ result: ToolResultMessage,
375
+ ) => ToolResultMessage | undefined | Promise<ToolResultMessage | undefined>;
376
+
377
+ export interface CursorMcpCall {
378
+ name: string;
379
+ providerIdentifier: string;
380
+ toolName: string;
381
+ toolCallId: string;
382
+ args: Record<string, unknown>;
383
+ rawArgs: Record<string, Uint8Array>;
384
+ }
385
+
386
+ export interface CursorShellStreamCallbacks {
387
+ onStdout(data: string): void;
388
+ onStderr(data: string): void;
389
+ }
390
+
391
+ export interface CursorExecHandlers {
392
+ read?: (args: ReadArgs) => Promise<CursorExecHandlerResult<ReadResult>>;
393
+ ls?: (args: LsArgs) => Promise<CursorExecHandlerResult<LsResult>>;
394
+ grep?: (args: GrepArgs) => Promise<CursorExecHandlerResult<GrepResult>>;
395
+ write?: (args: WriteArgs) => Promise<CursorExecHandlerResult<WriteResult>>;
396
+ delete?: (args: DeleteArgs) => Promise<CursorExecHandlerResult<DeleteResult>>;
397
+ shell?: (args: ShellArgs) => Promise<CursorExecHandlerResult<ShellResult>>;
398
+ shellStream?: (
399
+ args: ShellArgs,
400
+ callbacks: CursorShellStreamCallbacks,
401
+ ) => Promise<CursorExecHandlerResult<ShellResult>>;
402
+ diagnostics?: (args: DiagnosticsArgs) => Promise<CursorExecHandlerResult<DiagnosticsResult>>;
403
+ mcp?: (call: CursorMcpCall) => Promise<CursorExecHandlerResult<McpResult>>;
404
+ onToolResult?: CursorToolResultHandler;
405
+ }
406
+
407
+ export interface Tool<TParameters extends TSchema = TSchema> {
408
+ name: string;
409
+ description: string;
410
+ parameters: TParameters;
411
+ /** If true, tool is strictly typed and validated against the parameters schema before execution */
412
+ strict?: boolean;
413
+ }
414
+
415
+ export interface Context {
416
+ systemPrompt?: string;
417
+ messages: Message[];
418
+ tools?: Tool[];
419
+ }
420
+
421
+ export type AssistantMessageEvent =
422
+ | { type: "start"; contentIndex?: undefined; partial: AssistantMessage }
423
+ | { type: "text_start"; contentIndex: number; partial: AssistantMessage }
424
+ | { type: "text_delta"; contentIndex: number; delta: string; partial: AssistantMessage }
425
+ | { type: "text_end"; contentIndex: number; content: string; partial: AssistantMessage }
426
+ | { type: "thinking_start"; contentIndex: number; partial: AssistantMessage }
427
+ | { type: "thinking_delta"; contentIndex: number; delta: string; partial: AssistantMessage }
428
+ | { type: "thinking_end"; contentIndex: number; content: string; partial: AssistantMessage }
429
+ | { type: "toolcall_start"; contentIndex: number; partial: AssistantMessage }
430
+ | { type: "toolcall_delta"; contentIndex: number; delta: string; partial: AssistantMessage }
431
+ | { type: "toolcall_end"; contentIndex: number; toolCall: ToolCall; partial: AssistantMessage }
432
+ | {
433
+ type: "done";
434
+ contentIndex?: undefined;
435
+ reason: Extract<StopReason, "stop" | "length" | "toolUse">;
436
+ message: AssistantMessage;
437
+ }
438
+ | {
439
+ type: "error";
440
+ contentIndex?: undefined;
441
+ reason: Extract<StopReason, "aborted" | "error">;
442
+ error: AssistantMessage;
443
+ };
444
+
445
+ /**
446
+ * Compatibility settings for openai-completions API.
447
+ * Use this to override URL-based auto-detection for custom providers.
448
+ */
449
+ export interface OpenAICompat {
450
+ /** Whether the provider supports the `store` field. Default: auto-detected from URL. */
451
+ supportsStore?: boolean;
452
+ /** Whether the provider supports the `developer` role (vs `system`). Default: auto-detected from URL. */
453
+ supportsDeveloperRole?: boolean;
454
+ /** Whether the provider supports `reasoning_effort`. Default: auto-detected from URL. */
455
+ supportsReasoningEffort?: boolean;
456
+ /** Optional mapping from pi-ai reasoning levels to provider/model-specific `reasoning_effort` values. */
457
+ reasoningEffortMap?: Partial<Record<Effort, string>>;
458
+ /** Whether the provider supports `stream_options: { include_usage: true }` for token usage in streaming responses. Default: true. */
459
+ supportsUsageInStreaming?: boolean;
460
+ /** Which field to use for max tokens. Default: auto-detected from URL. */
461
+ maxTokensField?: "max_completion_tokens" | "max_tokens";
462
+ /** Whether tool results require the `name` field. Default: auto-detected from URL. */
463
+ requiresToolResultName?: boolean;
464
+ /** Whether a user message after tool results requires an assistant message in between. Default: auto-detected from URL. */
465
+ requiresAssistantAfterToolResult?: boolean;
466
+ /** Whether thinking blocks must be converted to text blocks with <thinking> delimiters. Default: auto-detected from URL. */
467
+ requiresThinkingAsText?: boolean;
468
+ /** Whether tool call IDs must be normalized to Mistral format (exactly 9 alphanumeric chars). Default: auto-detected from URL. */
469
+ requiresMistralToolIds?: boolean;
470
+ /** Format for reasoning/thinking parameter. "openai" uses reasoning_effort, "openrouter" uses reasoning: { effort }, "zai" uses thinking: { type: "enabled" }, "qwen" uses top-level enable_thinking, and "qwen-chat-template" uses chat_template_kwargs.enable_thinking. Default: "openai". */
471
+ thinkingFormat?: "openai" | "openrouter" | "zai" | "qwen" | "qwen-chat-template";
472
+ /** Which reasoning content field to emit on assistant messages. Default: auto-detected. */
473
+ reasoningContentField?: "reasoning_content" | "reasoning" | "reasoning_text";
474
+ /** Whether assistant tool-call messages must include reasoning content. Default: false. */
475
+ requiresReasoningContentForToolCalls?: boolean;
476
+ /** Whether assistant tool-call messages must include non-empty content. Default: false. */
477
+ requiresAssistantContentForToolCalls?: boolean;
478
+ /** Whether the provider supports the `tool_choice` parameter. Default: true. */
479
+ supportsToolChoice?: boolean;
480
+ /** OpenRouter-specific routing preferences. Only used when baseUrl points to OpenRouter. */
481
+ openRouterRouting?: OpenRouterRouting;
482
+ /** Vercel AI Gateway routing preferences. Only used when baseUrl points to Vercel AI Gateway. */
483
+ vercelGatewayRouting?: VercelGatewayRouting;
484
+ /** Extra fields to include in request body (e.g. gateway routing hints for OpenClaw-style proxies). */
485
+ extraBody?: Record<string, unknown>;
486
+ /** Whether the provider supports the `strict` field in tool definitions. Default: auto-detected per provider/baseUrl (conservative for unknown providers). */
487
+ supportsStrictMode?: boolean;
488
+ /** Whether tool schemas must be sent either all strict or all non-strict. Undefined keeps the existing per-tool mixed behavior. */
489
+ toolStrictMode?: "all_strict" | "none";
490
+ }
491
+
492
+ /**
493
+ * OpenRouter provider routing preferences.
494
+ * Controls which upstream providers OpenRouter routes requests to.
495
+ * @see https://openrouter.ai/docs/provider-routing
496
+ */
497
+ export interface OpenRouterRouting {
498
+ /** List of provider slugs to exclusively use for this request (e.g., ["amazon-bedrock", "anthropic"]). */
499
+ only?: string[];
500
+ /** List of provider slugs to try in order (e.g., ["anthropic", "openai"]). */
501
+ order?: string[];
502
+ }
503
+
504
+ /**
505
+ * Vercel AI Gateway routing preferences.
506
+ * Controls which upstream providers the gateway routes requests to.
507
+ * @see https://vercel.com/docs/ai-gateway/models-and-providers/provider-options
508
+ */
509
+ export interface VercelGatewayRouting {
510
+ /** List of provider slugs to exclusively use for this request (e.g., ["bedrock", "anthropic"]). */
511
+ only?: string[];
512
+ /** List of provider slugs to try in order (e.g., ["anthropic", "openai"]). */
513
+ order?: string[];
514
+ }
515
+
516
+ // Model interface for the unified model system
517
+ export interface Model<TApi extends Api = any> {
518
+ id: string;
519
+ name: string;
520
+ api: TApi;
521
+ provider: Provider;
522
+ baseUrl: string;
523
+ reasoning: boolean;
524
+ input: ("text" | "image")[];
525
+ cost: {
526
+ input: number; // $/million tokens
527
+ output: number; // $/million tokens
528
+ cacheRead: number; // $/million tokens
529
+ cacheWrite: number; // $/million tokens
530
+ };
531
+ /** Premium Copilot requests charged per user-initiated request (defaults to 1). */
532
+ premiumMultiplier?: number;
533
+ contextWindow: number;
534
+ maxTokens: number;
535
+ headers?: Record<string, string>;
536
+ /** Hint that websocket transport should be preferred when supported by the provider implementation. */
537
+ preferWebsockets?: boolean;
538
+ /** Preferred model to switch to when context promotion is triggered (model id or provider/id). */
539
+ contextPromotionTarget?: string;
540
+ /** Provider-assigned priority value (lower = higher priority). */
541
+ priority?: number;
542
+ /** Canonical thinking capability metadata for this model. */
543
+ thinking?: ThinkingConfig;
544
+ /** Compatibility overrides for openai-completions API. If not set, auto-detected from baseUrl. */
545
+ compat?: TApi extends "openai-completions" ? OpenAICompat : never;
546
+ }