@openclaw/ai 0.0.0 → 2026.7.1-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.
- package/LICENSE +21 -0
- package/README.md +27 -3
- package/dist/anthropic-B5gZQM5X.mjs +1383 -0
- package/dist/api-registry-BXYnCOIR.d.mts +33 -0
- package/dist/azure-openai-responses-DNoSk8Uy.mjs +141 -0
- package/dist/azure-openai-responses-client-compat-a_O_GVQV.mjs +41 -0
- package/dist/diagnostics-BaTA9eVl.d.mts +25 -0
- package/dist/diagnostics-COpOtRwq.mjs +36 -0
- package/dist/diagnostics.d.mts +2 -0
- package/dist/diagnostics.mjs +2 -0
- package/dist/env-api-keys-CtMlqaQ4.mjs +171 -0
- package/dist/event-stream-0nZeBKl2.d.mts +26 -0
- package/dist/event-stream-ReMmOTzX.mjs +65 -0
- package/dist/event-stream.d.mts +2 -0
- package/dist/event-stream.mjs +2 -0
- package/dist/github-copilot-headers-BsH5cqGj.mjs +48 -0
- package/dist/google-D6sIQ1bL.mjs +55 -0
- package/dist/google-shared-ZPSl2qTi.mjs +548 -0
- package/dist/google-vertex-rDGwkoZK.mjs +111 -0
- package/dist/hash-CHgqbJmD.mjs +16 -0
- package/dist/headers-B_e4-1J0.mjs +9 -0
- package/dist/host-4t713IeR.mjs +37 -0
- package/dist/index-BoTnz8cv.d.mts +74 -0
- package/dist/index.d.mts +69 -0
- package/dist/index.mjs +7 -0
- package/dist/internal/anthropic.d.mts +234 -0
- package/dist/internal/anthropic.mjs +4 -0
- package/dist/internal/openai.d.mts +244 -0
- package/dist/internal/openai.mjs +7 -0
- package/dist/internal/runtime.d.mts +245 -0
- package/dist/internal/runtime.mjs +176 -0
- package/dist/internal/shared.d.mts +48 -0
- package/dist/internal/shared.mjs +3 -0
- package/dist/json-parse-DzNSIQBq.mjs +134 -0
- package/dist/llm-request-activity-CehVkZP-.mjs +35 -0
- package/dist/mistral-CePVNdws.mjs +563 -0
- package/dist/model-utils-DgmOla96.mjs +69 -0
- package/dist/openai-chatgpt-jwt-DhAAzLkj.mjs +39 -0
- package/dist/openai-chatgpt-responses-DVC4Bk_A.mjs +1068 -0
- package/dist/openai-completions-B9QLIq2U.mjs +844 -0
- package/dist/openai-responses-B6LylGxM.mjs +136 -0
- package/dist/openai-responses-shared-sj2YUPYc.mjs +1944 -0
- package/dist/openai-tool-projection-BknoV11q.mjs +195 -0
- package/dist/providers.d.mts +11 -0
- package/dist/providers.mjs +109 -0
- package/dist/reasoning-tag-text-partitioner-axhAdUwg.mjs +394 -0
- package/dist/sanitize-unicode-BZiVbGwK.d.mts +24 -0
- package/dist/sanitize-unicode-DT5o51ur.mjs +26 -0
- package/dist/src-CZ503MYJ.mjs +99 -0
- package/dist/stream-CREqxHgU.mjs +74 -0
- package/dist/stream-first-event-timeout-RjWszj8c.mjs +106 -0
- package/dist/streaming-byte-guard-BrbkbwUu.mjs +46 -0
- package/dist/tool-schema-json-projection-BXtBc_mD.mjs +74 -0
- package/dist/transform-messages-BhGF_fF4.mjs +507 -0
- package/dist/types-BVVgDSdq.d.mts +1 -0
- package/dist/types-DRgdPqaZ.d.mts +587 -0
- package/dist/types.d.mts +6 -0
- package/dist/types.mjs +5 -0
- package/dist/validation-BDMWOr8d.d.mts +9 -0
- package/dist/validation-FrchoOlv.mjs +199 -0
- package/dist/validation.d.mts +2 -0
- package/dist/validation.mjs +2 -0
- package/npm-shrinkwrap.json +645 -0
- package/package.json +74 -2
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { E as Model, F as SimpleStreamOptions, R as StreamFunction, n as Api, o as AssistantMessageEventStreamContract, u as Context, z as StreamOptions } from "./types-DRgdPqaZ.mjs";
|
|
2
|
+
|
|
3
|
+
//#region packages/ai/src/api-registry.d.ts
|
|
4
|
+
/** Runtime stream adapter signature stored in the API provider registry. */
|
|
5
|
+
type ApiStreamFunction = (model: Model, context: Context, options?: StreamOptions) => AssistantMessageEventStreamContract;
|
|
6
|
+
/** Runtime simple-stream adapter signature stored in the API provider registry. */
|
|
7
|
+
type ApiStreamSimpleFunction = (model: Model, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStreamContract;
|
|
8
|
+
/** Provider implementation registered by core or plugins for a specific model API. */
|
|
9
|
+
interface ApiProvider<TApi extends Api = Api, TOptions extends StreamOptions = StreamOptions> {
|
|
10
|
+
/** Model API id this provider handles. */
|
|
11
|
+
api: TApi;
|
|
12
|
+
/** Full streaming adapter for callers that already own structured options. */
|
|
13
|
+
stream: StreamFunction<TApi, TOptions>;
|
|
14
|
+
/** Simple streaming adapter used by agent and plugin runtime defaults. */
|
|
15
|
+
streamSimple: StreamFunction<TApi, SimpleStreamOptions>;
|
|
16
|
+
}
|
|
17
|
+
/** Type-erased provider returned by a registry after API guards are installed. */
|
|
18
|
+
interface RegisteredApiProvider {
|
|
19
|
+
api: Api;
|
|
20
|
+
stream: ApiStreamFunction;
|
|
21
|
+
streamSimple: ApiStreamSimpleFunction;
|
|
22
|
+
}
|
|
23
|
+
/** Creates an isolated provider registry for one runtime or tenant. */
|
|
24
|
+
declare function createApiRegistry(): {
|
|
25
|
+
registerApiProvider: <TApi extends Api, TOptions extends StreamOptions>(provider: ApiProvider<TApi, TOptions>, sourceId?: string) => void;
|
|
26
|
+
getApiProvider: (api: Api) => RegisteredApiProvider | undefined;
|
|
27
|
+
getApiProviders: () => RegisteredApiProvider[];
|
|
28
|
+
unregisterApiProviders: (sourceId: string) => void;
|
|
29
|
+
clearApiProviders: () => void;
|
|
30
|
+
};
|
|
31
|
+
type ApiRegistry = ReturnType<typeof createApiRegistry>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { RegisteredApiProvider as a, ApiStreamSimpleFunction as i, ApiRegistry as n, createApiRegistry as o, ApiStreamFunction as r, ApiProvider as t };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { n as getEnvApiKey } from "./env-api-keys-CtMlqaQ4.mjs";
|
|
2
|
+
import { t as AssistantMessageEventStream } from "./event-stream-ReMmOTzX.mjs";
|
|
3
|
+
import { n as getAiTransportHost } from "./host-4t713IeR.mjs";
|
|
4
|
+
import { o as buildBaseOptions } from "./transform-messages-BhGF_fF4.mjs";
|
|
5
|
+
import { a as resolveResponsesReasoningEffort, n as convertResponsesMessages, o as runResponsesStreamLifecycle, r as createResponsesAssistantOutput, t as applyCommonResponsesParams } from "./openai-responses-shared-sj2YUPYc.mjs";
|
|
6
|
+
import { i as resolveAzureDeploymentNameFromMap, t as isOpenAICompatibleAzureResponsesBaseUrl } from "./azure-openai-responses-client-compat-a_O_GVQV.mjs";
|
|
7
|
+
import { a as clampOpenAIPromptCacheKey } from "./openai-tool-projection-BknoV11q.mjs";
|
|
8
|
+
import OpenAI, { AzureOpenAI } from "openai";
|
|
9
|
+
//#region packages/ai/src/providers/azure-openai-responses.ts
|
|
10
|
+
const DEFAULT_AZURE_API_VERSION = "v1";
|
|
11
|
+
const AZURE_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set([
|
|
12
|
+
"openai",
|
|
13
|
+
"opencode",
|
|
14
|
+
"azure-openai-responses"
|
|
15
|
+
]);
|
|
16
|
+
function resolveDeploymentName(model, options) {
|
|
17
|
+
if (options?.azureDeploymentName) return options.azureDeploymentName;
|
|
18
|
+
return resolveAzureDeploymentNameFromMap({
|
|
19
|
+
modelId: model.id,
|
|
20
|
+
deploymentMap: process.env.AZURE_OPENAI_DEPLOYMENT_NAME_MAP
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function formatAzureOpenAIError(error) {
|
|
24
|
+
if (error instanceof Error) {
|
|
25
|
+
const status = error.status;
|
|
26
|
+
const statusCode = typeof status === "number" ? status : void 0;
|
|
27
|
+
if (statusCode !== void 0) return `Azure OpenAI API error (${statusCode}): ${error.message}`;
|
|
28
|
+
return error.message;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
return JSON.stringify(error);
|
|
32
|
+
} catch {
|
|
33
|
+
return String(error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Generate function for Azure OpenAI Responses API
|
|
38
|
+
*/
|
|
39
|
+
const streamAzureOpenAIResponses = (model, context, options) => {
|
|
40
|
+
const stream = new AssistantMessageEventStream();
|
|
41
|
+
runResponsesStreamLifecycle({
|
|
42
|
+
stream,
|
|
43
|
+
model,
|
|
44
|
+
output: createResponsesAssistantOutput(model, "azure-openai-responses"),
|
|
45
|
+
options,
|
|
46
|
+
createClient: () => {
|
|
47
|
+
return createClient(model, options?.apiKey || getEnvApiKey(model.provider) || "", options);
|
|
48
|
+
},
|
|
49
|
+
buildParams: () => buildParams(model, context, options, resolveDeploymentName(model, options)),
|
|
50
|
+
formatError: formatAzureOpenAIError
|
|
51
|
+
});
|
|
52
|
+
return stream;
|
|
53
|
+
};
|
|
54
|
+
const streamSimpleAzureOpenAIResponses = (model, context, options) => {
|
|
55
|
+
const apiKey = options?.apiKey || getEnvApiKey(model.provider);
|
|
56
|
+
if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
|
|
57
|
+
const base = buildBaseOptions(model, options, apiKey);
|
|
58
|
+
const reasoningEffort = resolveResponsesReasoningEffort(model, options?.reasoning);
|
|
59
|
+
return streamAzureOpenAIResponses(model, context, {
|
|
60
|
+
...base,
|
|
61
|
+
reasoningEffort: reasoningEffort === "max" ? "xhigh" : reasoningEffort
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
function normalizeAzureBaseUrl(baseUrl) {
|
|
65
|
+
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
66
|
+
let url;
|
|
67
|
+
try {
|
|
68
|
+
url = new URL(trimmed);
|
|
69
|
+
} catch {
|
|
70
|
+
throw new Error(`Invalid Azure OpenAI base URL: ${baseUrl}`);
|
|
71
|
+
}
|
|
72
|
+
const isAzureHost = url.hostname.endsWith(".openai.azure.com") || url.hostname.endsWith(".cognitiveservices.azure.com");
|
|
73
|
+
const normalizedPath = url.pathname.replace(/\/+$/, "");
|
|
74
|
+
if (isAzureHost && (normalizedPath === "" || normalizedPath === "/" || normalizedPath === "/openai")) {
|
|
75
|
+
url.pathname = "/openai/v1";
|
|
76
|
+
url.search = "";
|
|
77
|
+
}
|
|
78
|
+
return url.toString().replace(/\/+$/, "");
|
|
79
|
+
}
|
|
80
|
+
function buildDefaultBaseUrl(resourceName) {
|
|
81
|
+
return `https://${resourceName}.openai.azure.com/openai/v1`;
|
|
82
|
+
}
|
|
83
|
+
function resolveAzureConfig(model, options) {
|
|
84
|
+
const apiVersion = options?.azureApiVersion || process.env.AZURE_OPENAI_API_VERSION || DEFAULT_AZURE_API_VERSION;
|
|
85
|
+
const baseUrl = options?.azureBaseUrl?.trim() || process.env.AZURE_OPENAI_BASE_URL?.trim() || void 0;
|
|
86
|
+
const resourceName = options?.azureResourceName || process.env.AZURE_OPENAI_RESOURCE_NAME;
|
|
87
|
+
let resolvedBaseUrl = baseUrl;
|
|
88
|
+
if (!resolvedBaseUrl && resourceName) resolvedBaseUrl = buildDefaultBaseUrl(resourceName);
|
|
89
|
+
if (!resolvedBaseUrl && model.baseUrl) resolvedBaseUrl = model.baseUrl;
|
|
90
|
+
if (!resolvedBaseUrl) throw new Error("Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.");
|
|
91
|
+
return {
|
|
92
|
+
baseUrl: normalizeAzureBaseUrl(resolvedBaseUrl),
|
|
93
|
+
apiVersion
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function createClient(model, apiKeyInput, options) {
|
|
97
|
+
let apiKey = apiKeyInput;
|
|
98
|
+
if (!apiKey) {
|
|
99
|
+
if (!process.env.AZURE_OPENAI_API_KEY) throw new Error("Azure OpenAI API key is required. Set AZURE_OPENAI_API_KEY environment variable or pass it as an argument.");
|
|
100
|
+
apiKey = process.env.AZURE_OPENAI_API_KEY;
|
|
101
|
+
}
|
|
102
|
+
const headers = { ...model.headers };
|
|
103
|
+
if (options?.headers) Object.assign(headers, options.headers);
|
|
104
|
+
const { baseUrl, apiVersion } = resolveAzureConfig(model, options);
|
|
105
|
+
const guardedFetch = getAiTransportHost().buildModelFetch({
|
|
106
|
+
...model,
|
|
107
|
+
baseUrl
|
|
108
|
+
});
|
|
109
|
+
if (isOpenAICompatibleAzureResponsesBaseUrl(baseUrl)) return new OpenAI({
|
|
110
|
+
apiKey,
|
|
111
|
+
dangerouslyAllowBrowser: true,
|
|
112
|
+
defaultHeaders: headers,
|
|
113
|
+
baseURL: baseUrl,
|
|
114
|
+
fetch: guardedFetch
|
|
115
|
+
});
|
|
116
|
+
return new AzureOpenAI({
|
|
117
|
+
apiKey,
|
|
118
|
+
apiVersion,
|
|
119
|
+
dangerouslyAllowBrowser: true,
|
|
120
|
+
defaultHeaders: headers,
|
|
121
|
+
baseURL: baseUrl,
|
|
122
|
+
fetch: guardedFetch
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function buildParams(model, context, options, deploymentName) {
|
|
126
|
+
const params = {
|
|
127
|
+
model: deploymentName,
|
|
128
|
+
input: convertResponsesMessages(model, context, AZURE_TOOL_CALL_PROVIDERS),
|
|
129
|
+
stream: true,
|
|
130
|
+
prompt_cache_key: options?.cacheRetention === "none" ? void 0 : clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId)
|
|
131
|
+
};
|
|
132
|
+
applyCommonResponsesParams(params, model, context, options);
|
|
133
|
+
return params;
|
|
134
|
+
}
|
|
135
|
+
const testing = {
|
|
136
|
+
isOpenAICompatibleAzureResponsesBaseUrl,
|
|
137
|
+
normalizeAzureBaseUrl,
|
|
138
|
+
resolveAzureConfig
|
|
139
|
+
};
|
|
140
|
+
//#endregion
|
|
141
|
+
export { streamAzureOpenAIResponses, streamSimpleAzureOpenAIResponses, testing };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region packages/ai/src/providers/azure-deployment-map.ts
|
|
2
|
+
/** Parses AZURE_OPENAI_DEPLOYMENT_MAP-style model=deployment entries. */
|
|
3
|
+
function parseAzureDeploymentNameMap(value) {
|
|
4
|
+
const map = /* @__PURE__ */ new Map();
|
|
5
|
+
if (!value) return map;
|
|
6
|
+
for (const entry of value.split(",")) {
|
|
7
|
+
const trimmed = entry.trim();
|
|
8
|
+
if (!trimmed) continue;
|
|
9
|
+
const separator = trimmed.indexOf("=");
|
|
10
|
+
if (separator <= 0) continue;
|
|
11
|
+
const modelId = trimmed.slice(0, separator).trim();
|
|
12
|
+
const deploymentName = trimmed.slice(separator + 1).trim();
|
|
13
|
+
if (!modelId || !deploymentName) continue;
|
|
14
|
+
map.set(modelId, deploymentName);
|
|
15
|
+
}
|
|
16
|
+
return map;
|
|
17
|
+
}
|
|
18
|
+
/** Resolves the Azure deployment name for a model id, falling back to the model id. */
|
|
19
|
+
function resolveAzureDeploymentNameFromMap(params) {
|
|
20
|
+
return parseAzureDeploymentNameMap(params.deploymentMap).get(params.modelId) || params.modelId;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region packages/ai/src/providers/azure-openai-responses-client-compat.ts
|
|
24
|
+
function isTraditionalAzureOpenAIHost(hostname) {
|
|
25
|
+
return hostname.endsWith(".openai.azure.com") || hostname.endsWith(".cognitiveservices.azure.com");
|
|
26
|
+
}
|
|
27
|
+
function isOpenAICompatibleAzureResponsesBaseUrl(baseUrl) {
|
|
28
|
+
let url;
|
|
29
|
+
try {
|
|
30
|
+
url = new URL(baseUrl);
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
if (isTraditionalAzureOpenAIHost(url.hostname)) return false;
|
|
35
|
+
const hostname = url.hostname.toLowerCase();
|
|
36
|
+
if (!(hostname.endsWith(".services.ai.azure.com") || hostname.endsWith(".api.cognitive.microsoft.com"))) return false;
|
|
37
|
+
const normalizedPath = url.pathname.replace(/\/+$/, "");
|
|
38
|
+
return normalizedPath === "/openai/v1" || normalizedPath.endsWith("/openai/v1");
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { resolveAzureDeploymentNameFromMap as i, isTraditionalAzureOpenAIHost as n, parseAzureDeploymentNameMap as r, isOpenAICompatibleAzureResponsesBaseUrl as t };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region packages/llm-core/src/utils/diagnostics.d.ts
|
|
2
|
+
interface DiagnosticErrorInfo {
|
|
3
|
+
name?: string;
|
|
4
|
+
message: string;
|
|
5
|
+
stack?: string;
|
|
6
|
+
code?: string | number;
|
|
7
|
+
}
|
|
8
|
+
interface AssistantMessageDiagnostic {
|
|
9
|
+
type: string;
|
|
10
|
+
timestamp: number;
|
|
11
|
+
error?: DiagnosticErrorInfo;
|
|
12
|
+
details?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
/** Formats arbitrary thrown values into diagnostic-safe text. */
|
|
15
|
+
declare function formatThrownValue(value: unknown): string;
|
|
16
|
+
/** Extracts serializable diagnostic error fields from Error and non-Error throws. */
|
|
17
|
+
declare function extractDiagnosticError(error: unknown): DiagnosticErrorInfo;
|
|
18
|
+
/** Creates a timestamped assistant-message diagnostic entry. */
|
|
19
|
+
declare function createAssistantMessageDiagnostic(type: string, error: unknown, details?: Record<string, unknown>): AssistantMessageDiagnostic;
|
|
20
|
+
/** Appends a diagnostic while preserving existing message diagnostics. */
|
|
21
|
+
declare function appendAssistantMessageDiagnostic(message: {
|
|
22
|
+
diagnostics?: AssistantMessageDiagnostic[];
|
|
23
|
+
}, diagnostic: AssistantMessageDiagnostic): void;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { extractDiagnosticError as a, createAssistantMessageDiagnostic as i, DiagnosticErrorInfo as n, formatThrownValue as o, appendAssistantMessageDiagnostic as r, AssistantMessageDiagnostic as t };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region packages/llm-core/src/utils/diagnostics.ts
|
|
2
|
+
/** Formats arbitrary thrown values into diagnostic-safe text. */
|
|
3
|
+
function formatThrownValue(value) {
|
|
4
|
+
if (value instanceof Error) return value.message || value.name;
|
|
5
|
+
if (typeof value === "string") return value;
|
|
6
|
+
return String(value);
|
|
7
|
+
}
|
|
8
|
+
/** Extracts serializable diagnostic error fields from Error and non-Error throws. */
|
|
9
|
+
function extractDiagnosticError(error) {
|
|
10
|
+
if (!(error instanceof Error)) return {
|
|
11
|
+
name: "ThrownValue",
|
|
12
|
+
message: formatThrownValue(error)
|
|
13
|
+
};
|
|
14
|
+
const code = error.code;
|
|
15
|
+
return {
|
|
16
|
+
name: error.name || void 0,
|
|
17
|
+
message: error.message || error.name,
|
|
18
|
+
stack: error.stack,
|
|
19
|
+
code: typeof code === "string" || typeof code === "number" ? code : void 0
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** Creates a timestamped assistant-message diagnostic entry. */
|
|
23
|
+
function createAssistantMessageDiagnostic(type, error, details) {
|
|
24
|
+
return {
|
|
25
|
+
type,
|
|
26
|
+
timestamp: Date.now(),
|
|
27
|
+
error: extractDiagnosticError(error),
|
|
28
|
+
details
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Appends a diagnostic while preserving existing message diagnostics. */
|
|
32
|
+
function appendAssistantMessageDiagnostic(message, diagnostic) {
|
|
33
|
+
message.diagnostics = [...message.diagnostics ?? [], diagnostic];
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { formatThrownValue as i, createAssistantMessageDiagnostic as n, extractDiagnosticError as r, appendAssistantMessageDiagnostic as t };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as extractDiagnosticError, i as createAssistantMessageDiagnostic, n as DiagnosticErrorInfo, o as formatThrownValue, r as appendAssistantMessageDiagnostic, t as AssistantMessageDiagnostic } from "./diagnostics-BaTA9eVl.mjs";
|
|
2
|
+
export { AssistantMessageDiagnostic, DiagnosticErrorInfo, appendAssistantMessageDiagnostic, createAssistantMessageDiagnostic, extractDiagnosticError, formatThrownValue };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { i as formatThrownValue, n as createAssistantMessageDiagnostic, r as extractDiagnosticError, t as appendAssistantMessageDiagnostic } from "./diagnostics-COpOtRwq.mjs";
|
|
2
|
+
export { appendAssistantMessageDiagnostic, createAssistantMessageDiagnostic, extractDiagnosticError, formatThrownValue };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __exportAll = (all, no_symbols) => {
|
|
5
|
+
let target = {};
|
|
6
|
+
for (var name in all) __defProp(target, name, {
|
|
7
|
+
get: all[name],
|
|
8
|
+
enumerable: true
|
|
9
|
+
});
|
|
10
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
11
|
+
return target;
|
|
12
|
+
};
|
|
13
|
+
var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region packages/ai/src/env-api-keys.ts
|
|
16
|
+
let existsSync = null;
|
|
17
|
+
let homedir = null;
|
|
18
|
+
let join = null;
|
|
19
|
+
const dynamicImport = (specifier) => import(specifier);
|
|
20
|
+
const NODE_FS_SPECIFIER = "node:fs";
|
|
21
|
+
const NODE_OS_SPECIFIER = "node:os";
|
|
22
|
+
const NODE_PATH_SPECIFIER = "node:path";
|
|
23
|
+
function loadNodeBuiltinModule(specifier) {
|
|
24
|
+
const getBuiltinModule = typeof process !== "undefined" ? process : void 0;
|
|
25
|
+
if (typeof getBuiltinModule?.getBuiltinModule === "function") return getBuiltinModule.getBuiltinModule(specifier);
|
|
26
|
+
if (typeof __require === "function") return __require(specifier);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
function loadNodeHelpersSync() {
|
|
30
|
+
try {
|
|
31
|
+
const fsModule = loadNodeBuiltinModule(NODE_FS_SPECIFIER);
|
|
32
|
+
const osModule = loadNodeBuiltinModule(NODE_OS_SPECIFIER);
|
|
33
|
+
const pathModule = loadNodeBuiltinModule(NODE_PATH_SPECIFIER);
|
|
34
|
+
existsSync ??= fsModule?.existsSync ?? null;
|
|
35
|
+
homedir ??= osModule?.homedir ?? null;
|
|
36
|
+
join ??= pathModule?.join ?? null;
|
|
37
|
+
if (!existsSync || !homedir || !join) return false;
|
|
38
|
+
return true;
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) {
|
|
44
|
+
if (!loadNodeHelpersSync()) {
|
|
45
|
+
dynamicImport(NODE_FS_SPECIFIER).then((m) => {
|
|
46
|
+
existsSync = m.existsSync;
|
|
47
|
+
});
|
|
48
|
+
dynamicImport(NODE_OS_SPECIFIER).then((m) => {
|
|
49
|
+
homedir = m.homedir;
|
|
50
|
+
});
|
|
51
|
+
dynamicImport(NODE_PATH_SPECIFIER).then((m) => {
|
|
52
|
+
join = m.join;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
let procEnvCache = null;
|
|
57
|
+
function getProcessEnv() {
|
|
58
|
+
return typeof process === "undefined" ? void 0 : process.env;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Fallback for https://github.com/oven-sh/bun/issues/27802
|
|
62
|
+
* Bun compiled binaries have an empty `process.env` inside sandbox
|
|
63
|
+
* environments on Linux. We can recover the env from `/proc/self/environ`.
|
|
64
|
+
*/
|
|
65
|
+
function getProcEnv(key) {
|
|
66
|
+
if (typeof process === "undefined" || !process.versions?.bun) return;
|
|
67
|
+
const env = getProcessEnv();
|
|
68
|
+
if (!env) return;
|
|
69
|
+
if (Object.keys(env).length > 0) return;
|
|
70
|
+
if (procEnvCache === null) {
|
|
71
|
+
procEnvCache = /* @__PURE__ */ new Map();
|
|
72
|
+
try {
|
|
73
|
+
const { readFileSync } = __require("node:fs");
|
|
74
|
+
const data = readFileSync("/proc/self/environ", "utf-8");
|
|
75
|
+
for (const entry of data.split("\0")) {
|
|
76
|
+
const idx = entry.indexOf("=");
|
|
77
|
+
if (idx > 0) procEnvCache.set(entry.slice(0, idx), entry.slice(idx + 1));
|
|
78
|
+
}
|
|
79
|
+
} catch {}
|
|
80
|
+
}
|
|
81
|
+
return procEnvCache.get(key);
|
|
82
|
+
}
|
|
83
|
+
function getEnvValue(key) {
|
|
84
|
+
return getProcessEnv()?.[key] || getProcEnv(key);
|
|
85
|
+
}
|
|
86
|
+
let cachedVertexAdcCredentialsExists = null;
|
|
87
|
+
function hasVertexAdcCredentials() {
|
|
88
|
+
if (cachedVertexAdcCredentialsExists === null) {
|
|
89
|
+
if (!existsSync || !homedir || !join) {
|
|
90
|
+
if (!(typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) || !loadNodeHelpersSync()) return false;
|
|
91
|
+
}
|
|
92
|
+
const nodeExistsSync = existsSync;
|
|
93
|
+
const nodeHomedir = homedir;
|
|
94
|
+
const nodeJoin = join;
|
|
95
|
+
if (!nodeExistsSync || !nodeHomedir || !nodeJoin) return false;
|
|
96
|
+
const gacPath = getEnvValue("GOOGLE_APPLICATION_CREDENTIALS");
|
|
97
|
+
if (gacPath) cachedVertexAdcCredentialsExists = nodeExistsSync(gacPath) ? true : null;
|
|
98
|
+
else cachedVertexAdcCredentialsExists = nodeExistsSync(nodeJoin(nodeHomedir(), ".config", "gcloud", "application_default_credentials.json")) ? true : null;
|
|
99
|
+
}
|
|
100
|
+
return cachedVertexAdcCredentialsExists === true;
|
|
101
|
+
}
|
|
102
|
+
function getApiKeyEnvVars(provider) {
|
|
103
|
+
if (provider === "github-copilot") return ["COPILOT_GITHUB_TOKEN"];
|
|
104
|
+
if (provider === "anthropic") return ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"];
|
|
105
|
+
if (provider === "moonshot") return ["MOONSHOT_API_KEY", "KIMI_API_KEY"];
|
|
106
|
+
if (provider === "kimi" || provider === "kimi-coding") return ["KIMI_API_KEY", "KIMICODE_API_KEY"];
|
|
107
|
+
const envVar = {
|
|
108
|
+
openai: "OPENAI_API_KEY",
|
|
109
|
+
"meta": "MODEL_API_KEY",
|
|
110
|
+
"azure-openai-responses": "AZURE_OPENAI_API_KEY",
|
|
111
|
+
deepseek: "DEEPSEEK_API_KEY",
|
|
112
|
+
google: "GEMINI_API_KEY",
|
|
113
|
+
"google-vertex": "GOOGLE_CLOUD_API_KEY",
|
|
114
|
+
groq: "GROQ_API_KEY",
|
|
115
|
+
cerebras: "CEREBRAS_API_KEY",
|
|
116
|
+
xai: "XAI_API_KEY",
|
|
117
|
+
openrouter: "OPENROUTER_API_KEY",
|
|
118
|
+
"vercel-ai-gateway": "AI_GATEWAY_API_KEY",
|
|
119
|
+
zai: "ZAI_API_KEY",
|
|
120
|
+
mistral: "MISTRAL_API_KEY",
|
|
121
|
+
minimax: "MINIMAX_API_KEY",
|
|
122
|
+
"minimax-cn": "MINIMAX_CN_API_KEY",
|
|
123
|
+
moonshotai: "MOONSHOT_API_KEY",
|
|
124
|
+
"moonshotai-cn": "MOONSHOT_API_KEY",
|
|
125
|
+
huggingface: "HF_TOKEN",
|
|
126
|
+
fireworks: "FIREWORKS_API_KEY",
|
|
127
|
+
together: "TOGETHER_API_KEY",
|
|
128
|
+
opencode: "OPENCODE_API_KEY",
|
|
129
|
+
"opencode-go": "OPENCODE_API_KEY",
|
|
130
|
+
"cloudflare-workers-ai": "CLOUDFLARE_API_KEY",
|
|
131
|
+
"cloudflare-ai-gateway": "CLOUDFLARE_API_KEY",
|
|
132
|
+
xiaomi: "XIAOMI_API_KEY",
|
|
133
|
+
"xiaomi-token-plan-cn": "XIAOMI_TOKEN_PLAN_CN_API_KEY",
|
|
134
|
+
"xiaomi-token-plan-ams": "XIAOMI_TOKEN_PLAN_AMS_API_KEY",
|
|
135
|
+
"xiaomi-token-plan-sgp": "XIAOMI_TOKEN_PLAN_SGP_API_KEY"
|
|
136
|
+
}[provider];
|
|
137
|
+
return envVar ? [envVar] : void 0;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Find configured environment variables that can provide an API key for a provider.
|
|
141
|
+
*
|
|
142
|
+
* This only reports actual API key variables. It intentionally excludes ambient
|
|
143
|
+
* credential sources such as AWS profiles, AWS IAM credentials, and Google
|
|
144
|
+
* Application Default Credentials.
|
|
145
|
+
*/
|
|
146
|
+
function findEnvKeys(provider) {
|
|
147
|
+
const envVars = getApiKeyEnvVars(provider);
|
|
148
|
+
if (!envVars) return;
|
|
149
|
+
const found = envVars.filter((envVar) => Boolean(getEnvValue(envVar)));
|
|
150
|
+
return found.length > 0 ? found : void 0;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get API key for provider from known environment variables, e.g. OPENAI_API_KEY.
|
|
154
|
+
*
|
|
155
|
+
* Will not return API keys for providers that require OAuth tokens.
|
|
156
|
+
*/
|
|
157
|
+
function getEnvApiKey(provider) {
|
|
158
|
+
const envKeys = findEnvKeys(provider);
|
|
159
|
+
if (envKeys?.[0]) return getEnvValue(envKeys[0]);
|
|
160
|
+
if (provider === "google-vertex") {
|
|
161
|
+
const hasCredentials = hasVertexAdcCredentials();
|
|
162
|
+
const hasProject = Boolean(getEnvValue("GOOGLE_CLOUD_PROJECT") || getEnvValue("GCLOUD_PROJECT"));
|
|
163
|
+
const hasLocation = Boolean(getEnvValue("GOOGLE_CLOUD_LOCATION"));
|
|
164
|
+
if (hasCredentials && hasProject && hasLocation) return "<authenticated>";
|
|
165
|
+
}
|
|
166
|
+
if (provider === "amazon-bedrock") {
|
|
167
|
+
if (getEnvValue("AWS_PROFILE") || getEnvValue("AWS_ACCESS_KEY_ID") && getEnvValue("AWS_SECRET_ACCESS_KEY") || getEnvValue("AWS_BEARER_TOKEN_BEDROCK") || getEnvValue("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") || getEnvValue("AWS_CONTAINER_CREDENTIALS_FULL_URI") || getEnvValue("AWS_WEB_IDENTITY_TOKEN_FILE")) return "<authenticated>";
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
export { getEnvApiKey as n, __exportAll as r, findEnvKeys as t };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { a as AssistantMessageEvent, i as AssistantMessage, o as AssistantMessageEventStreamContract } from "./types-DRgdPqaZ.mjs";
|
|
2
|
+
|
|
3
|
+
//#region packages/llm-core/src/utils/event-stream.d.ts
|
|
4
|
+
/** Generic async-iterable event stream with a separately awaited final result. */
|
|
5
|
+
declare class EventStream<T, R = T> implements AsyncIterable<T> {
|
|
6
|
+
private queue;
|
|
7
|
+
private waiting;
|
|
8
|
+
private done;
|
|
9
|
+
private finalResultPromise;
|
|
10
|
+
private resolveFinalResult;
|
|
11
|
+
private isComplete;
|
|
12
|
+
private extractResult;
|
|
13
|
+
constructor(isComplete: (event: T) => boolean, extractResult: (event: T) => R);
|
|
14
|
+
push(event: T): void;
|
|
15
|
+
end(result?: R): void;
|
|
16
|
+
[Symbol.asyncIterator](): AsyncIterator<T>;
|
|
17
|
+
result(): Promise<R>;
|
|
18
|
+
}
|
|
19
|
+
/** Assistant-message event stream that resolves on done/error terminal events. */
|
|
20
|
+
declare class AssistantMessageEventStream extends EventStream<AssistantMessageEvent, AssistantMessage> implements AssistantMessageEventStreamContract {
|
|
21
|
+
constructor();
|
|
22
|
+
}
|
|
23
|
+
/** Creates an assistant-message stream for provider and plugin adapters. */
|
|
24
|
+
declare function createAssistantMessageEventStream(): AssistantMessageEventStream;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { EventStream as n, createAssistantMessageEventStream as r, AssistantMessageEventStream as t };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
//#region packages/llm-core/src/utils/event-stream.ts
|
|
2
|
+
/** Generic async-iterable event stream with a separately awaited final result. */
|
|
3
|
+
var EventStream = class {
|
|
4
|
+
constructor(isComplete, extractResult) {
|
|
5
|
+
this.queue = [];
|
|
6
|
+
this.waiting = [];
|
|
7
|
+
this.done = false;
|
|
8
|
+
this.isComplete = isComplete;
|
|
9
|
+
this.extractResult = extractResult;
|
|
10
|
+
this.finalResultPromise = new Promise((resolve) => {
|
|
11
|
+
this.resolveFinalResult = resolve;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
push(event) {
|
|
15
|
+
if (this.done) return;
|
|
16
|
+
if (this.isComplete(event)) {
|
|
17
|
+
this.done = true;
|
|
18
|
+
this.resolveFinalResult(this.extractResult(event));
|
|
19
|
+
}
|
|
20
|
+
const waiter = this.waiting.shift();
|
|
21
|
+
if (waiter) waiter({
|
|
22
|
+
value: event,
|
|
23
|
+
done: false
|
|
24
|
+
});
|
|
25
|
+
else this.queue.push(event);
|
|
26
|
+
}
|
|
27
|
+
end(result) {
|
|
28
|
+
this.done = true;
|
|
29
|
+
if (result !== void 0) this.resolveFinalResult(result);
|
|
30
|
+
while (this.waiting.length > 0) this.waiting.shift()({
|
|
31
|
+
value: void 0,
|
|
32
|
+
done: true
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async *[Symbol.asyncIterator]() {
|
|
36
|
+
while (true) if (this.queue.length > 0) yield this.queue.shift();
|
|
37
|
+
else if (this.done) return;
|
|
38
|
+
else {
|
|
39
|
+
const result = await new Promise((resolve) => {
|
|
40
|
+
this.waiting.push(resolve);
|
|
41
|
+
});
|
|
42
|
+
if (result.done) return;
|
|
43
|
+
yield result.value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
result() {
|
|
47
|
+
return this.finalResultPromise;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/** Assistant-message event stream that resolves on done/error terminal events. */
|
|
51
|
+
var AssistantMessageEventStream = class extends EventStream {
|
|
52
|
+
constructor() {
|
|
53
|
+
super((event) => event.type === "done" || event.type === "error", (event) => {
|
|
54
|
+
if (event.type === "done") return event.message;
|
|
55
|
+
else if (event.type === "error") return event.error;
|
|
56
|
+
throw new Error("Unexpected event type for final result");
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
/** Creates an assistant-message stream for provider and plugin adapters. */
|
|
61
|
+
function createAssistantMessageEventStream() {
|
|
62
|
+
return new AssistantMessageEventStream();
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { EventStream as n, createAssistantMessageEventStream as r, AssistantMessageEventStream as t };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//#region packages/ai/src/providers/cache-retention.ts
|
|
2
|
+
/**
|
|
3
|
+
* Resolve cache retention preference.
|
|
4
|
+
* Defaults to "short" and uses OPENCLAW_CACHE_RETENTION for backward compatibility.
|
|
5
|
+
*/
|
|
6
|
+
function resolveCacheRetention(cacheRetention) {
|
|
7
|
+
if (cacheRetention) return cacheRetention;
|
|
8
|
+
if (typeof process !== "undefined" && process.env.OPENCLAW_CACHE_RETENTION === "long") return "long";
|
|
9
|
+
return "short";
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region packages/ai/src/providers/cloudflare.ts
|
|
13
|
+
function isCloudflareProvider(provider) {
|
|
14
|
+
return provider === "cloudflare-workers-ai" || provider === "cloudflare-ai-gateway";
|
|
15
|
+
}
|
|
16
|
+
/** Substitute `{VAR}` placeholders in a Cloudflare baseUrl from process.env. */
|
|
17
|
+
function resolveCloudflareBaseUrl(model) {
|
|
18
|
+
const url = model.baseUrl;
|
|
19
|
+
if (!url.includes("{")) return url;
|
|
20
|
+
return url.replace(/\{([A-Z_][A-Z0-9_]*)\}/g, (_match, name) => {
|
|
21
|
+
const value = process.env[name];
|
|
22
|
+
if (!value) throw new Error(`${name} is required for provider ${model.provider} but is not set.`);
|
|
23
|
+
return value;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region packages/ai/src/providers/github-copilot-headers.ts
|
|
28
|
+
function inferCopilotInitiator(messages) {
|
|
29
|
+
const last = messages[messages.length - 1];
|
|
30
|
+
return last && last.role !== "user" ? "agent" : "user";
|
|
31
|
+
}
|
|
32
|
+
function hasCopilotVisionInput(messages) {
|
|
33
|
+
return messages.some((msg) => {
|
|
34
|
+
if (msg.role === "user" && Array.isArray(msg.content)) return msg.content.some((c) => c.type === "image");
|
|
35
|
+
if (msg.role === "toolResult" && Array.isArray(msg.content)) return msg.content.some((c) => c.type === "image");
|
|
36
|
+
return false;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function buildCopilotDynamicHeaders(params) {
|
|
40
|
+
const headers = {
|
|
41
|
+
"X-Initiator": inferCopilotInitiator(params.messages),
|
|
42
|
+
"Openai-Intent": "conversation-edits"
|
|
43
|
+
};
|
|
44
|
+
if (params.hasImages) headers["Copilot-Vision-Request"] = "true";
|
|
45
|
+
return headers;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { resolveCacheRetention as a, resolveCloudflareBaseUrl as i, hasCopilotVisionInput as n, isCloudflareProvider as r, buildCopilotDynamicHeaders as t };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { n as getEnvApiKey } from "./env-api-keys-CtMlqaQ4.mjs";
|
|
2
|
+
import { t as AssistantMessageEventStream } from "./event-stream-ReMmOTzX.mjs";
|
|
3
|
+
import { n as getAiTransportHost, r as resolveAiTransportHeaderSentinels } from "./host-4t713IeR.mjs";
|
|
4
|
+
import { o as buildBaseOptions } from "./transform-messages-BhGF_fF4.mjs";
|
|
5
|
+
import { a as runGoogleGenerateContentLifecycle, i as getDisabledGoogleThinkingConfig, n as buildGoogleSimpleThinking, r as createGoogleAssistantOutput, t as buildGoogleGenerateContentParams } from "./google-shared-ZPSl2qTi.mjs";
|
|
6
|
+
import { GoogleGenAI } from "@google/genai";
|
|
7
|
+
//#region packages/ai/src/providers/google.ts
|
|
8
|
+
let toolCallCounter = 0;
|
|
9
|
+
const streamGoogle = (model, context, options) => {
|
|
10
|
+
const stream = new AssistantMessageEventStream();
|
|
11
|
+
runGoogleGenerateContentLifecycle({
|
|
12
|
+
stream,
|
|
13
|
+
model,
|
|
14
|
+
output: createGoogleAssistantOutput(model, "google-generative-ai"),
|
|
15
|
+
options,
|
|
16
|
+
createClient: () => {
|
|
17
|
+
return createClient(model, options?.apiKey || getEnvApiKey(model.provider) || "", options?.headers);
|
|
18
|
+
},
|
|
19
|
+
buildParams: () => buildParams(model, context, options),
|
|
20
|
+
nextToolCallId: (name) => `${name}_${Date.now()}_${++toolCallCounter}`
|
|
21
|
+
});
|
|
22
|
+
return stream;
|
|
23
|
+
};
|
|
24
|
+
const streamSimpleGoogle = (model, context, options) => {
|
|
25
|
+
const apiKey = options?.apiKey || getEnvApiKey(model.provider);
|
|
26
|
+
if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
|
|
27
|
+
const base = buildBaseOptions(model, options, apiKey);
|
|
28
|
+
return streamGoogle(model, context, {
|
|
29
|
+
...base,
|
|
30
|
+
thinking: buildGoogleSimpleThinking(model, options, {
|
|
31
|
+
includeGemma4ThinkingLevel: true,
|
|
32
|
+
useFlashLiteBudgets: true
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
function createClient(model, apiKey, optionsHeaders) {
|
|
37
|
+
const httpOptions = {};
|
|
38
|
+
if (model.baseUrl) {
|
|
39
|
+
httpOptions.baseUrl = model.baseUrl;
|
|
40
|
+
httpOptions.apiVersion = "";
|
|
41
|
+
}
|
|
42
|
+
if (model.headers || optionsHeaders) httpOptions.headers = resolveAiTransportHeaderSentinels({
|
|
43
|
+
...model.headers,
|
|
44
|
+
...optionsHeaders
|
|
45
|
+
});
|
|
46
|
+
return new GoogleGenAI({
|
|
47
|
+
apiKey: apiKey ? getAiTransportHost().resolveSecretSentinel(apiKey) : void 0,
|
|
48
|
+
httpOptions: Object.keys(httpOptions).length > 0 ? httpOptions : void 0
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function buildParams(model, context, options = {}) {
|
|
52
|
+
return buildGoogleGenerateContentParams(model, context, options, { getDisabledThinkingConfig: (modelLocal) => getDisabledGoogleThinkingConfig(modelLocal, { includeGemma4: true }) });
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { streamGoogle, streamSimpleGoogle };
|