@omnicross/core 0.1.0
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.
- package/LICENSE +21 -0
- package/NOTICE +57 -0
- package/README.md +15 -0
- package/dist/ApiKeyPoolService-BmMkau07.d.cts +170 -0
- package/dist/ApiKeyPoolService-BmMkau07.d.ts +170 -0
- package/dist/ProviderProxy-f_8ziIhW.d.cts +120 -0
- package/dist/ProviderProxy-vjt8sQQk.d.ts +120 -0
- package/dist/SubscriptionAuthSource-Cr4fVEYY.d.cts +264 -0
- package/dist/SubscriptionAuthSource-D89zmiSS.d.ts +264 -0
- package/dist/auth/GeminiCodeAssistProjectResolver.cjs +218 -0
- package/dist/auth/GeminiCodeAssistProjectResolver.d.cts +68 -0
- package/dist/auth/GeminiCodeAssistProjectResolver.d.ts +68 -0
- package/dist/auth/GeminiCodeAssistProjectResolver.js +189 -0
- package/dist/completion/ApiKeyPoolService.cjs +331 -0
- package/dist/completion/ApiKeyPoolService.d.cts +2 -0
- package/dist/completion/ApiKeyPoolService.d.ts +2 -0
- package/dist/completion/ApiKeyPoolService.js +306 -0
- package/dist/completion.cjs +4027 -0
- package/dist/completion.d.cts +17 -0
- package/dist/completion.d.ts +17 -0
- package/dist/completion.js +3983 -0
- package/dist/index-BTSmc9Sm.d.ts +645 -0
- package/dist/index-DXazdTzZ.d.cts +645 -0
- package/dist/index.cjs +10428 -0
- package/dist/index.d.cts +128 -0
- package/dist/index.d.ts +128 -0
- package/dist/index.js +10339 -0
- package/dist/outbound-api/subscriptionRegistryPort.cjs +38 -0
- package/dist/outbound-api/subscriptionRegistryPort.d.cts +73 -0
- package/dist/outbound-api/subscriptionRegistryPort.d.ts +73 -0
- package/dist/outbound-api/subscriptionRegistryPort.js +12 -0
- package/dist/outbound-api.cjs +5264 -0
- package/dist/outbound-api.d.cts +320 -0
- package/dist/outbound-api.d.ts +320 -0
- package/dist/outbound-api.js +5218 -0
- package/dist/pipeline/SubscriptionAuthSource.cjs +131 -0
- package/dist/pipeline/SubscriptionAuthSource.d.cts +3 -0
- package/dist/pipeline/SubscriptionAuthSource.d.ts +3 -0
- package/dist/pipeline/SubscriptionAuthSource.js +103 -0
- package/dist/pipeline/SubscriptionAuthStrategy.cjs +18 -0
- package/dist/pipeline/SubscriptionAuthStrategy.d.cts +61 -0
- package/dist/pipeline/SubscriptionAuthStrategy.d.ts +61 -0
- package/dist/pipeline/SubscriptionAuthStrategy.js +0 -0
- package/dist/ports/gemini-code-assist-resolver.cjs +38 -0
- package/dist/ports/gemini-code-assist-resolver.d.cts +26 -0
- package/dist/ports/gemini-code-assist-resolver.d.ts +26 -0
- package/dist/ports/gemini-code-assist-resolver.js +12 -0
- package/dist/ports.cjs +18 -0
- package/dist/ports.d.cts +15 -0
- package/dist/ports.d.ts +15 -0
- package/dist/ports.js +0 -0
- package/dist/provider-proxy/ingress/providerProxyShared.cjs +2958 -0
- package/dist/provider-proxy/ingress/providerProxyShared.d.cts +77 -0
- package/dist/provider-proxy/ingress/providerProxyShared.d.ts +77 -0
- package/dist/provider-proxy/ingress/providerProxyShared.js +2925 -0
- package/dist/provider-proxy/matchText.cjs +73 -0
- package/dist/provider-proxy/matchText.d.cts +47 -0
- package/dist/provider-proxy/matchText.d.ts +47 -0
- package/dist/provider-proxy/matchText.js +45 -0
- package/dist/provider-proxy/types.cjs +18 -0
- package/dist/provider-proxy/types.d.cts +12 -0
- package/dist/provider-proxy/types.d.ts +12 -0
- package/dist/provider-proxy/types.js +0 -0
- package/dist/provider-proxy.cjs +4667 -0
- package/dist/provider-proxy.d.cts +69 -0
- package/dist/provider-proxy.d.ts +69 -0
- package/dist/provider-proxy.js +4636 -0
- package/dist/serializeError.cjs +82 -0
- package/dist/serializeError.d.cts +24 -0
- package/dist/serializeError.d.ts +24 -0
- package/dist/serializeError.js +57 -0
- package/dist/sse-parser.cjs +456 -0
- package/dist/sse-parser.d.cts +143 -0
- package/dist/sse-parser.d.ts +143 -0
- package/dist/sse-parser.js +430 -0
- package/dist/transformer/TransformerChainExecutor.cjs +321 -0
- package/dist/transformer/TransformerChainExecutor.d.cts +104 -0
- package/dist/transformer/TransformerChainExecutor.d.ts +104 -0
- package/dist/transformer/TransformerChainExecutor.js +294 -0
- package/dist/transformer/TransformerService.cjs +290 -0
- package/dist/transformer/TransformerService.d.cts +138 -0
- package/dist/transformer/TransformerService.d.ts +138 -0
- package/dist/transformer/TransformerService.js +265 -0
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +1115 -0
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.d.cts +102 -0
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.d.ts +102 -0
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +1085 -0
- package/dist/transformer/transformers/GeminiTransformer.cjs +1013 -0
- package/dist/transformer/transformers/GeminiTransformer.d.cts +70 -0
- package/dist/transformer/transformers/GeminiTransformer.d.ts +70 -0
- package/dist/transformer/transformers/GeminiTransformer.js +986 -0
- package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +538 -0
- package/dist/transformer/transformers/OpenAIResponseTransformer.d.cts +53 -0
- package/dist/transformer/transformers/OpenAIResponseTransformer.d.ts +53 -0
- package/dist/transformer/transformers/OpenAIResponseTransformer.js +513 -0
- package/dist/transformer/transformers/OpenCodeGoTransformer.cjs +73 -0
- package/dist/transformer/transformers/OpenCodeGoTransformer.d.cts +51 -0
- package/dist/transformer/transformers/OpenCodeGoTransformer.d.ts +51 -0
- package/dist/transformer/transformers/OpenCodeGoTransformer.js +48 -0
- package/dist/transformer/types.cjs +18 -0
- package/dist/transformer/types.d.cts +405 -0
- package/dist/transformer/types.d.ts +405 -0
- package/dist/transformer/types.js +0 -0
- package/dist/transformer.cjs +3736 -0
- package/dist/transformer.d.cts +33 -0
- package/dist/transformer.d.ts +33 -0
- package/dist/transformer.js +3712 -0
- package/dist/types-CGGrKqC_.d.cts +142 -0
- package/dist/types-CbCN2NQP.d.ts +142 -0
- package/dist/types-DCzHkhJt.d.ts +467 -0
- package/dist/types-DZIQbgp0.d.cts +467 -0
- package/dist/usage-event-sink-BX7FE1NL.d.cts +59 -0
- package/dist/usage-event-sink-BX7FE1NL.d.ts +59 -0
- package/package.json +62 -0
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
import { MessageBlock } from '@omnicross/contracts/message-blocks';
|
|
2
|
+
import { SimpleChatMessage, ThinkLevel, SimpleChatAudio, SimpleChatVideo, AnthropicMessage, OpenAIMessage } from '@omnicross/contracts/completion-types';
|
|
3
|
+
import { LLMProvider, OpenRouterProviderRouting } from '@omnicross/contracts/llm-config';
|
|
4
|
+
import { C as CorePaths, U as UsageEventSink } from './usage-event-sink-BX7FE1NL.cjs';
|
|
5
|
+
import { L as Logger, A as ApiKeyPoolService } from './ApiKeyPoolService-BmMkau07.cjs';
|
|
6
|
+
import { W as WebSearchBackend, P as ProviderConfigSource, U as UsageRecorderImport } from './types-DZIQbgp0.cjs';
|
|
7
|
+
import { MCPCallToolResponse, MCPTool } from '@omnicross/contracts/mcp-types';
|
|
8
|
+
import { resolveProviderEndpoint as resolveProviderEndpoint$1 } from '@omnicross/contracts/endpoint-resolver';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Native Search Types
|
|
12
|
+
*
|
|
13
|
+
* Type definitions for provider-native web search capabilities.
|
|
14
|
+
* Used by NativeSearchInjector to detect and configure built-in
|
|
15
|
+
* search for OpenAI, Anthropic, Google, xAI, and OpenRouter.
|
|
16
|
+
*
|
|
17
|
+
* @module completion/native-search-types
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Providers that support native/built-in web search */
|
|
21
|
+
type NativeSearchProvider = 'openai' | 'anthropic' | 'google' | 'xai' | 'openrouter';
|
|
22
|
+
/** Result of detecting native search support for a model */
|
|
23
|
+
interface NativeSearchDetectionResult {
|
|
24
|
+
/** Whether the model supports native search */
|
|
25
|
+
supported: boolean;
|
|
26
|
+
/** Which native provider to use, if supported */
|
|
27
|
+
nativeProvider: NativeSearchProvider | null;
|
|
28
|
+
}
|
|
29
|
+
/** Native search tool names that should NOT be executed locally */
|
|
30
|
+
declare const NATIVE_SEARCH_TOOL_NAMES: string[];
|
|
31
|
+
/** User-facing configuration for native search */
|
|
32
|
+
interface NativeSearchUserConfig {
|
|
33
|
+
/** Whether native search is enabled */
|
|
34
|
+
enabled: boolean;
|
|
35
|
+
/** Max search results / uses (maps to provider-specific settings) */
|
|
36
|
+
maxResults?: number;
|
|
37
|
+
/** Domains to block (Anthropic) */
|
|
38
|
+
blockedDomains?: string[];
|
|
39
|
+
/** xAI search mode override */
|
|
40
|
+
searchMode?: 'on' | 'off' | 'auto';
|
|
41
|
+
/** xAI search sources */
|
|
42
|
+
sources?: Array<{
|
|
43
|
+
type: 'web' | 'x' | 'news';
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Request body augmentation produced by NativeSearchInjector.
|
|
48
|
+
*
|
|
49
|
+
* - `additionalTools`: Appended to the tools array in the request body.
|
|
50
|
+
* - `bodyFields`: Merged into the top-level request body.
|
|
51
|
+
*/
|
|
52
|
+
interface NativeSearchAugmentation {
|
|
53
|
+
/** Extra tools to append (OpenAI web_search, Anthropic web_search_20250305, Gemini grounding) */
|
|
54
|
+
additionalTools?: unknown[];
|
|
55
|
+
/** Top-level body fields (xAI search_parameters, OpenRouter plugins, OpenAI web_search_options) */
|
|
56
|
+
bodyFields?: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Completion Service Types
|
|
61
|
+
*
|
|
62
|
+
* Type definitions for completion options, results, and callbacks.
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
interface CompletionOptions {
|
|
66
|
+
providerId: string;
|
|
67
|
+
model: string;
|
|
68
|
+
messages: SimpleChatMessage[];
|
|
69
|
+
maxTokens?: number;
|
|
70
|
+
temperature?: number;
|
|
71
|
+
stream?: boolean;
|
|
72
|
+
/** Thinking effort level for reasoning models */
|
|
73
|
+
thinkLevel?: ThinkLevel;
|
|
74
|
+
/** Native search augmentation to apply to the request body */
|
|
75
|
+
nativeSearchAugmentation?: NativeSearchAugmentation;
|
|
76
|
+
/** Session ID for API key pool affinity (preserves prompt cache) and usage attribution. */
|
|
77
|
+
sessionId?: string;
|
|
78
|
+
/**
|
|
79
|
+
* Assistant-message id this request is producing — used to attribute
|
|
80
|
+
* recorded usage rows back to host messages. Optional; if absent the row is
|
|
81
|
+
* still recorded but won't be linked.
|
|
82
|
+
*/
|
|
83
|
+
messageId?: string;
|
|
84
|
+
/**
|
|
85
|
+
* Parent message id (for subagent-style nested calls). Best-effort: callers
|
|
86
|
+
* that know the parent should fill this; otherwise leave unset.
|
|
87
|
+
*/
|
|
88
|
+
parentMessageId?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Opt into the Anthropic 1M-context tier for this request. The transformer
|
|
91
|
+
* pipeline (and any direct Anthropic-format paths) inject the
|
|
92
|
+
* `'context-1m-2025-08-07'` beta into the outbound request body when this
|
|
93
|
+
* is true AND the resolved model is in the 1M-capable allowlist.
|
|
94
|
+
*/
|
|
95
|
+
useExtendedContext?: boolean;
|
|
96
|
+
}
|
|
97
|
+
interface CompletionResult {
|
|
98
|
+
success: boolean;
|
|
99
|
+
message?: SimpleChatMessage;
|
|
100
|
+
error?: string;
|
|
101
|
+
usage?: {
|
|
102
|
+
promptTokens: number;
|
|
103
|
+
completionTokens: number;
|
|
104
|
+
totalTokens: number;
|
|
105
|
+
};
|
|
106
|
+
/** Provider finish reason (e.g. 'stop', 'tool_use', 'max_tokens') */
|
|
107
|
+
finishReason?: string;
|
|
108
|
+
}
|
|
109
|
+
interface StreamCallbacks {
|
|
110
|
+
onStart?: (messageId: string) => void;
|
|
111
|
+
onDelta?: (content: string) => void;
|
|
112
|
+
onReasoning?: (reasoning: string) => void;
|
|
113
|
+
onAudio?: (audio: SimpleChatAudio) => void;
|
|
114
|
+
onVideo?: (video: SimpleChatVideo) => void;
|
|
115
|
+
/** Called when a new content block is created (thinking, text, tool_use, tool_result) */
|
|
116
|
+
onBlock?: (block: MessageBlock) => void;
|
|
117
|
+
onDone?: (message: SimpleChatMessage, usage?: CompletionResult['usage'], metrics?: {
|
|
118
|
+
completionTokens: number;
|
|
119
|
+
timeCompletionMs: number;
|
|
120
|
+
timeFirstTokenMs?: number;
|
|
121
|
+
}) => void;
|
|
122
|
+
onError?: (error: string) => void;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* API format type for determining endpoint structure
|
|
126
|
+
*/
|
|
127
|
+
type ApiFormat = 'openai' | 'anthropic' | 'google' | 'azure-openai' | 'openai-response';
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Core-owned tool-shape types.
|
|
131
|
+
*
|
|
132
|
+
* The structural tool definitions (`OpenAITool`, `AnthropicTool`,
|
|
133
|
+
* `GeminiTools`) are pure data shapes with no host dependency — hoisted here
|
|
134
|
+
* (verbatim from the host `tools/mcp-users/ToolsLoader.ts`) so the serving core
|
|
135
|
+
* names no host module. The host `ToolsLoader.ts` re-exports these from
|
|
136
|
+
* `@omnicross/core`, keeping every existing host consumer unchanged.
|
|
137
|
+
*
|
|
138
|
+
* `McpToolProvider` is the narrow structural port for the single `callTool`
|
|
139
|
+
* method the completion tool-loop consumes from the host's concrete
|
|
140
|
+
* `McpService`. The concrete `McpService` instance is injected at the existing
|
|
141
|
+
* seam and satisfies this port structurally (type-only — no runtime coupling).
|
|
142
|
+
*/
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* OpenAI-compatible tool definition
|
|
146
|
+
*/
|
|
147
|
+
interface OpenAITool {
|
|
148
|
+
type: 'function';
|
|
149
|
+
function: {
|
|
150
|
+
name: string;
|
|
151
|
+
description: string;
|
|
152
|
+
parameters: Record<string, any>;
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Anthropic tool definition
|
|
157
|
+
*/
|
|
158
|
+
interface AnthropicTool {
|
|
159
|
+
name: string;
|
|
160
|
+
description: string;
|
|
161
|
+
input_schema: Record<string, any>;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Google Gemini tool definition
|
|
165
|
+
* Gemini REST API expects tools wrapped in functionDeclarations
|
|
166
|
+
*/
|
|
167
|
+
type GeminiTools = Array<{
|
|
168
|
+
functionDeclarations: Array<{
|
|
169
|
+
name: string;
|
|
170
|
+
description: string;
|
|
171
|
+
parameters: Record<string, any>;
|
|
172
|
+
}>;
|
|
173
|
+
}>;
|
|
174
|
+
/**
|
|
175
|
+
* Narrow structural port for the host MCP tool provider — only the `callTool`
|
|
176
|
+
* method the serving-core tool-loop dispatches to. The host's concrete
|
|
177
|
+
* `McpService` satisfies this structurally.
|
|
178
|
+
*/
|
|
179
|
+
interface McpToolProvider {
|
|
180
|
+
callTool(serverId: string, toolName: string, args: unknown, callId: string): Promise<MCPCallToolResponse>;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* BuiltinToolExecutor — Executes built-in tools (web_search, web_fetch)
|
|
185
|
+
* for the non-agent chat pipeline.
|
|
186
|
+
*
|
|
187
|
+
* Built-in tools use `serverId: 'builtin'` in MCPTool metadata and are
|
|
188
|
+
* dispatched here instead of going through McpService.callTool().
|
|
189
|
+
*/
|
|
190
|
+
|
|
191
|
+
declare class BuiltinToolExecutor {
|
|
192
|
+
private webSearch;
|
|
193
|
+
constructor(webSearch: WebSearchBackend);
|
|
194
|
+
execute(toolName: string, args: Record<string, unknown>): Promise<MCPCallToolResponse>;
|
|
195
|
+
private executeWebSearch;
|
|
196
|
+
private resolveProviderChain;
|
|
197
|
+
private executeWebFetch;
|
|
198
|
+
}
|
|
199
|
+
/** Get the built-in MCPTool definitions for web search tools. */
|
|
200
|
+
declare function getBuiltinSearchTools(): MCPTool[];
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* ToolHandler - Handles streaming completion with MCP tool support
|
|
204
|
+
*
|
|
205
|
+
* Extracted from CompletionService to isolate the agentic loop logic
|
|
206
|
+
* that handles tool calls: LLM -> execute tools -> LLM again until done.
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
/** Extended options for tool-based completion */
|
|
210
|
+
interface StreamWithToolsOptions extends CompletionOptions {
|
|
211
|
+
tools: OpenAITool[] | AnthropicTool[] | GeminiTools;
|
|
212
|
+
mcpTools?: MCPTool[];
|
|
213
|
+
}
|
|
214
|
+
/** Extended callbacks for tool-based completion */
|
|
215
|
+
interface StreamWithToolsCallbacks extends StreamCallbacks {
|
|
216
|
+
onToolCall?: (toolCall: {
|
|
217
|
+
id: string;
|
|
218
|
+
name: string;
|
|
219
|
+
args: unknown;
|
|
220
|
+
}) => void;
|
|
221
|
+
onToolResult?: (toolId: string, result: unknown) => void;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* VisionFallbackProvider — serving-core port for image-to-text fallback.
|
|
226
|
+
*
|
|
227
|
+
* When the active completion model lacks vision capability but a message
|
|
228
|
+
* carries images, `CompletionService.applyVisionFallback` delegates to this
|
|
229
|
+
* port to turn the images into a text description (which is then appended to
|
|
230
|
+
* the message content) before stripping the image attachments.
|
|
231
|
+
*
|
|
232
|
+
* The concrete implementation is built ON TOP OF CompletionService, so it
|
|
233
|
+
* lives in the embedding host and is injected DOWN into the serving core via
|
|
234
|
+
* `setVisionFallbackProvider` at bootstrap (instead of the core importing
|
|
235
|
+
* upward).
|
|
236
|
+
*
|
|
237
|
+
* @module completion/VisionFallbackProvider
|
|
238
|
+
*/
|
|
239
|
+
/**
|
|
240
|
+
* Describe a batch of images as text using an auxiliary vision-capable model.
|
|
241
|
+
*
|
|
242
|
+
* @param images Image data URLs to describe (`{ data: 'data:<mime>;base64,…' }`).
|
|
243
|
+
* @param context Free-form context (the surrounding user message content).
|
|
244
|
+
* @param model The resolved vision aux ModelRef (`"providerId,modelId"`).
|
|
245
|
+
* @returns A textual description, or an empty / sentinel string when
|
|
246
|
+
* unavailable. Callers MUST tolerate `''` and
|
|
247
|
+
* `'[Image description unavailable]'`.
|
|
248
|
+
*/
|
|
249
|
+
interface VisionFallbackProvider {
|
|
250
|
+
describeImages(images: {
|
|
251
|
+
data: string;
|
|
252
|
+
}[], context: string, model: string): Promise<string>;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* CompletionService - Handles completion API calls
|
|
257
|
+
*
|
|
258
|
+
* This service provides a unified interface for making completion API calls
|
|
259
|
+
* to different providers, handling format conversion as needed.
|
|
260
|
+
* Supports transformer chains for advanced request/response transformation.
|
|
261
|
+
*
|
|
262
|
+
* This is a thin facade that delegates to domain-specific handlers:
|
|
263
|
+
* - DirectApiHandler: Non-streaming API calls (OpenAI, Anthropic, Gemini)
|
|
264
|
+
* - StreamHandler: SSE-based streaming (OpenAI, Anthropic, Gemini)
|
|
265
|
+
* - TransformerHandler: Transformer chain-based completion
|
|
266
|
+
* - ToolHandler: Agentic tool-calling loop
|
|
267
|
+
* - ThinkingResolver: Thinking budget and max tokens resolution
|
|
268
|
+
*/
|
|
269
|
+
|
|
270
|
+
declare class CompletionService {
|
|
271
|
+
private paths;
|
|
272
|
+
private llmConfig;
|
|
273
|
+
private logger;
|
|
274
|
+
private apiKeyPool;
|
|
275
|
+
private usageRecorder;
|
|
276
|
+
private usageEventSink;
|
|
277
|
+
private visionFallbackProvider;
|
|
278
|
+
constructor(paths: CorePaths, llmConfig: ProviderConfigSource, logger: Logger);
|
|
279
|
+
/**
|
|
280
|
+
* Set the API key pool service for multi-key load balancing.
|
|
281
|
+
* When set, keys are resolved via the pool instead of directly from the provider.
|
|
282
|
+
*/
|
|
283
|
+
setApiKeyPool(pool: ApiKeyPoolService): void;
|
|
284
|
+
/**
|
|
285
|
+
* Set the usage recorder so completion paths can persist token/cost stats.
|
|
286
|
+
* Optional — when unset, all calls succeed but nothing is recorded.
|
|
287
|
+
*/
|
|
288
|
+
setUsageRecorder(recorder: UsageRecorderImport): void;
|
|
289
|
+
/**
|
|
290
|
+
* Set the usage-event sink so completion paths can push live usage events
|
|
291
|
+
* (context-meter, aggregate recorder) into the in-process hub. Injected DOWN
|
|
292
|
+
* at bootstrap with `getUsageEventHub()` immediately after construction, so
|
|
293
|
+
* emission is unconditional in production. Optional — when unset (unit-test
|
|
294
|
+
* constructors), the emit calls no-op, identical to `usageRecorder`.
|
|
295
|
+
*/
|
|
296
|
+
setUsageEventSink(sink: UsageEventSink): void;
|
|
297
|
+
/**
|
|
298
|
+
* Set the vision-fallback provider used by `applyVisionFallback` to describe
|
|
299
|
+
* images for non-vision models. Injected DOWN by the host at bootstrap
|
|
300
|
+
* (the host's impl is built on top of CompletionService).
|
|
301
|
+
* Optional — when unset, `applyVisionFallback` strips images instead.
|
|
302
|
+
*/
|
|
303
|
+
setVisionFallbackProvider(provider: VisionFallbackProvider): void;
|
|
304
|
+
/**
|
|
305
|
+
* Get provider by ID
|
|
306
|
+
* Delegates to the `ProviderConfigSource` which maintains its own in-memory cache.
|
|
307
|
+
*/
|
|
308
|
+
getProvider(providerId: string): Promise<LLMProvider | null>;
|
|
309
|
+
/**
|
|
310
|
+
* Send a completion request
|
|
311
|
+
*/
|
|
312
|
+
complete(options: CompletionOptions): Promise<CompletionResult>;
|
|
313
|
+
/**
|
|
314
|
+
* Send a streaming completion request
|
|
315
|
+
*/
|
|
316
|
+
completeStream(options: CompletionOptions, callbacks: StreamCallbacks): Promise<void>;
|
|
317
|
+
/**
|
|
318
|
+
* Get available models for a provider
|
|
319
|
+
*/
|
|
320
|
+
getAvailableModels(providerId: string): Promise<string[]>;
|
|
321
|
+
/**
|
|
322
|
+
* Test provider connection with a specific model.
|
|
323
|
+
* Sends "Hello" and returns the AI response, duration, etc.
|
|
324
|
+
*/
|
|
325
|
+
testModel(providerId: string, modelId: string): Promise<{
|
|
326
|
+
success: boolean;
|
|
327
|
+
message: string;
|
|
328
|
+
response?: string;
|
|
329
|
+
model: string;
|
|
330
|
+
durationMs?: number;
|
|
331
|
+
}>;
|
|
332
|
+
/**
|
|
333
|
+
* Check if any messages contain images and the model lacks vision capability.
|
|
334
|
+
* If so, use the auxiliary vision model to describe images as text and remove
|
|
335
|
+
* the image attachments from the messages.
|
|
336
|
+
*
|
|
337
|
+
* Mutates options.messages in-place.
|
|
338
|
+
*/
|
|
339
|
+
private applyVisionFallback;
|
|
340
|
+
/**
|
|
341
|
+
* Resolve API key for a request with priority:
|
|
342
|
+
* 1. Coding Plan override (if enabled)
|
|
343
|
+
* 2. API key pool (session-affinity weighted round-robin)
|
|
344
|
+
* 3. Legacy single key from provider config
|
|
345
|
+
*/
|
|
346
|
+
private resolveApiKeyForRequest;
|
|
347
|
+
/**
|
|
348
|
+
* Extract HTTP status code from error messages like "API error (429): ..."
|
|
349
|
+
*/
|
|
350
|
+
private extractHttpStatus;
|
|
351
|
+
/**
|
|
352
|
+
* Dispatch a non-streaming completion to the appropriate handler.
|
|
353
|
+
*/
|
|
354
|
+
private callDirectHandler;
|
|
355
|
+
/**
|
|
356
|
+
* Dispatch a streaming completion to the appropriate handler.
|
|
357
|
+
*/
|
|
358
|
+
private callStreamHandler;
|
|
359
|
+
/**
|
|
360
|
+
* Resolve API key (handle environment variable references)
|
|
361
|
+
*/
|
|
362
|
+
resolveApiKey(apiKey: string): string;
|
|
363
|
+
/**
|
|
364
|
+
* Resolve effective max_tokens value with priority:
|
|
365
|
+
* 1. Session settings (if provided)
|
|
366
|
+
* 2. Global model parameters (if enabled)
|
|
367
|
+
* 3. Model's maxTokens from provider config
|
|
368
|
+
* 4. Discovered models cache (from API)
|
|
369
|
+
* 5. undefined - let API use its default
|
|
370
|
+
*/
|
|
371
|
+
resolveEffectiveMaxTokens(providerId: string, modelId: string, sessionMaxTokens?: number): Promise<number | undefined>;
|
|
372
|
+
/**
|
|
373
|
+
* Get required max_tokens for providers that need it (e.g., Anthropic)
|
|
374
|
+
* Falls back to DEFAULT_MAX_TOKENS if no value is configured
|
|
375
|
+
*/
|
|
376
|
+
getRequiredMaxTokens(providerId: string, modelId: string, sessionMaxTokens?: number): Promise<number>;
|
|
377
|
+
/**
|
|
378
|
+
* Calculate thinking budget and adjust max_tokens for the provider
|
|
379
|
+
*/
|
|
380
|
+
resolveThinkingBudget(providerId: string, modelId: string, maxTokens: number, thinkLevel: ThinkLevel): Promise<{
|
|
381
|
+
adjustedMaxTokens: number;
|
|
382
|
+
thinkingBudget: number | undefined;
|
|
383
|
+
thinkingConfig: {
|
|
384
|
+
type?: 'enabled' | 'disabled';
|
|
385
|
+
budget_tokens?: number;
|
|
386
|
+
} | undefined;
|
|
387
|
+
}>;
|
|
388
|
+
/**
|
|
389
|
+
* Send a completion request using transformer chain
|
|
390
|
+
*/
|
|
391
|
+
completeWithTransformers(options: CompletionOptions): Promise<CompletionResult>;
|
|
392
|
+
/**
|
|
393
|
+
* Send a streaming completion request using transformer chain
|
|
394
|
+
*/
|
|
395
|
+
completeStreamWithTransformers(options: CompletionOptions, callbacks: StreamCallbacks): Promise<void>;
|
|
396
|
+
/**
|
|
397
|
+
* Stream completion with MCP tools support (direct API call)
|
|
398
|
+
* Implements agentic loop: calls LLM -> executes tools -> calls LLM again until done
|
|
399
|
+
*/
|
|
400
|
+
streamWithTools(options: StreamWithToolsOptions, callbacks: StreamWithToolsCallbacks, mcpService?: McpToolProvider, builtinExecutor?: BuiltinToolExecutor): Promise<void>;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* StreamEventBuffer — per-streamId event queue for streamed completion delivery.
|
|
405
|
+
*
|
|
406
|
+
* Closes the subscribe-vs-emit race between a producer that starts the LLM call
|
|
407
|
+
* asynchronously and a consumer that only attaches its listener after awaiting a
|
|
408
|
+
* reply. Events emitted before `attach(streamId)` is called are queued and
|
|
409
|
+
* replayed in order on attach.
|
|
410
|
+
*/
|
|
411
|
+
/**
|
|
412
|
+
* Minimal structural sender — the subset of an Electron `WebContents` (or any
|
|
413
|
+
* IPC channel) this buffer actually uses. Kept LOCAL so core has zero electron
|
|
414
|
+
* dependency; the host passes any object satisfying this shape.
|
|
415
|
+
*/
|
|
416
|
+
interface StreamSender {
|
|
417
|
+
isDestroyed(): boolean;
|
|
418
|
+
send(channel: string, payload: StreamEvent): void;
|
|
419
|
+
}
|
|
420
|
+
type StreamEventType = 'start' | 'delta' | 'reasoning' | 'tool_call' | 'tool_result' | 'tool_use' | 'block' | 'search_start' | 'search_result' | 'done' | 'error' | 'abort';
|
|
421
|
+
interface StreamEvent {
|
|
422
|
+
type: StreamEventType;
|
|
423
|
+
[key: string]: unknown;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Register a new stream. Called by the engine / handler immediately after the
|
|
427
|
+
* `streamId` is created, before any `emit`. Idempotent re-registration replaces
|
|
428
|
+
* the sender (covers the rare case of the engine retrying with the same id).
|
|
429
|
+
*/
|
|
430
|
+
declare function register(streamId: string, sender: StreamSender): void;
|
|
431
|
+
/**
|
|
432
|
+
* Emit an event for `streamId`. Forwards directly if the client has attached;
|
|
433
|
+
* otherwise queues until `attach` is called. Bounded at QUEUE_CAP — overflow
|
|
434
|
+
* evicts the oldest non-terminal event.
|
|
435
|
+
*/
|
|
436
|
+
declare function emit(streamId: string, event: StreamEvent): void;
|
|
437
|
+
/**
|
|
438
|
+
* The client announced readiness via the `completion:stream:subscribe` IPC. Drains
|
|
439
|
+
* the queue synchronously to the bound sender, then flips to direct-forward mode.
|
|
440
|
+
* Returns the number of events drained for diagnostic purposes.
|
|
441
|
+
*/
|
|
442
|
+
declare function attach(streamId: string): {
|
|
443
|
+
ok: boolean;
|
|
444
|
+
drained: number;
|
|
445
|
+
};
|
|
446
|
+
/**
|
|
447
|
+
* Mark a stream finished. If the client has already attached, release
|
|
448
|
+
* synchronously. Otherwise defer one tick so a late `subscribe` arriving on the
|
|
449
|
+
* heels of the `done`/`error` event still drains the queue before cleanup.
|
|
450
|
+
*/
|
|
451
|
+
declare function release(streamId: string): void;
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* API URL Building Utilities
|
|
455
|
+
*
|
|
456
|
+
* Functions for building correct API URLs based on provider format.
|
|
457
|
+
*/
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Resolve API format from provider configuration
|
|
461
|
+
*
|
|
462
|
+
* Priority:
|
|
463
|
+
* 1. apiFormat (v3 preferred field)
|
|
464
|
+
* 2. chatApiFormat (legacy v3 field)
|
|
465
|
+
* 3. apiType if it's an explicit format (claudecode/anthropic/google)
|
|
466
|
+
* 4. Default to openai
|
|
467
|
+
*
|
|
468
|
+
* Note: This enables implicit routing - the API format determines which
|
|
469
|
+
* transformer is automatically applied without explicit router configuration.
|
|
470
|
+
*/
|
|
471
|
+
declare function resolveApiFormat(provider: LLMProvider): ApiFormat;
|
|
472
|
+
/**
|
|
473
|
+
* Build OpenAI Chat Completions API URL
|
|
474
|
+
* Handles various input formats:
|
|
475
|
+
* - https://api.openai.com → https://api.openai.com/v1/chat/completions
|
|
476
|
+
* - https://api.openai.com/v1/chat/completions → unchanged
|
|
477
|
+
* - https://api.deepseek.com/v1 → https://api.deepseek.com/v1/chat/completions
|
|
478
|
+
* - https://api.z.ai/api/coding/paas/v4 → https://api.z.ai/api/coding/paas/v4/chat/completions
|
|
479
|
+
*/
|
|
480
|
+
declare function buildOpenAIApiUrl(baseUrl: string): string;
|
|
481
|
+
/**
|
|
482
|
+
* Build Anthropic Messages API URL
|
|
483
|
+
* Handles various input formats:
|
|
484
|
+
* - https://api.anthropic.com → https://api.anthropic.com/v1/messages
|
|
485
|
+
* - https://api.anthropic.com/v1/messages → unchanged
|
|
486
|
+
* - https://api.z.ai/api/anthropic → https://api.z.ai/api/anthropic/v1/messages
|
|
487
|
+
* - https://api.z.ai/api/anthropic/v2 → https://api.z.ai/api/anthropic/v2/messages
|
|
488
|
+
*/
|
|
489
|
+
declare function buildAnthropicApiUrl(baseUrl: string): string;
|
|
490
|
+
/**
|
|
491
|
+
* Build Google Gemini API URL
|
|
492
|
+
* Gemini uses a dynamic URL structure: /v1beta/models/{model}:generateContent or :streamGenerateContent
|
|
493
|
+
* @param baseUrl - Base URL (e.g., https://generativelanguage.googleapis.com)
|
|
494
|
+
* @param model - Model name (e.g., gemini-2.0-flash)
|
|
495
|
+
* @param stream - Whether to use streaming endpoint
|
|
496
|
+
*/
|
|
497
|
+
declare function buildGeminiApiUrl(baseUrl: string, model: string, stream: boolean): string;
|
|
498
|
+
/**
|
|
499
|
+
* Normalize Azure OpenAI endpoint
|
|
500
|
+
* Strips trailing /, /openai, /openai/v1 etc.
|
|
501
|
+
*/
|
|
502
|
+
declare function normalizeAzureEndpoint(endpoint: string): string;
|
|
503
|
+
/**
|
|
504
|
+
* Build Azure OpenAI API URL
|
|
505
|
+
* Format: {endpoint}/openai/deployments/{deploymentName}/chat/completions?api-version={version}
|
|
506
|
+
* @param baseUrl - Azure endpoint (e.g., https://my-resource.openai.azure.com)
|
|
507
|
+
* @param model - Deployment name (used as model in Azure)
|
|
508
|
+
* @param apiVersion - API version (e.g., 2024-08-01-preview)
|
|
509
|
+
*/
|
|
510
|
+
declare function buildAzureOpenAIApiUrl(baseUrl: string, model: string, apiVersion: string): string;
|
|
511
|
+
/**
|
|
512
|
+
* Build OpenAI Responses API URL
|
|
513
|
+
* Format: {baseUrl}/v1/responses
|
|
514
|
+
*/
|
|
515
|
+
declare function buildOpenAIResponseApiUrl(baseUrl: string): string;
|
|
516
|
+
|
|
517
|
+
declare const resolveProviderEndpoint: typeof resolveProviderEndpoint$1;
|
|
518
|
+
/**
|
|
519
|
+
* Build API URL based on provider format and options
|
|
520
|
+
* This is the main entry point for URL building
|
|
521
|
+
*/
|
|
522
|
+
declare function buildProviderApiUrl(provider: LLMProvider, options?: {
|
|
523
|
+
model?: string;
|
|
524
|
+
stream?: boolean;
|
|
525
|
+
}): string;
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Request Header Building Utilities
|
|
529
|
+
*
|
|
530
|
+
* Functions for building correct request headers based on provider format.
|
|
531
|
+
*/
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Get request headers based on provider format
|
|
535
|
+
*/
|
|
536
|
+
declare function getProviderHeaders(provider: LLMProvider, apiKey: string): Record<string, string>;
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Message Format Conversion Utilities
|
|
540
|
+
*
|
|
541
|
+
* Functions for converting SimpleChatMessage to different API formats.
|
|
542
|
+
*/
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Convert SimpleChatMessage to OpenAI-compatible format (covers OpenAI, OpenRouter,
|
|
546
|
+
* and other OpenAI-compatible providers — DO NOT call from Anthropic / Gemini paths,
|
|
547
|
+
* which have their own converters above).
|
|
548
|
+
*
|
|
549
|
+
* - Text only: { role, content: string }
|
|
550
|
+
* - With media: { role, content: [{ type: "text" | "image_url" | "input_audio" | "video_url", ... }] }
|
|
551
|
+
*
|
|
552
|
+
* Audio is emitted as `input_audio` with base64 + format (the standard OpenAI / OpenRouter
|
|
553
|
+
* shape). Video is emitted as `video_url`: HTTPS URLs pass through; local data is sent as a
|
|
554
|
+
* `data:<mime>;base64,...` URL with a 25 MB cap before the request is even built.
|
|
555
|
+
*/
|
|
556
|
+
declare function convertMessageToOpenAI(msg: SimpleChatMessage): OpenAIMessage;
|
|
557
|
+
/**
|
|
558
|
+
* Convert SimpleChatMessage to Anthropic format (with vision support)
|
|
559
|
+
* Anthropic format:
|
|
560
|
+
* - Text only: { role, content: string }
|
|
561
|
+
* - With images: { role, content: [{ type: "text", text: "..." }, { type: "image", source: { type: "base64", media_type: "...", data: "..." } }] }
|
|
562
|
+
*/
|
|
563
|
+
declare function convertMessageToAnthropic(msg: SimpleChatMessage): AnthropicMessage;
|
|
564
|
+
/**
|
|
565
|
+
* Minimal Gemini part shape for the simple-chat DIRECT path (text + inline
|
|
566
|
+
* media only), serialized with the official REST JSON casing
|
|
567
|
+
* (`inlineData` / `mimeType`).
|
|
568
|
+
*
|
|
569
|
+
* NOT the same wire model as the transformer pipeline's full `GeminiPart`
|
|
570
|
+
* union in `transformer/transformers/utils/gemini.util.ts` (function calls /
|
|
571
|
+
* file data, snake_case alias keys). The two paths intentionally serialize
|
|
572
|
+
* differently — do not merge them blindly.
|
|
573
|
+
*/
|
|
574
|
+
interface SimpleChatGeminiPart {
|
|
575
|
+
text?: string;
|
|
576
|
+
inlineData?: {
|
|
577
|
+
mimeType: string;
|
|
578
|
+
data: string;
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
/** Gemini message for the simple-chat direct path. */
|
|
582
|
+
interface SimpleChatGeminiMessage {
|
|
583
|
+
role: string;
|
|
584
|
+
parts: SimpleChatGeminiPart[];
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Convert SimpleChatMessage to Gemini format (with vision support)
|
|
588
|
+
* Gemini format:
|
|
589
|
+
* - { role: "user"|"model", parts: [{ text: "..." }, { inlineData: { mimeType: "...", data: "..." } }] }
|
|
590
|
+
*/
|
|
591
|
+
declare function convertMessageToGemini(msg: SimpleChatMessage): SimpleChatGeminiMessage;
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* OpenRouter Provider Utilities
|
|
595
|
+
*
|
|
596
|
+
* Functions for handling OpenRouter-specific configuration and routing.
|
|
597
|
+
*/
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Get OpenRouter provider routing config from model configuration
|
|
601
|
+
* Returns the provider routing config if the provider is OpenRouter and model has config
|
|
602
|
+
*/
|
|
603
|
+
declare function getOpenRouterProviderConfig(provider: LLMProvider, modelId: string): OpenRouterProviderRouting | undefined;
|
|
604
|
+
/**
|
|
605
|
+
* Add OpenRouter provider routing to request body if applicable
|
|
606
|
+
*/
|
|
607
|
+
declare function addOpenRouterProviderToRequest(requestBody: Record<string, unknown>, provider: LLMProvider, modelId: string): Record<string, unknown>;
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Native Search Injector
|
|
611
|
+
*
|
|
612
|
+
* Detects provider-native web search support and builds request body
|
|
613
|
+
* augmentations for OpenAI, Anthropic, Google, xAI, and OpenRouter.
|
|
614
|
+
*
|
|
615
|
+
* This module does NOT execute searches — it only prepares the request
|
|
616
|
+
* so the LLM provider's server-side search runs automatically.
|
|
617
|
+
*
|
|
618
|
+
* @module completion/NativeSearchInjector
|
|
619
|
+
*/
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Detect whether a model supports provider-native web search.
|
|
623
|
+
*
|
|
624
|
+
* Detection order:
|
|
625
|
+
* 1. OpenRouter — detected by provider base URL, not model pattern.
|
|
626
|
+
* 2. xAI — detected by base URL containing `x.ai` or `grok`.
|
|
627
|
+
* 3. Model-pattern match against known providers (OpenAI, Anthropic, Google).
|
|
628
|
+
* 4. If `userExplicit` is true, fall back to API format mapping even
|
|
629
|
+
* when the model ID doesn't match known patterns (user opted-in).
|
|
630
|
+
*/
|
|
631
|
+
declare function detectNativeSearch(modelId: string, apiFormat: ApiFormat, provider: LLMProvider, userExplicit?: boolean): NativeSearchDetectionResult;
|
|
632
|
+
/**
|
|
633
|
+
* Build a {@link NativeSearchAugmentation} for the given provider.
|
|
634
|
+
* Returns `null` if the provider is unknown or config is disabled.
|
|
635
|
+
*/
|
|
636
|
+
declare function buildNativeSearchAugmentation(nativeProvider: NativeSearchProvider, config: NativeSearchUserConfig, _apiFormat: ApiFormat, modelId: string): NativeSearchAugmentation | null;
|
|
637
|
+
/**
|
|
638
|
+
* Merge an augmentation into the request body **in-place**.
|
|
639
|
+
*
|
|
640
|
+
* - `additionalTools` are appended to the existing `tools` array.
|
|
641
|
+
* - `bodyFields` are shallow-merged into the top-level body.
|
|
642
|
+
*/
|
|
643
|
+
declare function applyAugmentation(requestBody: Record<string, unknown>, augmentation: NativeSearchAugmentation): Record<string, unknown>;
|
|
644
|
+
|
|
645
|
+
export { type AnthropicTool as A, BuiltinToolExecutor as B, type CompletionOptions as C, emit as D, getBuiltinSearchTools as E, getOpenRouterProviderConfig as F, type GeminiTools as G, getProviderHeaders as H, normalizeAzureEndpoint as I, register as J, release as K, resolveApiFormat as L, type McpToolProvider as M, NATIVE_SEARCH_TOOL_NAMES as N, type OpenAITool as O, resolveProviderEndpoint as P, type SimpleChatGeminiMessage as S, type VisionFallbackProvider as V, type ApiFormat as a, type CompletionResult as b, CompletionService as c, type NativeSearchAugmentation as d, type NativeSearchDetectionResult as e, type NativeSearchProvider as f, type NativeSearchUserConfig as g, type SimpleChatGeminiPart as h, type StreamCallbacks as i, type StreamEvent as j, type StreamEventType as k, type StreamSender as l, addOpenRouterProviderToRequest as m, applyAugmentation as n, attach as o, buildAnthropicApiUrl as p, buildAzureOpenAIApiUrl as q, buildGeminiApiUrl as r, buildNativeSearchAugmentation as s, buildOpenAIApiUrl as t, buildOpenAIResponseApiUrl as u, buildProviderApiUrl as v, convertMessageToAnthropic as w, convertMessageToGemini as x, convertMessageToOpenAI as y, detectNativeSearch as z };
|