@codeworksh/aikit 0.4.0 → 0.4.1-dev.20260530133433
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 +109 -137
- package/cli.d.mts +1 -0
- package/cli.mjs +308 -0
- package/cli.mjs.map +1 -0
- package/codex-DfYk740t.mjs +521 -0
- package/codex-DfYk740t.mjs.map +1 -0
- package/index.d.mts +7197 -0
- package/index.mjs +1478 -0
- package/index.mjs.map +1 -0
- package/oauth/openai/codex.d.mts +107 -0
- package/oauth/openai/codex.mjs +2 -0
- package/package.json +28 -33
- package/{dist/pack/index.mjs → registry-CYfzJ6lk.mjs} +210 -3300
- package/registry-CYfzJ6lk.mjs.map +1 -0
- package/dist/pack/agent/codemode/drivers/drivers.d.mts +0 -7
- package/dist/pack/agent/codemode/drivers/drivers.mjs +0 -122
- package/dist/pack/agent/codemode/drivers/drivers.mjs.map +0 -1
- package/dist/pack/codemode-BEDXG7WN.d.mts +0 -8736
- package/dist/pack/index.d.mts +0 -71
- package/dist/pack/index.mjs.map +0 -1
- package/src/agent/agent.ts +0 -790
- package/src/agent/codemode/codemode.ts +0 -561
- package/src/agent/codemode/drivers/drivers.ts +0 -1
- package/src/agent/codemode/drivers/quickjs-wasi-driver.ts +0 -149
- package/src/agent/codemode/index.ts +0 -1
- package/src/agent/loop.ts +0 -903
- package/src/agent.ts +0 -11
- package/src/event/event.ts +0 -277
- package/src/index.ts +0 -6
- package/src/llm.ts +0 -31
- package/src/message/message.ts +0 -311
- package/src/model/catalog.ts +0 -94
- package/src/model/model.ts +0 -250
- package/src/model/transform.ts +0 -59
- package/src/provider/provider.ts +0 -60
- package/src/provider/providers/anthropic/index.ts +0 -792
- package/src/provider/providers/github/github.ts +0 -34
- package/src/provider/providers/openai/completions.ts +0 -953
- package/src/provider/providers/utils.ts +0 -7
- package/src/provider/register.ts +0 -6
- package/src/provider/stream.ts +0 -278
- package/src/stream.ts +0 -72
- package/src/utils/eventstream.ts +0 -95
- package/src/utils/helpers.ts +0 -24
- package/src/utils/jsonparse.ts +0 -32
- package/src/utils/overflow.ts +0 -121
- package/src/utils/sanitize.ts +0 -25
- package/src/utils/validation.ts +0 -87
|
@@ -1,24 +1,17 @@
|
|
|
1
|
+
import Type from "typebox";
|
|
1
2
|
import { createWriteStream, existsSync, lstatSync, readdir, readdirSync, readlinkSync, realpathSync, statSync } from "fs";
|
|
2
3
|
import { chmod, mkdir, readFile, writeFile } from "fs/promises";
|
|
3
4
|
import { dirname, join, relative, resolve } from "path";
|
|
4
5
|
import { Readable } from "stream";
|
|
5
6
|
import { pipeline } from "stream/promises";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
import { posix, win32 } from "node:path";
|
|
8
|
+
import { join as join$1, posix, resolve as resolve$1, win32 } from "node:path";
|
|
8
9
|
import * as xi from "node:fs";
|
|
9
10
|
import { lstat, readdir as readdir$1, readlink, realpath } from "node:fs/promises";
|
|
10
11
|
import { EventEmitter } from "node:events";
|
|
11
12
|
import Pe from "node:stream";
|
|
12
13
|
import { StringDecoder } from "node:string_decoder";
|
|
13
|
-
import
|
|
14
|
-
import Type from "typebox";
|
|
15
|
-
import { capitalize, keys, mapValues, pick, pipe } from "remeda";
|
|
16
|
-
import Schema from "typebox/schema";
|
|
17
|
-
import { uuidv7 } from "uuidv7";
|
|
18
|
-
import Anthropic from "@anthropic-ai/sdk";
|
|
19
|
-
import { parse } from "partial-json";
|
|
20
|
-
import OpenAI from "openai";
|
|
21
|
-
import { transform } from "esbuild";
|
|
14
|
+
import "typebox/value";
|
|
22
15
|
//#region ../utils/src/error.ts
|
|
23
16
|
var NamedError = class NamedError extends Error {
|
|
24
17
|
static create(name, data) {
|
|
@@ -185,10 +178,10 @@ let Filesystem;
|
|
|
185
178
|
}
|
|
186
179
|
}
|
|
187
180
|
_Filesystem.up = up;
|
|
188
|
-
function resolve$
|
|
181
|
+
function resolve$2(p) {
|
|
189
182
|
return normalizePath(resolve(windowsPath(p)));
|
|
190
183
|
}
|
|
191
|
-
_Filesystem.resolve = resolve$
|
|
184
|
+
_Filesystem.resolve = resolve$2;
|
|
192
185
|
})(Filesystem || (Filesystem = {}));
|
|
193
186
|
//#endregion
|
|
194
187
|
//#region ../utils/src/lazy.ts
|
|
@@ -4837,145 +4830,99 @@ let Glob;
|
|
|
4837
4830
|
_Glob.match = match;
|
|
4838
4831
|
})(Glob || (Glob = {}));
|
|
4839
4832
|
//#endregion
|
|
4840
|
-
//#region src/
|
|
4841
|
-
let
|
|
4842
|
-
(function(
|
|
4843
|
-
const KnownProviderEnum =
|
|
4833
|
+
//#region src/model/catalog.ts
|
|
4834
|
+
let ModelCatalog;
|
|
4835
|
+
(function(_ModelCatalog) {
|
|
4836
|
+
const KnownProviderEnum = _ModelCatalog.KnownProviderEnum = {
|
|
4844
4837
|
anthropic: "anthropic",
|
|
4838
|
+
google: "google",
|
|
4839
|
+
googleVertex: "google-vertex",
|
|
4840
|
+
googleVertexAnthropic: "google-vertex-anthropic",
|
|
4845
4841
|
openai: "openai",
|
|
4846
|
-
|
|
4842
|
+
openaiCompatible: "openai-compatible",
|
|
4847
4843
|
openrouter: "openrouter",
|
|
4848
|
-
|
|
4849
|
-
xai: "xai",
|
|
4850
|
-
cerebras: "cerebras",
|
|
4851
|
-
zai: "zai",
|
|
4852
|
-
opencode: "opencode"
|
|
4844
|
+
xai: "xai"
|
|
4853
4845
|
};
|
|
4854
|
-
|
|
4846
|
+
_ModelCatalog.KnownProviderEnumSchema = Type.Union([
|
|
4855
4847
|
Type.Literal(KnownProviderEnum.anthropic),
|
|
4848
|
+
Type.Literal(KnownProviderEnum.google),
|
|
4849
|
+
Type.Literal(KnownProviderEnum.googleVertex),
|
|
4850
|
+
Type.Literal(KnownProviderEnum.googleVertexAnthropic),
|
|
4856
4851
|
Type.Literal(KnownProviderEnum.openai),
|
|
4857
|
-
Type.Literal(KnownProviderEnum.
|
|
4852
|
+
Type.Literal(KnownProviderEnum.openaiCompatible),
|
|
4858
4853
|
Type.Literal(KnownProviderEnum.openrouter),
|
|
4859
|
-
Type.Literal(KnownProviderEnum.
|
|
4860
|
-
Type.Literal(KnownProviderEnum.xai),
|
|
4861
|
-
Type.Literal(KnownProviderEnum.cerebras),
|
|
4862
|
-
Type.Literal(KnownProviderEnum.zai),
|
|
4863
|
-
Type.Literal(KnownProviderEnum.opencode)
|
|
4854
|
+
Type.Literal(KnownProviderEnum.xai)
|
|
4864
4855
|
]);
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
});
|
|
4879
|
-
_Provider.OpenRouterRoutingSchema = Type.Object({
|
|
4880
|
-
only: Type.Optional(Type.Array(Type.String())),
|
|
4881
|
-
order: Type.Optional(Type.Array(Type.String()))
|
|
4882
|
-
});
|
|
4883
|
-
_Provider.VercelGatewayRoutingSchema = Type.Object({
|
|
4884
|
-
only: Type.Optional(Type.Array(Type.String())),
|
|
4885
|
-
order: Type.Optional(Type.Array(Type.String()))
|
|
4886
|
-
});
|
|
4887
|
-
})(Provider || (Provider = {}));
|
|
4888
|
-
//#endregion
|
|
4889
|
-
//#region src/model/catalog.ts
|
|
4890
|
-
let ModelCatalog;
|
|
4891
|
-
(function(_ModelCatalog) {
|
|
4892
|
-
function modelsDevURL() {
|
|
4893
|
-
return process.env.OPENCODE_MODELS_URL || "https://models.dev";
|
|
4894
|
-
}
|
|
4895
|
-
function modelsDevPath() {
|
|
4896
|
-
return process.env.CODEWORK_AIKIT_MODELS_PATH;
|
|
4897
|
-
}
|
|
4898
|
-
const modelsDevData = _ModelCatalog.modelsDevData = lazy(async () => {
|
|
4899
|
-
const path = modelsDevPath();
|
|
4900
|
-
if (path) {
|
|
4901
|
-
const result = await Filesystem.readJson(path).catch(() => void 0);
|
|
4902
|
-
if (result) return result;
|
|
4903
|
-
}
|
|
4904
|
-
const json = await fetch(`${modelsDevURL()}/api.json`).then((x) => x.text());
|
|
4905
|
-
return JSON.parse(json);
|
|
4856
|
+
function projectRoot() {
|
|
4857
|
+
return fileURLToPath(new URL("../../../..", import.meta.url));
|
|
4858
|
+
}
|
|
4859
|
+
_ModelCatalog.projectRoot = projectRoot;
|
|
4860
|
+
const filename = _ModelCatalog.filename = "models.gen.json";
|
|
4861
|
+
function path() {
|
|
4862
|
+
return resolve$1(process.env.CODEWORK_MODELGEN_PATH ?? join$1(projectRoot(), filename));
|
|
4863
|
+
}
|
|
4864
|
+
_ModelCatalog.path = path;
|
|
4865
|
+
const data = _ModelCatalog.data = lazy(async () => {
|
|
4866
|
+
const content = await Filesystem.readText(path()).catch(() => void 0);
|
|
4867
|
+
if (!content?.trim()) return {};
|
|
4868
|
+
return JSON.parse(content);
|
|
4906
4869
|
});
|
|
4907
4870
|
async function get() {
|
|
4908
|
-
return
|
|
4871
|
+
return data().catch(() => ({}));
|
|
4909
4872
|
}
|
|
4910
4873
|
_ModelCatalog.get = get;
|
|
4911
|
-
async function refresh() {
|
|
4912
|
-
const result = await fetch(`${modelsDevURL()}/api.json`, { signal: AbortSignal.timeout(10 * 1e3) }).catch(() => void 0);
|
|
4913
|
-
if (!result?.ok) return;
|
|
4914
|
-
const json = await result.text();
|
|
4915
|
-
const path = modelsDevPath();
|
|
4916
|
-
if (path) await Filesystem.write(path, json);
|
|
4917
|
-
modelsDevData.reset();
|
|
4918
|
-
}
|
|
4919
|
-
_ModelCatalog.refresh = refresh;
|
|
4920
|
-
ModelCatalog.refresh();
|
|
4921
|
-
setInterval(async () => {
|
|
4922
|
-
await ModelCatalog.refresh();
|
|
4923
|
-
}, 60 * 1e3 * 60).unref();
|
|
4924
4874
|
})(ModelCatalog || (ModelCatalog = {}));
|
|
4925
4875
|
//#endregion
|
|
4926
|
-
//#region src/model/transform.ts
|
|
4927
|
-
function defaultBaseUrl(providerId) {
|
|
4928
|
-
switch (providerId) {
|
|
4929
|
-
case Provider.KnownProviderEnum.openai: return "https://api.openai.com/v1";
|
|
4930
|
-
default: return;
|
|
4931
|
-
}
|
|
4932
|
-
}
|
|
4933
|
-
function resolveDefaultProtocol(providerId) {
|
|
4934
|
-
switch (providerId) {
|
|
4935
|
-
case Provider.KnownProviderEnum.anthropic: return Model.KnownProtocolEnum.anthropicMessages;
|
|
4936
|
-
case Provider.KnownProviderEnum.openai: return Model.KnownProtocolEnum.openaiResponses;
|
|
4937
|
-
default: return Model.KnownProtocolEnum.openaiCompletions;
|
|
4938
|
-
}
|
|
4939
|
-
}
|
|
4940
|
-
function applyModification(providerId, provider, model) {
|
|
4941
|
-
const baseUrl = model.baseUrl ?? provider.baseUrl ?? provider.api ?? defaultBaseUrl(providerId);
|
|
4942
|
-
const normalized = {
|
|
4943
|
-
id: model.id,
|
|
4944
|
-
name: model.name,
|
|
4945
|
-
provider: Model.toProviderInfo(providerId, provider),
|
|
4946
|
-
baseUrl,
|
|
4947
|
-
reasoning: Boolean(model.reasoning),
|
|
4948
|
-
input: Model.normalizeInput(model.modalities.input),
|
|
4949
|
-
cost: {
|
|
4950
|
-
input: model.cost?.input ?? 0,
|
|
4951
|
-
output: model.cost?.output ?? 0,
|
|
4952
|
-
cacheRead: model.cost?.cache_read ?? 0,
|
|
4953
|
-
cacheWrite: model.cost?.cache_write ?? 0
|
|
4954
|
-
},
|
|
4955
|
-
contextWindow: model.limit?.context ?? 0,
|
|
4956
|
-
maxTokens: model.limit?.output ?? 0,
|
|
4957
|
-
headers: model.headers ?? provider.headers,
|
|
4958
|
-
protocol: resolveDefaultProtocol(providerId)
|
|
4959
|
-
};
|
|
4960
|
-
if (providerId === Provider.KnownProviderEnum.openai) {
|
|
4961
|
-
normalized.supportedProtocols = { openaiCompletions: Model.KnownProtocolEnum.openaiCompletions };
|
|
4962
|
-
return normalized;
|
|
4963
|
-
} else return normalized;
|
|
4964
|
-
}
|
|
4965
|
-
//#endregion
|
|
4966
4876
|
//#region src/model/model.ts
|
|
4967
4877
|
let Model;
|
|
4968
4878
|
(function(_Model) {
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4879
|
+
_Model.KnownProviderEnum = ModelCatalog.KnownProviderEnum;
|
|
4880
|
+
const KnownProviderEnumSchema = _Model.KnownProviderEnumSchema = ModelCatalog.KnownProviderEnumSchema;
|
|
4881
|
+
const ThinkingLevelEnum = _Model.ThinkingLevelEnum = {
|
|
4882
|
+
off: "off",
|
|
4883
|
+
minimal: "minimal",
|
|
4884
|
+
low: "low",
|
|
4885
|
+
medium: "medium",
|
|
4886
|
+
high: "high",
|
|
4887
|
+
xhigh: "xhigh"
|
|
4973
4888
|
};
|
|
4974
|
-
_Model.
|
|
4975
|
-
Type.Literal(
|
|
4976
|
-
Type.Literal(
|
|
4977
|
-
Type.Literal(
|
|
4889
|
+
const ThinkingLevel = _Model.ThinkingLevel = Type.Union([
|
|
4890
|
+
Type.Literal(ThinkingLevelEnum.off),
|
|
4891
|
+
Type.Literal(ThinkingLevelEnum.minimal),
|
|
4892
|
+
Type.Literal(ThinkingLevelEnum.low),
|
|
4893
|
+
Type.Literal(ThinkingLevelEnum.medium),
|
|
4894
|
+
Type.Literal(ThinkingLevelEnum.high),
|
|
4895
|
+
Type.Literal(ThinkingLevelEnum.xhigh)
|
|
4978
4896
|
]);
|
|
4897
|
+
_Model.ActiveThinkingLevel = Type.Union([
|
|
4898
|
+
Type.Literal(ThinkingLevelEnum.minimal),
|
|
4899
|
+
Type.Literal(ThinkingLevelEnum.low),
|
|
4900
|
+
Type.Literal(ThinkingLevelEnum.medium),
|
|
4901
|
+
Type.Literal(ThinkingLevelEnum.high),
|
|
4902
|
+
Type.Literal(ThinkingLevelEnum.xhigh)
|
|
4903
|
+
]);
|
|
4904
|
+
const ACTIVE_THINKING_LEVELS = [
|
|
4905
|
+
ThinkingLevelEnum.minimal,
|
|
4906
|
+
ThinkingLevelEnum.low,
|
|
4907
|
+
ThinkingLevelEnum.medium,
|
|
4908
|
+
ThinkingLevelEnum.high,
|
|
4909
|
+
ThinkingLevelEnum.xhigh
|
|
4910
|
+
];
|
|
4911
|
+
const MODEL_THINKING_LEVELS = [ThinkingLevelEnum.off, ...ACTIVE_THINKING_LEVELS];
|
|
4912
|
+
const ProviderInfo = _Model.ProviderInfo = Type.Object({
|
|
4913
|
+
id: Type.String(),
|
|
4914
|
+
name: Type.String(),
|
|
4915
|
+
source: Type.Enum([
|
|
4916
|
+
"env",
|
|
4917
|
+
"config",
|
|
4918
|
+
"custom",
|
|
4919
|
+
"api",
|
|
4920
|
+
"unknown"
|
|
4921
|
+
]),
|
|
4922
|
+
env: Type.Array(Type.String()),
|
|
4923
|
+
key: Type.Optional(Type.String()),
|
|
4924
|
+
options: Type.Optional(Type.Record(Type.String(), Type.Any()))
|
|
4925
|
+
});
|
|
4979
4926
|
const InputSchema = Type.Array(Type.Union([Type.Literal("text"), Type.Literal("image")]));
|
|
4980
4927
|
const CostSchema = Type.Object({
|
|
4981
4928
|
input: Type.Number(),
|
|
@@ -4983,64 +4930,60 @@ let Model;
|
|
|
4983
4930
|
cacheRead: Type.Number(),
|
|
4984
4931
|
cacheWrite: Type.Number()
|
|
4985
4932
|
});
|
|
4986
|
-
const
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4933
|
+
const SupportedProtocolsSchema = Type.Partial(Type.Object({
|
|
4934
|
+
anthropic: KnownProviderEnumSchema,
|
|
4935
|
+
google: KnownProviderEnumSchema,
|
|
4936
|
+
googleVertex: KnownProviderEnumSchema,
|
|
4937
|
+
googleVertexAnthropic: KnownProviderEnumSchema,
|
|
4938
|
+
openai: KnownProviderEnumSchema,
|
|
4939
|
+
openaiCompatible: KnownProviderEnumSchema,
|
|
4940
|
+
openrouter: KnownProviderEnumSchema,
|
|
4941
|
+
xai: KnownProviderEnumSchema
|
|
4942
|
+
}));
|
|
4943
|
+
const APIMethodEnum = _Model.APIMethodEnum = {
|
|
4944
|
+
languageModel: "languageModel",
|
|
4945
|
+
chat: "chat",
|
|
4946
|
+
completion: "completion",
|
|
4947
|
+
completionModel: "completionModel",
|
|
4948
|
+
messages: "messages",
|
|
4949
|
+
responses: "responses"
|
|
4950
|
+
};
|
|
4951
|
+
const APIMethodEnumSchema = _Model.APIMethodEnumSchema = Type.Union([
|
|
4952
|
+
Type.Literal(APIMethodEnum.languageModel),
|
|
4953
|
+
Type.Literal(APIMethodEnum.chat),
|
|
4954
|
+
Type.Literal(APIMethodEnum.completion),
|
|
4955
|
+
Type.Literal(APIMethodEnum.completionModel),
|
|
4956
|
+
Type.Literal(APIMethodEnum.messages),
|
|
4957
|
+
Type.Literal(APIMethodEnum.responses)
|
|
4958
|
+
]);
|
|
4959
|
+
const APIMetadataSchema = _Model.APIMetadataSchema = Type.Object({
|
|
4960
|
+
id: Type.Optional(Type.String()),
|
|
4961
|
+
url: Type.Optional(Type.String()),
|
|
4962
|
+
method: Type.Optional(APIMethodEnumSchema)
|
|
4991
4963
|
});
|
|
4992
|
-
const
|
|
4964
|
+
const ThinkingLevelMapSchema = _Model.ThinkingLevelMapSchema = Type.Partial(Type.Record(ThinkingLevel, Type.Union([Type.String(), Type.Null()])));
|
|
4965
|
+
const Schema = _Model.Schema = Type.Object({
|
|
4993
4966
|
id: Type.String(),
|
|
4994
4967
|
name: Type.String(),
|
|
4995
|
-
provider:
|
|
4968
|
+
provider: ProviderInfo,
|
|
4996
4969
|
baseUrl: Type.String(),
|
|
4997
4970
|
reasoning: Type.Boolean(),
|
|
4971
|
+
thinkingLevelMap: Type.Optional(ThinkingLevelMapSchema),
|
|
4998
4972
|
input: InputSchema,
|
|
4999
4973
|
cost: CostSchema,
|
|
5000
4974
|
contextWindow: Type.Number(),
|
|
5001
4975
|
maxTokens: Type.Number(),
|
|
5002
|
-
headers:
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
supportsUsageInStreaming: Type.Optional(Type.Boolean()),
|
|
5011
|
-
maxTokensField: Type.Optional(Type.Union([Type.Literal("max_completion_tokens"), Type.Literal("max_tokens")])),
|
|
5012
|
-
requiresToolResultName: Type.Optional(Type.Boolean()),
|
|
5013
|
-
requiresAssistantAfterToolResult: Type.Optional(Type.Boolean()),
|
|
5014
|
-
requiresThinkingAsText: Type.Optional(Type.Boolean()),
|
|
5015
|
-
thinkingFormat: Type.Optional(Type.Union([
|
|
5016
|
-
Type.Literal("openai"),
|
|
5017
|
-
Type.Literal("openrouter"),
|
|
5018
|
-
Type.Literal("zai"),
|
|
5019
|
-
Type.Literal("qwen"),
|
|
5020
|
-
Type.Literal("qwen-chat-template")
|
|
5021
|
-
])),
|
|
5022
|
-
openRouterRouting: Type.Optional(Provider.OpenRouterRoutingSchema),
|
|
5023
|
-
vercelGatewayRouting: Type.Optional(Provider.VercelGatewayRoutingSchema),
|
|
5024
|
-
zaiToolStream: Type.Optional(Type.Boolean()),
|
|
5025
|
-
supportsStrictMode: Type.Optional(Type.Boolean())
|
|
4976
|
+
headers: Type.Optional(Type.Record(Type.String(), Type.String())),
|
|
4977
|
+
npm: Type.Optional(Type.String()),
|
|
4978
|
+
api: Type.Optional(APIMetadataSchema),
|
|
4979
|
+
providerOptionsKey: Type.Optional(Type.String()),
|
|
4980
|
+
options: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
|
|
4981
|
+
providerOptions: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
|
|
4982
|
+
protocol: KnownProviderEnumSchema,
|
|
4983
|
+
supportedProtocols: Type.Optional(SupportedProtocolsSchema)
|
|
5026
4984
|
});
|
|
5027
|
-
const
|
|
5028
|
-
_Model.
|
|
5029
|
-
const AnthropicSchema = _Model.AnthropicSchema = Type.Evaluate(Type.Intersect([BaseSchema, Type.Object({ protocol: Type.Literal(KnownProtocolEnum.anthropicMessages) })]));
|
|
5030
|
-
const OpenAICompletionsSchema = _Model.OpenAICompletionsSchema = Type.Evaluate(Type.Intersect([BaseSchema, Type.Object({
|
|
5031
|
-
protocol: Type.Literal(KnownProtocolEnum.openaiCompletions),
|
|
5032
|
-
compat: Type.Optional(OpenAICompletionsCompatSchema)
|
|
5033
|
-
})]));
|
|
5034
|
-
const OpenAIResponsesSchema = _Model.OpenAIResponsesSchema = Type.Evaluate(Type.Intersect([BaseSchema, Type.Object({
|
|
5035
|
-
protocol: Type.Literal(KnownProtocolEnum.openaiResponses),
|
|
5036
|
-
compat: Type.Optional(OpenAIResponsesCompatSchema)
|
|
5037
|
-
})]));
|
|
5038
|
-
_Model.Info = Type.Union([
|
|
5039
|
-
AnthropicSchema,
|
|
5040
|
-
OpenAICompletionsSchema,
|
|
5041
|
-
OpenAIResponsesSchema
|
|
5042
|
-
]);
|
|
5043
|
-
const BUILTINS = keys(Provider.KnownProviderEnum);
|
|
4985
|
+
const ExtrasSchema = _Model.ExtrasSchema = Type.Object({});
|
|
4986
|
+
_Model.Info = Type.Evaluate(Type.Intersect([Schema, ExtrasSchema]));
|
|
5044
4987
|
function calculateCost(model, usage) {
|
|
5045
4988
|
usage.cost.input = usage.input / 1e6 * model.cost.input;
|
|
5046
4989
|
usage.cost.output = usage.output / 1e6 * model.cost.output;
|
|
@@ -5056,21 +4999,8 @@ let Model;
|
|
|
5056
4999
|
return [...normalized];
|
|
5057
5000
|
}
|
|
5058
5001
|
_Model.normalizeInput = normalizeInput;
|
|
5059
|
-
function toProviderInfo(providerId, provider) {
|
|
5060
|
-
return {
|
|
5061
|
-
id: providerId,
|
|
5062
|
-
name: provider.name,
|
|
5063
|
-
env: provider.env,
|
|
5064
|
-
key: provider.key,
|
|
5065
|
-
options: provider.headers
|
|
5066
|
-
};
|
|
5067
|
-
}
|
|
5068
|
-
_Model.toProviderInfo = toProviderInfo;
|
|
5069
|
-
function toModelValue(providerId, provider, model) {
|
|
5070
|
-
return applyModification(providerId, provider, model);
|
|
5071
|
-
}
|
|
5072
5002
|
async function getBuiltInModels() {
|
|
5073
|
-
return
|
|
5003
|
+
return await ModelCatalog.get();
|
|
5074
5004
|
}
|
|
5075
5005
|
_Model.getBuiltInModels = getBuiltInModels;
|
|
5076
5006
|
const registry = _Model.registry = lazy(async () => {
|
|
@@ -5083,12 +5013,20 @@ let Model;
|
|
|
5083
5013
|
}
|
|
5084
5014
|
return registry;
|
|
5085
5015
|
});
|
|
5016
|
+
function supportsProtocol(model, protocol) {
|
|
5017
|
+
if (model.protocol === protocol) return true;
|
|
5018
|
+
return Object.values(model.supportedProtocols ?? {}).includes(protocol);
|
|
5019
|
+
}
|
|
5020
|
+
_Model.supportsProtocol = supportsProtocol;
|
|
5086
5021
|
async function getModel(provider, model, overrides) {
|
|
5087
5022
|
const result = (await registry()).get(provider)?.get(model);
|
|
5088
|
-
if (result && overrides)
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5023
|
+
if (result && overrides) {
|
|
5024
|
+
if (overrides.protocol && !supportsProtocol(result, overrides.protocol)) return;
|
|
5025
|
+
return {
|
|
5026
|
+
...result,
|
|
5027
|
+
...overrides
|
|
5028
|
+
};
|
|
5029
|
+
}
|
|
5092
5030
|
return result;
|
|
5093
5031
|
}
|
|
5094
5032
|
_Model.getModel = getModel;
|
|
@@ -5102,3125 +5040,97 @@ let Model;
|
|
|
5102
5040
|
return models ? Array.from(models.values()) : [];
|
|
5103
5041
|
}
|
|
5104
5042
|
_Model.getModels = getModels;
|
|
5105
|
-
function isGpt5OrLater(modelID) {
|
|
5106
|
-
const match = /^gpt-(\d+)/.exec(modelID);
|
|
5107
|
-
if (!match) return false;
|
|
5108
|
-
return Number(match[1]) >= 5;
|
|
5109
|
-
}
|
|
5110
|
-
function supportsXhigh(model) {
|
|
5111
|
-
return isGpt5OrLater(model.id);
|
|
5112
|
-
}
|
|
5113
|
-
_Model.supportsXhigh = supportsXhigh;
|
|
5114
5043
|
function modelsAreEqual(a, b) {
|
|
5115
5044
|
if (!a || !b) return false;
|
|
5116
5045
|
return a.id === b.id && a.provider.id === b.provider.id;
|
|
5117
5046
|
}
|
|
5118
5047
|
_Model.modelsAreEqual = modelsAreEqual;
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
(
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
actual: Model.KnownProtocolSchema,
|
|
5127
|
-
expected: Model.KnownProtocolSchema
|
|
5128
|
-
}));
|
|
5129
|
-
const ThinkingLevelEnum = _Stream.ThinkingLevelEnum = {
|
|
5130
|
-
off: "off",
|
|
5131
|
-
minimal: "minimal",
|
|
5132
|
-
low: "low",
|
|
5133
|
-
medium: "medium",
|
|
5134
|
-
high: "high",
|
|
5135
|
-
xhigh: "xhigh"
|
|
5136
|
-
};
|
|
5137
|
-
const ThinkingLevelSchema = _Stream.ThinkingLevelSchema = Type.Union([
|
|
5138
|
-
Type.Literal(ThinkingLevelEnum.off),
|
|
5139
|
-
Type.Literal(ThinkingLevelEnum.minimal),
|
|
5140
|
-
Type.Literal(ThinkingLevelEnum.low),
|
|
5141
|
-
Type.Literal(ThinkingLevelEnum.medium),
|
|
5142
|
-
Type.Literal(ThinkingLevelEnum.high),
|
|
5143
|
-
Type.Literal(ThinkingLevelEnum.xhigh)
|
|
5144
|
-
]);
|
|
5145
|
-
const ThinkingBudgetsSchema = _Stream.ThinkingBudgetsSchema = Type.Object({
|
|
5146
|
-
off: Type.Optional(Type.Number()),
|
|
5147
|
-
minimal: Type.Optional(Type.Number()),
|
|
5148
|
-
low: Type.Optional(Type.Number()),
|
|
5149
|
-
medium: Type.Optional(Type.Number()),
|
|
5150
|
-
high: Type.Optional(Type.Number())
|
|
5151
|
-
});
|
|
5152
|
-
const CacheRetentionSchema = _Stream.CacheRetentionSchema = Type.Union([
|
|
5153
|
-
Type.Literal("none"),
|
|
5154
|
-
Type.Literal("short"),
|
|
5155
|
-
Type.Literal("long")
|
|
5156
|
-
]);
|
|
5157
|
-
const TransportSchema = _Stream.TransportSchema = Type.Union([
|
|
5158
|
-
Type.Literal("sse"),
|
|
5159
|
-
Type.Literal("websocket"),
|
|
5160
|
-
Type.Literal("auto")
|
|
5161
|
-
]);
|
|
5162
|
-
const OptionsSchema = _Stream.OptionsSchema = Type.Object({
|
|
5163
|
-
temperature: Type.Optional(Type.Number()),
|
|
5164
|
-
maxTokens: Type.Optional(Type.Number()),
|
|
5165
|
-
signal: Type.Optional(Type.Unsafe({})),
|
|
5166
|
-
apiKey: Type.Optional(Type.String()),
|
|
5167
|
-
transport: Type.Optional(TransportSchema),
|
|
5168
|
-
cacheRetention: Type.Optional(CacheRetentionSchema),
|
|
5169
|
-
sessionId: Type.Optional(Type.String()),
|
|
5170
|
-
onPayload: Type.Optional(Type.Unsafe({})),
|
|
5171
|
-
headers: Type.Optional(Type.Record(Type.String(), Type.String())),
|
|
5172
|
-
maxRetryDelayMs: Type.Optional(Type.Number()),
|
|
5173
|
-
metadata: Type.Optional(Type.Record(Type.String(), Type.Unknown()))
|
|
5174
|
-
});
|
|
5175
|
-
_Stream.SimpleOptionsSchema = Type.Evaluate(Type.Intersect([OptionsSchema, Type.Object({
|
|
5176
|
-
reasoning: Type.Optional(ThinkingLevelSchema),
|
|
5177
|
-
thinkingBudgets: Type.Optional(ThinkingBudgetsSchema)
|
|
5178
|
-
})]));
|
|
5179
|
-
function buildBaseOptions(model, options, apiKey) {
|
|
5180
|
-
return {
|
|
5181
|
-
temperature: options?.temperature,
|
|
5182
|
-
maxTokens: options?.maxTokens || Math.min(model.maxTokens, 32e3),
|
|
5183
|
-
signal: options?.signal,
|
|
5184
|
-
apiKey: apiKey || options?.apiKey,
|
|
5185
|
-
transport: options?.transport,
|
|
5186
|
-
cacheRetention: options?.cacheRetention,
|
|
5187
|
-
sessionId: options?.sessionId,
|
|
5188
|
-
headers: options?.headers,
|
|
5189
|
-
onPayload: options?.onPayload,
|
|
5190
|
-
maxRetryDelayMs: options?.maxRetryDelayMs,
|
|
5191
|
-
metadata: options?.metadata
|
|
5192
|
-
};
|
|
5193
|
-
}
|
|
5194
|
-
_Stream.buildBaseOptions = buildBaseOptions;
|
|
5195
|
-
function clampReasoning(effort) {
|
|
5196
|
-
return effort === ThinkingLevelEnum.xhigh ? ThinkingLevelEnum.high : effort;
|
|
5197
|
-
}
|
|
5198
|
-
_Stream.clampReasoning = clampReasoning;
|
|
5199
|
-
function adjustMaxTokensForThinking(baseMaxTokens, modelMaxTokens, reasoningLevel, customBudgets) {
|
|
5200
|
-
const budgets = {
|
|
5201
|
-
minimal: 1024,
|
|
5202
|
-
low: 2048,
|
|
5203
|
-
medium: 8192,
|
|
5204
|
-
high: 16384,
|
|
5205
|
-
...customBudgets
|
|
5206
|
-
};
|
|
5207
|
-
const minOutputTokens = 1024;
|
|
5208
|
-
let thinkingBudget = budgets[clampReasoning(reasoningLevel)];
|
|
5209
|
-
const maxTokens = Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);
|
|
5210
|
-
if (maxTokens <= thinkingBudget) thinkingBudget = Math.max(0, maxTokens - minOutputTokens);
|
|
5211
|
-
return {
|
|
5212
|
-
maxTokens,
|
|
5213
|
-
thinkingBudget
|
|
5214
|
-
};
|
|
5215
|
-
}
|
|
5216
|
-
_Stream.adjustMaxTokensForThinking = adjustMaxTokensForThinking;
|
|
5217
|
-
const protocolProviderRegistry = /* @__PURE__ */ new Map();
|
|
5218
|
-
function wrapStream(protocol, stream) {
|
|
5219
|
-
return (model, context, options) => {
|
|
5220
|
-
if (model.protocol !== protocol) throw new ProtocolMismatchError({
|
|
5221
|
-
actual: model.protocol,
|
|
5222
|
-
expected: protocol
|
|
5223
|
-
});
|
|
5224
|
-
return stream(model, context, options);
|
|
5225
|
-
};
|
|
5226
|
-
}
|
|
5227
|
-
function wrapStreamSimple(protocol, streamSimple) {
|
|
5228
|
-
return (model, context, options) => {
|
|
5229
|
-
if (model.protocol !== protocol) throw new ProtocolMismatchError({
|
|
5230
|
-
actual: model.protocol,
|
|
5231
|
-
expected: protocol
|
|
5232
|
-
});
|
|
5233
|
-
return streamSimple(model, context, options);
|
|
5234
|
-
};
|
|
5235
|
-
}
|
|
5236
|
-
function registerProtocolProvider(provider, sourceId) {
|
|
5237
|
-
protocolProviderRegistry.set(provider.protocol, {
|
|
5238
|
-
provider: {
|
|
5239
|
-
protocol: provider.protocol,
|
|
5240
|
-
stream: wrapStream(provider.protocol, provider.stream),
|
|
5241
|
-
streamSimple: wrapStreamSimple(provider.protocol, provider.streamSimple)
|
|
5242
|
-
},
|
|
5243
|
-
sourceId
|
|
5244
|
-
});
|
|
5245
|
-
}
|
|
5246
|
-
_Stream.registerProtocolProvider = registerProtocolProvider;
|
|
5247
|
-
function getProtocolProvider(protocol) {
|
|
5248
|
-
return protocolProviderRegistry.get(protocol)?.provider;
|
|
5249
|
-
}
|
|
5250
|
-
_Stream.getProtocolProvider = getProtocolProvider;
|
|
5251
|
-
function resolveProtocolProvider(model) {
|
|
5252
|
-
const provider = getProtocolProvider(model.protocol);
|
|
5253
|
-
if (!provider) throw new ProtocolProviderNotFoundError({ protocol: model.protocol });
|
|
5254
|
-
return provider;
|
|
5255
|
-
}
|
|
5256
|
-
_Stream.resolveProtocolProvider = resolveProtocolProvider;
|
|
5257
|
-
function stream(model, context, options) {
|
|
5258
|
-
return resolveProtocolProvider(model).stream(model, context, options);
|
|
5259
|
-
}
|
|
5260
|
-
_Stream.stream = stream;
|
|
5261
|
-
async function complete(model, context, options) {
|
|
5262
|
-
return stream(model, context, options).result();
|
|
5263
|
-
}
|
|
5264
|
-
_Stream.complete = complete;
|
|
5265
|
-
function streamSimple(model, context, options) {
|
|
5266
|
-
return resolveProtocolProvider(model).streamSimple(model, context, options);
|
|
5267
|
-
}
|
|
5268
|
-
_Stream.streamSimple = streamSimple;
|
|
5269
|
-
async function completeSimple(model, context, options) {
|
|
5270
|
-
return streamSimple(model, context, options).result();
|
|
5271
|
-
}
|
|
5272
|
-
_Stream.completeSimple = completeSimple;
|
|
5273
|
-
function getApiProviders() {
|
|
5274
|
-
return Array.from(protocolProviderRegistry.values(), (entry) => entry.provider);
|
|
5275
|
-
}
|
|
5276
|
-
_Stream.getApiProviders = getApiProviders;
|
|
5277
|
-
function unregisterProtocolProviders(sourceId) {
|
|
5278
|
-
for (const [api, entry] of protocolProviderRegistry.entries()) if (entry.sourceId === sourceId) protocolProviderRegistry.delete(api);
|
|
5279
|
-
}
|
|
5280
|
-
_Stream.unregisterProtocolProviders = unregisterProtocolProviders;
|
|
5281
|
-
function clearProtocolProviders() {
|
|
5282
|
-
protocolProviderRegistry.clear();
|
|
5283
|
-
}
|
|
5284
|
-
_Stream.clearProtocolProviders = clearProtocolProviders;
|
|
5285
|
-
})(Stream || (Stream = {}));
|
|
5286
|
-
//#endregion
|
|
5287
|
-
//#region src/utils/eventstream.ts
|
|
5288
|
-
var EventStream = class {
|
|
5289
|
-
queue = [];
|
|
5290
|
-
waiting = [];
|
|
5291
|
-
done = false;
|
|
5292
|
-
finalResultPromise;
|
|
5293
|
-
resolveFinalResult;
|
|
5294
|
-
constructor(isComplete, extractResult) {
|
|
5295
|
-
this.isComplete = isComplete;
|
|
5296
|
-
this.extractResult = extractResult;
|
|
5297
|
-
this.finalResultPromise = new Promise((resolve) => {
|
|
5298
|
-
this.resolveFinalResult = resolve;
|
|
5048
|
+
function getSupportedThinkingLevels(model) {
|
|
5049
|
+
if (!model.reasoning) return ["off"];
|
|
5050
|
+
return MODEL_THINKING_LEVELS.filter((level) => {
|
|
5051
|
+
const mapped = model.thinkingLevelMap?.[level];
|
|
5052
|
+
if (mapped === null) return false;
|
|
5053
|
+
if (level === "xhigh") return mapped !== void 0;
|
|
5054
|
+
return true;
|
|
5299
5055
|
});
|
|
5300
5056
|
}
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5057
|
+
_Model.getSupportedThinkingLevels = getSupportedThinkingLevels;
|
|
5058
|
+
function clampThinkingLevel(model, level) {
|
|
5059
|
+
const availableLevels = getSupportedThinkingLevels(model);
|
|
5060
|
+
if (availableLevels.includes(level)) return level;
|
|
5061
|
+
const requestedIndex = MODEL_THINKING_LEVELS.indexOf(level);
|
|
5062
|
+
if (requestedIndex === -1) return availableLevels[0] ?? "off";
|
|
5063
|
+
for (let i = requestedIndex; i < MODEL_THINKING_LEVELS.length; i++) {
|
|
5064
|
+
const candidate = MODEL_THINKING_LEVELS[i];
|
|
5065
|
+
if (availableLevels.includes(candidate)) return candidate;
|
|
5306
5066
|
}
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
done: false
|
|
5311
|
-
});
|
|
5312
|
-
else this.queue.push(event);
|
|
5313
|
-
}
|
|
5314
|
-
end(result) {
|
|
5315
|
-
this.done = true;
|
|
5316
|
-
if (result !== void 0) this.resolveFinalResult(result);
|
|
5317
|
-
while (this.waiting.length > 0) this.waiting.shift()({
|
|
5318
|
-
value: void 0,
|
|
5319
|
-
done: true
|
|
5320
|
-
});
|
|
5321
|
-
}
|
|
5322
|
-
async *[Symbol.asyncIterator]() {
|
|
5323
|
-
while (true) if (this.queue.length > 0) yield this.queue.shift();
|
|
5324
|
-
else if (this.done) return;
|
|
5325
|
-
else {
|
|
5326
|
-
const result = await new Promise((resolve) => this.waiting.push(resolve));
|
|
5327
|
-
if (result.done) return;
|
|
5328
|
-
yield result.value;
|
|
5067
|
+
for (let i = requestedIndex - 1; i >= 0; i--) {
|
|
5068
|
+
const candidate = MODEL_THINKING_LEVELS[i];
|
|
5069
|
+
if (availableLevels.includes(candidate)) return candidate;
|
|
5329
5070
|
}
|
|
5071
|
+
return availableLevels[0] ?? "off";
|
|
5330
5072
|
}
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5073
|
+
_Model.clampThinkingLevel = clampThinkingLevel;
|
|
5074
|
+
})(Model || (Model = {}));
|
|
5075
|
+
//#endregion
|
|
5076
|
+
//#region src/llm/registry.ts
|
|
5077
|
+
const DEFAULT_AI_SDK_PACKAGE = "@ai-sdk/openai-compatible";
|
|
5078
|
+
const AI_SDK_PACKAGE_TO_PROTOCOL = {
|
|
5079
|
+
"@ai-sdk/anthropic": Model.KnownProviderEnum.anthropic,
|
|
5080
|
+
"@ai-sdk/google": Model.KnownProviderEnum.google,
|
|
5081
|
+
"@ai-sdk/google-vertex": Model.KnownProviderEnum.googleVertex,
|
|
5082
|
+
"@ai-sdk/google-vertex/anthropic": Model.KnownProviderEnum.googleVertexAnthropic,
|
|
5083
|
+
"@ai-sdk/openai": Model.KnownProviderEnum.openai,
|
|
5084
|
+
"@ai-sdk/openai-compatible": Model.KnownProviderEnum.openaiCompatible,
|
|
5085
|
+
"@openrouter/ai-sdk-provider": Model.KnownProviderEnum.openrouter,
|
|
5086
|
+
"@ai-sdk/xai": Model.KnownProviderEnum.xai
|
|
5334
5087
|
};
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5088
|
+
const PROVIDER_LOADERS = {
|
|
5089
|
+
"@ai-sdk/anthropic": () => import("@ai-sdk/anthropic").then((m) => m.createAnthropic),
|
|
5090
|
+
"@ai-sdk/google": () => import("@ai-sdk/google").then((m) => m.createGoogleGenerativeAI),
|
|
5091
|
+
"@ai-sdk/google-vertex": () => import("@ai-sdk/google-vertex").then((m) => m.createVertex),
|
|
5092
|
+
"@ai-sdk/google-vertex/anthropic": () => import("@ai-sdk/google-vertex/anthropic").then((m) => m.createVertexAnthropic),
|
|
5093
|
+
"@ai-sdk/openai": () => import("@ai-sdk/openai").then((m) => m.createOpenAI),
|
|
5094
|
+
"@ai-sdk/openai-compatible": () => import("@ai-sdk/openai-compatible").then((m) => m.createOpenAICompatible),
|
|
5095
|
+
"@openrouter/ai-sdk-provider": () => import("@openrouter/ai-sdk-provider").then((m) => m.createOpenRouter),
|
|
5096
|
+
"@ai-sdk/xai": () => import("@ai-sdk/xai").then((m) => m.createXai)
|
|
5343
5097
|
};
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
const validators = /* @__PURE__ */ new WeakMap();
|
|
5347
|
-
function getValidator(schema) {
|
|
5348
|
-
const existing = validators.get(schema);
|
|
5349
|
-
if (existing) return existing;
|
|
5350
|
-
const validator = Schema.Compile(schema);
|
|
5351
|
-
validators.set(schema, validator);
|
|
5352
|
-
return validator;
|
|
5098
|
+
function isAISDKPackage(value) {
|
|
5099
|
+
return value in AI_SDK_PACKAGE_TO_PROTOCOL;
|
|
5353
5100
|
}
|
|
5354
|
-
function
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
if (Array.isArray(requiredProperties)) return requiredProperties.join(", ");
|
|
5358
|
-
return "root";
|
|
5101
|
+
function packageForModel(model) {
|
|
5102
|
+
const npm = model.npm ?? "@ai-sdk/openai-compatible";
|
|
5103
|
+
return isAISDKPackage(npm) ? npm : DEFAULT_AI_SDK_PACKAGE;
|
|
5359
5104
|
}
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
*/
|
|
5363
|
-
function validateSchema(schema, value, label) {
|
|
5364
|
-
const validator = getValidator(schema);
|
|
5365
|
-
const input = Value.Convert(schema, structuredClone(value));
|
|
5366
|
-
try {
|
|
5367
|
-
return validator.Parse(input);
|
|
5368
|
-
} catch {
|
|
5369
|
-
const [_result, validationErrors] = validator.Errors(input);
|
|
5370
|
-
const errors = validationErrors.map((err) => {
|
|
5371
|
-
return ` - ${errorPath(err)}: ${err.message}`;
|
|
5372
|
-
}).join("\n") || "Unknown Validation Error";
|
|
5373
|
-
throw new Error([
|
|
5374
|
-
`Validation Failed For ${label}`,
|
|
5375
|
-
`${errors}\n`,
|
|
5376
|
-
"Received Value:",
|
|
5377
|
-
`${JSON.stringify(value, null, 2)}\n`
|
|
5378
|
-
].join("\n"));
|
|
5379
|
-
}
|
|
5105
|
+
function protocolForPackage(npm) {
|
|
5106
|
+
return AI_SDK_PACKAGE_TO_PROTOCOL[npm && isAISDKPackage(npm) ? npm : DEFAULT_AI_SDK_PACKAGE];
|
|
5380
5107
|
}
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
*/
|
|
5384
|
-
function validateToolArguments(tool, toolExecution) {
|
|
5385
|
-
return validateSchema(tool.parameters, toolExecution.rawArgs, `Tool "${toolExecution.name}"`);
|
|
5108
|
+
async function loadProviderFactory(npm) {
|
|
5109
|
+
return PROVIDER_LOADERS[npm]();
|
|
5386
5110
|
}
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
(function(_Loop) {
|
|
5391
|
-
function createAgentStream() {
|
|
5392
|
-
return new EventStream((event) => event.type === "agent.end", (event) => event.type === "agent.end" ? event.messages : []);
|
|
5393
|
-
}
|
|
5394
|
-
const AgentContextError = _Loop.AgentContextError = NamedError.create("AgentContextError", Type.Object({ message: Type.String() }));
|
|
5395
|
-
function snapshotAssistantMessage(message) {
|
|
5396
|
-
return structuredClone(message);
|
|
5397
|
-
}
|
|
5398
|
-
function snapshotAssistantPartEvent(message, partIndex) {
|
|
5399
|
-
const snapshot = snapshotAssistantMessage(message);
|
|
5400
|
-
const part = snapshot.parts[partIndex];
|
|
5401
|
-
if (!part) throw new Error(`Assistant message part at index ${partIndex} was not found`);
|
|
5402
|
-
return {
|
|
5403
|
-
message: snapshot,
|
|
5404
|
-
part
|
|
5405
|
-
};
|
|
5406
|
-
}
|
|
5407
|
-
async function emitEvent(emit, event) {
|
|
5408
|
-
await emit(event);
|
|
5409
|
-
}
|
|
5410
|
-
async function streamAssistantResponse(config, context, emit, streamFn, signal) {
|
|
5411
|
-
let messages = context.messages;
|
|
5412
|
-
if (config.transformContext) messages = await config.transformContext(messages, signal);
|
|
5413
|
-
const llmMessages = await config.convertToLlm(messages);
|
|
5414
|
-
const llmContext = {
|
|
5415
|
-
systemPrompt: context.systemPrompt,
|
|
5416
|
-
messages: llmMessages,
|
|
5417
|
-
tools: context.tools
|
|
5418
|
-
};
|
|
5419
|
-
const streamFunction = streamFn || Stream.streamSimple;
|
|
5420
|
-
const resolvedApiKey = (config.getApiKey ? await config.getApiKey(config.model.provider) : void 0) || config.apiKey;
|
|
5421
|
-
const events = await streamFunction(config.model, llmContext, {
|
|
5422
|
-
...config,
|
|
5423
|
-
apiKey: resolvedApiKey,
|
|
5424
|
-
signal
|
|
5425
|
-
});
|
|
5426
|
-
let partialMessage = null;
|
|
5427
|
-
let started = false;
|
|
5428
|
-
const ensureMessageStarted = async (message) => {
|
|
5429
|
-
if (started) return;
|
|
5430
|
-
started = true;
|
|
5431
|
-
await emitEvent(emit, {
|
|
5432
|
-
type: "message.start",
|
|
5433
|
-
message: snapshotAssistantMessage(message)
|
|
5434
|
-
});
|
|
5435
|
-
};
|
|
5436
|
-
const emitMessageUpdate = async (message) => {
|
|
5437
|
-
await emitEvent(emit, {
|
|
5438
|
-
type: "message.update",
|
|
5439
|
-
message: snapshotAssistantMessage(message)
|
|
5440
|
-
});
|
|
5441
|
-
};
|
|
5442
|
-
const emitPartStart = async (message, partIndex) => {
|
|
5443
|
-
await emitEvent(emit, {
|
|
5444
|
-
type: "message.part.start",
|
|
5445
|
-
partIndex,
|
|
5446
|
-
...snapshotAssistantPartEvent(message, partIndex)
|
|
5447
|
-
});
|
|
5448
|
-
};
|
|
5449
|
-
const emitPartUpdate = async (message, partIndex) => {
|
|
5450
|
-
await emitEvent(emit, {
|
|
5451
|
-
type: "message.part.update",
|
|
5452
|
-
partIndex,
|
|
5453
|
-
...snapshotAssistantPartEvent(message, partIndex),
|
|
5454
|
-
source: "llm"
|
|
5455
|
-
});
|
|
5456
|
-
};
|
|
5457
|
-
const emitPartEnd = async (message, partIndex) => {
|
|
5458
|
-
await emitEvent(emit, {
|
|
5459
|
-
type: "message.part.end",
|
|
5460
|
-
partIndex,
|
|
5461
|
-
...snapshotAssistantPartEvent(message, partIndex)
|
|
5462
|
-
});
|
|
5463
|
-
};
|
|
5464
|
-
for await (const event of events) switch (event.type) {
|
|
5465
|
-
case "start":
|
|
5466
|
-
partialMessage = event.partial;
|
|
5467
|
-
await ensureMessageStarted(partialMessage);
|
|
5468
|
-
break;
|
|
5469
|
-
case "text.start":
|
|
5470
|
-
case "thinking.start":
|
|
5471
|
-
case "toolcall.start":
|
|
5472
|
-
partialMessage = event.partial;
|
|
5473
|
-
await ensureMessageStarted(partialMessage);
|
|
5474
|
-
await emitPartStart(partialMessage, event.partIndex);
|
|
5475
|
-
break;
|
|
5476
|
-
case "text.delta":
|
|
5477
|
-
case "thinking.delta":
|
|
5478
|
-
case "toolcall.delta":
|
|
5479
|
-
partialMessage = event.partial;
|
|
5480
|
-
await ensureMessageStarted(partialMessage);
|
|
5481
|
-
await emitPartUpdate(partialMessage, event.partIndex);
|
|
5482
|
-
break;
|
|
5483
|
-
case "text.end":
|
|
5484
|
-
case "thinking.end":
|
|
5485
|
-
case "toolcall.end":
|
|
5486
|
-
partialMessage = event.partial;
|
|
5487
|
-
await ensureMessageStarted(partialMessage);
|
|
5488
|
-
await emitPartEnd(partialMessage, event.partIndex);
|
|
5489
|
-
await emitMessageUpdate(partialMessage);
|
|
5490
|
-
break;
|
|
5491
|
-
case "done":
|
|
5492
|
-
await ensureMessageStarted(event.message);
|
|
5493
|
-
await emitEvent(emit, {
|
|
5494
|
-
type: "message.end",
|
|
5495
|
-
message: snapshotAssistantMessage(event.message)
|
|
5496
|
-
});
|
|
5497
|
-
return event.message;
|
|
5498
|
-
case "error":
|
|
5499
|
-
await ensureMessageStarted(event.error);
|
|
5500
|
-
await emitEvent(emit, {
|
|
5501
|
-
type: "message.end",
|
|
5502
|
-
message: snapshotAssistantMessage(event.error)
|
|
5503
|
-
});
|
|
5504
|
-
return event.error;
|
|
5505
|
-
}
|
|
5506
|
-
const finalMessage = await events.result();
|
|
5507
|
-
await ensureMessageStarted(finalMessage);
|
|
5508
|
-
await emitEvent(emit, {
|
|
5509
|
-
type: "message.end",
|
|
5510
|
-
message: snapshotAssistantMessage(finalMessage)
|
|
5511
|
-
});
|
|
5512
|
-
return finalMessage;
|
|
5513
|
-
}
|
|
5514
|
-
async function executeToolCalls(config, currentContext, message, toolCalls, emit, signal) {
|
|
5515
|
-
if (config.toolExecution === "sequential") return executeToolCallsSequential(config, currentContext, message, toolCalls, emit, signal);
|
|
5516
|
-
return executeToolCallsParallel(config, currentContext, message, toolCalls, emit, signal);
|
|
5517
|
-
}
|
|
5518
|
-
async function executeToolCallsSequential(config, currentContext, message, toolCalls, emit, signal) {
|
|
5519
|
-
for (const toolCall of toolCalls) {
|
|
5520
|
-
const toolCallInFlight = {
|
|
5521
|
-
callID: toolCall.callID,
|
|
5522
|
-
name: toolCall.name,
|
|
5523
|
-
rawArgs: toolCall.arguments
|
|
5524
|
-
};
|
|
5525
|
-
await emitEvent(emit, {
|
|
5526
|
-
type: "tool.execution.start",
|
|
5527
|
-
...toolCallInFlight
|
|
5528
|
-
});
|
|
5529
|
-
const prepared = await prepareToolCall(config, currentContext, message, toolCallInFlight, signal);
|
|
5530
|
-
if (prepared.error) {
|
|
5531
|
-
const error = {
|
|
5532
|
-
status: "error",
|
|
5533
|
-
result: {
|
|
5534
|
-
content: [{
|
|
5535
|
-
type: "text",
|
|
5536
|
-
text: prepared.error.message
|
|
5537
|
-
}],
|
|
5538
|
-
details: prepared.error.details,
|
|
5539
|
-
isError: true
|
|
5540
|
-
}
|
|
5541
|
-
};
|
|
5542
|
-
await emitToolCallTerminalResult(toolCall, prepared.runnable, message, emit, error);
|
|
5543
|
-
} else {
|
|
5544
|
-
const runnable = {
|
|
5545
|
-
toolCall,
|
|
5546
|
-
runnable: prepared.runnable,
|
|
5547
|
-
tool: prepared.tool
|
|
5548
|
-
};
|
|
5549
|
-
const executed = await executeRunnableToolCall(runnable, message, emit, signal);
|
|
5550
|
-
if (executed.error) {
|
|
5551
|
-
const error = {
|
|
5552
|
-
status: "error",
|
|
5553
|
-
result: {
|
|
5554
|
-
content: [{
|
|
5555
|
-
type: "text",
|
|
5556
|
-
text: executed.error.message
|
|
5557
|
-
}],
|
|
5558
|
-
details: executed.error.details,
|
|
5559
|
-
isError: true
|
|
5560
|
-
}
|
|
5561
|
-
};
|
|
5562
|
-
await emitToolCallTerminalResult(runnable.toolCall, runnable.runnable, message, emit, error);
|
|
5563
|
-
} else await finalizeExecutedToolCall(config, currentContext, runnable.toolCall, runnable.runnable, message, emit, executed.result);
|
|
5564
|
-
}
|
|
5565
|
-
}
|
|
5566
|
-
}
|
|
5567
|
-
async function executeToolCallsParallel(config, currentContext, message, toolCalls, emit, signal) {
|
|
5568
|
-
const runnables = [];
|
|
5569
|
-
for (const toolCall of toolCalls) {
|
|
5570
|
-
const toolCallInFlight = {
|
|
5571
|
-
callID: toolCall.callID,
|
|
5572
|
-
name: toolCall.name,
|
|
5573
|
-
rawArgs: toolCall.arguments
|
|
5574
|
-
};
|
|
5575
|
-
await emitEvent(emit, {
|
|
5576
|
-
type: "tool.execution.start",
|
|
5577
|
-
...toolCallInFlight
|
|
5578
|
-
});
|
|
5579
|
-
const prepared = await prepareToolCall(config, currentContext, message, toolCallInFlight, signal);
|
|
5580
|
-
if (prepared.error) {
|
|
5581
|
-
const error = {
|
|
5582
|
-
status: "error",
|
|
5583
|
-
result: {
|
|
5584
|
-
content: [{
|
|
5585
|
-
type: "text",
|
|
5586
|
-
text: prepared.error.message
|
|
5587
|
-
}],
|
|
5588
|
-
details: prepared.error.details,
|
|
5589
|
-
isError: true
|
|
5590
|
-
}
|
|
5591
|
-
};
|
|
5592
|
-
await emitToolCallTerminalResult(toolCall, prepared.runnable, message, emit, error);
|
|
5593
|
-
} else runnables.push({
|
|
5594
|
-
toolCall,
|
|
5595
|
-
runnable: prepared.runnable,
|
|
5596
|
-
tool: prepared.tool
|
|
5597
|
-
});
|
|
5598
|
-
}
|
|
5599
|
-
const runningExecutions = runnables.map((runnable) => ({
|
|
5600
|
-
runnable,
|
|
5601
|
-
execution: executeRunnableToolCall(runnable, message, emit, signal)
|
|
5602
|
-
}));
|
|
5603
|
-
for (const running of runningExecutions) {
|
|
5604
|
-
const executed = await running.execution;
|
|
5605
|
-
const { runnable } = running;
|
|
5606
|
-
if (executed.error) {
|
|
5607
|
-
const error = {
|
|
5608
|
-
status: "error",
|
|
5609
|
-
result: {
|
|
5610
|
-
content: [{
|
|
5611
|
-
type: "text",
|
|
5612
|
-
text: executed.error.message
|
|
5613
|
-
}],
|
|
5614
|
-
details: executed.error.details,
|
|
5615
|
-
isError: true
|
|
5616
|
-
}
|
|
5617
|
-
};
|
|
5618
|
-
await emitToolCallTerminalResult(runnable.toolCall, runnable.runnable, message, emit, error);
|
|
5619
|
-
} else await finalizeExecutedToolCall(config, currentContext, runnable.toolCall, runnable.runnable, message, emit, executed.result);
|
|
5620
|
-
}
|
|
5621
|
-
}
|
|
5622
|
-
async function prepareToolCall(config, currentContext, assistantMessage, toolCallInFlight, signal) {
|
|
5623
|
-
const tool = currentContext.tools?.find((t) => t.name === toolCallInFlight.name);
|
|
5624
|
-
if (!tool) return {
|
|
5625
|
-
error: {
|
|
5626
|
-
kind: "error",
|
|
5627
|
-
message: `Tool ${toolCallInFlight.name} Not Found`
|
|
5628
|
-
},
|
|
5629
|
-
runnable: toolCallInFlight
|
|
5630
|
-
};
|
|
5631
|
-
try {
|
|
5632
|
-
toolCallInFlight.args = validateToolArguments(tool, toolCallInFlight);
|
|
5633
|
-
if (config.beforeToolExecution) {
|
|
5634
|
-
const beforeResult = await config.beforeToolExecution({
|
|
5635
|
-
context: currentContext,
|
|
5636
|
-
assistantMessage,
|
|
5637
|
-
toolCall: toolCallInFlight
|
|
5638
|
-
}, signal);
|
|
5639
|
-
if (beforeResult?.block) return {
|
|
5640
|
-
error: {
|
|
5641
|
-
kind: "blocked",
|
|
5642
|
-
message: beforeResult?.reason || "Tool Execution was Blocked",
|
|
5643
|
-
details: beforeResult?.details
|
|
5644
|
-
},
|
|
5645
|
-
runnable: toolCallInFlight
|
|
5646
|
-
};
|
|
5647
|
-
}
|
|
5648
|
-
return {
|
|
5649
|
-
runnable: toolCallInFlight,
|
|
5650
|
-
tool
|
|
5651
|
-
};
|
|
5652
|
-
} catch (err) {
|
|
5653
|
-
return {
|
|
5654
|
-
error: {
|
|
5655
|
-
kind: "error",
|
|
5656
|
-
message: err instanceof Error ? err.message : String(err)
|
|
5657
|
-
},
|
|
5658
|
-
runnable: toolCallInFlight
|
|
5659
|
-
};
|
|
5660
|
-
}
|
|
5661
|
-
}
|
|
5662
|
-
async function executeRunnableToolCall(toolCallRunnable, message, emit, signal) {
|
|
5663
|
-
const { toolCall, runnable, tool } = toolCallRunnable;
|
|
5664
|
-
const { partIndex, ...pendingPart } = toolCall;
|
|
5665
|
-
try {
|
|
5666
|
-
return { result: await tool.execute(runnable.callID, runnable.args, signal, async (result) => {
|
|
5667
|
-
const runningResult = {
|
|
5668
|
-
status: "running",
|
|
5669
|
-
partial: result.partial
|
|
5670
|
-
};
|
|
5671
|
-
await emitEvent(emit, {
|
|
5672
|
-
type: "tool.execution.update",
|
|
5673
|
-
...runnable,
|
|
5674
|
-
...runningResult
|
|
5675
|
-
});
|
|
5676
|
-
const runningPart = {
|
|
5677
|
-
...pendingPart,
|
|
5678
|
-
...runningResult
|
|
5679
|
-
};
|
|
5680
|
-
message.parts[partIndex] = runningPart;
|
|
5681
|
-
await emitEvent(emit, {
|
|
5682
|
-
type: "message.part.update",
|
|
5683
|
-
message,
|
|
5684
|
-
partIndex,
|
|
5685
|
-
part: runningPart,
|
|
5686
|
-
source: "tool"
|
|
5687
|
-
});
|
|
5688
|
-
}) };
|
|
5689
|
-
} catch (err) {
|
|
5690
|
-
return { error: { message: err instanceof Error ? err.message : String(err) } };
|
|
5691
|
-
}
|
|
5692
|
-
}
|
|
5693
|
-
async function emitToolCallTerminalResult(toolCall, runnable, message, emit, result) {
|
|
5694
|
-
const { partIndex, ...pendingPart } = toolCall;
|
|
5695
|
-
const { time } = pendingPart;
|
|
5696
|
-
await emitEvent(emit, {
|
|
5697
|
-
type: "tool.execution.end",
|
|
5698
|
-
...runnable,
|
|
5699
|
-
...result
|
|
5700
|
-
});
|
|
5701
|
-
const part = {
|
|
5702
|
-
...pendingPart,
|
|
5703
|
-
...result,
|
|
5704
|
-
time: {
|
|
5705
|
-
start: time.start,
|
|
5706
|
-
end: Date.now()
|
|
5707
|
-
}
|
|
5708
|
-
};
|
|
5709
|
-
message.parts[partIndex] = part;
|
|
5710
|
-
await emitEvent(emit, {
|
|
5711
|
-
type: "message.part.start",
|
|
5712
|
-
message,
|
|
5713
|
-
partIndex,
|
|
5714
|
-
part
|
|
5715
|
-
});
|
|
5716
|
-
await emitEvent(emit, {
|
|
5717
|
-
type: "message.part.end",
|
|
5718
|
-
message,
|
|
5719
|
-
partIndex,
|
|
5720
|
-
part
|
|
5721
|
-
});
|
|
5722
|
-
await emitEvent(emit, {
|
|
5723
|
-
type: "message.update",
|
|
5724
|
-
message
|
|
5725
|
-
});
|
|
5726
|
-
}
|
|
5727
|
-
async function finalizeExecutedToolCall(config, currentContext, toolCall, runnable, message, emit, result, signal) {
|
|
5728
|
-
if (config.afterToolExecution) {
|
|
5729
|
-
const afterResult = await config.afterToolExecution({
|
|
5730
|
-
context: currentContext,
|
|
5731
|
-
assistantMessage: message,
|
|
5732
|
-
toolCall: runnable,
|
|
5733
|
-
result
|
|
5734
|
-
}, signal);
|
|
5735
|
-
if (afterResult) {
|
|
5736
|
-
await emitToolCallTerminalResult(toolCall, runnable, message, emit, afterResult);
|
|
5737
|
-
return;
|
|
5738
|
-
}
|
|
5739
|
-
}
|
|
5740
|
-
await emitToolCallTerminalResult(toolCall, runnable, message, emit, result);
|
|
5741
|
-
}
|
|
5742
|
-
/**
|
|
5743
|
-
* Main core loop shared by run and runContinue.
|
|
5744
|
-
*/
|
|
5745
|
-
async function runLoop(config, currentContext, newMessages, emit, streamFn, signal) {
|
|
5746
|
-
let firstTurn = true;
|
|
5747
|
-
let pendingMessages = await config.getSteeringMessages?.() || [];
|
|
5748
|
-
while (true) {
|
|
5749
|
-
let hasMoreToolCalls = true;
|
|
5750
|
-
while (hasMoreToolCalls || pendingMessages.length > 0) {
|
|
5751
|
-
if (!firstTurn) await emitEvent(emit, { type: "turn.start" });
|
|
5752
|
-
else firstTurn = false;
|
|
5753
|
-
if (pendingMessages.length > 0) {
|
|
5754
|
-
for (const message of pendingMessages) {
|
|
5755
|
-
await emitEvent(emit, {
|
|
5756
|
-
type: "message.start",
|
|
5757
|
-
message
|
|
5758
|
-
});
|
|
5759
|
-
for (const [partIndex, part] of message.parts.entries()) {
|
|
5760
|
-
await emitEvent(emit, {
|
|
5761
|
-
type: "message.part.start",
|
|
5762
|
-
message,
|
|
5763
|
-
partIndex,
|
|
5764
|
-
part
|
|
5765
|
-
});
|
|
5766
|
-
await emitEvent(emit, {
|
|
5767
|
-
type: "message.part.end",
|
|
5768
|
-
message,
|
|
5769
|
-
partIndex,
|
|
5770
|
-
part
|
|
5771
|
-
});
|
|
5772
|
-
await emitEvent(emit, {
|
|
5773
|
-
type: "message.update",
|
|
5774
|
-
message
|
|
5775
|
-
});
|
|
5776
|
-
}
|
|
5777
|
-
await emitEvent(emit, {
|
|
5778
|
-
type: "message.end",
|
|
5779
|
-
message
|
|
5780
|
-
});
|
|
5781
|
-
currentContext.messages.push(message);
|
|
5782
|
-
newMessages.push(message);
|
|
5783
|
-
}
|
|
5784
|
-
pendingMessages = [];
|
|
5785
|
-
}
|
|
5786
|
-
const message = await streamAssistantResponse(config, currentContext, emit, streamFn, signal);
|
|
5787
|
-
if (message.stopReason === "error" || message.stopReason === "aborted") {
|
|
5788
|
-
currentContext.messages.push(message);
|
|
5789
|
-
newMessages.push(message);
|
|
5790
|
-
await emitEvent(emit, {
|
|
5791
|
-
type: "turn.end",
|
|
5792
|
-
message
|
|
5793
|
-
});
|
|
5794
|
-
await emitEvent(emit, {
|
|
5795
|
-
type: "agent.end",
|
|
5796
|
-
messages: newMessages
|
|
5797
|
-
});
|
|
5798
|
-
return;
|
|
5799
|
-
}
|
|
5800
|
-
const toolCalls = message.parts.map((part, index) => ({
|
|
5801
|
-
...part,
|
|
5802
|
-
partIndex: index
|
|
5803
|
-
})).filter((part) => part.type === "toolCall" && part.status === "pending");
|
|
5804
|
-
hasMoreToolCalls = toolCalls.length > 0;
|
|
5805
|
-
if (hasMoreToolCalls) await executeToolCalls(config, currentContext, message, toolCalls, emit, signal);
|
|
5806
|
-
currentContext.messages.push(message);
|
|
5807
|
-
newMessages.push(message);
|
|
5808
|
-
await emitEvent(emit, {
|
|
5809
|
-
type: "turn.end",
|
|
5810
|
-
message
|
|
5811
|
-
});
|
|
5812
|
-
pendingMessages = await config.getSteeringMessages?.() || [];
|
|
5813
|
-
}
|
|
5814
|
-
const followUpMessages = await config.getFollowUpMessages?.() || [];
|
|
5815
|
-
if (followUpMessages.length > 0) {
|
|
5816
|
-
pendingMessages = followUpMessages;
|
|
5817
|
-
continue;
|
|
5818
|
-
}
|
|
5819
|
-
break;
|
|
5820
|
-
}
|
|
5821
|
-
await emitEvent(emit, {
|
|
5822
|
-
type: "agent.end",
|
|
5823
|
-
messages: newMessages
|
|
5824
|
-
});
|
|
5825
|
-
}
|
|
5826
|
-
async function runAgentLoop(config, context, prompts, emit, streamFn, signal) {
|
|
5827
|
-
/**
|
|
5828
|
-
* maintain 2 arrays to represent state, `context` the actual full state sent to the LLM,
|
|
5829
|
-
* `newMessages` for intermediate current loop state.
|
|
5830
|
-
* think of newMessages as subset of context.messages for the running current loop.
|
|
5831
|
-
* they do move at the same speed staring with initial user prompts.
|
|
5832
|
-
* */
|
|
5833
|
-
const newMessages = [...prompts];
|
|
5834
|
-
const currentContext = {
|
|
5835
|
-
...context,
|
|
5836
|
-
messages: [...context.messages, ...prompts]
|
|
5837
|
-
};
|
|
5838
|
-
await emitEvent(emit, { type: "agent.start" });
|
|
5839
|
-
await emitEvent(emit, { type: "turn.start" });
|
|
5840
|
-
for (const prompt of prompts) {
|
|
5841
|
-
await emitEvent(emit, {
|
|
5842
|
-
type: "message.start",
|
|
5843
|
-
message: prompt
|
|
5844
|
-
});
|
|
5845
|
-
for (const [partIndex, part] of prompt.parts.entries()) {
|
|
5846
|
-
await emitEvent(emit, {
|
|
5847
|
-
type: "message.part.start",
|
|
5848
|
-
message: prompt,
|
|
5849
|
-
partIndex,
|
|
5850
|
-
part
|
|
5851
|
-
});
|
|
5852
|
-
await emitEvent(emit, {
|
|
5853
|
-
type: "message.part.end",
|
|
5854
|
-
message: prompt,
|
|
5855
|
-
partIndex,
|
|
5856
|
-
part
|
|
5857
|
-
});
|
|
5858
|
-
}
|
|
5859
|
-
await emitEvent(emit, {
|
|
5860
|
-
type: "message.end",
|
|
5861
|
-
message: prompt
|
|
5862
|
-
});
|
|
5863
|
-
}
|
|
5864
|
-
await runLoop(config, currentContext, newMessages, emit, streamFn, signal);
|
|
5865
|
-
return newMessages;
|
|
5866
|
-
}
|
|
5867
|
-
_Loop.runAgentLoop = runAgentLoop;
|
|
5868
|
-
async function runAgentLoopContinue(config, context, emit, streamFn, signal) {
|
|
5869
|
-
if (context.messages.length === 0) throw new AgentContextError({ message: "connot continue: no messages in context" });
|
|
5870
|
-
if (context.messages[context.messages.length - 1]?.role === "assistant") throw new AgentContextError({ message: "cannot continue from message role: assistant" });
|
|
5871
|
-
const newMessages = [];
|
|
5872
|
-
const currentContext = { ...context };
|
|
5873
|
-
await emitEvent(emit, { type: "agent.start" });
|
|
5874
|
-
await emitEvent(emit, { type: "turn.start" });
|
|
5875
|
-
await runLoop(config, currentContext, newMessages, emit, streamFn, signal);
|
|
5876
|
-
return newMessages;
|
|
5877
|
-
}
|
|
5878
|
-
_Loop.runAgentLoopContinue = runAgentLoopContinue;
|
|
5879
|
-
function run(config, context, prompts, streamFn, signal) {
|
|
5880
|
-
const stream = createAgentStream();
|
|
5881
|
-
runAgentLoop(config, context, prompts, async (event) => {
|
|
5882
|
-
stream.push(event);
|
|
5883
|
-
}, streamFn, signal).then((messages) => {
|
|
5884
|
-
stream.end(messages);
|
|
5885
|
-
});
|
|
5886
|
-
return stream;
|
|
5887
|
-
}
|
|
5888
|
-
_Loop.run = run;
|
|
5889
|
-
function runContinue(config, context, streamFn, signal) {
|
|
5890
|
-
const stream = createAgentStream();
|
|
5891
|
-
runAgentLoopContinue(config, context, async (event) => {
|
|
5892
|
-
stream.push(event);
|
|
5893
|
-
}, streamFn, signal).then((messages) => {
|
|
5894
|
-
stream.end(messages);
|
|
5895
|
-
});
|
|
5896
|
-
return stream;
|
|
5897
|
-
}
|
|
5898
|
-
_Loop.runContinue = runContinue;
|
|
5899
|
-
})(Loop || (Loop = {}));
|
|
5900
|
-
//#endregion
|
|
5901
|
-
//#region src/agent.ts
|
|
5902
|
-
const agent = {
|
|
5903
|
-
loop: Loop.run,
|
|
5904
|
-
loopContinue: Loop.runContinue
|
|
5905
|
-
};
|
|
5906
|
-
//#endregion
|
|
5907
|
-
//#region src/message/message.ts
|
|
5908
|
-
let Message;
|
|
5909
|
-
(function(_Message) {
|
|
5910
|
-
const TextContentSchema = _Message.TextContentSchema = Type.Object({
|
|
5911
|
-
type: Type.Literal("text"),
|
|
5912
|
-
text: Type.String(),
|
|
5913
|
-
textSignature: Type.Optional(Type.String())
|
|
5914
|
-
});
|
|
5915
|
-
const ImageContentSchema = _Message.ImageContentSchema = Type.Object({
|
|
5916
|
-
type: Type.Literal("image"),
|
|
5917
|
-
data: Type.String(),
|
|
5918
|
-
mimeType: Type.String()
|
|
5919
|
-
});
|
|
5920
|
-
const ThinkingContentSchema = _Message.ThinkingContentSchema = Type.Object({
|
|
5921
|
-
type: Type.Literal("thinking"),
|
|
5922
|
-
thinking: Type.String(),
|
|
5923
|
-
thinkingSignature: Type.Optional(Type.String()),
|
|
5924
|
-
redacted: Type.Optional(Type.Boolean())
|
|
5925
|
-
});
|
|
5926
|
-
const ToolCallBaseSchema = _Message.ToolCallBaseSchema = Type.Object({
|
|
5927
|
-
type: Type.Literal("toolCall"),
|
|
5928
|
-
callID: Type.String(),
|
|
5929
|
-
name: Type.String(),
|
|
5930
|
-
arguments: Type.Record(Type.String(), Type.Any()),
|
|
5931
|
-
thoughtSignature: Type.Optional(Type.String()),
|
|
5932
|
-
time: Type.Object({
|
|
5933
|
-
start: Type.Number(),
|
|
5934
|
-
end: Type.Number()
|
|
5935
|
-
})
|
|
5936
|
-
});
|
|
5937
|
-
const ToolSuccessResult = _Message.ToolSuccessResult = Type.Object({
|
|
5938
|
-
content: Type.Array(Type.Union([TextContentSchema, ImageContentSchema])),
|
|
5939
|
-
details: Type.Optional(Type.Any()),
|
|
5940
|
-
isError: Type.Literal(false)
|
|
5941
|
-
});
|
|
5942
|
-
const ToolErrorResult = _Message.ToolErrorResult = Type.Object({
|
|
5943
|
-
content: Type.Array(Type.Union([TextContentSchema, ImageContentSchema])),
|
|
5944
|
-
details: Type.Optional(Type.Any()),
|
|
5945
|
-
isError: Type.Literal(true)
|
|
5946
|
-
});
|
|
5947
|
-
const ToolRunningPartial = _Message.ToolRunningPartial = Type.Object({
|
|
5948
|
-
content: Type.Optional(Type.Array(Type.Union([TextContentSchema, ImageContentSchema]))),
|
|
5949
|
-
details: Type.Optional(Type.Any())
|
|
5950
|
-
});
|
|
5951
|
-
const ToolStatusEnum = _Message.ToolStatusEnum = {
|
|
5952
|
-
pending: "pending",
|
|
5953
|
-
running: "running",
|
|
5954
|
-
completed: "completed",
|
|
5955
|
-
error: "error",
|
|
5956
|
-
skipped: "skipped",
|
|
5957
|
-
aborted: "aborted"
|
|
5958
|
-
};
|
|
5959
|
-
const ToolRunningSchema = _Message.ToolRunningSchema = Type.Object({
|
|
5960
|
-
status: Type.Literal(ToolStatusEnum.running),
|
|
5961
|
-
partial: Type.Optional(ToolRunningPartial)
|
|
5962
|
-
});
|
|
5963
|
-
const ToolCompletedSchema = _Message.ToolCompletedSchema = Type.Object({
|
|
5964
|
-
status: Type.Literal(ToolStatusEnum.completed),
|
|
5965
|
-
result: ToolSuccessResult
|
|
5966
|
-
});
|
|
5967
|
-
const ToolErrorSchema = _Message.ToolErrorSchema = Type.Object({
|
|
5968
|
-
status: Type.Literal(ToolStatusEnum.error),
|
|
5969
|
-
result: ToolErrorResult
|
|
5970
|
-
});
|
|
5971
|
-
const ToolSkippedSchema = _Message.ToolSkippedSchema = Type.Object({
|
|
5972
|
-
status: Type.Literal(ToolStatusEnum.skipped),
|
|
5973
|
-
result: ToolErrorResult
|
|
5974
|
-
});
|
|
5975
|
-
const ToolAbortedSchema = _Message.ToolAbortedSchema = Type.Object({
|
|
5976
|
-
status: Type.Literal(ToolStatusEnum.aborted),
|
|
5977
|
-
result: ToolErrorResult
|
|
5978
|
-
});
|
|
5979
|
-
const ToolCallPendingPart = Type.Intersect([ToolCallBaseSchema, Type.Object({ status: Type.Literal(ToolStatusEnum.pending) })]);
|
|
5980
|
-
const ToolCallRunningPart = Type.Evaluate(Type.Intersect([ToolCallBaseSchema, ToolRunningSchema]));
|
|
5981
|
-
const ToolCallCompletedPart = Type.Evaluate(Type.Intersect([ToolCallBaseSchema, ToolCompletedSchema]));
|
|
5982
|
-
const ToolCallErrorPart = Type.Evaluate(Type.Intersect([ToolCallBaseSchema, ToolErrorSchema]));
|
|
5983
|
-
const ToolCallSkippedPart = Type.Evaluate(Type.Intersect([ToolCallBaseSchema, ToolSkippedSchema]));
|
|
5984
|
-
const ToolCallAbortedPart = Type.Evaluate(Type.Intersect([ToolCallBaseSchema, ToolAbortedSchema]));
|
|
5985
|
-
const ToolCallSchema = _Message.ToolCallSchema = Type.Union([
|
|
5986
|
-
ToolCallPendingPart,
|
|
5987
|
-
ToolCallRunningPart,
|
|
5988
|
-
ToolCallCompletedPart,
|
|
5989
|
-
ToolCallErrorPart,
|
|
5990
|
-
ToolCallSkippedPart,
|
|
5991
|
-
ToolCallAbortedPart
|
|
5992
|
-
]);
|
|
5993
|
-
const UsageSchema = _Message.UsageSchema = Type.Object({
|
|
5994
|
-
input: Type.Number(),
|
|
5995
|
-
output: Type.Number(),
|
|
5996
|
-
cacheRead: Type.Number(),
|
|
5997
|
-
cacheWrite: Type.Number(),
|
|
5998
|
-
totalTokens: Type.Number(),
|
|
5999
|
-
cost: Type.Object({
|
|
6000
|
-
input: Type.Number(),
|
|
6001
|
-
output: Type.Number(),
|
|
6002
|
-
cacheRead: Type.Number(),
|
|
6003
|
-
cacheWrite: Type.Number(),
|
|
6004
|
-
total: Type.Number()
|
|
6005
|
-
})
|
|
6006
|
-
});
|
|
6007
|
-
const StopReasonSchema = _Message.StopReasonSchema = Type.Union([
|
|
6008
|
-
Type.Literal("stop"),
|
|
6009
|
-
Type.Literal("length"),
|
|
6010
|
-
Type.Literal("toolUse"),
|
|
6011
|
-
Type.Literal("error"),
|
|
6012
|
-
Type.Literal("aborted")
|
|
6013
|
-
]);
|
|
6014
|
-
const UserMessageSchema = _Message.UserMessageSchema = Type.Object({
|
|
6015
|
-
messageId: Type.String(),
|
|
6016
|
-
role: Type.Literal("user"),
|
|
6017
|
-
time: Type.Object({ created: Type.Number() }),
|
|
6018
|
-
parts: Type.Array(Type.Union([TextContentSchema, ImageContentSchema]))
|
|
6019
|
-
});
|
|
6020
|
-
const AssistantMessageSchema = _Message.AssistantMessageSchema = Type.Object({
|
|
6021
|
-
role: Type.Literal("assistant"),
|
|
6022
|
-
protocol: Model.KnownProtocolSchema,
|
|
6023
|
-
provider: Provider.Info,
|
|
6024
|
-
model: Type.String(),
|
|
6025
|
-
usage: UsageSchema,
|
|
6026
|
-
stopReason: StopReasonSchema,
|
|
6027
|
-
errorMessage: Type.Optional(Type.String()),
|
|
6028
|
-
time: Type.Object({
|
|
6029
|
-
created: Type.Number(),
|
|
6030
|
-
completed: Type.Number()
|
|
6031
|
-
}),
|
|
6032
|
-
parts: Type.Array(Type.Union([
|
|
6033
|
-
TextContentSchema,
|
|
6034
|
-
ImageContentSchema,
|
|
6035
|
-
ThinkingContentSchema,
|
|
6036
|
-
ToolCallSchema
|
|
6037
|
-
])),
|
|
6038
|
-
responseId: Type.Optional(Type.String()),
|
|
6039
|
-
messageId: Type.String()
|
|
6040
|
-
});
|
|
6041
|
-
const MessageSchema = _Message.MessageSchema = Type.Union([UserMessageSchema, AssistantMessageSchema]);
|
|
6042
|
-
function createMessageId() {
|
|
6043
|
-
return uuidv7();
|
|
6044
|
-
}
|
|
6045
|
-
_Message.createMessageId = createMessageId;
|
|
6046
|
-
function createUserMessage(message) {
|
|
6047
|
-
const { messageId = createMessageId(), ...rest } = message;
|
|
6048
|
-
return {
|
|
6049
|
-
messageId,
|
|
6050
|
-
...rest
|
|
6051
|
-
};
|
|
6052
|
-
}
|
|
6053
|
-
_Message.createUserMessage = createUserMessage;
|
|
6054
|
-
function createAssistantMessage(message) {
|
|
6055
|
-
const { messageId = createMessageId(), ...rest } = message;
|
|
6056
|
-
return {
|
|
6057
|
-
messageId,
|
|
6058
|
-
...rest
|
|
6059
|
-
};
|
|
6060
|
-
}
|
|
6061
|
-
_Message.createAssistantMessage = createAssistantMessage;
|
|
6062
|
-
const ToolSchema = _Message.ToolSchema = Type.Object({
|
|
6063
|
-
name: Type.String(),
|
|
6064
|
-
description: Type.String(),
|
|
6065
|
-
parameters: Type.Unsafe({})
|
|
6066
|
-
});
|
|
6067
|
-
function defineTool(tool) {
|
|
6068
|
-
return tool;
|
|
6069
|
-
}
|
|
6070
|
-
_Message.defineTool = defineTool;
|
|
6071
|
-
_Message.ContextSchema = Type.Object({
|
|
6072
|
-
systemPrompt: Type.Optional(Type.String()),
|
|
6073
|
-
messages: Type.Array(MessageSchema),
|
|
6074
|
-
tools: Type.Optional(Type.Array(ToolSchema))
|
|
6075
|
-
});
|
|
6076
|
-
function transformMessages(messages, model, normalizeToolCallId) {
|
|
6077
|
-
const toolCallIDMap = /* @__PURE__ */ new Map();
|
|
6078
|
-
const transformed = [];
|
|
6079
|
-
for (const msg of messages) {
|
|
6080
|
-
if (msg.role === "user") {
|
|
6081
|
-
transformed.push(msg);
|
|
6082
|
-
continue;
|
|
6083
|
-
}
|
|
6084
|
-
const assistantMsg = msg;
|
|
6085
|
-
const isSameModel = assistantMsg.provider.id === model.provider.id && assistantMsg.protocol === model.protocol && assistantMsg.model === model.id;
|
|
6086
|
-
const parts = assistantMsg.parts.flatMap((block) => {
|
|
6087
|
-
if (block.type === "thinking") {
|
|
6088
|
-
if (isSameModel && block.thinkingSignature) return block;
|
|
6089
|
-
if (!block.thinking || block.thinking.trim() === "") return [];
|
|
6090
|
-
if (isSameModel) return block;
|
|
6091
|
-
return {
|
|
6092
|
-
type: "text",
|
|
6093
|
-
text: block.thinking
|
|
6094
|
-
};
|
|
6095
|
-
}
|
|
6096
|
-
if (block.type === "text") {
|
|
6097
|
-
if (isSameModel) return block;
|
|
6098
|
-
return {
|
|
6099
|
-
type: "text",
|
|
6100
|
-
text: block.text
|
|
6101
|
-
};
|
|
6102
|
-
}
|
|
6103
|
-
if (block.type === "toolCall") {
|
|
6104
|
-
const toolCall = block;
|
|
6105
|
-
let normalizedToolCall = toolCall;
|
|
6106
|
-
if (!isSameModel && toolCall.thoughtSignature) {
|
|
6107
|
-
normalizedToolCall = { ...toolCall };
|
|
6108
|
-
delete normalizedToolCall.thoughtSignature;
|
|
6109
|
-
}
|
|
6110
|
-
const normalizedID = toolCallIDMap.get(block.callID);
|
|
6111
|
-
if (normalizedID && normalizedID !== block.callID) normalizedToolCall = {
|
|
6112
|
-
...normalizedToolCall,
|
|
6113
|
-
callID: normalizedID
|
|
6114
|
-
};
|
|
6115
|
-
else if (!isSameModel && normalizeToolCallId) {
|
|
6116
|
-
const nextID = normalizeToolCallId(toolCall.callID, model, assistantMsg);
|
|
6117
|
-
if (nextID !== toolCall.callID) {
|
|
6118
|
-
toolCallIDMap.set(toolCall.callID, nextID);
|
|
6119
|
-
normalizedToolCall = {
|
|
6120
|
-
...normalizedToolCall,
|
|
6121
|
-
callID: nextID
|
|
6122
|
-
};
|
|
6123
|
-
}
|
|
6124
|
-
}
|
|
6125
|
-
return normalizedToolCall;
|
|
6126
|
-
}
|
|
6127
|
-
return block;
|
|
6128
|
-
});
|
|
6129
|
-
transformed.push({
|
|
6130
|
-
...assistantMsg,
|
|
6131
|
-
parts
|
|
6132
|
-
});
|
|
6133
|
-
}
|
|
6134
|
-
return transformed;
|
|
6135
|
-
}
|
|
6136
|
-
_Message.transformMessages = transformMessages;
|
|
6137
|
-
})(Message || (Message = {}));
|
|
6138
|
-
//#endregion
|
|
6139
|
-
//#region src/utils/jsonparse.ts
|
|
6140
|
-
/**
|
|
6141
|
-
* @description Helper function to parse partial jsons during LLM streaming.
|
|
6142
|
-
*/
|
|
6143
|
-
/**
|
|
6144
|
-
* Attempts to parse potentially incomplete JSON during streaming.
|
|
6145
|
-
* Always returns a valid object, even if the JSON is incomplete.
|
|
6146
|
-
*
|
|
6147
|
-
* @param partialJson The partial JSON string from streaming
|
|
6148
|
-
* @returns Parsed object or empty object if parsing fails
|
|
6149
|
-
*/
|
|
6150
|
-
function parseStreamingJson(partialJson) {
|
|
6151
|
-
if (!partialJson || partialJson.trim() === "") return {};
|
|
6152
|
-
try {
|
|
6153
|
-
return JSON.parse(partialJson);
|
|
6154
|
-
} catch {
|
|
6155
|
-
try {
|
|
6156
|
-
return parse(partialJson) ?? {};
|
|
6157
|
-
} catch {
|
|
6158
|
-
return {};
|
|
6159
|
-
}
|
|
6160
|
-
}
|
|
6161
|
-
}
|
|
6162
|
-
//#endregion
|
|
6163
|
-
//#region src/utils/sanitize.ts
|
|
6164
|
-
/**
|
|
6165
|
-
* Removes unpaired Unicode surrogate characters from a string.
|
|
6166
|
-
*
|
|
6167
|
-
* Unpaired surrogates (high surrogates 0xD800-0xDBFF without matching low surrogates 0xDC00-0xDFFF,
|
|
6168
|
-
* or vice versa) cause JSON serialization errors in many API providers.
|
|
6169
|
-
*
|
|
6170
|
-
* Valid emoji and other characters outside the Basic Multilingual Plane use properly paired
|
|
6171
|
-
* surrogates and will NOT be affected by this function.
|
|
6172
|
-
*
|
|
6173
|
-
* @param text - The text to sanitize
|
|
6174
|
-
* @returns The sanitized text with unpaired surrogates removed
|
|
6175
|
-
*
|
|
6176
|
-
* @example
|
|
6177
|
-
* // Valid emoji (properly paired surrogates) are preserved
|
|
6178
|
-
* sanitizeSurrogates("Hello 🙈 World") // => "Hello 🙈 World"
|
|
6179
|
-
*
|
|
6180
|
-
* // Unpaired high surrogate is removed
|
|
6181
|
-
* const unpaired = String.fromCharCode(0xD83D); // high surrogate without low
|
|
6182
|
-
* sanitizeSurrogates(`Text ${unpaired} here`) // => "Text here"
|
|
6183
|
-
*/
|
|
6184
|
-
function sanitizeSurrogates(text) {
|
|
6185
|
-
return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
5111
|
+
function defaultMethodForModel(model) {
|
|
5112
|
+
if (model.protocol === Model.KnownProviderEnum.openai || model.protocol === Model.KnownProviderEnum.xai) return Model.APIMethodEnum.responses;
|
|
5113
|
+
return Model.APIMethodEnum.languageModel;
|
|
6186
5114
|
}
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
if (
|
|
6194
|
-
|
|
6195
|
-
|
|
5115
|
+
function resolveLanguageModel(provider, model, methodOverride) {
|
|
5116
|
+
const modelId = model.api?.id ?? model.id;
|
|
5117
|
+
const method = methodOverride ?? model.api?.method ?? defaultMethodForModel(model);
|
|
5118
|
+
const callable = provider;
|
|
5119
|
+
if (method === Model.APIMethodEnum.responses && callable.responses) return callable.responses(modelId);
|
|
5120
|
+
if (method === Model.APIMethodEnum.messages && callable.messages) return callable.messages(modelId);
|
|
5121
|
+
if (method === Model.APIMethodEnum.chat) {
|
|
5122
|
+
if (callable.chat) return callable.chat(modelId);
|
|
5123
|
+
if (callable.chatModel) return callable.chatModel(modelId);
|
|
5124
|
+
}
|
|
5125
|
+
if (method === Model.APIMethodEnum.completion) {
|
|
5126
|
+
if (callable.completion) return callable.completion(modelId);
|
|
5127
|
+
if (callable.completionModel) return callable.completionModel(modelId);
|
|
5128
|
+
}
|
|
5129
|
+
if (method === Model.APIMethodEnum.completionModel && callable.completionModel) return callable.completionModel(modelId);
|
|
5130
|
+
if (callable.languageModel) return callable.languageModel(modelId);
|
|
5131
|
+
return callable(modelId);
|
|
6196
5132
|
}
|
|
6197
|
-
function getCacheControl(baseUrl, cacheRetention) {
|
|
6198
|
-
const retention = resolveCacheRetention(cacheRetention);
|
|
6199
|
-
if (retention === "none") return { retention };
|
|
6200
|
-
const ttl = retention === "long" && baseUrl.includes("api.anthropic.com") ? "1h" : void 0;
|
|
6201
|
-
return {
|
|
6202
|
-
retention,
|
|
6203
|
-
cacheControl: {
|
|
6204
|
-
type: "ephemeral",
|
|
6205
|
-
...ttl && { ttl }
|
|
6206
|
-
}
|
|
6207
|
-
};
|
|
6208
|
-
}
|
|
6209
|
-
const claudeCodeVersion = "2.1.2";
|
|
6210
|
-
const ccToolLookup = new Map([
|
|
6211
|
-
"Read",
|
|
6212
|
-
"Write",
|
|
6213
|
-
"Edit",
|
|
6214
|
-
"Bash",
|
|
6215
|
-
"Grep",
|
|
6216
|
-
"Glob",
|
|
6217
|
-
"AskUserQuestion",
|
|
6218
|
-
"EnterPlanMode",
|
|
6219
|
-
"ExitPlanMode",
|
|
6220
|
-
"KillShell",
|
|
6221
|
-
"NotebookEdit",
|
|
6222
|
-
"Skill",
|
|
6223
|
-
"Task",
|
|
6224
|
-
"TaskOutput",
|
|
6225
|
-
"TodoWrite",
|
|
6226
|
-
"WebFetch",
|
|
6227
|
-
"WebSearch"
|
|
6228
|
-
].map((t) => [t.toLowerCase(), t]));
|
|
6229
|
-
const toClaudeCodeName = (name) => ccToolLookup.get(name.toLowerCase()) ?? name;
|
|
6230
|
-
const fromClaudeCodeName = (name, tools) => {
|
|
6231
|
-
if (tools && tools.length > 0) {
|
|
6232
|
-
const lowerName = name.toLowerCase();
|
|
6233
|
-
const matchedTool = tools.find((tool) => tool.name.toLowerCase() === lowerName);
|
|
6234
|
-
if (matchedTool) return matchedTool.name;
|
|
6235
|
-
}
|
|
6236
|
-
return name;
|
|
6237
|
-
};
|
|
6238
|
-
function convertContentBlocks(content) {
|
|
6239
|
-
if (!content.some((c) => c.type === "image")) return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
|
|
6240
|
-
const blocks = content.map((block) => {
|
|
6241
|
-
if (block.type === "text") return {
|
|
6242
|
-
type: "text",
|
|
6243
|
-
text: sanitizeSurrogates(block.text)
|
|
6244
|
-
};
|
|
6245
|
-
return {
|
|
6246
|
-
type: "image",
|
|
6247
|
-
source: {
|
|
6248
|
-
type: "base64",
|
|
6249
|
-
media_type: block.mimeType,
|
|
6250
|
-
data: block.data
|
|
6251
|
-
}
|
|
6252
|
-
};
|
|
6253
|
-
});
|
|
6254
|
-
if (!blocks.some((b) => b.type === "text")) blocks.unshift({
|
|
6255
|
-
type: "text",
|
|
6256
|
-
text: "(see attached image)"
|
|
6257
|
-
});
|
|
6258
|
-
return blocks;
|
|
6259
|
-
}
|
|
6260
|
-
function mergeHeaders(...headerSources) {
|
|
6261
|
-
const merged = {};
|
|
6262
|
-
for (const headers of headerSources) if (headers) Object.assign(merged, headers);
|
|
6263
|
-
return merged;
|
|
6264
|
-
}
|
|
6265
|
-
function isOAuthToken(apiKey) {
|
|
6266
|
-
return apiKey.includes("sk-ant-oat");
|
|
6267
|
-
}
|
|
6268
|
-
function createClient$1(model, apiKey, interleavedThinking, optionsHeaders) {
|
|
6269
|
-
const betaFeatures = ["fine-grained-tool-streaming-2025-05-14"];
|
|
6270
|
-
if (interleavedThinking) betaFeatures.push("interleaved-thinking-2025-05-14");
|
|
6271
|
-
if (isOAuthToken(apiKey)) {
|
|
6272
|
-
const defaultHeaders = mergeHeaders({
|
|
6273
|
-
accept: "application/json",
|
|
6274
|
-
"anthropic-dangerous-direct-browser-access": "true",
|
|
6275
|
-
"anthropic-beta": `claude-code-20250219,oauth-2025-04-20,${betaFeatures.join(",")}`,
|
|
6276
|
-
"user-agent": `claude-cli/${claudeCodeVersion} (external, cli)`,
|
|
6277
|
-
"x-app": "cli"
|
|
6278
|
-
}, model.headers, optionsHeaders);
|
|
6279
|
-
return {
|
|
6280
|
-
client: new Anthropic({
|
|
6281
|
-
apiKey: null,
|
|
6282
|
-
authToken: apiKey,
|
|
6283
|
-
baseURL: model.baseUrl,
|
|
6284
|
-
defaultHeaders,
|
|
6285
|
-
dangerouslyAllowBrowser: true
|
|
6286
|
-
}),
|
|
6287
|
-
isOAuthToken: true
|
|
6288
|
-
};
|
|
6289
|
-
}
|
|
6290
|
-
const defaultHeaders = mergeHeaders({
|
|
6291
|
-
accept: "application/json",
|
|
6292
|
-
"anthropic-dangerous-direct-browser-access": "true",
|
|
6293
|
-
"anthropic-beta": betaFeatures.join(",")
|
|
6294
|
-
}, model.headers, optionsHeaders);
|
|
6295
|
-
return {
|
|
6296
|
-
client: new Anthropic({
|
|
6297
|
-
apiKey,
|
|
6298
|
-
baseURL: model.baseUrl,
|
|
6299
|
-
dangerouslyAllowBrowser: true,
|
|
6300
|
-
defaultHeaders
|
|
6301
|
-
}),
|
|
6302
|
-
isOAuthToken: false
|
|
6303
|
-
};
|
|
6304
|
-
}
|
|
6305
|
-
function normalizeToolCallId(id) {
|
|
6306
|
-
return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
|
|
6307
|
-
}
|
|
6308
|
-
function assertReplayableAssistant(message) {
|
|
6309
|
-
let sawToolCall = false;
|
|
6310
|
-
let sawNonTerminalToolCall = false;
|
|
6311
|
-
let sawTerminalToolCall = false;
|
|
6312
|
-
for (const part of message.parts) {
|
|
6313
|
-
if (part.type === "image") throw new Error("Anthropic replay does not support assistant image parts");
|
|
6314
|
-
if (part.type === "toolCall") {
|
|
6315
|
-
sawToolCall = true;
|
|
6316
|
-
if (part.status === "pending" || part.status === "running") sawNonTerminalToolCall = true;
|
|
6317
|
-
else sawTerminalToolCall = true;
|
|
6318
|
-
continue;
|
|
6319
|
-
}
|
|
6320
|
-
if (sawToolCall) throw new Error("Assistant parts after a toolCall are not replayable for Anthropic");
|
|
6321
|
-
}
|
|
6322
|
-
if (sawToolCall && message.stopReason !== "toolUse") throw new Error("Assistant message with tool calls must have stopReason 'toolUse'");
|
|
6323
|
-
if (!sawToolCall && message.stopReason === "toolUse") throw new Error("Assistant message with stopReason 'toolUse' must contain at least one toolCall");
|
|
6324
|
-
if (sawTerminalToolCall && sawNonTerminalToolCall) throw new Error("Assistant message cannot mix terminal and non-terminal toolCall states");
|
|
6325
|
-
}
|
|
6326
|
-
function buildSyntheticToolResult$1(block) {
|
|
6327
|
-
return {
|
|
6328
|
-
type: "tool_result",
|
|
6329
|
-
tool_use_id: block.callID,
|
|
6330
|
-
content: convertContentBlocks([{
|
|
6331
|
-
type: "text",
|
|
6332
|
-
text: [
|
|
6333
|
-
"<result>",
|
|
6334
|
-
"No Result Provided",
|
|
6335
|
-
"</result>"
|
|
6336
|
-
].join("\n")
|
|
6337
|
-
}]),
|
|
6338
|
-
is_error: true
|
|
6339
|
-
};
|
|
6340
|
-
}
|
|
6341
|
-
function convertMessages$1(messages, model, isOAuthToken, cacheControl) {
|
|
6342
|
-
const params = [];
|
|
6343
|
-
const transformedMessages = Message.transformMessages(messages, model, normalizeToolCallId);
|
|
6344
|
-
for (const msg of transformedMessages) {
|
|
6345
|
-
if (msg.role === "user") {
|
|
6346
|
-
const blocks = msg.parts.map((item) => {
|
|
6347
|
-
if (item.type === "text") return {
|
|
6348
|
-
type: "text",
|
|
6349
|
-
text: sanitizeSurrogates(item.text)
|
|
6350
|
-
};
|
|
6351
|
-
return {
|
|
6352
|
-
type: "image",
|
|
6353
|
-
source: {
|
|
6354
|
-
type: "base64",
|
|
6355
|
-
media_type: item.mimeType,
|
|
6356
|
-
data: item.data
|
|
6357
|
-
}
|
|
6358
|
-
};
|
|
6359
|
-
});
|
|
6360
|
-
let filteredBlocks = !model.input.includes("image") ? blocks.filter((b) => b.type !== "image") : blocks;
|
|
6361
|
-
filteredBlocks = filteredBlocks.filter((b) => b.type === "text" ? b.text.trim().length > 0 : true);
|
|
6362
|
-
if (filteredBlocks.length === 0) continue;
|
|
6363
|
-
params.push({
|
|
6364
|
-
role: "user",
|
|
6365
|
-
content: filteredBlocks
|
|
6366
|
-
});
|
|
6367
|
-
continue;
|
|
6368
|
-
}
|
|
6369
|
-
if (msg.stopReason === "error" || msg.stopReason === "aborted") continue;
|
|
6370
|
-
assertReplayableAssistant(msg);
|
|
6371
|
-
const assistantBlocks = [];
|
|
6372
|
-
const toolResults = [];
|
|
6373
|
-
for (const block of msg.parts) if (block.type === "text") {
|
|
6374
|
-
if (block.text.trim().length === 0) continue;
|
|
6375
|
-
assistantBlocks.push({
|
|
6376
|
-
type: "text",
|
|
6377
|
-
text: sanitizeSurrogates(block.text)
|
|
6378
|
-
});
|
|
6379
|
-
} else if (block.type === "thinking") {
|
|
6380
|
-
if (block.thinking.trim().length === 0) continue;
|
|
6381
|
-
if (!block.thinkingSignature || block.thinkingSignature.trim().length === 0) assistantBlocks.push({
|
|
6382
|
-
type: "text",
|
|
6383
|
-
text: sanitizeSurrogates(block.thinking)
|
|
6384
|
-
});
|
|
6385
|
-
else assistantBlocks.push({
|
|
6386
|
-
type: "thinking",
|
|
6387
|
-
thinking: sanitizeSurrogates(block.thinking),
|
|
6388
|
-
signature: block.thinkingSignature
|
|
6389
|
-
});
|
|
6390
|
-
} else if (block.type === "toolCall") {
|
|
6391
|
-
assistantBlocks.push({
|
|
6392
|
-
type: "tool_use",
|
|
6393
|
-
id: block.callID,
|
|
6394
|
-
name: isOAuthToken ? toClaudeCodeName(block.name) : block.name,
|
|
6395
|
-
input: block.arguments ?? {}
|
|
6396
|
-
});
|
|
6397
|
-
if (block.status === "pending" || block.status === "running") toolResults.push(buildSyntheticToolResult$1(block));
|
|
6398
|
-
else toolResults.push({
|
|
6399
|
-
type: "tool_result",
|
|
6400
|
-
tool_use_id: block.callID,
|
|
6401
|
-
content: convertContentBlocks(block.result.content),
|
|
6402
|
-
is_error: block.result.isError
|
|
6403
|
-
});
|
|
6404
|
-
}
|
|
6405
|
-
if (assistantBlocks.length > 0) params.push({
|
|
6406
|
-
role: "assistant",
|
|
6407
|
-
content: assistantBlocks
|
|
6408
|
-
});
|
|
6409
|
-
if (toolResults.length > 0) params.push({
|
|
6410
|
-
role: "user",
|
|
6411
|
-
content: toolResults
|
|
6412
|
-
});
|
|
6413
|
-
}
|
|
6414
|
-
if (cacheControl && params.length > 0) {
|
|
6415
|
-
const lastMessage = params[params.length - 1];
|
|
6416
|
-
if (lastMessage.role === "user") {
|
|
6417
|
-
if (Array.isArray(lastMessage.content)) {
|
|
6418
|
-
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
6419
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) lastBlock.cache_control = cacheControl;
|
|
6420
|
-
} else if (typeof lastMessage.content === "string") lastMessage.content = [{
|
|
6421
|
-
type: "text",
|
|
6422
|
-
text: lastMessage.content,
|
|
6423
|
-
cache_control: cacheControl
|
|
6424
|
-
}];
|
|
6425
|
-
}
|
|
6426
|
-
}
|
|
6427
|
-
return params;
|
|
6428
|
-
}
|
|
6429
|
-
function convertTools$1(tools, isOAuthToken) {
|
|
6430
|
-
if (!tools) return [];
|
|
6431
|
-
return tools.map((tool) => {
|
|
6432
|
-
const jsonSchema = tool.parameters;
|
|
6433
|
-
return {
|
|
6434
|
-
name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name,
|
|
6435
|
-
description: tool.description,
|
|
6436
|
-
input_schema: {
|
|
6437
|
-
type: "object",
|
|
6438
|
-
properties: jsonSchema.properties || {},
|
|
6439
|
-
required: jsonSchema.required || []
|
|
6440
|
-
}
|
|
6441
|
-
};
|
|
6442
|
-
});
|
|
6443
|
-
}
|
|
6444
|
-
function mapStopReason$1(reason) {
|
|
6445
|
-
switch (reason) {
|
|
6446
|
-
case "end_turn": return "stop";
|
|
6447
|
-
case "max_tokens": return "length";
|
|
6448
|
-
case "tool_use": return "toolUse";
|
|
6449
|
-
case "pause_turn":
|
|
6450
|
-
case "stop_sequence": return "stop";
|
|
6451
|
-
case "refusal":
|
|
6452
|
-
case "sensitive": return "error";
|
|
6453
|
-
default: throw new Error("Unhandled Anthropic stop reason");
|
|
6454
|
-
}
|
|
6455
|
-
}
|
|
6456
|
-
function buildParams$1(model, context, isOAuthToken, options) {
|
|
6457
|
-
const { cacheControl } = getCacheControl(model.baseUrl, options?.cacheRetention);
|
|
6458
|
-
const params = {
|
|
6459
|
-
model: model.id,
|
|
6460
|
-
messages: convertMessages$1(context.messages, model, isOAuthToken, cacheControl),
|
|
6461
|
-
max_tokens: options?.maxTokens || model.maxTokens / 3 | 0,
|
|
6462
|
-
stream: true
|
|
6463
|
-
};
|
|
6464
|
-
if (isOAuthToken) {
|
|
6465
|
-
params.system = [{
|
|
6466
|
-
type: "text",
|
|
6467
|
-
text: "You are Claude Code, Anthropic's official CLI for Claude.",
|
|
6468
|
-
...cacheControl ? { cache_control: cacheControl } : {}
|
|
6469
|
-
}];
|
|
6470
|
-
if (context.systemPrompt) params.system.push({
|
|
6471
|
-
type: "text",
|
|
6472
|
-
text: sanitizeSurrogates(context.systemPrompt),
|
|
6473
|
-
...cacheControl ? { cache_control: cacheControl } : {}
|
|
6474
|
-
});
|
|
6475
|
-
} else if (context.systemPrompt) params.system = [{
|
|
6476
|
-
type: "text",
|
|
6477
|
-
text: sanitizeSurrogates(context.systemPrompt),
|
|
6478
|
-
...cacheControl ? { cache_control: cacheControl } : {}
|
|
6479
|
-
}];
|
|
6480
|
-
if (options?.temperature !== void 0 && !options?.thinkingEnabled) params.temperature = options.temperature;
|
|
6481
|
-
if (context.tools) params.tools = convertTools$1(context.tools, isOAuthToken);
|
|
6482
|
-
if (options?.thinkingEnabled && model.reasoning) params.thinking = {
|
|
6483
|
-
type: "enabled",
|
|
6484
|
-
budget_tokens: options.thinkingBudgetTokens || 1024
|
|
6485
|
-
};
|
|
6486
|
-
if (options?.metadata) {
|
|
6487
|
-
const userId = options.metadata.user_id;
|
|
6488
|
-
if (typeof userId === "string") params.metadata = { user_id: userId };
|
|
6489
|
-
}
|
|
6490
|
-
if (options?.toolChoice) params.tool_choice = typeof options.toolChoice === "string" ? { type: options.toolChoice } : options.toolChoice;
|
|
6491
|
-
return params;
|
|
6492
|
-
}
|
|
6493
|
-
const streamAnthropic = (model, context, options) => {
|
|
6494
|
-
const stream = new AssistantMessageEventStream();
|
|
6495
|
-
(async () => {
|
|
6496
|
-
const output = Message.createAssistantMessage({
|
|
6497
|
-
role: "assistant",
|
|
6498
|
-
parts: [],
|
|
6499
|
-
protocol: model.protocol,
|
|
6500
|
-
provider: model.provider,
|
|
6501
|
-
model: model.id,
|
|
6502
|
-
usage: {
|
|
6503
|
-
input: 0,
|
|
6504
|
-
output: 0,
|
|
6505
|
-
cacheRead: 0,
|
|
6506
|
-
cacheWrite: 0,
|
|
6507
|
-
totalTokens: 0,
|
|
6508
|
-
cost: {
|
|
6509
|
-
input: 0,
|
|
6510
|
-
output: 0,
|
|
6511
|
-
cacheRead: 0,
|
|
6512
|
-
cacheWrite: 0,
|
|
6513
|
-
total: 0
|
|
6514
|
-
}
|
|
6515
|
-
},
|
|
6516
|
-
stopReason: "stop",
|
|
6517
|
-
time: {
|
|
6518
|
-
created: Date.now(),
|
|
6519
|
-
completed: Date.now()
|
|
6520
|
-
}
|
|
6521
|
-
});
|
|
6522
|
-
try {
|
|
6523
|
-
let client;
|
|
6524
|
-
let isOAuthToken;
|
|
6525
|
-
if (options?.client) {
|
|
6526
|
-
client = options.client;
|
|
6527
|
-
isOAuthToken = false;
|
|
6528
|
-
} else {
|
|
6529
|
-
const apiKey = options?.apiKey ?? /* @__PURE__ */ getEnvApiKey(model.provider);
|
|
6530
|
-
if (!apiKey) throw new Error(`No API key for provider: ${model.provider.id}`);
|
|
6531
|
-
const created = createClient$1(model, apiKey, options?.interleavedThinking ?? true, options?.headers);
|
|
6532
|
-
client = created.client;
|
|
6533
|
-
isOAuthToken = created.isOAuthToken;
|
|
6534
|
-
}
|
|
6535
|
-
let params = buildParams$1(model, context, isOAuthToken, options);
|
|
6536
|
-
const nextParams = await options?.onPayload?.(params, model);
|
|
6537
|
-
if (nextParams !== void 0) params = nextParams;
|
|
6538
|
-
const anthropicStream = client.messages.stream({
|
|
6539
|
-
...params,
|
|
6540
|
-
stream: true
|
|
6541
|
-
}, { signal: options?.signal });
|
|
6542
|
-
stream.push({
|
|
6543
|
-
type: "start",
|
|
6544
|
-
partial: output
|
|
6545
|
-
});
|
|
6546
|
-
const blocks = output.parts;
|
|
6547
|
-
for await (const event of anthropicStream) if (event.type === "message_start") {
|
|
6548
|
-
output.responseId = event.message.id;
|
|
6549
|
-
output.usage.input = event.message.usage.input_tokens || 0;
|
|
6550
|
-
output.usage.output = event.message.usage.output_tokens || 0;
|
|
6551
|
-
output.usage.cacheRead = event.message.usage.cache_read_input_tokens || 0;
|
|
6552
|
-
output.usage.cacheWrite = event.message.usage.cache_creation_input_tokens || 0;
|
|
6553
|
-
output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
|
|
6554
|
-
Model.calculateCost(model, output.usage);
|
|
6555
|
-
} else if (event.type === "content_block_start") {
|
|
6556
|
-
if (event.content_block.type === "text") {
|
|
6557
|
-
const block = {
|
|
6558
|
-
type: "text",
|
|
6559
|
-
text: "",
|
|
6560
|
-
index: event.index
|
|
6561
|
-
};
|
|
6562
|
-
output.parts.push(block);
|
|
6563
|
-
stream.push({
|
|
6564
|
-
type: "text.start",
|
|
6565
|
-
partIndex: output.parts.length - 1,
|
|
6566
|
-
partial: output
|
|
6567
|
-
});
|
|
6568
|
-
} else if (event.content_block.type === "thinking") {
|
|
6569
|
-
const block = {
|
|
6570
|
-
type: "thinking",
|
|
6571
|
-
thinking: "",
|
|
6572
|
-
thinkingSignature: "",
|
|
6573
|
-
index: event.index
|
|
6574
|
-
};
|
|
6575
|
-
output.parts.push(block);
|
|
6576
|
-
stream.push({
|
|
6577
|
-
type: "thinking.start",
|
|
6578
|
-
partIndex: output.parts.length - 1,
|
|
6579
|
-
partial: output
|
|
6580
|
-
});
|
|
6581
|
-
} else if (event.content_block.type === "redacted_thinking") {
|
|
6582
|
-
const block = {
|
|
6583
|
-
type: "thinking",
|
|
6584
|
-
thinking: "[Reasoning redacted]",
|
|
6585
|
-
thinkingSignature: event.content_block.data,
|
|
6586
|
-
redacted: true,
|
|
6587
|
-
index: event.index
|
|
6588
|
-
};
|
|
6589
|
-
output.parts.push(block);
|
|
6590
|
-
stream.push({
|
|
6591
|
-
type: "thinking.start",
|
|
6592
|
-
partIndex: output.parts.length - 1,
|
|
6593
|
-
partial: output
|
|
6594
|
-
});
|
|
6595
|
-
} else if (event.content_block.type === "tool_use") {
|
|
6596
|
-
const block = {
|
|
6597
|
-
type: "toolCall",
|
|
6598
|
-
callID: event.content_block.id,
|
|
6599
|
-
name: isOAuthToken ? fromClaudeCodeName(event.content_block.name, context.tools) : event.content_block.name,
|
|
6600
|
-
arguments: event.content_block.input ?? {},
|
|
6601
|
-
partialJson: "",
|
|
6602
|
-
status: "pending",
|
|
6603
|
-
time: {
|
|
6604
|
-
start: Date.now(),
|
|
6605
|
-
end: Date.now()
|
|
6606
|
-
},
|
|
6607
|
-
index: event.index
|
|
6608
|
-
};
|
|
6609
|
-
output.parts.push(block);
|
|
6610
|
-
stream.push({
|
|
6611
|
-
type: "toolcall.start",
|
|
6612
|
-
partIndex: output.parts.length - 1,
|
|
6613
|
-
partial: output
|
|
6614
|
-
});
|
|
6615
|
-
}
|
|
6616
|
-
} else if (event.type === "content_block_delta") {
|
|
6617
|
-
const partIndex = blocks.findIndex((b) => b.index === event.index);
|
|
6618
|
-
const block = blocks[partIndex];
|
|
6619
|
-
if (!block) continue;
|
|
6620
|
-
if (event.delta.type === "text_delta" && block.type === "text") {
|
|
6621
|
-
block.text += event.delta.text;
|
|
6622
|
-
stream.push({
|
|
6623
|
-
type: "text.delta",
|
|
6624
|
-
partIndex,
|
|
6625
|
-
delta: event.delta.text,
|
|
6626
|
-
partial: output
|
|
6627
|
-
});
|
|
6628
|
-
} else if (event.delta.type === "thinking_delta" && block.type === "thinking") {
|
|
6629
|
-
block.thinking += event.delta.thinking;
|
|
6630
|
-
stream.push({
|
|
6631
|
-
type: "thinking.delta",
|
|
6632
|
-
partIndex,
|
|
6633
|
-
delta: event.delta.thinking,
|
|
6634
|
-
partial: output
|
|
6635
|
-
});
|
|
6636
|
-
} else if (event.delta.type === "input_json_delta" && block.type === "toolCall") {
|
|
6637
|
-
block.partialJson += event.delta.partial_json;
|
|
6638
|
-
block.arguments = parseStreamingJson(block.partialJson);
|
|
6639
|
-
stream.push({
|
|
6640
|
-
type: "toolcall.delta",
|
|
6641
|
-
partIndex,
|
|
6642
|
-
delta: event.delta.partial_json,
|
|
6643
|
-
partial: output
|
|
6644
|
-
});
|
|
6645
|
-
} else if (event.delta.type === "signature_delta" && block.type === "thinking") {
|
|
6646
|
-
block.thinkingSignature = block.thinkingSignature || "";
|
|
6647
|
-
block.thinkingSignature += event.delta.signature;
|
|
6648
|
-
}
|
|
6649
|
-
} else if (event.type === "content_block_stop") {
|
|
6650
|
-
const partIndex = blocks.findIndex((b) => b.index === event.index);
|
|
6651
|
-
const block = blocks[partIndex];
|
|
6652
|
-
if (block) {
|
|
6653
|
-
delete block.index;
|
|
6654
|
-
if (block.type === "text") stream.push({
|
|
6655
|
-
type: "text.end",
|
|
6656
|
-
partIndex,
|
|
6657
|
-
content: block.text,
|
|
6658
|
-
partial: output
|
|
6659
|
-
});
|
|
6660
|
-
else if (block.type === "thinking") stream.push({
|
|
6661
|
-
type: "thinking.end",
|
|
6662
|
-
partIndex,
|
|
6663
|
-
content: block.thinking,
|
|
6664
|
-
partial: output
|
|
6665
|
-
});
|
|
6666
|
-
else if (block.type === "toolCall") {
|
|
6667
|
-
block.arguments = parseStreamingJson(block.partialJson);
|
|
6668
|
-
delete block.partialJson;
|
|
6669
|
-
stream.push({
|
|
6670
|
-
type: "toolcall.end",
|
|
6671
|
-
partIndex,
|
|
6672
|
-
toolCall: block,
|
|
6673
|
-
partial: output
|
|
6674
|
-
});
|
|
6675
|
-
}
|
|
6676
|
-
}
|
|
6677
|
-
} else if (event.type === "message_delta") {
|
|
6678
|
-
if (event.delta.stop_reason) output.stopReason = mapStopReason$1(event.delta.stop_reason);
|
|
6679
|
-
if (event.usage.input_tokens != null) output.usage.input = event.usage.input_tokens;
|
|
6680
|
-
if (event.usage.output_tokens != null) output.usage.output = event.usage.output_tokens;
|
|
6681
|
-
if (event.usage.cache_read_input_tokens != null) output.usage.cacheRead = event.usage.cache_read_input_tokens;
|
|
6682
|
-
if (event.usage.cache_creation_input_tokens != null) output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
|
|
6683
|
-
output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
|
|
6684
|
-
Model.calculateCost(model, output.usage);
|
|
6685
|
-
}
|
|
6686
|
-
if (options?.signal?.aborted) throw new Error("Request was aborted");
|
|
6687
|
-
if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error("An unknown error occurred");
|
|
6688
|
-
output.time.completed = Date.now();
|
|
6689
|
-
stream.push({
|
|
6690
|
-
type: "done",
|
|
6691
|
-
reason: output.stopReason,
|
|
6692
|
-
message: output
|
|
6693
|
-
});
|
|
6694
|
-
stream.end();
|
|
6695
|
-
} catch (error) {
|
|
6696
|
-
for (const block of output.parts) delete block.index;
|
|
6697
|
-
output.time.completed = Date.now();
|
|
6698
|
-
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
6699
|
-
output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
|
|
6700
|
-
stream.push({
|
|
6701
|
-
type: "error",
|
|
6702
|
-
reason: output.stopReason,
|
|
6703
|
-
error: output
|
|
6704
|
-
});
|
|
6705
|
-
stream.end();
|
|
6706
|
-
}
|
|
6707
|
-
})();
|
|
6708
|
-
return stream;
|
|
6709
|
-
};
|
|
6710
|
-
const streamSimpleAnthropic = (model, context, options) => {
|
|
6711
|
-
const apiKey = options?.apiKey || /* @__PURE__ */ getEnvApiKey(model.provider);
|
|
6712
|
-
if (!apiKey) throw new Error(`No API key for provider: ${model.provider.id}`);
|
|
6713
|
-
const base = Stream.buildBaseOptions(model, options, apiKey);
|
|
6714
|
-
if (!options?.reasoning) return streamAnthropic(model, context, {
|
|
6715
|
-
...base,
|
|
6716
|
-
thinkingEnabled: false
|
|
6717
|
-
});
|
|
6718
|
-
const adjusted = Stream.adjustMaxTokensForThinking(base.maxTokens || 0, model.maxTokens, options.reasoning, options.thinkingBudgets);
|
|
6719
|
-
return streamAnthropic(model, context, {
|
|
6720
|
-
...base,
|
|
6721
|
-
maxTokens: adjusted.maxTokens,
|
|
6722
|
-
thinkingEnabled: true,
|
|
6723
|
-
thinkingBudgetTokens: adjusted.thinkingBudget
|
|
6724
|
-
});
|
|
6725
|
-
};
|
|
6726
|
-
const anthropicProtocolProvider = {
|
|
6727
|
-
protocol: Model.KnownProtocolEnum.anthropicMessages,
|
|
6728
|
-
stream: streamAnthropic,
|
|
6729
|
-
streamSimple: streamSimpleAnthropic
|
|
6730
|
-
};
|
|
6731
|
-
//#endregion
|
|
6732
|
-
//#region src/provider/providers/github/github.ts
|
|
6733
|
-
function inferCopilotInitiator(messages) {
|
|
6734
|
-
const last = messages[messages.length - 1];
|
|
6735
|
-
return last && last.role !== "user" ? "agent" : "user";
|
|
6736
|
-
}
|
|
6737
|
-
function hasCopilotVisionInput(messages) {
|
|
6738
|
-
return messages.some((msg) => {
|
|
6739
|
-
if (msg.role === "user") return msg.parts.some((c) => c.type === "image");
|
|
6740
|
-
return false;
|
|
6741
|
-
});
|
|
6742
|
-
}
|
|
6743
|
-
function buildCopilotDynamicHeaders(params) {
|
|
6744
|
-
const headers = {
|
|
6745
|
-
"X-Initiator": inferCopilotInitiator(params.messages),
|
|
6746
|
-
"Openai-Intent": "conversation-edits"
|
|
6747
|
-
};
|
|
6748
|
-
if (params.hasImages) headers["Copilot-Vision-Request"] = "true";
|
|
6749
|
-
return headers;
|
|
6750
|
-
}
|
|
6751
|
-
//#endregion
|
|
6752
|
-
//#region src/provider/providers/openai/completions.ts
|
|
6753
|
-
function hasToolHistory(messages) {
|
|
6754
|
-
for (const msg of messages) {
|
|
6755
|
-
if (msg.role !== "assistant") continue;
|
|
6756
|
-
if (msg.parts.some((block) => block.type === "toolCall")) return true;
|
|
6757
|
-
}
|
|
6758
|
-
return false;
|
|
6759
|
-
}
|
|
6760
|
-
function buildSyntheticToolResult(block, compat) {
|
|
6761
|
-
const message = {
|
|
6762
|
-
role: "tool",
|
|
6763
|
-
content: [
|
|
6764
|
-
"<result>",
|
|
6765
|
-
"No Result Provided",
|
|
6766
|
-
"</result>"
|
|
6767
|
-
].join("\n"),
|
|
6768
|
-
tool_call_id: block.callID
|
|
6769
|
-
};
|
|
6770
|
-
if (compat.requiresToolResultName) message.name = block.name;
|
|
6771
|
-
return message;
|
|
6772
|
-
}
|
|
6773
|
-
function resolveBaseUrl(model) {
|
|
6774
|
-
return model.baseUrl || (model.provider.id === Provider.KnownProviderEnum.openai ? "https://api.openai.com/v1" : "");
|
|
6775
|
-
}
|
|
6776
|
-
const streamOpenAICompletions = (model, context, options) => {
|
|
6777
|
-
const stream = new AssistantMessageEventStream();
|
|
6778
|
-
(async () => {
|
|
6779
|
-
const output = Message.createAssistantMessage({
|
|
6780
|
-
role: "assistant",
|
|
6781
|
-
parts: [],
|
|
6782
|
-
protocol: model.protocol,
|
|
6783
|
-
provider: model.provider,
|
|
6784
|
-
model: model.id,
|
|
6785
|
-
usage: {
|
|
6786
|
-
input: 0,
|
|
6787
|
-
output: 0,
|
|
6788
|
-
cacheRead: 0,
|
|
6789
|
-
cacheWrite: 0,
|
|
6790
|
-
totalTokens: 0,
|
|
6791
|
-
cost: {
|
|
6792
|
-
input: 0,
|
|
6793
|
-
output: 0,
|
|
6794
|
-
cacheRead: 0,
|
|
6795
|
-
cacheWrite: 0,
|
|
6796
|
-
total: 0
|
|
6797
|
-
}
|
|
6798
|
-
},
|
|
6799
|
-
stopReason: "stop",
|
|
6800
|
-
time: {
|
|
6801
|
-
created: Date.now(),
|
|
6802
|
-
completed: Date.now()
|
|
6803
|
-
}
|
|
6804
|
-
});
|
|
6805
|
-
try {
|
|
6806
|
-
const client = createClient(model, context, options?.apiKey || /* @__PURE__ */ getEnvApiKey(model.provider) || "", options?.headers);
|
|
6807
|
-
let params = buildParams(model, context, options);
|
|
6808
|
-
const nextParams = await options?.onPayload?.(params, model);
|
|
6809
|
-
if (nextParams !== void 0) params = nextParams;
|
|
6810
|
-
const openaiStream = await client.chat.completions.create(params, { signal: options?.signal });
|
|
6811
|
-
stream.push({
|
|
6812
|
-
type: "start",
|
|
6813
|
-
partial: output
|
|
6814
|
-
});
|
|
6815
|
-
let currentBlock = null;
|
|
6816
|
-
const blocks = output.parts;
|
|
6817
|
-
const activeToolCalls = /* @__PURE__ */ new Map();
|
|
6818
|
-
const finishCurrentBlock = (block) => {
|
|
6819
|
-
if (block) {
|
|
6820
|
-
const partIndex = block.index ?? blocks.indexOf(block);
|
|
6821
|
-
delete block.index;
|
|
6822
|
-
if (block.type === "text") stream.push({
|
|
6823
|
-
type: "text.end",
|
|
6824
|
-
partIndex,
|
|
6825
|
-
content: block.text,
|
|
6826
|
-
partial: output
|
|
6827
|
-
});
|
|
6828
|
-
else if (block.type === "thinking") stream.push({
|
|
6829
|
-
type: "thinking.end",
|
|
6830
|
-
partIndex,
|
|
6831
|
-
content: block.thinking,
|
|
6832
|
-
partial: output
|
|
6833
|
-
});
|
|
6834
|
-
else if (block.type === "toolCall") {
|
|
6835
|
-
if (block.streamIndex !== void 0) activeToolCalls.delete(block.streamIndex);
|
|
6836
|
-
block.arguments = parseStreamingJson(block.partialArgs);
|
|
6837
|
-
delete block.partialArgs;
|
|
6838
|
-
delete block.streamIndex;
|
|
6839
|
-
stream.push({
|
|
6840
|
-
type: "toolcall.end",
|
|
6841
|
-
partIndex,
|
|
6842
|
-
toolCall: block,
|
|
6843
|
-
partial: output
|
|
6844
|
-
});
|
|
6845
|
-
}
|
|
6846
|
-
}
|
|
6847
|
-
};
|
|
6848
|
-
const flushActiveToolCalls = () => {
|
|
6849
|
-
for (const toolBlock of [...activeToolCalls.values()].sort((a, b) => (a.index ?? 0) - (b.index ?? 0))) finishCurrentBlock(toolBlock);
|
|
6850
|
-
};
|
|
6851
|
-
for await (const chunk of openaiStream) {
|
|
6852
|
-
if (!chunk || typeof chunk !== "object") continue;
|
|
6853
|
-
output.responseId ||= chunk.id;
|
|
6854
|
-
if (chunk.usage) output.usage = parseChunkUsage(chunk.usage, model);
|
|
6855
|
-
const choice = Array.isArray(chunk.choices) ? chunk.choices[0] : void 0;
|
|
6856
|
-
if (!choice) continue;
|
|
6857
|
-
const choiceWithUsage = choice;
|
|
6858
|
-
if (!chunk.usage && choiceWithUsage.usage) output.usage = parseChunkUsage(choiceWithUsage.usage, model);
|
|
6859
|
-
if (choice.finish_reason) {
|
|
6860
|
-
const finishReasonResult = mapStopReason(choice.finish_reason);
|
|
6861
|
-
output.stopReason = finishReasonResult.stopReason;
|
|
6862
|
-
if (finishReasonResult.errorMessage) output.errorMessage = finishReasonResult.errorMessage;
|
|
6863
|
-
}
|
|
6864
|
-
if (!choice.delta) continue;
|
|
6865
|
-
if (choice.delta.content !== null && choice.delta.content !== void 0 && choice.delta.content.length > 0) {
|
|
6866
|
-
if (activeToolCalls.size > 0) flushActiveToolCalls();
|
|
6867
|
-
if (!currentBlock || currentBlock.type !== "text") {
|
|
6868
|
-
finishCurrentBlock(currentBlock);
|
|
6869
|
-
currentBlock = {
|
|
6870
|
-
type: "text",
|
|
6871
|
-
text: "",
|
|
6872
|
-
index: output.parts.length
|
|
6873
|
-
};
|
|
6874
|
-
output.parts.push(currentBlock);
|
|
6875
|
-
stream.push({
|
|
6876
|
-
type: "text.start",
|
|
6877
|
-
partIndex: currentBlock.index,
|
|
6878
|
-
partial: output
|
|
6879
|
-
});
|
|
6880
|
-
}
|
|
6881
|
-
if (currentBlock.type === "text") {
|
|
6882
|
-
currentBlock.text += choice.delta.content;
|
|
6883
|
-
stream.push({
|
|
6884
|
-
type: "text.delta",
|
|
6885
|
-
partIndex: currentBlock.index,
|
|
6886
|
-
delta: choice.delta.content,
|
|
6887
|
-
partial: output
|
|
6888
|
-
});
|
|
6889
|
-
}
|
|
6890
|
-
}
|
|
6891
|
-
const reasoningFields = [
|
|
6892
|
-
"reasoning_content",
|
|
6893
|
-
"reasoning",
|
|
6894
|
-
"reasoning_text"
|
|
6895
|
-
];
|
|
6896
|
-
let foundReasoningField = null;
|
|
6897
|
-
for (const field of reasoningFields) {
|
|
6898
|
-
const value = choice.delta[field];
|
|
6899
|
-
if (typeof value === "string" && value.length > 0) {
|
|
6900
|
-
foundReasoningField = field;
|
|
6901
|
-
break;
|
|
6902
|
-
}
|
|
6903
|
-
}
|
|
6904
|
-
if (foundReasoningField) {
|
|
6905
|
-
if (activeToolCalls.size > 0) flushActiveToolCalls();
|
|
6906
|
-
if (!currentBlock || currentBlock.type !== "thinking") {
|
|
6907
|
-
finishCurrentBlock(currentBlock);
|
|
6908
|
-
currentBlock = {
|
|
6909
|
-
type: "thinking",
|
|
6910
|
-
thinking: "",
|
|
6911
|
-
thinkingSignature: foundReasoningField,
|
|
6912
|
-
index: output.parts.length
|
|
6913
|
-
};
|
|
6914
|
-
output.parts.push(currentBlock);
|
|
6915
|
-
stream.push({
|
|
6916
|
-
type: "thinking.start",
|
|
6917
|
-
partIndex: currentBlock.index,
|
|
6918
|
-
partial: output
|
|
6919
|
-
});
|
|
6920
|
-
}
|
|
6921
|
-
if (currentBlock.type === "thinking") {
|
|
6922
|
-
const delta = choice.delta[foundReasoningField];
|
|
6923
|
-
if (typeof delta === "string") {
|
|
6924
|
-
currentBlock.thinking += delta;
|
|
6925
|
-
stream.push({
|
|
6926
|
-
type: "thinking.delta",
|
|
6927
|
-
partIndex: currentBlock.index,
|
|
6928
|
-
delta,
|
|
6929
|
-
partial: output
|
|
6930
|
-
});
|
|
6931
|
-
}
|
|
6932
|
-
}
|
|
6933
|
-
}
|
|
6934
|
-
if (choice.delta.tool_calls) {
|
|
6935
|
-
if (currentBlock) {
|
|
6936
|
-
finishCurrentBlock(currentBlock);
|
|
6937
|
-
currentBlock = null;
|
|
6938
|
-
}
|
|
6939
|
-
for (const toolCall of choice.delta.tool_calls) {
|
|
6940
|
-
const streamIndex = toolCall.index ?? activeToolCalls.size;
|
|
6941
|
-
let toolBlock = activeToolCalls.get(streamIndex);
|
|
6942
|
-
if (!toolBlock) {
|
|
6943
|
-
toolBlock = {
|
|
6944
|
-
type: "toolCall",
|
|
6945
|
-
callID: toolCall.id || "",
|
|
6946
|
-
name: toolCall.function?.name || "",
|
|
6947
|
-
arguments: {},
|
|
6948
|
-
partialArgs: "",
|
|
6949
|
-
index: output.parts.length,
|
|
6950
|
-
streamIndex,
|
|
6951
|
-
status: "pending",
|
|
6952
|
-
time: {
|
|
6953
|
-
start: Date.now(),
|
|
6954
|
-
end: Date.now()
|
|
6955
|
-
}
|
|
6956
|
-
};
|
|
6957
|
-
activeToolCalls.set(streamIndex, toolBlock);
|
|
6958
|
-
output.parts.push(toolBlock);
|
|
6959
|
-
stream.push({
|
|
6960
|
-
type: "toolcall.start",
|
|
6961
|
-
partIndex: toolBlock.index,
|
|
6962
|
-
partial: output
|
|
6963
|
-
});
|
|
6964
|
-
}
|
|
6965
|
-
if (toolCall.id) toolBlock.callID = toolCall.id;
|
|
6966
|
-
if (toolCall.function?.name) toolBlock.name = toolCall.function.name;
|
|
6967
|
-
let delta = "";
|
|
6968
|
-
if (toolCall.function?.arguments) {
|
|
6969
|
-
delta = toolCall.function.arguments;
|
|
6970
|
-
toolBlock.partialArgs = (toolBlock.partialArgs || "") + delta;
|
|
6971
|
-
toolBlock.arguments = parseStreamingJson(toolBlock.partialArgs);
|
|
6972
|
-
}
|
|
6973
|
-
toolBlock.time.end = Date.now();
|
|
6974
|
-
stream.push({
|
|
6975
|
-
type: "toolcall.delta",
|
|
6976
|
-
partIndex: toolBlock.index,
|
|
6977
|
-
delta,
|
|
6978
|
-
partial: output
|
|
6979
|
-
});
|
|
6980
|
-
}
|
|
6981
|
-
}
|
|
6982
|
-
const reasoningDetails = choice.delta.reasoning_details;
|
|
6983
|
-
if (reasoningDetails && Array.isArray(reasoningDetails)) {
|
|
6984
|
-
for (const detail of reasoningDetails) if (detail.type === "reasoning.encrypted" && typeof detail.id === "string" && detail.data !== void 0) {
|
|
6985
|
-
const matchingToolCall = output.parts.find((block) => block.type === "toolCall" && block.callID === detail.id);
|
|
6986
|
-
if (matchingToolCall) matchingToolCall.thoughtSignature = JSON.stringify(detail);
|
|
6987
|
-
}
|
|
6988
|
-
}
|
|
6989
|
-
}
|
|
6990
|
-
finishCurrentBlock(currentBlock);
|
|
6991
|
-
flushActiveToolCalls();
|
|
6992
|
-
if (options?.signal?.aborted) throw new Error("Request was aborted");
|
|
6993
|
-
if (output.stopReason === "aborted") throw new Error("Request was aborted");
|
|
6994
|
-
if (output.stopReason === "error") throw new Error(output.errorMessage || "Provider returned an error stop reason");
|
|
6995
|
-
output.time.completed = Date.now();
|
|
6996
|
-
stream.push({
|
|
6997
|
-
type: "done",
|
|
6998
|
-
reason: output.stopReason,
|
|
6999
|
-
message: output
|
|
7000
|
-
});
|
|
7001
|
-
stream.end();
|
|
7002
|
-
} catch (error) {
|
|
7003
|
-
for (const block of output.parts) {
|
|
7004
|
-
delete block.index;
|
|
7005
|
-
delete block.partialArgs;
|
|
7006
|
-
delete block.streamIndex;
|
|
7007
|
-
}
|
|
7008
|
-
output.time.completed = Date.now();
|
|
7009
|
-
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
7010
|
-
output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
|
|
7011
|
-
const rawMetadata = error?.error?.metadata?.raw;
|
|
7012
|
-
if (rawMetadata) output.errorMessage += `\n${rawMetadata}`;
|
|
7013
|
-
stream.push({
|
|
7014
|
-
type: "error",
|
|
7015
|
-
reason: output.stopReason,
|
|
7016
|
-
error: output
|
|
7017
|
-
});
|
|
7018
|
-
stream.end();
|
|
7019
|
-
}
|
|
7020
|
-
})();
|
|
7021
|
-
return stream;
|
|
7022
|
-
};
|
|
7023
|
-
const streamSimpleOpenAICompletions = (model, context, options) => {
|
|
7024
|
-
const apiKey = options?.apiKey || /* @__PURE__ */ getEnvApiKey(model.provider);
|
|
7025
|
-
if (!apiKey) throw new Error(`No API key for provider: ${model.provider.id}`);
|
|
7026
|
-
const base = Stream.buildBaseOptions(model, options, apiKey);
|
|
7027
|
-
const simpleReasoning = Model.supportsXhigh(model) ? options?.reasoning : Stream.clampReasoning(options?.reasoning);
|
|
7028
|
-
const reasoningEffort = simpleReasoning && simpleReasoning !== Stream.ThinkingLevelEnum.off ? simpleReasoning : void 0;
|
|
7029
|
-
const toolChoice = options?.toolChoice;
|
|
7030
|
-
return streamOpenAICompletions(model, context, {
|
|
7031
|
-
...base,
|
|
7032
|
-
reasoningEffort,
|
|
7033
|
-
toolChoice
|
|
7034
|
-
});
|
|
7035
|
-
};
|
|
7036
|
-
function buildParams(model, context, options) {
|
|
7037
|
-
const compat = getCompat(model);
|
|
7038
|
-
const messages = convertMessages(model, context, compat);
|
|
7039
|
-
maybeAddOpenRouterAnthropicCacheControl(model, messages);
|
|
7040
|
-
const baseUrl = resolveBaseUrl(model);
|
|
7041
|
-
const params = {
|
|
7042
|
-
model: model.id,
|
|
7043
|
-
messages,
|
|
7044
|
-
stream: true
|
|
7045
|
-
};
|
|
7046
|
-
if (compat.supportsUsageInStreaming !== false) params.stream_options = { include_usage: true };
|
|
7047
|
-
if (compat.supportsStore) params.store = false;
|
|
7048
|
-
if (options?.maxTokens) if (compat.maxTokensField === "max_tokens") params.max_tokens = options.maxTokens;
|
|
7049
|
-
else params.max_completion_tokens = options.maxTokens;
|
|
7050
|
-
if (options?.temperature !== void 0) params.temperature = options.temperature;
|
|
7051
|
-
if (context.tools) {
|
|
7052
|
-
params.tools = convertTools(context.tools, compat);
|
|
7053
|
-
if (compat.zaiToolStream) params.tool_stream = true;
|
|
7054
|
-
} else if (hasToolHistory(context.messages)) params.tools = [];
|
|
7055
|
-
if (options?.toolChoice) params.tool_choice = options.toolChoice;
|
|
7056
|
-
if ((compat.thinkingFormat === "zai" || compat.thinkingFormat === "qwen") && model.reasoning) params.enable_thinking = !!options?.reasoningEffort;
|
|
7057
|
-
else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) params.chat_template_kwargs = { enable_thinking: !!options?.reasoningEffort };
|
|
7058
|
-
else if (compat.thinkingFormat === "openrouter" && model.reasoning) {
|
|
7059
|
-
const openRouterParams = params;
|
|
7060
|
-
if (options?.reasoningEffort) openRouterParams.reasoning = { effort: mapReasoningEffort(options.reasoningEffort, compat.reasoningEffortMap) };
|
|
7061
|
-
else openRouterParams.reasoning = { effort: "none" };
|
|
7062
|
-
} else if (options?.reasoningEffort && model.reasoning && compat.supportsReasoningEffort) params.reasoning_effort = mapReasoningEffort(options.reasoningEffort, compat.reasoningEffortMap);
|
|
7063
|
-
if (baseUrl.includes("openrouter.ai") && model.compat?.openRouterRouting) params.provider = model.compat.openRouterRouting;
|
|
7064
|
-
if (baseUrl.includes("ai-gateway.vercel.sh") && model.compat?.vercelGatewayRouting) {
|
|
7065
|
-
const routing = model.compat.vercelGatewayRouting;
|
|
7066
|
-
if (routing.only || routing.order) {
|
|
7067
|
-
const gatewayOptions = {};
|
|
7068
|
-
if (routing.only) gatewayOptions.only = routing.only;
|
|
7069
|
-
if (routing.order) gatewayOptions.order = routing.order;
|
|
7070
|
-
params.providerOptions = { gateway: gatewayOptions };
|
|
7071
|
-
}
|
|
7072
|
-
}
|
|
7073
|
-
return params;
|
|
7074
|
-
}
|
|
7075
|
-
function createClient(model, context, apiKey, optsHeaders) {
|
|
7076
|
-
const baseUrl = resolveBaseUrl(model);
|
|
7077
|
-
if (!apiKey) {
|
|
7078
|
-
if (!process.env.OPENAI_API_KEY) throw new Error("OpenAI API key is required. set OPENAI_API_KEY environment variable or pass it as an argument");
|
|
7079
|
-
apiKey = process.env.OPENAI_API_KEY;
|
|
7080
|
-
}
|
|
7081
|
-
const headers = { ...model.headers };
|
|
7082
|
-
if (model.provider.id === Provider.KnownProviderEnum.githubCopilot) {
|
|
7083
|
-
const hasImages = hasCopilotVisionInput(context.messages);
|
|
7084
|
-
const copilotHeaders = buildCopilotDynamicHeaders({
|
|
7085
|
-
messages: context.messages,
|
|
7086
|
-
hasImages
|
|
7087
|
-
});
|
|
7088
|
-
Object.assign(headers, copilotHeaders);
|
|
7089
|
-
}
|
|
7090
|
-
if (optsHeaders) Object.assign(headers, optsHeaders);
|
|
7091
|
-
return new OpenAI({
|
|
7092
|
-
apiKey,
|
|
7093
|
-
baseURL: baseUrl,
|
|
7094
|
-
dangerouslyAllowBrowser: true,
|
|
7095
|
-
defaultHeaders: headers
|
|
7096
|
-
});
|
|
7097
|
-
}
|
|
7098
|
-
function mapReasoningEffort(effort, reasoningEffortMap) {
|
|
7099
|
-
return reasoningEffortMap[effort] ?? effort;
|
|
7100
|
-
}
|
|
7101
|
-
function maybeAddOpenRouterAnthropicCacheControl(model, messages) {
|
|
7102
|
-
if (model.provider.id !== Provider.KnownProviderEnum.openrouter || !model.id.startsWith("anthropic/")) return;
|
|
7103
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
7104
|
-
const msg = messages[i];
|
|
7105
|
-
if (!msg) continue;
|
|
7106
|
-
if (msg.role !== "user" && msg.role !== "assistant") continue;
|
|
7107
|
-
const content = msg.content;
|
|
7108
|
-
if (typeof content === "string") {
|
|
7109
|
-
msg.content = [Object.assign({
|
|
7110
|
-
type: "text",
|
|
7111
|
-
text: content
|
|
7112
|
-
}, { cache_control: { type: "ephemeral" } })];
|
|
7113
|
-
return;
|
|
7114
|
-
}
|
|
7115
|
-
if (!Array.isArray(content)) continue;
|
|
7116
|
-
for (let j = content.length - 1; j >= 0; j--) {
|
|
7117
|
-
const part = content[j];
|
|
7118
|
-
if (part?.type === "text") {
|
|
7119
|
-
Object.assign(part, { cache_control: { type: "ephemeral" } });
|
|
7120
|
-
return;
|
|
7121
|
-
}
|
|
7122
|
-
}
|
|
7123
|
-
}
|
|
7124
|
-
}
|
|
7125
|
-
function convertMessages(model, context, compat) {
|
|
7126
|
-
const params = [];
|
|
7127
|
-
const normalizeToolCallId = (id) => {
|
|
7128
|
-
if (id.includes("|")) return (id.split("|")[0] ?? id).replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 40);
|
|
7129
|
-
if (model.provider.id === Provider.KnownProviderEnum.openai) return id.length > 40 ? id.slice(0, 40) : id;
|
|
7130
|
-
return id;
|
|
7131
|
-
};
|
|
7132
|
-
const transformedMessages = Message.transformMessages(context.messages, model, normalizeToolCallId);
|
|
7133
|
-
if (context.systemPrompt) {
|
|
7134
|
-
const role = model.reasoning && compat.supportsDeveloperRole ? "developer" : "system";
|
|
7135
|
-
params.push({
|
|
7136
|
-
role,
|
|
7137
|
-
content: sanitizeSurrogates(context.systemPrompt)
|
|
7138
|
-
});
|
|
7139
|
-
}
|
|
7140
|
-
let lastRole = null;
|
|
7141
|
-
for (const msg of transformedMessages) {
|
|
7142
|
-
if (compat.requiresAssistantAfterToolResult && lastRole === "tool" && msg.role === "user") {
|
|
7143
|
-
params.push({
|
|
7144
|
-
role: "assistant",
|
|
7145
|
-
content: "I have processed the tool results."
|
|
7146
|
-
});
|
|
7147
|
-
lastRole = "assistant";
|
|
7148
|
-
}
|
|
7149
|
-
if (msg.role === "user") {
|
|
7150
|
-
const content = msg.parts.flatMap((item) => {
|
|
7151
|
-
if (item.type === "text") {
|
|
7152
|
-
const text = sanitizeSurrogates(item.text);
|
|
7153
|
-
if (text.trim().length === 0) return [];
|
|
7154
|
-
return [{
|
|
7155
|
-
type: "text",
|
|
7156
|
-
text
|
|
7157
|
-
}];
|
|
7158
|
-
}
|
|
7159
|
-
if (!model.input.includes("image")) return [];
|
|
7160
|
-
return [{
|
|
7161
|
-
type: "image_url",
|
|
7162
|
-
image_url: { url: `data:${item.mimeType};base64,${item.data}` }
|
|
7163
|
-
}];
|
|
7164
|
-
});
|
|
7165
|
-
if (content.length === 0) continue;
|
|
7166
|
-
params.push({
|
|
7167
|
-
role: "user",
|
|
7168
|
-
content
|
|
7169
|
-
});
|
|
7170
|
-
lastRole = "user";
|
|
7171
|
-
continue;
|
|
7172
|
-
}
|
|
7173
|
-
const assistantMsg = {
|
|
7174
|
-
role: "assistant",
|
|
7175
|
-
content: compat.requiresAssistantAfterToolResult ? "" : null
|
|
7176
|
-
};
|
|
7177
|
-
const textSegments = msg.parts.filter((block) => block.type === "text").map((block) => sanitizeSurrogates(block.text)).filter((text) => text.trim().length > 0);
|
|
7178
|
-
const nonEmptyThinkingBlocks = msg.parts.filter((block) => block.type === "thinking").filter((block) => block.thinking.trim().length > 0);
|
|
7179
|
-
if (compat.requiresThinkingAsText && nonEmptyThinkingBlocks.length > 0) textSegments.unshift(...nonEmptyThinkingBlocks.map((block) => sanitizeSurrogates(block.thinking)));
|
|
7180
|
-
else if (nonEmptyThinkingBlocks.length > 0) {
|
|
7181
|
-
const signature = nonEmptyThinkingBlocks[0]?.thinkingSignature;
|
|
7182
|
-
if (signature && signature.length > 0) assistantMsg[signature] = nonEmptyThinkingBlocks.map((block) => sanitizeSurrogates(block.thinking)).join("\n");
|
|
7183
|
-
}
|
|
7184
|
-
if (textSegments.length > 0) assistantMsg.content = textSegments.join("");
|
|
7185
|
-
const toolCalls = msg.parts.filter((block) => block.type === "toolCall");
|
|
7186
|
-
if (toolCalls.length > 0) {
|
|
7187
|
-
assistantMsg.tool_calls = toolCalls.map((toolCall) => ({
|
|
7188
|
-
id: toolCall.callID,
|
|
7189
|
-
type: "function",
|
|
7190
|
-
function: {
|
|
7191
|
-
name: toolCall.name,
|
|
7192
|
-
arguments: JSON.stringify(toolCall.arguments)
|
|
7193
|
-
}
|
|
7194
|
-
}));
|
|
7195
|
-
const reasoningDetails = toolCalls.filter((toolCall) => toolCall.thoughtSignature).map((toolCall) => {
|
|
7196
|
-
try {
|
|
7197
|
-
return JSON.parse(toolCall.thoughtSignature);
|
|
7198
|
-
} catch {
|
|
7199
|
-
return null;
|
|
7200
|
-
}
|
|
7201
|
-
}).filter(Boolean);
|
|
7202
|
-
if (reasoningDetails.length > 0) assistantMsg.reasoning_details = reasoningDetails;
|
|
7203
|
-
}
|
|
7204
|
-
const assistantContent = assistantMsg.content;
|
|
7205
|
-
if (!(assistantContent !== null && assistantContent !== void 0 && (typeof assistantContent === "string" ? assistantContent.length > 0 : assistantContent.length > 0)) && !assistantMsg.tool_calls) continue;
|
|
7206
|
-
params.push(assistantMsg);
|
|
7207
|
-
lastRole = "assistant";
|
|
7208
|
-
const imageBlocks = [];
|
|
7209
|
-
for (const toolCall of toolCalls) {
|
|
7210
|
-
if (toolCall.status === "pending" || toolCall.status === "running") {
|
|
7211
|
-
params.push(buildSyntheticToolResult(toolCall, compat));
|
|
7212
|
-
lastRole = "tool";
|
|
7213
|
-
continue;
|
|
7214
|
-
}
|
|
7215
|
-
const textResult = toolCall.result.content.filter((content) => content.type === "text").map((content) => content.text).join("\n");
|
|
7216
|
-
const hasImages = toolCall.result.content.some((content) => content.type === "image");
|
|
7217
|
-
const toolResultMsg = {
|
|
7218
|
-
role: "tool",
|
|
7219
|
-
content: sanitizeSurrogates(textResult.length > 0 ? textResult : "(see attached image)"),
|
|
7220
|
-
tool_call_id: toolCall.callID
|
|
7221
|
-
};
|
|
7222
|
-
if (compat.requiresToolResultName) toolResultMsg.name = toolCall.name;
|
|
7223
|
-
params.push(toolResultMsg);
|
|
7224
|
-
lastRole = "tool";
|
|
7225
|
-
if (hasImages && model.input.includes("image")) {
|
|
7226
|
-
for (const block of toolCall.result.content) if (block.type === "image") imageBlocks.push({
|
|
7227
|
-
type: "image_url",
|
|
7228
|
-
image_url: { url: `data:${block.mimeType};base64,${block.data}` }
|
|
7229
|
-
});
|
|
7230
|
-
}
|
|
7231
|
-
}
|
|
7232
|
-
if (imageBlocks.length > 0) {
|
|
7233
|
-
if (compat.requiresAssistantAfterToolResult) params.push({
|
|
7234
|
-
role: "assistant",
|
|
7235
|
-
content: "I have processed the tool results."
|
|
7236
|
-
});
|
|
7237
|
-
params.push({
|
|
7238
|
-
role: "user",
|
|
7239
|
-
content: [{
|
|
7240
|
-
type: "text",
|
|
7241
|
-
text: "Attached image(s) from tool result:"
|
|
7242
|
-
}, ...imageBlocks]
|
|
7243
|
-
});
|
|
7244
|
-
lastRole = "user";
|
|
7245
|
-
}
|
|
7246
|
-
}
|
|
7247
|
-
return params;
|
|
7248
|
-
}
|
|
7249
|
-
function convertTools(tools, compat) {
|
|
7250
|
-
return tools.map((tool) => ({
|
|
7251
|
-
type: "function",
|
|
7252
|
-
function: {
|
|
7253
|
-
name: tool.name,
|
|
7254
|
-
description: tool.description,
|
|
7255
|
-
parameters: tool.parameters,
|
|
7256
|
-
...compat.supportsStrictMode !== false && { strict: false }
|
|
7257
|
-
}
|
|
7258
|
-
}));
|
|
7259
|
-
}
|
|
7260
|
-
function parseChunkUsage(rawUsage, model) {
|
|
7261
|
-
const promptTokens = rawUsage.prompt_tokens || 0;
|
|
7262
|
-
const reportedCachedTokens = rawUsage.prompt_tokens_details?.cached_tokens || 0;
|
|
7263
|
-
const cacheWriteTokens = rawUsage.prompt_tokens_details?.cache_write_tokens || 0;
|
|
7264
|
-
const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens || 0;
|
|
7265
|
-
const cacheReadTokens = cacheWriteTokens > 0 ? Math.max(0, reportedCachedTokens - cacheWriteTokens) : reportedCachedTokens;
|
|
7266
|
-
const input = Math.max(0, promptTokens - cacheReadTokens - cacheWriteTokens);
|
|
7267
|
-
const outputTokens = (rawUsage.completion_tokens || 0) + reasoningTokens;
|
|
7268
|
-
const usage = {
|
|
7269
|
-
input,
|
|
7270
|
-
output: outputTokens,
|
|
7271
|
-
cacheRead: cacheReadTokens,
|
|
7272
|
-
cacheWrite: cacheWriteTokens,
|
|
7273
|
-
totalTokens: input + outputTokens + cacheReadTokens + cacheWriteTokens,
|
|
7274
|
-
cost: {
|
|
7275
|
-
input: 0,
|
|
7276
|
-
output: 0,
|
|
7277
|
-
cacheRead: 0,
|
|
7278
|
-
cacheWrite: 0,
|
|
7279
|
-
total: 0
|
|
7280
|
-
}
|
|
7281
|
-
};
|
|
7282
|
-
Model.calculateCost(model, usage);
|
|
7283
|
-
return usage;
|
|
7284
|
-
}
|
|
7285
|
-
function mapStopReason(reason) {
|
|
7286
|
-
if (reason === null) return { stopReason: "stop" };
|
|
7287
|
-
switch (reason) {
|
|
7288
|
-
case "stop":
|
|
7289
|
-
case "end": return { stopReason: "stop" };
|
|
7290
|
-
case "length": return { stopReason: "length" };
|
|
7291
|
-
case "function_call":
|
|
7292
|
-
case "tool_calls": return { stopReason: "toolUse" };
|
|
7293
|
-
case "content_filter": return {
|
|
7294
|
-
stopReason: "error",
|
|
7295
|
-
errorMessage: "Provider finish_reason: content_filter"
|
|
7296
|
-
};
|
|
7297
|
-
case "network_error": return {
|
|
7298
|
-
stopReason: "error",
|
|
7299
|
-
errorMessage: "Provider finish_reason: network_error"
|
|
7300
|
-
};
|
|
7301
|
-
default: return {
|
|
7302
|
-
stopReason: "error",
|
|
7303
|
-
errorMessage: `Provider finish_reason: ${reason}`
|
|
7304
|
-
};
|
|
7305
|
-
}
|
|
7306
|
-
}
|
|
7307
|
-
function detectCompat(model) {
|
|
7308
|
-
const provider = model.provider.id;
|
|
7309
|
-
const baseUrl = resolveBaseUrl(model);
|
|
7310
|
-
const isZai = provider === "zai" || baseUrl.includes("api.z.ai");
|
|
7311
|
-
const isNonStandard = provider === "cerebras" || baseUrl.includes("cerebras.ai") || provider === "xai" || baseUrl.includes("api.x.ai") || baseUrl.includes("chutes.ai") || baseUrl.includes("deepseek.com") || isZai || provider === "opencode" || baseUrl.includes("opencode.ai");
|
|
7312
|
-
const useMaxTokens = baseUrl.includes("chutes.ai");
|
|
7313
|
-
const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
|
|
7314
|
-
const reasoningEffortMap = (provider === "groq" || baseUrl.includes("groq.com")) && model.id === "qwen/qwen3-32b" ? {
|
|
7315
|
-
minimal: "default",
|
|
7316
|
-
low: "default",
|
|
7317
|
-
medium: "default",
|
|
7318
|
-
high: "default",
|
|
7319
|
-
xhigh: "default"
|
|
7320
|
-
} : {};
|
|
7321
|
-
return {
|
|
7322
|
-
supportsStore: !isNonStandard,
|
|
7323
|
-
supportsDeveloperRole: !isNonStandard,
|
|
7324
|
-
supportsReasoningEffort: !isGrok && !isZai,
|
|
7325
|
-
reasoningEffortMap,
|
|
7326
|
-
supportsUsageInStreaming: true,
|
|
7327
|
-
maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
|
|
7328
|
-
requiresToolResultName: false,
|
|
7329
|
-
requiresAssistantAfterToolResult: false,
|
|
7330
|
-
requiresThinkingAsText: false,
|
|
7331
|
-
thinkingFormat: isZai ? "zai" : provider === "openrouter" || baseUrl.includes("openrouter.ai") ? "openrouter" : "openai",
|
|
7332
|
-
openRouterRouting: {},
|
|
7333
|
-
vercelGatewayRouting: {},
|
|
7334
|
-
zaiToolStream: false,
|
|
7335
|
-
supportsStrictMode: true
|
|
7336
|
-
};
|
|
7337
|
-
}
|
|
7338
|
-
/**
|
|
7339
|
-
* Get resolved compatibility settings for a model.
|
|
7340
|
-
* Uses explicit model.compat if provided, otherwise auto-detects from provider/URL.
|
|
7341
|
-
*/
|
|
7342
|
-
function getCompat(model) {
|
|
7343
|
-
const detected = detectCompat(model);
|
|
7344
|
-
if (!model.compat) return detected;
|
|
7345
|
-
return {
|
|
7346
|
-
supportsStore: model.compat.supportsStore ?? detected.supportsStore,
|
|
7347
|
-
supportsDeveloperRole: model.compat.supportsDeveloperRole ?? detected.supportsDeveloperRole,
|
|
7348
|
-
supportsReasoningEffort: model.compat.supportsReasoningEffort ?? detected.supportsReasoningEffort,
|
|
7349
|
-
reasoningEffortMap: model.compat.reasoningEffortMap ?? detected.reasoningEffortMap,
|
|
7350
|
-
supportsUsageInStreaming: model.compat.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,
|
|
7351
|
-
maxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,
|
|
7352
|
-
requiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,
|
|
7353
|
-
requiresAssistantAfterToolResult: model.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
|
|
7354
|
-
requiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,
|
|
7355
|
-
thinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,
|
|
7356
|
-
openRouterRouting: model.compat.openRouterRouting ?? {},
|
|
7357
|
-
vercelGatewayRouting: model.compat.vercelGatewayRouting ?? detected.vercelGatewayRouting,
|
|
7358
|
-
zaiToolStream: model.compat.zaiToolStream ?? detected.zaiToolStream,
|
|
7359
|
-
supportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode
|
|
7360
|
-
};
|
|
7361
|
-
}
|
|
7362
|
-
const openAICompletionsProtocolProvider = {
|
|
7363
|
-
protocol: Model.KnownProtocolEnum.openaiCompletions,
|
|
7364
|
-
stream: streamOpenAICompletions,
|
|
7365
|
-
streamSimple: streamSimpleOpenAICompletions
|
|
7366
|
-
};
|
|
7367
|
-
//#endregion
|
|
7368
|
-
//#region src/provider/register.ts
|
|
7369
|
-
Stream.registerProtocolProvider(anthropicProtocolProvider, "providers/anthropic/index.ts");
|
|
7370
|
-
Stream.registerProtocolProvider(openAICompletionsProtocolProvider, "providers/openai/completions.ts");
|
|
7371
|
-
//#endregion
|
|
7372
|
-
//#region src/agent/agent.ts
|
|
7373
|
-
let Agent;
|
|
7374
|
-
(function(_Agent) {
|
|
7375
|
-
_Agent.ToolTerminalResultSchema = Type.Union([Message.ToolCompletedSchema, Message.ToolErrorSchema]);
|
|
7376
|
-
_Agent.ToolResultSchema = Type.Union([
|
|
7377
|
-
Message.ToolRunningSchema,
|
|
7378
|
-
Message.ToolCompletedSchema,
|
|
7379
|
-
Message.ToolErrorSchema
|
|
7380
|
-
]);
|
|
7381
|
-
function defineTool(tool) {
|
|
7382
|
-
return tool;
|
|
7383
|
-
}
|
|
7384
|
-
_Agent.defineTool = defineTool;
|
|
7385
|
-
_Agent.ToolCallInFlightSchema = Type.Object({
|
|
7386
|
-
callID: Type.String(),
|
|
7387
|
-
name: Type.String(),
|
|
7388
|
-
rawArgs: Type.Record(Type.String(), Type.Unknown()),
|
|
7389
|
-
args: Type.Optional(Type.Unknown())
|
|
7390
|
-
});
|
|
7391
|
-
const ModelNotFoundErr = _Agent.ModelNotFoundErr = NamedError.create("ModelNotFoundErr", Type.Object({
|
|
7392
|
-
message: Type.String(),
|
|
7393
|
-
provider: Type.String(),
|
|
7394
|
-
model: Type.String()
|
|
7395
|
-
}));
|
|
7396
|
-
const ModelNotConfiguredErr = _Agent.ModelNotConfiguredErr = NamedError.create("ModelNotConfiguredErr", Type.Object({ message: Type.String() }));
|
|
7397
|
-
const AgentInStreamingErr = _Agent.AgentInStreamingErr = NamedError.create("AgentInStreamingErr", Type.Object({
|
|
7398
|
-
message: Type.String(),
|
|
7399
|
-
name: Type.String()
|
|
7400
|
-
}));
|
|
7401
|
-
class Instance {
|
|
7402
|
-
_state;
|
|
7403
|
-
listeners = /* @__PURE__ */ new Set();
|
|
7404
|
-
abortController;
|
|
7405
|
-
convertToLlm;
|
|
7406
|
-
transformContext;
|
|
7407
|
-
steeringQueue = [];
|
|
7408
|
-
followUpQueue = [];
|
|
7409
|
-
steeringMode;
|
|
7410
|
-
followUpMode;
|
|
7411
|
-
streamFn;
|
|
7412
|
-
_sessionId;
|
|
7413
|
-
getApiKey;
|
|
7414
|
-
_onPayload;
|
|
7415
|
-
runningPrompt;
|
|
7416
|
-
resolveRunningPrompt;
|
|
7417
|
-
_thinkingBudgets;
|
|
7418
|
-
_transport;
|
|
7419
|
-
_maxRetryDelayMs;
|
|
7420
|
-
_toolExecution;
|
|
7421
|
-
_beforeToolExecution;
|
|
7422
|
-
_afterToolExecution;
|
|
7423
|
-
constructor(name, model, opts = {}) {
|
|
7424
|
-
this._state = {
|
|
7425
|
-
systemPrompt: "",
|
|
7426
|
-
thinkingLevel: "off",
|
|
7427
|
-
tools: [],
|
|
7428
|
-
messages: [],
|
|
7429
|
-
isStreaming: false,
|
|
7430
|
-
streamMessage: null,
|
|
7431
|
-
pendingToolCalls: /* @__PURE__ */ new Set(),
|
|
7432
|
-
error: void 0,
|
|
7433
|
-
...opts.initialState,
|
|
7434
|
-
name,
|
|
7435
|
-
model
|
|
7436
|
-
};
|
|
7437
|
-
/**
|
|
7438
|
-
* Transformation logic to prepare messages for the LLM.
|
|
7439
|
-
* * @remarks
|
|
7440
|
-
* Currently just forwards messages as-is. Modify this logic when
|
|
7441
|
-
* specific formatting or filtering is required.
|
|
7442
|
-
* A good example is using user message parts with custom content
|
|
7443
|
-
* * @default
|
|
7444
|
-
* forwards messages as is.
|
|
7445
|
-
*/
|
|
7446
|
-
this.convertToLlm = opts.convertToLlm || ((messages) => messages);
|
|
7447
|
-
this.transformContext = opts.transformContext;
|
|
7448
|
-
this.steeringMode = opts.steeringMode || "one-at-a-time";
|
|
7449
|
-
this.followUpMode = opts.followUpMode || "one-at-a-time";
|
|
7450
|
-
this.streamFn = opts.streamFn || Stream.streamSimple;
|
|
7451
|
-
this._sessionId = opts.sessionId;
|
|
7452
|
-
this.getApiKey = opts.getApiKey;
|
|
7453
|
-
this._onPayload = opts.onPayload;
|
|
7454
|
-
this._thinkingBudgets = opts.thinkingBudgets;
|
|
7455
|
-
this._transport = opts.transport ?? "sse";
|
|
7456
|
-
this._maxRetryDelayMs = opts.maxRetryDelayMs;
|
|
7457
|
-
this._toolExecution = opts.toolExecution ?? "parallel";
|
|
7458
|
-
this._beforeToolExecution = opts.beforeToolExecution;
|
|
7459
|
-
this._afterToolExecution = opts.afterToolExecution;
|
|
7460
|
-
}
|
|
7461
|
-
/**
|
|
7462
|
-
* Get the current session ID used for provider caching.
|
|
7463
|
-
*/
|
|
7464
|
-
get sessionId() {
|
|
7465
|
-
return this._sessionId;
|
|
7466
|
-
}
|
|
7467
|
-
/**
|
|
7468
|
-
* Set the session ID for provider caching.
|
|
7469
|
-
* Call this when switching sessions (new session, branch, resume, etc).
|
|
7470
|
-
*/
|
|
7471
|
-
set sessionId(value) {
|
|
7472
|
-
this._sessionId = value;
|
|
7473
|
-
}
|
|
7474
|
-
/**
|
|
7475
|
-
* Get the current thinking budgets.
|
|
7476
|
-
*/
|
|
7477
|
-
get thinkingBudgets() {
|
|
7478
|
-
return this._thinkingBudgets;
|
|
7479
|
-
}
|
|
7480
|
-
/**
|
|
7481
|
-
* Set custom thinking budgets for token-based providers.
|
|
7482
|
-
*/
|
|
7483
|
-
set thinkingBudgets(value) {
|
|
7484
|
-
this._thinkingBudgets = value;
|
|
7485
|
-
}
|
|
7486
|
-
/**
|
|
7487
|
-
* Get the current preferred transport.
|
|
7488
|
-
*/
|
|
7489
|
-
get transport() {
|
|
7490
|
-
return this._transport;
|
|
7491
|
-
}
|
|
7492
|
-
/**
|
|
7493
|
-
* Set the preferred transport.
|
|
7494
|
-
*/
|
|
7495
|
-
setTransport(value) {
|
|
7496
|
-
this._transport = value;
|
|
7497
|
-
}
|
|
7498
|
-
/**
|
|
7499
|
-
* Get the current max retry delay in milliseconds.
|
|
7500
|
-
*/
|
|
7501
|
-
get maxRetryDelayMs() {
|
|
7502
|
-
return this._maxRetryDelayMs;
|
|
7503
|
-
}
|
|
7504
|
-
/**
|
|
7505
|
-
* Set the maximum delay to wait for server-requested retries.
|
|
7506
|
-
* Set to 0 to disable the cap.
|
|
7507
|
-
*/
|
|
7508
|
-
set maxRetryDelayMs(value) {
|
|
7509
|
-
this._maxRetryDelayMs = value;
|
|
7510
|
-
}
|
|
7511
|
-
get toolExecution() {
|
|
7512
|
-
return this._toolExecution;
|
|
7513
|
-
}
|
|
7514
|
-
setToolExecution(value) {
|
|
7515
|
-
this._toolExecution = value;
|
|
7516
|
-
}
|
|
7517
|
-
setBeforeToolExecution(value) {
|
|
7518
|
-
this._beforeToolExecution = value;
|
|
7519
|
-
}
|
|
7520
|
-
setAfterToolExecution(value) {
|
|
7521
|
-
this._afterToolExecution = value;
|
|
7522
|
-
}
|
|
7523
|
-
get state() {
|
|
7524
|
-
return this._state;
|
|
7525
|
-
}
|
|
7526
|
-
subscribe(fn) {
|
|
7527
|
-
this.listeners.add(fn);
|
|
7528
|
-
return () => this.listeners.delete(fn);
|
|
7529
|
-
}
|
|
7530
|
-
setSystemPrompt(v) {
|
|
7531
|
-
this._state.systemPrompt = v;
|
|
7532
|
-
}
|
|
7533
|
-
setModel(m) {
|
|
7534
|
-
this._state.model = m;
|
|
7535
|
-
}
|
|
7536
|
-
setThinkingLevel(l) {
|
|
7537
|
-
this._state.thinkingLevel = l;
|
|
7538
|
-
}
|
|
7539
|
-
setSteeringMode(mode) {
|
|
7540
|
-
this.steeringMode = mode;
|
|
7541
|
-
}
|
|
7542
|
-
getSteeringMode() {
|
|
7543
|
-
return this.steeringMode;
|
|
7544
|
-
}
|
|
7545
|
-
setFollowUpMode(mode) {
|
|
7546
|
-
this.followUpMode = mode;
|
|
7547
|
-
}
|
|
7548
|
-
getFollowUpMode() {
|
|
7549
|
-
return this.followUpMode;
|
|
7550
|
-
}
|
|
7551
|
-
setTools(t) {
|
|
7552
|
-
this._state.tools = t;
|
|
7553
|
-
}
|
|
7554
|
-
replaceMessages(ms) {
|
|
7555
|
-
this._state.messages = ms.slice();
|
|
7556
|
-
}
|
|
7557
|
-
appendMessage(m) {
|
|
7558
|
-
this._state.messages = [...this._state.messages, m];
|
|
7559
|
-
}
|
|
7560
|
-
findMessageIndexById(messageId) {
|
|
7561
|
-
return this._state.messages.findIndex((message) => message.messageId === messageId);
|
|
7562
|
-
}
|
|
7563
|
-
replaceMessageById(message) {
|
|
7564
|
-
const messageIndex = this.findMessageIndexById(message.messageId);
|
|
7565
|
-
if (messageIndex === -1) return false;
|
|
7566
|
-
const messages = this._state.messages.slice();
|
|
7567
|
-
messages[messageIndex] = message;
|
|
7568
|
-
this._state.messages = messages;
|
|
7569
|
-
return true;
|
|
7570
|
-
}
|
|
7571
|
-
upsertMessage(message) {
|
|
7572
|
-
if (this.replaceMessageById(message)) return;
|
|
7573
|
-
this.appendMessage(message);
|
|
7574
|
-
}
|
|
7575
|
-
patchStoredAssistantPart(messageId, partIndex, part) {
|
|
7576
|
-
const messageIndex = this.findMessageIndexById(messageId);
|
|
7577
|
-
if (messageIndex === -1) return false;
|
|
7578
|
-
const messages = this._state.messages.slice();
|
|
7579
|
-
const existing = messages[messageIndex];
|
|
7580
|
-
if (!existing || existing.role !== "assistant") return false;
|
|
7581
|
-
const nextParts = existing.parts.slice();
|
|
7582
|
-
nextParts[partIndex] = part;
|
|
7583
|
-
messages[messageIndex] = {
|
|
7584
|
-
...existing,
|
|
7585
|
-
parts: nextParts
|
|
7586
|
-
};
|
|
7587
|
-
this._state.messages = messages;
|
|
7588
|
-
return true;
|
|
7589
|
-
}
|
|
7590
|
-
/**
|
|
7591
|
-
* Queue a steering message while the agent is running.
|
|
7592
|
-
* Delivered after the current assistant turn finishes executing its tool calls,
|
|
7593
|
-
* before the next LLM call.
|
|
7594
|
-
*/
|
|
7595
|
-
steer(m) {
|
|
7596
|
-
this.steeringQueue.push(m);
|
|
7597
|
-
}
|
|
7598
|
-
/**
|
|
7599
|
-
* Queue a follow-up message to be processed after the agent finishes.
|
|
7600
|
-
* Delivered only when agent has no more tool calls or steering messages.
|
|
7601
|
-
*/
|
|
7602
|
-
followUp(m) {
|
|
7603
|
-
this.followUpQueue.push(m);
|
|
7604
|
-
}
|
|
7605
|
-
clearSteeringQueue() {
|
|
7606
|
-
this.steeringQueue = [];
|
|
7607
|
-
}
|
|
7608
|
-
clearFollowUpQueue() {
|
|
7609
|
-
this.followUpQueue = [];
|
|
7610
|
-
}
|
|
7611
|
-
clearAllQueues() {
|
|
7612
|
-
this.steeringQueue = [];
|
|
7613
|
-
this.followUpQueue = [];
|
|
7614
|
-
}
|
|
7615
|
-
hasQueuedMessages() {
|
|
7616
|
-
return this.steeringQueue.length > 0 || this.followUpQueue.length > 0;
|
|
7617
|
-
}
|
|
7618
|
-
dequeueSteeringMessages() {
|
|
7619
|
-
if (this.steeringMode === "one-at-a-time") {
|
|
7620
|
-
if (this.steeringQueue.length > 0) {
|
|
7621
|
-
const first = this.steeringQueue[0];
|
|
7622
|
-
this.steeringQueue = this.steeringQueue.slice(1);
|
|
7623
|
-
return [first];
|
|
7624
|
-
}
|
|
7625
|
-
return [];
|
|
7626
|
-
}
|
|
7627
|
-
const steering = this.steeringQueue.slice();
|
|
7628
|
-
this.steeringQueue = [];
|
|
7629
|
-
return steering;
|
|
7630
|
-
}
|
|
7631
|
-
dequeueFollowUpMessages() {
|
|
7632
|
-
if (this.followUpMode === "one-at-a-time") {
|
|
7633
|
-
if (this.followUpQueue.length > 0) {
|
|
7634
|
-
const first = this.followUpQueue[0];
|
|
7635
|
-
this.followUpQueue = this.followUpQueue.slice(1);
|
|
7636
|
-
return [first];
|
|
7637
|
-
}
|
|
7638
|
-
return [];
|
|
7639
|
-
}
|
|
7640
|
-
const followUp = this.followUpQueue.slice();
|
|
7641
|
-
this.followUpQueue = [];
|
|
7642
|
-
return followUp;
|
|
7643
|
-
}
|
|
7644
|
-
clearMessages() {
|
|
7645
|
-
this._state.messages = [];
|
|
7646
|
-
}
|
|
7647
|
-
abort() {
|
|
7648
|
-
this.abortController?.abort();
|
|
7649
|
-
}
|
|
7650
|
-
waitForIdle() {
|
|
7651
|
-
return this.runningPrompt ?? Promise.resolve();
|
|
7652
|
-
}
|
|
7653
|
-
reset() {
|
|
7654
|
-
this._state.messages = [];
|
|
7655
|
-
this._state.isStreaming = false;
|
|
7656
|
-
this._state.streamMessage = null;
|
|
7657
|
-
this._state.pendingToolCalls = /* @__PURE__ */ new Set();
|
|
7658
|
-
this._state.error = void 0;
|
|
7659
|
-
this.steeringQueue = [];
|
|
7660
|
-
this.followUpQueue = [];
|
|
7661
|
-
}
|
|
7662
|
-
getName() {
|
|
7663
|
-
return this._state.name;
|
|
7664
|
-
}
|
|
7665
|
-
ensureIdle() {
|
|
7666
|
-
if (this._state.isStreaming) throw new AgentInStreamingErr({
|
|
7667
|
-
message: "agent is already processing a prompt. Use steer() or followup() to queue messages, or wait for completion.",
|
|
7668
|
-
name: this._state.name
|
|
7669
|
-
});
|
|
7670
|
-
}
|
|
7671
|
-
async _runLoop(messages, opts) {
|
|
7672
|
-
const model = this._state.model;
|
|
7673
|
-
if (!model) throw new ModelNotConfiguredErr({ message: "no model configured yet" });
|
|
7674
|
-
this.runningPrompt = new Promise((resolve) => {
|
|
7675
|
-
this.resolveRunningPrompt = resolve;
|
|
7676
|
-
});
|
|
7677
|
-
this.abortController = new AbortController();
|
|
7678
|
-
this._state.isStreaming = true;
|
|
7679
|
-
this._state.streamMessage = null;
|
|
7680
|
-
this._state.error = void 0;
|
|
7681
|
-
const reasoning = this.state.thinkingLevel === "off" ? void 0 : this._state.thinkingLevel;
|
|
7682
|
-
const context = {
|
|
7683
|
-
systemPrompt: this._state.systemPrompt,
|
|
7684
|
-
messages: this._state.messages.slice(),
|
|
7685
|
-
tools: this._state.tools
|
|
7686
|
-
};
|
|
7687
|
-
let skipInitialSteeringPoll = opts?.skipInitialSteeringPoll === true;
|
|
7688
|
-
const config = {
|
|
7689
|
-
model,
|
|
7690
|
-
reasoning,
|
|
7691
|
-
sessionId: this._sessionId,
|
|
7692
|
-
onPayload: this._onPayload,
|
|
7693
|
-
transport: this._transport,
|
|
7694
|
-
thinkingBudgets: this._thinkingBudgets,
|
|
7695
|
-
maxRetryDelayMs: this._maxRetryDelayMs,
|
|
7696
|
-
toolExecution: this._toolExecution,
|
|
7697
|
-
beforeToolExecution: this._beforeToolExecution,
|
|
7698
|
-
afterToolExecution: this._afterToolExecution,
|
|
7699
|
-
convertToLlm: this.convertToLlm,
|
|
7700
|
-
transformContext: this.transformContext,
|
|
7701
|
-
getApiKey: this.getApiKey,
|
|
7702
|
-
getSteeringMessages: async () => {
|
|
7703
|
-
if (skipInitialSteeringPoll) {
|
|
7704
|
-
skipInitialSteeringPoll = false;
|
|
7705
|
-
return [];
|
|
7706
|
-
}
|
|
7707
|
-
return this.dequeueSteeringMessages();
|
|
7708
|
-
},
|
|
7709
|
-
getFollowUpMessages: async () => this.dequeueFollowUpMessages()
|
|
7710
|
-
};
|
|
7711
|
-
try {
|
|
7712
|
-
if (messages) await Loop.runAgentLoop(config, context, messages, async (e) => this._processLoopEvent(e), this.streamFn, this.abortController.signal);
|
|
7713
|
-
else await Loop.runAgentLoopContinue(config, context, async (e) => this._processLoopEvent(e), this.streamFn, this.abortController.signal);
|
|
7714
|
-
} catch (err) {
|
|
7715
|
-
const message = Message.createAssistantMessage({
|
|
7716
|
-
role: "assistant",
|
|
7717
|
-
protocol: model.protocol,
|
|
7718
|
-
provider: model.provider,
|
|
7719
|
-
model: model.id,
|
|
7720
|
-
usage: {
|
|
7721
|
-
input: 0,
|
|
7722
|
-
output: 0,
|
|
7723
|
-
cacheRead: 0,
|
|
7724
|
-
cacheWrite: 0,
|
|
7725
|
-
totalTokens: 0,
|
|
7726
|
-
cost: {
|
|
7727
|
-
input: 0,
|
|
7728
|
-
output: 0,
|
|
7729
|
-
cacheRead: 0,
|
|
7730
|
-
cacheWrite: 0,
|
|
7731
|
-
total: 0
|
|
7732
|
-
}
|
|
7733
|
-
},
|
|
7734
|
-
stopReason: this.abortController.signal.aborted ? "aborted" : "error",
|
|
7735
|
-
errorMessage: err?.message || String(err),
|
|
7736
|
-
time: {
|
|
7737
|
-
created: Date.now(),
|
|
7738
|
-
completed: Date.now()
|
|
7739
|
-
},
|
|
7740
|
-
parts: []
|
|
7741
|
-
});
|
|
7742
|
-
this.appendMessage(message);
|
|
7743
|
-
this._state.error = err?.message || String(err);
|
|
7744
|
-
this.emit({
|
|
7745
|
-
type: "agent.end",
|
|
7746
|
-
messages: [message]
|
|
7747
|
-
});
|
|
7748
|
-
} finally {
|
|
7749
|
-
this._state.isStreaming = false;
|
|
7750
|
-
this._state.streamMessage = null;
|
|
7751
|
-
this._state.pendingToolCalls = /* @__PURE__ */ new Set();
|
|
7752
|
-
this.abortController = void 0;
|
|
7753
|
-
this.resolveRunningPrompt?.();
|
|
7754
|
-
this.runningPrompt = void 0;
|
|
7755
|
-
this.resolveRunningPrompt = void 0;
|
|
7756
|
-
}
|
|
7757
|
-
}
|
|
7758
|
-
async loop(messages) {
|
|
7759
|
-
this.ensureIdle();
|
|
7760
|
-
await this._runLoop(messages);
|
|
7761
|
-
}
|
|
7762
|
-
async loopContinue() {
|
|
7763
|
-
this.ensureIdle();
|
|
7764
|
-
await this._runLoop();
|
|
7765
|
-
}
|
|
7766
|
-
async prompt(messages, images) {
|
|
7767
|
-
this.ensureIdle();
|
|
7768
|
-
if (!this._state.model) throw new ModelNotConfiguredErr({ message: "no model configured yet." });
|
|
7769
|
-
const message = Message.createUserMessage({
|
|
7770
|
-
role: "user",
|
|
7771
|
-
time: { created: Date.now() },
|
|
7772
|
-
parts: [...messages, ...images ?? []]
|
|
7773
|
-
});
|
|
7774
|
-
await this.loop([message]);
|
|
7775
|
-
}
|
|
7776
|
-
_processLoopEvent(event) {
|
|
7777
|
-
switch (event.type) {
|
|
7778
|
-
case "message.start":
|
|
7779
|
-
this._state.streamMessage = event.message;
|
|
7780
|
-
break;
|
|
7781
|
-
case "message.part.start":
|
|
7782
|
-
case "message.part.update":
|
|
7783
|
-
case "message.part.end":
|
|
7784
|
-
this._state.streamMessage = event.message;
|
|
7785
|
-
if (event.message.role === "assistant") this.patchStoredAssistantPart(event.message.messageId, event.partIndex, event.part);
|
|
7786
|
-
break;
|
|
7787
|
-
case "message.update":
|
|
7788
|
-
this._state.streamMessage = event.message;
|
|
7789
|
-
this.replaceMessageById(event.message);
|
|
7790
|
-
break;
|
|
7791
|
-
case "message.end":
|
|
7792
|
-
this._state.streamMessage = null;
|
|
7793
|
-
this.upsertMessage(event.message);
|
|
7794
|
-
break;
|
|
7795
|
-
case "tool.execution.start": {
|
|
7796
|
-
const pendingToolCalls = new Set(this._state.pendingToolCalls);
|
|
7797
|
-
pendingToolCalls.add(event.callID);
|
|
7798
|
-
this._state.pendingToolCalls = pendingToolCalls;
|
|
7799
|
-
break;
|
|
7800
|
-
}
|
|
7801
|
-
case "tool.execution.end": {
|
|
7802
|
-
const pendingToolCalls = new Set(this._state.pendingToolCalls);
|
|
7803
|
-
pendingToolCalls.delete(event.callID);
|
|
7804
|
-
this._state.pendingToolCalls = pendingToolCalls;
|
|
7805
|
-
break;
|
|
7806
|
-
}
|
|
7807
|
-
case "turn.end":
|
|
7808
|
-
if (event.message.role === "assistant" && event.message.parts.length > 0) this._state.error = event.message.errorMessage;
|
|
7809
|
-
break;
|
|
7810
|
-
case "agent.end":
|
|
7811
|
-
this._state.isStreaming = false;
|
|
7812
|
-
this._state.streamMessage = null;
|
|
7813
|
-
break;
|
|
7814
|
-
}
|
|
7815
|
-
this.emit(event);
|
|
7816
|
-
}
|
|
7817
|
-
emit(e) {
|
|
7818
|
-
for (const listener of this.listeners) listener(e);
|
|
7819
|
-
}
|
|
7820
|
-
}
|
|
7821
|
-
_Agent.Instance = Instance;
|
|
7822
|
-
async function create(options) {
|
|
7823
|
-
let resolvedModel;
|
|
7824
|
-
if ("provider" in options) {
|
|
7825
|
-
const result = await Model.getModel(options.provider, options.model);
|
|
7826
|
-
if (!result) throw new ModelNotFoundErr({
|
|
7827
|
-
message: "model not found or not configured yet",
|
|
7828
|
-
provider: options.provider,
|
|
7829
|
-
model: options.model
|
|
7830
|
-
});
|
|
7831
|
-
resolvedModel = result;
|
|
7832
|
-
} else resolvedModel = options.model;
|
|
7833
|
-
return new Instance(options.name ?? "main", resolvedModel, options);
|
|
7834
|
-
}
|
|
7835
|
-
_Agent.create = create;
|
|
7836
|
-
})(Agent || (Agent = {}));
|
|
7837
|
-
//#endregion
|
|
7838
|
-
//#region src/agent/codemode/codemode.ts
|
|
7839
|
-
let CodeMode;
|
|
7840
|
-
(function(_CodeMode) {
|
|
7841
|
-
const ToolDefinitionErr = _CodeMode.ToolDefinitionErr = NamedError.create("ToolDefinitionErr", Type.Object({ message: Type.String() }));
|
|
7842
|
-
const toolFnPrefix = process.env.CODEWORK_CODEMODE_FN_PREFIX ?? "external_";
|
|
7843
|
-
const SandboxExecutionInputSchema = _CodeMode.SandboxExecutionInputSchema = Type.Object({ typescriptCode: Type.String({ description: "TypeScript code to execute in the sandbox." }) });
|
|
7844
|
-
const SandboxExecutionOutputSchema = _CodeMode.SandboxExecutionOutputSchema = Type.Object({
|
|
7845
|
-
result: Type.Optional(Type.Unknown()),
|
|
7846
|
-
logs: Type.Optional(Type.Array(Type.String()))
|
|
7847
|
-
});
|
|
7848
|
-
const SandboxExecutionErrorSchema = _CodeMode.SandboxExecutionErrorSchema = Type.Object({
|
|
7849
|
-
message: Type.String(),
|
|
7850
|
-
name: Type.Optional(Type.String()),
|
|
7851
|
-
stack: Type.Optional(Type.String()),
|
|
7852
|
-
line: Type.Optional(Type.Number()),
|
|
7853
|
-
logs: Type.Optional(Type.Array(Type.String()))
|
|
7854
|
-
});
|
|
7855
|
-
function withMessageInStack(message, stack) {
|
|
7856
|
-
if (!stack) return void 0;
|
|
7857
|
-
return stack.includes(message) ? stack : `${message}\n${stack}`;
|
|
7858
|
-
}
|
|
7859
|
-
function normalizeExecutionError(error) {
|
|
7860
|
-
if (error instanceof Error) return {
|
|
7861
|
-
name: error.name,
|
|
7862
|
-
message: error.message,
|
|
7863
|
-
stack: withMessageInStack(error.message, error.stack),
|
|
7864
|
-
line: parseErrorLine(error.stack)
|
|
7865
|
-
};
|
|
7866
|
-
if (typeof error === "object" && error !== null) {
|
|
7867
|
-
const candidate = error;
|
|
7868
|
-
return {
|
|
7869
|
-
name: typeof candidate.name === "string" ? candidate.name : void 0,
|
|
7870
|
-
message: typeof candidate.message === "string" ? candidate.message : JSON.stringify(candidate) || "Unknown execution error",
|
|
7871
|
-
stack: typeof candidate.stack === "string" ? withMessageInStack(typeof candidate.message === "string" ? candidate.message : JSON.stringify(candidate) || "Unknown execution error", candidate.stack) : void 0,
|
|
7872
|
-
line: typeof candidate.line === "number" ? candidate.line : parseErrorLine(candidate.stack)
|
|
7873
|
-
};
|
|
7874
|
-
}
|
|
7875
|
-
return {
|
|
7876
|
-
name: "Error",
|
|
7877
|
-
message: String(error)
|
|
7878
|
-
};
|
|
7879
|
-
}
|
|
7880
|
-
function parseErrorLine(stack) {
|
|
7881
|
-
if (typeof stack !== "string") return void 0;
|
|
7882
|
-
const lineMatch = stack.match(/:(\d+)(?::\d+)?\)?$/m);
|
|
7883
|
-
return lineMatch ? Number(lineMatch[1]) : void 0;
|
|
7884
|
-
}
|
|
7885
|
-
function serializeForContent(value) {
|
|
7886
|
-
return JSON.stringify(value, (_key, currentValue) => typeof currentValue === "bigint" ? currentValue.toString() : currentValue, 2);
|
|
7887
|
-
}
|
|
7888
|
-
function toolContentToText(result) {
|
|
7889
|
-
return result.content.filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join("\n").trim();
|
|
7890
|
-
}
|
|
7891
|
-
function unwrapToolResult(tool, result) {
|
|
7892
|
-
if (result.status === "completed") {
|
|
7893
|
-
if (tool.outputSchema) return validateSchema(tool.outputSchema, result.result.details, `Tool "${tool.name}" output`);
|
|
7894
|
-
return result.result.details;
|
|
7895
|
-
}
|
|
7896
|
-
if (tool.errorSchema && result.result.details !== void 0) validateSchema(tool.errorSchema, result.result.details, `Tool "${tool.name}" error`);
|
|
7897
|
-
const message = toolContentToText(result.result) || `Tool "${tool.name}" failed`;
|
|
7898
|
-
const error = new Error(message);
|
|
7899
|
-
if (result.result.details !== void 0) error.cause = result.result.details;
|
|
7900
|
-
throw error;
|
|
7901
|
-
}
|
|
7902
|
-
function toolToBinding(tool, prefix = "") {
|
|
7903
|
-
const inputSchema = Type.IsSchema(tool.parameters) ? tool.parameters : Type.Object({});
|
|
7904
|
-
const outputSchema = Type.IsSchema(tool.outputSchema) ? tool.outputSchema : void 0;
|
|
7905
|
-
const errorSchema = Type.IsSchema(tool.errorSchema) ? tool.errorSchema : void 0;
|
|
7906
|
-
if (!("execute" in tool) || typeof tool.execute !== "function") throw new ToolDefinitionErr({ message: `tool "${tool.name}" does not have an execute function. code mode requires tools with implementation` });
|
|
7907
|
-
return {
|
|
7908
|
-
name: `${prefix}${tool.name}`,
|
|
7909
|
-
description: tool.description,
|
|
7910
|
-
inputSchema,
|
|
7911
|
-
outputSchema,
|
|
7912
|
-
errorSchema,
|
|
7913
|
-
execute: async (callID, params, signal) => {
|
|
7914
|
-
const validatedParams = validateSchema(inputSchema, params, `Tool "${tool.name}" input`);
|
|
7915
|
-
return unwrapToolResult(tool, await tool.execute(callID, validatedParams, signal));
|
|
7916
|
-
}
|
|
7917
|
-
};
|
|
7918
|
-
}
|
|
7919
|
-
function toolsForBinding(tools, prefix) {
|
|
7920
|
-
const bindings = {};
|
|
7921
|
-
for (const tool of tools) {
|
|
7922
|
-
const name = `${prefix}${tool.name}`;
|
|
7923
|
-
bindings[name] = toolToBinding(tool, prefix);
|
|
7924
|
-
}
|
|
7925
|
-
return bindings;
|
|
7926
|
-
}
|
|
7927
|
-
function indent(value, depth = 1) {
|
|
7928
|
-
const prefix = " ".repeat(depth);
|
|
7929
|
-
return value.split("\n").map((line) => `${prefix}${line}`).join("\n");
|
|
7930
|
-
}
|
|
7931
|
-
function toPropertyKey(name) {
|
|
7932
|
-
return /^[$A-Z_a-z][$\w]*$/i.test(name) ? name : JSON.stringify(name);
|
|
7933
|
-
}
|
|
7934
|
-
function schemaToTypeScript(schema) {
|
|
7935
|
-
if (Type.IsAny(schema)) return "any";
|
|
7936
|
-
if (Type.IsUnknown(schema)) return "unknown";
|
|
7937
|
-
if (Type.IsString(schema)) return "string";
|
|
7938
|
-
if (Type.IsNumber(schema) || Type.IsInteger(schema)) return "number";
|
|
7939
|
-
if (Type.IsBoolean(schema)) return "boolean";
|
|
7940
|
-
if (Type.IsNull(schema)) return "null";
|
|
7941
|
-
if (Type.IsUndefined(schema) || Type.IsVoid(schema)) return "undefined";
|
|
7942
|
-
if (Type.IsLiteral(schema)) return JSON.stringify(schema.const);
|
|
7943
|
-
if (Type.IsArray(schema)) return `Array<${schemaToTypeScript(schema.items)}>`;
|
|
7944
|
-
if (Type.IsTuple(schema)) return `[${(schema.items ?? []).map((item) => schemaToTypeScript(item)).join(", ")}]`;
|
|
7945
|
-
if (Type.IsUnion(schema)) return schema.anyOf.map((item) => schemaToTypeScript(item)).join(" | ");
|
|
7946
|
-
if (Type.IsIntersect(schema)) return schema.allOf.map((item) => schemaToTypeScript(item)).join(" & ");
|
|
7947
|
-
if (Type.IsRecord(schema)) {
|
|
7948
|
-
const additionalProperties = schema.additionalProperties;
|
|
7949
|
-
return `Record<string, ${schemaToTypeScript(Object.values(schema.patternProperties ?? {}).find(Type.IsSchema) ?? (additionalProperties && Type.IsSchema(additionalProperties) ? additionalProperties : Type.Unknown()))}>`;
|
|
7950
|
-
}
|
|
7951
|
-
if (Type.IsObject(schema)) {
|
|
7952
|
-
const additionalProperties = schema.additionalProperties;
|
|
7953
|
-
const required = new Set(schema.required ?? []);
|
|
7954
|
-
const properties = Object.entries(schema.properties ?? {}).map(([key, value]) => {
|
|
7955
|
-
const optional = required.has(key) ? "" : "?";
|
|
7956
|
-
return `${toPropertyKey(key)}${optional}: ${schemaToTypeScript(value)};`;
|
|
7957
|
-
});
|
|
7958
|
-
if (additionalProperties === true) properties.push("[key: string]: unknown;");
|
|
7959
|
-
else if (additionalProperties && Type.IsSchema(additionalProperties)) properties.push(`[key: string]: ${schemaToTypeScript(additionalProperties)};`);
|
|
7960
|
-
if (properties.length === 0) return "{}";
|
|
7961
|
-
return `{\n${indent(properties.join("\n"))}\n}`;
|
|
7962
|
-
}
|
|
7963
|
-
return "unknown";
|
|
7964
|
-
}
|
|
7965
|
-
function generateTypeStubs(bindings, options = {}) {
|
|
7966
|
-
const { includeDescriptions = true } = options;
|
|
7967
|
-
const declarations = [];
|
|
7968
|
-
for (const [name, binding] of Object.entries(bindings)) {
|
|
7969
|
-
const inputTypeName = `${capitalize(name)}Input`;
|
|
7970
|
-
const outputTypeName = `${capitalize(name)}Output`;
|
|
7971
|
-
declarations.push(`type ${inputTypeName} = ${schemaToTypeScript(binding.inputSchema)};`);
|
|
7972
|
-
let outputTypeRef = "unknown";
|
|
7973
|
-
if (binding.outputSchema !== void 0) {
|
|
7974
|
-
declarations.push(`type ${outputTypeName} = ${schemaToTypeScript(binding.outputSchema)};`);
|
|
7975
|
-
outputTypeRef = outputTypeName;
|
|
7976
|
-
}
|
|
7977
|
-
const description = includeDescriptions && binding.description ? `/** ${binding.description} */\n` : "";
|
|
7978
|
-
declarations.push(`${description}declare function ${name}(input: ${inputTypeName}): Promise<${outputTypeRef}>;`);
|
|
7979
|
-
}
|
|
7980
|
-
return declarations.join("\n\n");
|
|
7981
|
-
}
|
|
7982
|
-
_CodeMode.generateTypeStubs = generateTypeStubs;
|
|
7983
|
-
function buildExampleSnippet() {
|
|
7984
|
-
return [
|
|
7985
|
-
"```typescript",
|
|
7986
|
-
"const numbers = [12, 24, 36];",
|
|
7987
|
-
"const total = numbers.reduce((sum, value) => sum + value, 0);",
|
|
7988
|
-
"",
|
|
7989
|
-
"return {",
|
|
7990
|
-
" count: numbers.length,",
|
|
7991
|
-
" average: total / numbers.length,",
|
|
7992
|
-
"};",
|
|
7993
|
-
"```"
|
|
7994
|
-
];
|
|
7995
|
-
}
|
|
7996
|
-
function generateSystemPrompt(config) {
|
|
7997
|
-
const fnPrefix = config.fnPrefix ?? toolFnPrefix;
|
|
7998
|
-
const bindings = toolsForBinding(config.tools, fnPrefix);
|
|
7999
|
-
const typeStubs = generateTypeStubs(bindings);
|
|
8000
|
-
return [
|
|
8001
|
-
"## Code Execution Tool",
|
|
8002
|
-
"",
|
|
8003
|
-
"You have access to `sandbox_execute_typescript` which runs TypeScript code in a sandboxed environment.",
|
|
8004
|
-
"",
|
|
8005
|
-
"### When to Use",
|
|
8006
|
-
"",
|
|
8007
|
-
"Use `sandbox_execute_typescript` when you need to:",
|
|
8008
|
-
"- Process data with loops, conditionals, or complex logic",
|
|
8009
|
-
"- Make multiple tool calls in parallel with `Promise.all(...)`",
|
|
8010
|
-
"- Transform, filter, or aggregate data",
|
|
8011
|
-
"- Perform calculations or data analysis",
|
|
8012
|
-
"",
|
|
8013
|
-
"For simple operations, prefer calling tools directly.",
|
|
8014
|
-
"",
|
|
8015
|
-
"### Available External APIs",
|
|
8016
|
-
"",
|
|
8017
|
-
"Inside your TypeScript code, you can call these async functions:",
|
|
8018
|
-
"",
|
|
8019
|
-
Object.entries(bindings).map(([name, binding]) => `- \`${name}(input)\`: ${binding.description}`).join("\n") || "- No external APIs available for this run.",
|
|
8020
|
-
"",
|
|
8021
|
-
"### Type Definitions",
|
|
8022
|
-
"",
|
|
8023
|
-
"```typescript",
|
|
8024
|
-
typeStubs,
|
|
8025
|
-
"```",
|
|
8026
|
-
"",
|
|
8027
|
-
"### Example",
|
|
8028
|
-
"",
|
|
8029
|
-
...buildExampleSnippet(),
|
|
8030
|
-
"",
|
|
8031
|
-
"### Important Notes",
|
|
8032
|
-
"",
|
|
8033
|
-
`- All\`${fnPrefix}\`*calls are async, so always use \`await\``,
|
|
8034
|
-
"- Return a value to pass results back to you",
|
|
8035
|
-
"- Use `console.log()` for debugging (logs are captured)",
|
|
8036
|
-
"- The sandbox is isolated - no network access or file system",
|
|
8037
|
-
"- Each execution is isolated and does not share state with previous runs",
|
|
8038
|
-
""
|
|
8039
|
-
].join("\n");
|
|
8040
|
-
}
|
|
8041
|
-
_CodeMode.generateSystemPrompt = generateSystemPrompt;
|
|
8042
|
-
async function transpileTypeScript(typescriptCode) {
|
|
8043
|
-
return (await transform([
|
|
8044
|
-
"(async () => {",
|
|
8045
|
-
" const __codemodeNormalizeError = (error: unknown) => {",
|
|
8046
|
-
" if (error instanceof Error) return { name: error.name, message: error.message, stack: error.stack };",
|
|
8047
|
-
" if (typeof error === 'object' && error !== null) {",
|
|
8048
|
-
" const candidate = error as { name?: unknown; message?: unknown; stack?: unknown };",
|
|
8049
|
-
" return {",
|
|
8050
|
-
" name: typeof candidate.name === 'string' ? candidate.name : 'Error',",
|
|
8051
|
-
" message:",
|
|
8052
|
-
" typeof candidate.message === 'string'",
|
|
8053
|
-
" ? candidate.message",
|
|
8054
|
-
" : JSON.stringify(candidate) || 'Unknown execution error',",
|
|
8055
|
-
" stack: typeof candidate.stack === 'string' ? candidate.stack : undefined,",
|
|
8056
|
-
" };",
|
|
8057
|
-
" }",
|
|
8058
|
-
" return { name: 'Error', message: String(error) };",
|
|
8059
|
-
" };",
|
|
8060
|
-
" try {",
|
|
8061
|
-
typescriptCode,
|
|
8062
|
-
" } catch (error) {",
|
|
8063
|
-
" throw __codemodeNormalizeError(error);",
|
|
8064
|
-
" }",
|
|
8065
|
-
"})()"
|
|
8066
|
-
].join("\n"), {
|
|
8067
|
-
loader: "ts",
|
|
8068
|
-
target: "es2022",
|
|
8069
|
-
sourcefile: "script.ts",
|
|
8070
|
-
minify: false,
|
|
8071
|
-
keepNames: false
|
|
8072
|
-
})).code;
|
|
8073
|
-
}
|
|
8074
|
-
function buildToolDescription(tools, fnPrefix = toolFnPrefix) {
|
|
8075
|
-
return [
|
|
8076
|
-
"Execute TypeScript code in a secure sandbox environment. ",
|
|
8077
|
-
"The code can use these external API functions:",
|
|
8078
|
-
"<functions>",
|
|
8079
|
-
` ${tools.map((tool) => `${fnPrefix}${tool.name}`).join("\n")}`,
|
|
8080
|
-
"</functions>",
|
|
8081
|
-
`All ${fnPrefix}* calls are async and must be awaited. `,
|
|
8082
|
-
"Return a value to pass results back. Use console.log() for debugging."
|
|
8083
|
-
].join("\n");
|
|
8084
|
-
}
|
|
8085
|
-
function createCodeModeTool(config) {
|
|
8086
|
-
if (config.tools.length === 0) throw new ToolDefinitionErr({ message: "at least one tool must be provided to `createCodeModeTool`" });
|
|
8087
|
-
return Agent.defineTool({
|
|
8088
|
-
name: "sandbox_execute_typescript",
|
|
8089
|
-
label: "Sandbox TypeScript",
|
|
8090
|
-
description: buildToolDescription(config.tools, config.fnPrefix),
|
|
8091
|
-
parameters: SandboxExecutionInputSchema,
|
|
8092
|
-
outputSchema: SandboxExecutionOutputSchema,
|
|
8093
|
-
errorSchema: SandboxExecutionErrorSchema,
|
|
8094
|
-
async execute(_callID, params, signal, onUpdate) {
|
|
8095
|
-
const bindings = toolsForBinding(config.tools, config.fnPrefix ?? toolFnPrefix);
|
|
8096
|
-
let context;
|
|
8097
|
-
try {
|
|
8098
|
-
await onUpdate?.({
|
|
8099
|
-
status: "running",
|
|
8100
|
-
partial: { content: [{
|
|
8101
|
-
type: "text",
|
|
8102
|
-
text: "Transpiling TypeScript for sandbox execution"
|
|
8103
|
-
}] }
|
|
8104
|
-
});
|
|
8105
|
-
const javascriptCode = await transpileTypeScript(params.typescriptCode);
|
|
8106
|
-
await onUpdate?.({
|
|
8107
|
-
status: "running",
|
|
8108
|
-
partial: { content: [{
|
|
8109
|
-
type: "text",
|
|
8110
|
-
text: "Executing code in sandbox runtime"
|
|
8111
|
-
}] }
|
|
8112
|
-
});
|
|
8113
|
-
context = await config.driver.createContext({
|
|
8114
|
-
bindings,
|
|
8115
|
-
timeout: config.timeout,
|
|
8116
|
-
memoryLimit: config.memoryLimit,
|
|
8117
|
-
signal
|
|
8118
|
-
});
|
|
8119
|
-
const executionResult = await context.execute(javascriptCode);
|
|
8120
|
-
if (executionResult.success) {
|
|
8121
|
-
const details = {
|
|
8122
|
-
result: executionResult.value,
|
|
8123
|
-
...executionResult.logs && executionResult.logs.length > 0 ? { logs: executionResult.logs } : {}
|
|
8124
|
-
};
|
|
8125
|
-
return {
|
|
8126
|
-
status: "completed",
|
|
8127
|
-
result: {
|
|
8128
|
-
content: [{
|
|
8129
|
-
type: "text",
|
|
8130
|
-
text: serializeForContent(details)
|
|
8131
|
-
}],
|
|
8132
|
-
details,
|
|
8133
|
-
isError: false
|
|
8134
|
-
}
|
|
8135
|
-
};
|
|
8136
|
-
}
|
|
8137
|
-
const details = {
|
|
8138
|
-
message: executionResult.error?.message || "sandbox execution failed",
|
|
8139
|
-
...executionResult.error?.name ? { name: executionResult.error.name } : {},
|
|
8140
|
-
...executionResult.error?.stack ? { stack: executionResult.error.stack } : {},
|
|
8141
|
-
...executionResult.error?.line != null ? { line: executionResult.error.line } : {},
|
|
8142
|
-
...executionResult.logs && executionResult.logs.length > 0 ? { logs: executionResult.logs } : {}
|
|
8143
|
-
};
|
|
8144
|
-
return {
|
|
8145
|
-
status: "error",
|
|
8146
|
-
result: {
|
|
8147
|
-
content: [{
|
|
8148
|
-
type: "text",
|
|
8149
|
-
text: serializeForContent(details)
|
|
8150
|
-
}],
|
|
8151
|
-
details,
|
|
8152
|
-
isError: true
|
|
8153
|
-
}
|
|
8154
|
-
};
|
|
8155
|
-
} catch (error) {
|
|
8156
|
-
const normalizedError = normalizeExecutionError(error);
|
|
8157
|
-
const details = {
|
|
8158
|
-
message: normalizedError.message,
|
|
8159
|
-
...normalizedError.name ? { name: normalizedError.name } : {},
|
|
8160
|
-
...normalizedError.stack ? { stack: normalizedError.stack } : {},
|
|
8161
|
-
...normalizedError.line != null ? { line: normalizedError.line } : {}
|
|
8162
|
-
};
|
|
8163
|
-
return {
|
|
8164
|
-
status: "error",
|
|
8165
|
-
result: {
|
|
8166
|
-
content: [{
|
|
8167
|
-
type: "text",
|
|
8168
|
-
text: serializeForContent(details)
|
|
8169
|
-
}],
|
|
8170
|
-
details,
|
|
8171
|
-
isError: true
|
|
8172
|
-
}
|
|
8173
|
-
};
|
|
8174
|
-
} finally {
|
|
8175
|
-
await context?.dispose();
|
|
8176
|
-
}
|
|
8177
|
-
}
|
|
8178
|
-
});
|
|
8179
|
-
}
|
|
8180
|
-
_CodeMode.createCodeModeTool = createCodeModeTool;
|
|
8181
|
-
async function create(config) {
|
|
8182
|
-
return {
|
|
8183
|
-
tool: createCodeModeTool(config),
|
|
8184
|
-
systemPrompt: generateSystemPrompt(config)
|
|
8185
|
-
};
|
|
8186
|
-
}
|
|
8187
|
-
_CodeMode.create = create;
|
|
8188
|
-
})(CodeMode || (CodeMode = {}));
|
|
8189
|
-
//#endregion
|
|
8190
|
-
//#region src/llm.ts
|
|
8191
|
-
const llmImpl = async (provider, model, overrides) => Model.getModel(provider, model, overrides);
|
|
8192
|
-
const llm = Object.assign(llmImpl, {
|
|
8193
|
-
model: Model.getModel,
|
|
8194
|
-
models: Model.getModels,
|
|
8195
|
-
providers: Model.getProviders,
|
|
8196
|
-
registry: Model.registry,
|
|
8197
|
-
supportsXhigh: Model.supportsXhigh,
|
|
8198
|
-
modelsAreEqual: Model.modelsAreEqual
|
|
8199
|
-
});
|
|
8200
|
-
//#endregion
|
|
8201
|
-
//#region src/stream.ts
|
|
8202
|
-
const streamImpl = (model, context, options) => Stream.stream(model, context, options);
|
|
8203
|
-
/**
|
|
8204
|
-
* Start a streaming assistant response for a model/context pair.
|
|
8205
|
-
*
|
|
8206
|
-
* This is the main streaming entrypoint.
|
|
8207
|
-
* Attached helpers:
|
|
8208
|
-
*
|
|
8209
|
-
* - `stream.complete(...)` resolves the final assistant message without manually iterating events.
|
|
8210
|
-
* - `stream.simple(...)` uses `Stream.SimpleOptions` for higher-level reasoning controls.
|
|
8211
|
-
* - `stream.completeSimple(...)` is the non-streaming counterpart to `stream.simple(...)`.
|
|
8212
|
-
* - `stream.resolveProtocolProvider(...)` exposes protocol resolution for advanced integrations.
|
|
8213
|
-
*/
|
|
8214
|
-
const stream = Object.assign(streamImpl, {
|
|
8215
|
-
complete: Stream.complete,
|
|
8216
|
-
simple: Stream.streamSimple,
|
|
8217
|
-
completeSimple: Stream.completeSimple,
|
|
8218
|
-
resolveProtocolProvider: Stream.resolveProtocolProvider
|
|
8219
|
-
});
|
|
8220
|
-
Stream.complete;
|
|
8221
|
-
Stream.streamSimple;
|
|
8222
|
-
Stream.completeSimple;
|
|
8223
5133
|
//#endregion
|
|
8224
|
-
export {
|
|
5134
|
+
export { protocolForPackage as a, ModelCatalog as c, NamedError as d, packageForModel as i, lazy as l, isAISDKPackage as n, resolveLanguageModel as o, loadProviderFactory as r, Model as s, DEFAULT_AI_SDK_PACKAGE as t, Filesystem as u };
|
|
8225
5135
|
|
|
8226
|
-
//# sourceMappingURL=
|
|
5136
|
+
//# sourceMappingURL=registry-CYfzJ6lk.mjs.map
|