@ddlqhd/agent-sdk 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-AJD3DTL7.cjs → chunk-6X7EYQLS.cjs} +742 -103
- package/dist/chunk-6X7EYQLS.cjs.map +1 -0
- package/dist/{chunk-742JTNYI.js → chunk-D3UZNLZO.js} +570 -77
- package/dist/chunk-D3UZNLZO.js.map +1 -0
- package/dist/{chunk-DXMVWGLJ.js → chunk-EQ5CXH44.js} +730 -96
- package/dist/chunk-EQ5CXH44.js.map +1 -0
- package/dist/{chunk-THKEF32L.js → chunk-MEJHTQJM.js} +82 -112
- package/dist/chunk-MEJHTQJM.js.map +1 -0
- package/dist/{chunk-DQFTAD3I.cjs → chunk-NYZD3THB.cjs} +573 -76
- package/dist/chunk-NYZD3THB.cjs.map +1 -0
- package/dist/{chunk-Q3L4GIBG.cjs → chunk-Z45DHTDX.cjs} +83 -115
- package/dist/chunk-Z45DHTDX.cjs.map +1 -0
- package/dist/cli/index.cjs +40 -31
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +14 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/{index-DGPDMbW5.d.cts → index-Cw3SfEAB.d.ts} +13 -14
- package/dist/{index-nEfayAzD.d.ts → index-D2Qntkn_.d.cts} +13 -14
- package/dist/index.cjs +115 -91
- package/dist/index.d.cts +42 -22
- package/dist/index.d.ts +42 -22
- package/dist/index.js +3 -3
- package/dist/models/index.cjs +14 -10
- package/dist/models/index.d.cts +7 -2
- package/dist/models/index.d.ts +7 -2
- package/dist/models/index.js +1 -1
- package/dist/tools/index.cjs +52 -60
- package/dist/tools/index.d.cts +3 -3
- package/dist/tools/index.d.ts +3 -3
- package/dist/tools/index.js +1 -1
- package/dist/{types-BLf9IqRs.d.cts → types-CWPAYWzr.d.cts} +274 -13
- package/dist/{types-BLf9IqRs.d.ts → types-CWPAYWzr.d.ts} +274 -13
- package/package.json +11 -11
- package/dist/chunk-742JTNYI.js.map +0 -1
- package/dist/chunk-AJD3DTL7.cjs.map +0 -1
- package/dist/chunk-DQFTAD3I.cjs.map +0 -1
- package/dist/chunk-DXMVWGLJ.js.map +0 -1
- package/dist/chunk-Q3L4GIBG.cjs.map +0 -1
- package/dist/chunk-THKEF32L.js.map +0 -1
|
@@ -1,37 +1,358 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { BaseModelAdapter, toolsToModelSchema } from './chunk-LOYIGOBZ.js';
|
|
3
|
+
import { randomUUID } from 'crypto';
|
|
3
4
|
|
|
4
|
-
// src/models/
|
|
5
|
+
// src/models/default-capabilities.ts
|
|
6
|
+
var DEFAULT_ADAPTER_CAPABILITIES = {
|
|
7
|
+
contextLength: 2e5,
|
|
8
|
+
maxOutputTokens: 32e3
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/core/logger.ts
|
|
5
12
|
var TRUTHY = /^(1|true|yes)$/i;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
var DEFAULT_MAX_BODY_CHARS = 4e3;
|
|
14
|
+
var DEFAULT_REDACT_KEYS = [
|
|
15
|
+
"authorization",
|
|
16
|
+
"proxy-authorization",
|
|
17
|
+
"x-api-key",
|
|
18
|
+
"api-key",
|
|
19
|
+
"apikey",
|
|
20
|
+
"api_key",
|
|
21
|
+
"cookie",
|
|
22
|
+
"set-cookie",
|
|
23
|
+
"token",
|
|
24
|
+
"access_token",
|
|
25
|
+
"refresh_token",
|
|
26
|
+
"password",
|
|
27
|
+
"secret"
|
|
28
|
+
];
|
|
29
|
+
var LEVEL_PRIORITY = {
|
|
30
|
+
debug: 10,
|
|
31
|
+
info: 20,
|
|
32
|
+
warn: 30,
|
|
33
|
+
error: 40,
|
|
34
|
+
silent: 99
|
|
35
|
+
};
|
|
36
|
+
function parseEnvLogLevel(raw) {
|
|
37
|
+
switch ((raw ?? "").trim().toLowerCase()) {
|
|
38
|
+
case "debug":
|
|
39
|
+
case "info":
|
|
40
|
+
case "warn":
|
|
41
|
+
case "error":
|
|
42
|
+
case "silent":
|
|
43
|
+
return (raw ?? "").trim().toLowerCase();
|
|
44
|
+
default:
|
|
45
|
+
return void 0;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function parseBooleanEnv(name) {
|
|
49
|
+
const raw = process.env[name];
|
|
50
|
+
if (raw == null || raw === "") {
|
|
51
|
+
return void 0;
|
|
52
|
+
}
|
|
53
|
+
if (TRUTHY.test(raw.trim())) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
if (/^(0|false|no)$/i.test(raw.trim())) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return void 0;
|
|
60
|
+
}
|
|
61
|
+
function parseNumericEnv(name) {
|
|
62
|
+
const raw = process.env[name];
|
|
63
|
+
if (raw == null || raw === "") {
|
|
64
|
+
return void 0;
|
|
65
|
+
}
|
|
66
|
+
const value = Number(raw);
|
|
67
|
+
return Number.isFinite(value) ? value : void 0;
|
|
68
|
+
}
|
|
69
|
+
function resolveSDKLogLevel(level, hasLogger = false) {
|
|
70
|
+
if (level != null) {
|
|
71
|
+
return level;
|
|
72
|
+
}
|
|
73
|
+
const fromEnv = parseEnvLogLevel(process.env.AGENT_SDK_LOG_LEVEL);
|
|
74
|
+
if (fromEnv != null) {
|
|
75
|
+
return fromEnv;
|
|
76
|
+
}
|
|
77
|
+
if (hasLogger) {
|
|
78
|
+
return "info";
|
|
79
|
+
}
|
|
80
|
+
return "silent";
|
|
81
|
+
}
|
|
82
|
+
function resolveLogRedaction(config) {
|
|
83
|
+
const envIncludeBodies = parseBooleanEnv("AGENT_SDK_LOG_BODIES");
|
|
84
|
+
const envIncludeToolArgs = parseBooleanEnv("AGENT_SDK_LOG_INCLUDE_TOOL_ARGS");
|
|
85
|
+
const envMaxBodyChars = parseNumericEnv("AGENT_SDK_LOG_MAX_BODY_CHARS");
|
|
86
|
+
return {
|
|
87
|
+
includeBodies: config?.includeBodies ?? envIncludeBodies ?? false,
|
|
88
|
+
includeToolArguments: config?.includeToolArguments ?? envIncludeToolArgs ?? false,
|
|
89
|
+
maxBodyChars: Math.max(
|
|
90
|
+
0,
|
|
91
|
+
Math.floor(config?.maxBodyChars ?? envMaxBodyChars ?? DEFAULT_MAX_BODY_CHARS)
|
|
92
|
+
),
|
|
93
|
+
redactKeys: [
|
|
94
|
+
...DEFAULT_REDACT_KEYS,
|
|
95
|
+
...config?.redactKeys ?? []
|
|
96
|
+
]
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function shouldEmitLog(configuredLevel, hasLogger, eventLevel) {
|
|
100
|
+
const effectiveLevel = resolveSDKLogLevel(configuredLevel, hasLogger);
|
|
101
|
+
return LEVEL_PRIORITY[eventLevel] >= LEVEL_PRIORITY[effectiveLevel];
|
|
102
|
+
}
|
|
103
|
+
function truncateString(value, maxChars) {
|
|
104
|
+
if (maxChars <= 0 || value.length <= maxChars) {
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
return `${value.slice(0, maxChars)}... [truncated ${value.length - maxChars} chars]`;
|
|
108
|
+
}
|
|
109
|
+
function isSensitiveKey(key, redaction) {
|
|
110
|
+
if (key == null || redaction == null) {
|
|
9
111
|
return false;
|
|
10
112
|
}
|
|
11
|
-
|
|
113
|
+
const normalized = key.toLowerCase();
|
|
114
|
+
return redaction.redactKeys.some((candidate) => candidate.toLowerCase() === normalized);
|
|
12
115
|
}
|
|
13
|
-
function
|
|
14
|
-
|
|
116
|
+
function sanitizeObjectEntries(entries, redaction) {
|
|
117
|
+
const output = {};
|
|
118
|
+
for (const [key, value] of entries) {
|
|
119
|
+
if (isSensitiveKey(key, redaction)) {
|
|
120
|
+
output[key] = "[REDACTED]";
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (key === "messages" && !redaction.includeBodies && Array.isArray(value)) {
|
|
124
|
+
output[key] = `[REDACTED_MESSAGES:${value.length}]`;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if ((key === "arguments" || key === "input") && !redaction.includeToolArguments) {
|
|
128
|
+
output[key] = "[REDACTED_TOOL_ARGUMENTS]";
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
output[key] = sanitizeForLogging(value, redaction, key);
|
|
132
|
+
}
|
|
133
|
+
return output;
|
|
134
|
+
}
|
|
135
|
+
function sanitizeForLogging(value, redaction, key) {
|
|
136
|
+
if (isSensitiveKey(key, redaction)) {
|
|
137
|
+
return "[REDACTED]";
|
|
138
|
+
}
|
|
139
|
+
if (typeof value === "string") {
|
|
140
|
+
if (!redaction.includeBodies && (key === "content" || key === "text" || key === "thinking")) {
|
|
141
|
+
return "[REDACTED_BODY]";
|
|
142
|
+
}
|
|
143
|
+
return truncateString(value, redaction.maxBodyChars);
|
|
144
|
+
}
|
|
145
|
+
if (typeof value === "number" || typeof value === "boolean" || value == null) {
|
|
146
|
+
return value;
|
|
147
|
+
}
|
|
148
|
+
if (Array.isArray(value)) {
|
|
149
|
+
if (!redaction.includeBodies && key === "messages") {
|
|
150
|
+
return `[REDACTED_MESSAGES:${value.length}]`;
|
|
151
|
+
}
|
|
152
|
+
return value.map((item) => sanitizeForLogging(item, redaction));
|
|
153
|
+
}
|
|
154
|
+
if (typeof value === "object") {
|
|
155
|
+
return sanitizeObjectEntries(Object.entries(value), redaction);
|
|
156
|
+
}
|
|
157
|
+
return String(value);
|
|
158
|
+
}
|
|
159
|
+
function formatSDKLog(event) {
|
|
160
|
+
const prefix = `[agent-sdk][${event.component}][${event.event}]`;
|
|
161
|
+
const details = [];
|
|
162
|
+
if (event.provider) details.push(`provider=${event.provider}`);
|
|
163
|
+
if (event.model) details.push(`model=${event.model}`);
|
|
164
|
+
if (event.sessionId) details.push(`sessionId=${event.sessionId}`);
|
|
165
|
+
if (event.iteration !== void 0) details.push(`iteration=${event.iteration}`);
|
|
166
|
+
if (event.statusCode !== void 0) details.push(`statusCode=${event.statusCode}`);
|
|
167
|
+
if (event.durationMs !== void 0) details.push(`durationMs=${event.durationMs}`);
|
|
168
|
+
if (event.toolName) details.push(`tool=${event.toolName}`);
|
|
169
|
+
if (event.requestId) details.push(`requestId=${event.requestId}`);
|
|
170
|
+
if (event.clientRequestId) details.push(`clientRequestId=${event.clientRequestId}`);
|
|
171
|
+
const suffix = details.length > 0 ? ` ${details.join(" ")}` : "";
|
|
172
|
+
return event.message ? `${prefix} ${event.message}${suffix}` : `${prefix}${suffix}`;
|
|
173
|
+
}
|
|
174
|
+
function consoleMethod(level) {
|
|
175
|
+
if (level === "error") return console.error.bind(console);
|
|
176
|
+
if (level === "warn") return console.warn.bind(console);
|
|
177
|
+
if (level === "info") return console.info.bind(console);
|
|
178
|
+
return console.debug.bind(console);
|
|
179
|
+
}
|
|
180
|
+
function createConsoleSDKLogger() {
|
|
181
|
+
const write = (level, event) => {
|
|
182
|
+
const line = formatSDKLog(event);
|
|
183
|
+
const logFn = consoleMethod(level);
|
|
184
|
+
if (event.metadata != null) {
|
|
185
|
+
logFn(line, event.metadata);
|
|
186
|
+
} else {
|
|
187
|
+
logFn(line);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
return {
|
|
191
|
+
debug(event) {
|
|
192
|
+
write("debug", event);
|
|
193
|
+
},
|
|
194
|
+
info(event) {
|
|
195
|
+
write("info", event);
|
|
196
|
+
},
|
|
197
|
+
warn(event) {
|
|
198
|
+
write("warn", event);
|
|
199
|
+
},
|
|
200
|
+
error(event) {
|
|
201
|
+
write("error", event);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function emitSDKLog(args) {
|
|
206
|
+
if (!shouldEmitLog(args.logLevel, args.logger != null, args.level)) {
|
|
15
207
|
return;
|
|
16
208
|
}
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
209
|
+
const logger = args.logger ?? createConsoleSDKLogger();
|
|
210
|
+
const payload = {
|
|
211
|
+
source: "agent-sdk",
|
|
212
|
+
...args.event
|
|
213
|
+
};
|
|
214
|
+
logger[args.level]?.(payload);
|
|
215
|
+
}
|
|
216
|
+
function extractProviderRequestId(headers) {
|
|
217
|
+
if (headers == null) {
|
|
218
|
+
return void 0;
|
|
24
219
|
}
|
|
220
|
+
return headers.get("x-request-id") ?? headers.get("request-id") ?? headers.get("x-amzn-requestid") ?? void 0;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// src/models/model-request-log.ts
|
|
224
|
+
function countMessages(body) {
|
|
225
|
+
if (body == null || typeof body !== "object" || !("messages" in body)) {
|
|
226
|
+
return void 0;
|
|
227
|
+
}
|
|
228
|
+
const messages = body.messages;
|
|
229
|
+
return Array.isArray(messages) ? messages.length : void 0;
|
|
230
|
+
}
|
|
231
|
+
function countTools(body) {
|
|
232
|
+
if (body == null || typeof body !== "object" || !("tools" in body)) {
|
|
233
|
+
return void 0;
|
|
234
|
+
}
|
|
235
|
+
const tools = body.tools;
|
|
236
|
+
return Array.isArray(tools) ? tools.length : void 0;
|
|
237
|
+
}
|
|
238
|
+
function buildRequestMetadata(body, params) {
|
|
239
|
+
const redaction = resolveLogRedaction(params?.redaction);
|
|
240
|
+
const metadata = {};
|
|
241
|
+
const messageCount = countMessages(body);
|
|
242
|
+
const toolCount = countTools(body);
|
|
243
|
+
if (messageCount !== void 0) metadata.messageCount = messageCount;
|
|
244
|
+
if (toolCount !== void 0) metadata.toolCount = toolCount;
|
|
245
|
+
if (redaction.includeBodies) {
|
|
246
|
+
metadata.requestBody = sanitizeForLogging(body, redaction);
|
|
247
|
+
}
|
|
248
|
+
return metadata;
|
|
249
|
+
}
|
|
250
|
+
function logModelRequestStart(context, body, extraMetadata) {
|
|
251
|
+
const state = {
|
|
252
|
+
clientRequestId: randomUUID(),
|
|
253
|
+
startedAt: Date.now()
|
|
254
|
+
};
|
|
255
|
+
emitSDKLog({
|
|
256
|
+
logger: context.params?.logger,
|
|
257
|
+
logLevel: context.params?.logLevel,
|
|
258
|
+
level: "info",
|
|
259
|
+
event: {
|
|
260
|
+
component: "model",
|
|
261
|
+
event: "model.request.start",
|
|
262
|
+
message: `Starting ${context.operation} request`,
|
|
263
|
+
provider: context.provider,
|
|
264
|
+
model: context.model,
|
|
265
|
+
operation: context.operation,
|
|
266
|
+
sessionId: context.params?.sessionId,
|
|
267
|
+
iteration: context.iteration,
|
|
268
|
+
clientRequestId: state.clientRequestId,
|
|
269
|
+
metadata: {
|
|
270
|
+
path: context.path,
|
|
271
|
+
...buildRequestMetadata(body, context.params),
|
|
272
|
+
...extraMetadata
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
return state;
|
|
277
|
+
}
|
|
278
|
+
function logModelRequestEnd(context, state, response, extraMetadata) {
|
|
279
|
+
emitSDKLog({
|
|
280
|
+
logger: context.params?.logger,
|
|
281
|
+
logLevel: context.params?.logLevel,
|
|
282
|
+
level: response.ok ? "info" : "warn",
|
|
283
|
+
event: {
|
|
284
|
+
component: "model",
|
|
285
|
+
event: response.ok ? "model.request.end" : "model.request.error",
|
|
286
|
+
message: response.ok ? "Model request completed" : "Model request returned error response",
|
|
287
|
+
provider: context.provider,
|
|
288
|
+
model: context.model,
|
|
289
|
+
operation: context.operation,
|
|
290
|
+
sessionId: context.params?.sessionId,
|
|
291
|
+
iteration: context.iteration,
|
|
292
|
+
clientRequestId: state.clientRequestId,
|
|
293
|
+
requestId: extractProviderRequestId(response.headers),
|
|
294
|
+
statusCode: response.status,
|
|
295
|
+
durationMs: Date.now() - state.startedAt,
|
|
296
|
+
metadata: {
|
|
297
|
+
path: context.path,
|
|
298
|
+
...extraMetadata
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
function logModelRequestFailure(context, state, error, extraMetadata) {
|
|
304
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
305
|
+
emitSDKLog({
|
|
306
|
+
logger: context.params?.logger,
|
|
307
|
+
logLevel: context.params?.logLevel,
|
|
308
|
+
level: err.name === "AbortError" ? "info" : "error",
|
|
309
|
+
event: {
|
|
310
|
+
component: "model",
|
|
311
|
+
event: err.name === "AbortError" ? "model.request.aborted" : "model.request.error",
|
|
312
|
+
message: err.name === "AbortError" ? "Model request aborted" : "Model request failed",
|
|
313
|
+
provider: context.provider,
|
|
314
|
+
model: context.model,
|
|
315
|
+
operation: context.operation,
|
|
316
|
+
sessionId: context.params?.sessionId,
|
|
317
|
+
iteration: context.iteration,
|
|
318
|
+
clientRequestId: state.clientRequestId,
|
|
319
|
+
durationMs: Date.now() - state.startedAt,
|
|
320
|
+
errorName: err.name,
|
|
321
|
+
errorMessage: err.message,
|
|
322
|
+
metadata: {
|
|
323
|
+
path: context.path,
|
|
324
|
+
...extraMetadata
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
function logModelStreamParseError(context, rawChunk, error) {
|
|
330
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
331
|
+
const redaction = resolveLogRedaction(context.params?.redaction);
|
|
332
|
+
emitSDKLog({
|
|
333
|
+
logger: context.params?.logger,
|
|
334
|
+
logLevel: context.params?.logLevel,
|
|
335
|
+
level: "warn",
|
|
336
|
+
event: {
|
|
337
|
+
component: "streaming",
|
|
338
|
+
event: "model.stream.parse_error",
|
|
339
|
+
message: "Failed to parse provider stream chunk",
|
|
340
|
+
provider: context.provider,
|
|
341
|
+
model: context.model,
|
|
342
|
+
operation: context.operation,
|
|
343
|
+
sessionId: context.params?.sessionId,
|
|
344
|
+
iteration: context.iteration,
|
|
345
|
+
errorName: err.name,
|
|
346
|
+
errorMessage: err.message,
|
|
347
|
+
metadata: {
|
|
348
|
+
path: context.path,
|
|
349
|
+
rawChunk: sanitizeForLogging(rawChunk, redaction)
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
});
|
|
25
353
|
}
|
|
26
354
|
|
|
27
355
|
// src/models/openai.ts
|
|
28
|
-
var OPENAI_CAPABILITIES = {
|
|
29
|
-
"gpt-4o": { contextLength: 128e3, maxOutputTokens: 16384 },
|
|
30
|
-
"gpt-4o-mini": { contextLength: 128e3, maxOutputTokens: 16384 },
|
|
31
|
-
"gpt-4-turbo": { contextLength: 128e3, maxOutputTokens: 4096 },
|
|
32
|
-
"gpt-4": { contextLength: 8192, maxOutputTokens: 4096 },
|
|
33
|
-
"gpt-3.5-turbo": { contextLength: 16385, maxOutputTokens: 4096 }
|
|
34
|
-
};
|
|
35
356
|
var OpenAIAdapter = class extends BaseModelAdapter {
|
|
36
357
|
name;
|
|
37
358
|
apiKey;
|
|
@@ -48,11 +369,11 @@ var OpenAIAdapter = class extends BaseModelAdapter {
|
|
|
48
369
|
throw new Error("OpenAI API key is required. Set OPENAI_API_KEY environment variable or pass apiKey in config.");
|
|
49
370
|
}
|
|
50
371
|
this.name = `openai/${this.model}`;
|
|
51
|
-
this.capabilities = config.capabilities ??
|
|
372
|
+
this.capabilities = config.capabilities ?? DEFAULT_ADAPTER_CAPABILITIES;
|
|
52
373
|
}
|
|
53
374
|
async *stream(params) {
|
|
54
375
|
const body = this.buildRequestBody(params, true);
|
|
55
|
-
const response = await this.fetch("/chat/completions", body, params
|
|
376
|
+
const response = await this.fetch("/chat/completions", body, "stream", params);
|
|
56
377
|
if (!response.ok) {
|
|
57
378
|
const error = await response.text();
|
|
58
379
|
throw new Error(`OpenAI API error: ${response.status} - ${error}`);
|
|
@@ -151,7 +472,18 @@ var OpenAIAdapter = class extends BaseModelAdapter {
|
|
|
151
472
|
...raw
|
|
152
473
|
};
|
|
153
474
|
}
|
|
154
|
-
} catch {
|
|
475
|
+
} catch (error) {
|
|
476
|
+
logModelStreamParseError(
|
|
477
|
+
{
|
|
478
|
+
provider: "openai",
|
|
479
|
+
model: this.model,
|
|
480
|
+
path: "/chat/completions",
|
|
481
|
+
operation: "stream",
|
|
482
|
+
params
|
|
483
|
+
},
|
|
484
|
+
trimmed,
|
|
485
|
+
error
|
|
486
|
+
);
|
|
155
487
|
}
|
|
156
488
|
}
|
|
157
489
|
}
|
|
@@ -173,7 +505,7 @@ var OpenAIAdapter = class extends BaseModelAdapter {
|
|
|
173
505
|
}
|
|
174
506
|
async complete(params) {
|
|
175
507
|
const body = this.buildRequestBody(params, false);
|
|
176
|
-
const response = await this.fetch("/chat/completions", body);
|
|
508
|
+
const response = await this.fetch("/chat/completions", body, "complete", params);
|
|
177
509
|
if (!response.ok) {
|
|
178
510
|
const error = await response.text();
|
|
179
511
|
throw new Error(`OpenAI API error: ${response.status} - ${error}`);
|
|
@@ -204,13 +536,14 @@ var OpenAIAdapter = class extends BaseModelAdapter {
|
|
|
204
536
|
}
|
|
205
537
|
buildRequestBody(params, stream) {
|
|
206
538
|
const messages = this.transformMessages(params.messages);
|
|
539
|
+
const defaultMaxTokens = this.capabilities?.maxOutputTokens ?? DEFAULT_ADAPTER_CAPABILITIES.maxOutputTokens;
|
|
207
540
|
const body = {
|
|
208
541
|
model: this.model,
|
|
209
542
|
messages,
|
|
210
543
|
stream,
|
|
211
544
|
...stream && { stream_options: { include_usage: true } },
|
|
212
545
|
...params.temperature !== void 0 && { temperature: params.temperature },
|
|
213
|
-
|
|
546
|
+
max_tokens: params.maxTokens ?? defaultMaxTokens,
|
|
214
547
|
...params.stopSequences && { stop: params.stopSequences }
|
|
215
548
|
};
|
|
216
549
|
if (params.tools && params.tools.length > 0) {
|
|
@@ -221,21 +554,55 @@ var OpenAIAdapter = class extends BaseModelAdapter {
|
|
|
221
554
|
}
|
|
222
555
|
return body;
|
|
223
556
|
}
|
|
224
|
-
async fetch(path, body,
|
|
225
|
-
|
|
557
|
+
async fetch(path, body, operation, params) {
|
|
558
|
+
const requestLog = logModelRequestStart({
|
|
559
|
+
provider: "openai",
|
|
560
|
+
model: this.model,
|
|
561
|
+
path,
|
|
562
|
+
operation,
|
|
563
|
+
params
|
|
564
|
+
}, body);
|
|
226
565
|
const headers = {
|
|
227
566
|
"Content-Type": "application/json",
|
|
228
|
-
"Authorization": `Bearer ${this.apiKey}
|
|
567
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
568
|
+
"X-Client-Request-Id": requestLog.clientRequestId
|
|
229
569
|
};
|
|
230
570
|
if (this.organization) {
|
|
231
571
|
headers["OpenAI-Organization"] = this.organization;
|
|
232
572
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
573
|
+
try {
|
|
574
|
+
const response = await globalThis.fetch(`${this.baseUrl}${path}`, {
|
|
575
|
+
method: "POST",
|
|
576
|
+
headers,
|
|
577
|
+
body: JSON.stringify(body),
|
|
578
|
+
signal: params.signal
|
|
579
|
+
});
|
|
580
|
+
logModelRequestEnd(
|
|
581
|
+
{
|
|
582
|
+
provider: "openai",
|
|
583
|
+
model: this.model,
|
|
584
|
+
path,
|
|
585
|
+
operation,
|
|
586
|
+
params
|
|
587
|
+
},
|
|
588
|
+
requestLog,
|
|
589
|
+
response
|
|
590
|
+
);
|
|
591
|
+
return response;
|
|
592
|
+
} catch (error) {
|
|
593
|
+
logModelRequestFailure(
|
|
594
|
+
{
|
|
595
|
+
provider: "openai",
|
|
596
|
+
model: this.model,
|
|
597
|
+
path,
|
|
598
|
+
operation,
|
|
599
|
+
params
|
|
600
|
+
},
|
|
601
|
+
requestLog,
|
|
602
|
+
error
|
|
603
|
+
);
|
|
604
|
+
throw error;
|
|
605
|
+
}
|
|
239
606
|
}
|
|
240
607
|
safeParseJSON(str) {
|
|
241
608
|
try {
|
|
@@ -333,12 +700,6 @@ async function drainResponseBody(response) {
|
|
|
333
700
|
} catch {
|
|
334
701
|
}
|
|
335
702
|
}
|
|
336
|
-
var ANTHROPIC_CAPABILITIES = {
|
|
337
|
-
"claude-sonnet-4-20250514": { contextLength: 2e5, maxOutputTokens: 16384 },
|
|
338
|
-
"claude-haiku": { contextLength: 2e5, maxOutputTokens: 8192 },
|
|
339
|
-
"claude-3-5-sonnet-20241022": { contextLength: 2e5, maxOutputTokens: 8192 },
|
|
340
|
-
"claude-3-haiku-20240307": { contextLength: 2e5, maxOutputTokens: 4096 }
|
|
341
|
-
};
|
|
342
703
|
var AnthropicAdapter = class extends BaseModelAdapter {
|
|
343
704
|
name;
|
|
344
705
|
apiKey;
|
|
@@ -359,11 +720,11 @@ var AnthropicAdapter = class extends BaseModelAdapter {
|
|
|
359
720
|
throw new Error("Anthropic API key is required. Set ANTHROPIC_API_KEY environment variable or pass apiKey in config.");
|
|
360
721
|
}
|
|
361
722
|
this.name = `anthropic/${this.model}`;
|
|
362
|
-
this.capabilities = config.capabilities ??
|
|
723
|
+
this.capabilities = config.capabilities ?? DEFAULT_ADAPTER_CAPABILITIES;
|
|
363
724
|
}
|
|
364
725
|
async *stream(params) {
|
|
365
726
|
const body = this.buildRequestBody(params, true);
|
|
366
|
-
const response = await this.fetch("/v1/messages", body, params
|
|
727
|
+
const response = await this.fetch("/v1/messages", body, "stream", params);
|
|
367
728
|
if (!response.ok) {
|
|
368
729
|
const error = await response.text();
|
|
369
730
|
throw new Error(`Anthropic API error: ${response.status} - ${error}`);
|
|
@@ -461,6 +822,7 @@ var AnthropicAdapter = class extends BaseModelAdapter {
|
|
|
461
822
|
currentToolCall = null;
|
|
462
823
|
}
|
|
463
824
|
if (currentThinkingBlock) {
|
|
825
|
+
yield { type: "thinking_block_end", ...raw };
|
|
464
826
|
currentThinkingBlock = null;
|
|
465
827
|
}
|
|
466
828
|
break;
|
|
@@ -502,7 +864,18 @@ var AnthropicAdapter = class extends BaseModelAdapter {
|
|
|
502
864
|
}
|
|
503
865
|
break;
|
|
504
866
|
}
|
|
505
|
-
} catch {
|
|
867
|
+
} catch (error) {
|
|
868
|
+
logModelStreamParseError(
|
|
869
|
+
{
|
|
870
|
+
provider: "anthropic",
|
|
871
|
+
model: this.model,
|
|
872
|
+
path: "/v1/messages",
|
|
873
|
+
operation: "stream",
|
|
874
|
+
params
|
|
875
|
+
},
|
|
876
|
+
jsonStr,
|
|
877
|
+
error
|
|
878
|
+
);
|
|
506
879
|
}
|
|
507
880
|
}
|
|
508
881
|
}
|
|
@@ -513,7 +886,7 @@ var AnthropicAdapter = class extends BaseModelAdapter {
|
|
|
513
886
|
}
|
|
514
887
|
async complete(params) {
|
|
515
888
|
const body = this.buildRequestBody(params, false);
|
|
516
|
-
const response = await this.fetch("/v1/messages", body);
|
|
889
|
+
const response = await this.fetch("/v1/messages", body, "complete", params);
|
|
517
890
|
if (!response.ok) {
|
|
518
891
|
const error = await response.text();
|
|
519
892
|
throw new Error(`Anthropic API error: ${response.status} - ${error}`);
|
|
@@ -551,9 +924,10 @@ var AnthropicAdapter = class extends BaseModelAdapter {
|
|
|
551
924
|
buildRequestBody(params, stream) {
|
|
552
925
|
const { system, messages } = this.extractSystemMessage(params.messages);
|
|
553
926
|
const transformedMessages = this.transformAnthropicMessages(messages);
|
|
927
|
+
const defaultMaxTokens = this.capabilities?.maxOutputTokens ?? DEFAULT_ADAPTER_CAPABILITIES.maxOutputTokens;
|
|
554
928
|
const body = {
|
|
555
929
|
model: this.model,
|
|
556
|
-
max_tokens: params.maxTokens
|
|
930
|
+
max_tokens: params.maxTokens ?? defaultMaxTokens,
|
|
557
931
|
messages: transformedMessages,
|
|
558
932
|
stream,
|
|
559
933
|
...system && { system },
|
|
@@ -665,8 +1039,18 @@ var AnthropicAdapter = class extends BaseModelAdapter {
|
|
|
665
1039
|
/**
|
|
666
1040
|
* 发起 POST;按 `fetchRetry` 对网络错误与 429/502/503/504 重试(不含响应体已开始消费后的 SSE 读失败)。
|
|
667
1041
|
*/
|
|
668
|
-
async fetch(path, body,
|
|
669
|
-
|
|
1042
|
+
async fetch(path, body, operation, params) {
|
|
1043
|
+
const requestLog = logModelRequestStart(
|
|
1044
|
+
{
|
|
1045
|
+
provider: "anthropic",
|
|
1046
|
+
model: this.model,
|
|
1047
|
+
path,
|
|
1048
|
+
operation,
|
|
1049
|
+
params
|
|
1050
|
+
},
|
|
1051
|
+
body,
|
|
1052
|
+
{ httpMaxAttempts: this.fetchRetry.maxAttempts }
|
|
1053
|
+
);
|
|
670
1054
|
const url = `${this.baseUrl}${path}`;
|
|
671
1055
|
const init = {
|
|
672
1056
|
method: "POST",
|
|
@@ -676,15 +1060,43 @@ var AnthropicAdapter = class extends BaseModelAdapter {
|
|
|
676
1060
|
"anthropic-version": this.version
|
|
677
1061
|
},
|
|
678
1062
|
body: JSON.stringify(body),
|
|
679
|
-
signal
|
|
1063
|
+
signal: params.signal
|
|
680
1064
|
};
|
|
681
1065
|
for (let attempt = 0; attempt < this.fetchRetry.maxAttempts; attempt++) {
|
|
682
|
-
|
|
1066
|
+
const httpAttemptMeta = {
|
|
1067
|
+
httpAttempt: attempt + 1,
|
|
1068
|
+
httpMaxAttempts: this.fetchRetry.maxAttempts
|
|
1069
|
+
};
|
|
1070
|
+
if (params.signal?.aborted) {
|
|
1071
|
+
logModelRequestFailure(
|
|
1072
|
+
{
|
|
1073
|
+
provider: "anthropic",
|
|
1074
|
+
model: this.model,
|
|
1075
|
+
path,
|
|
1076
|
+
operation,
|
|
1077
|
+
params
|
|
1078
|
+
},
|
|
1079
|
+
requestLog,
|
|
1080
|
+
new DOMException("The operation was aborted.", "AbortError"),
|
|
1081
|
+
{ httpMaxAttempts: this.fetchRetry.maxAttempts }
|
|
1082
|
+
);
|
|
683
1083
|
throw new DOMException("The operation was aborted.", "AbortError");
|
|
684
1084
|
}
|
|
685
1085
|
try {
|
|
686
1086
|
const response = await globalThis.fetch(url, init);
|
|
687
1087
|
if (response.ok) {
|
|
1088
|
+
logModelRequestEnd(
|
|
1089
|
+
{
|
|
1090
|
+
provider: "anthropic",
|
|
1091
|
+
model: this.model,
|
|
1092
|
+
path,
|
|
1093
|
+
operation,
|
|
1094
|
+
params
|
|
1095
|
+
},
|
|
1096
|
+
requestLog,
|
|
1097
|
+
response,
|
|
1098
|
+
httpAttemptMeta
|
|
1099
|
+
);
|
|
688
1100
|
return response;
|
|
689
1101
|
}
|
|
690
1102
|
const canRetryHttp = attempt < this.fetchRetry.maxAttempts - 1 && isRetriableHttpStatus(response.status);
|
|
@@ -693,19 +1105,55 @@ var AnthropicAdapter = class extends BaseModelAdapter {
|
|
|
693
1105
|
const fromHeader = parseRetryAfterMs(response.headers.get("Retry-After"));
|
|
694
1106
|
const backoff = computeBackoffMs(attempt, this.fetchRetry.baseDelayMs, this.fetchRetry.maxDelayMs);
|
|
695
1107
|
const waitMs = fromHeader != null ? Math.min(fromHeader, this.fetchRetry.maxDelayMs) : backoff;
|
|
696
|
-
await delay(waitMs, signal);
|
|
1108
|
+
await delay(waitMs, params.signal);
|
|
697
1109
|
continue;
|
|
698
1110
|
}
|
|
1111
|
+
logModelRequestEnd(
|
|
1112
|
+
{
|
|
1113
|
+
provider: "anthropic",
|
|
1114
|
+
model: this.model,
|
|
1115
|
+
path,
|
|
1116
|
+
operation,
|
|
1117
|
+
params
|
|
1118
|
+
},
|
|
1119
|
+
requestLog,
|
|
1120
|
+
response,
|
|
1121
|
+
httpAttemptMeta
|
|
1122
|
+
);
|
|
699
1123
|
return response;
|
|
700
1124
|
} catch (e) {
|
|
701
|
-
if (isAbortError(e) || signal?.aborted) {
|
|
1125
|
+
if (isAbortError(e) || params.signal?.aborted) {
|
|
1126
|
+
logModelRequestFailure(
|
|
1127
|
+
{
|
|
1128
|
+
provider: "anthropic",
|
|
1129
|
+
model: this.model,
|
|
1130
|
+
path,
|
|
1131
|
+
operation,
|
|
1132
|
+
params
|
|
1133
|
+
},
|
|
1134
|
+
requestLog,
|
|
1135
|
+
e,
|
|
1136
|
+
httpAttemptMeta
|
|
1137
|
+
);
|
|
702
1138
|
throw e;
|
|
703
1139
|
}
|
|
704
1140
|
if (attempt < this.fetchRetry.maxAttempts - 1 && isRetriableFetchError(e)) {
|
|
705
1141
|
const backoff = computeBackoffMs(attempt, this.fetchRetry.baseDelayMs, this.fetchRetry.maxDelayMs);
|
|
706
|
-
await delay(backoff, signal);
|
|
1142
|
+
await delay(backoff, params.signal);
|
|
707
1143
|
continue;
|
|
708
1144
|
}
|
|
1145
|
+
logModelRequestFailure(
|
|
1146
|
+
{
|
|
1147
|
+
provider: "anthropic",
|
|
1148
|
+
model: this.model,
|
|
1149
|
+
path,
|
|
1150
|
+
operation,
|
|
1151
|
+
params
|
|
1152
|
+
},
|
|
1153
|
+
requestLog,
|
|
1154
|
+
e,
|
|
1155
|
+
httpAttemptMeta
|
|
1156
|
+
);
|
|
709
1157
|
throw e;
|
|
710
1158
|
}
|
|
711
1159
|
}
|
|
@@ -724,12 +1172,6 @@ function createAnthropic(config) {
|
|
|
724
1172
|
}
|
|
725
1173
|
|
|
726
1174
|
// src/models/ollama.ts
|
|
727
|
-
var OLLAMA_CAPABILITIES = {
|
|
728
|
-
"qwen3.5:0.8b": { contextLength: 32768, maxOutputTokens: 4096 },
|
|
729
|
-
"minimax-m2.7:cloud": { contextLength: 128e3, maxOutputTokens: 16384 },
|
|
730
|
-
"nemotron-3-super:cloud": { contextLength: 128e3, maxOutputTokens: 16384 },
|
|
731
|
-
"glm-5:cloud": { contextLength: 128e3, maxOutputTokens: 16384 }
|
|
732
|
-
};
|
|
733
1175
|
function ollamaStreamChunksFromChatData(data, parseToolArguments, nextToolCallId) {
|
|
734
1176
|
const chunks = [];
|
|
735
1177
|
const msg = data.message;
|
|
@@ -784,11 +1226,11 @@ var OllamaAdapter = class extends BaseModelAdapter {
|
|
|
784
1226
|
this.model = config.model || "qwen3.5:0.8b";
|
|
785
1227
|
this.think = config.think;
|
|
786
1228
|
this.name = `ollama/${this.model}`;
|
|
787
|
-
this.capabilities = config.capabilities ??
|
|
1229
|
+
this.capabilities = config.capabilities ?? DEFAULT_ADAPTER_CAPABILITIES;
|
|
788
1230
|
}
|
|
789
1231
|
async *stream(params) {
|
|
790
1232
|
const body = this.buildRequestBody(params, true);
|
|
791
|
-
const response = await this.fetch("/api/chat", body, params
|
|
1233
|
+
const response = await this.fetch("/api/chat", body, "stream", params);
|
|
792
1234
|
if (!response.ok) {
|
|
793
1235
|
const error = await response.text();
|
|
794
1236
|
throw new Error(`Ollama API error: ${response.status} - ${error}`);
|
|
@@ -842,7 +1284,18 @@ var OllamaAdapter = class extends BaseModelAdapter {
|
|
|
842
1284
|
}
|
|
843
1285
|
yield { type: "done", ...raw };
|
|
844
1286
|
}
|
|
845
|
-
} catch {
|
|
1287
|
+
} catch (error) {
|
|
1288
|
+
logModelStreamParseError(
|
|
1289
|
+
{
|
|
1290
|
+
provider: "ollama",
|
|
1291
|
+
model: this.model,
|
|
1292
|
+
path: "/api/chat",
|
|
1293
|
+
operation: "stream",
|
|
1294
|
+
params
|
|
1295
|
+
},
|
|
1296
|
+
trimmed,
|
|
1297
|
+
error
|
|
1298
|
+
);
|
|
846
1299
|
}
|
|
847
1300
|
}
|
|
848
1301
|
}
|
|
@@ -852,7 +1305,7 @@ var OllamaAdapter = class extends BaseModelAdapter {
|
|
|
852
1305
|
}
|
|
853
1306
|
async complete(params) {
|
|
854
1307
|
const body = this.buildRequestBody(params, false);
|
|
855
|
-
const response = await this.fetch("/api/chat", body);
|
|
1308
|
+
const response = await this.fetch("/api/chat", body, "complete", params);
|
|
856
1309
|
if (!response.ok) {
|
|
857
1310
|
const error = await response.text();
|
|
858
1311
|
throw new Error(`Ollama API error: ${response.status} - ${error}`);
|
|
@@ -932,11 +1385,18 @@ var OllamaAdapter = class extends BaseModelAdapter {
|
|
|
932
1385
|
});
|
|
933
1386
|
}
|
|
934
1387
|
buildRequestBody(params, stream) {
|
|
1388
|
+
const defaultMaxTokens = this.capabilities?.maxOutputTokens ?? DEFAULT_ADAPTER_CAPABILITIES.maxOutputTokens;
|
|
1389
|
+
const options = {
|
|
1390
|
+
num_predict: params.maxTokens ?? defaultMaxTokens
|
|
1391
|
+
};
|
|
1392
|
+
if (params.temperature !== void 0) {
|
|
1393
|
+
options.temperature = params.temperature;
|
|
1394
|
+
}
|
|
935
1395
|
const body = {
|
|
936
1396
|
model: this.model,
|
|
937
1397
|
messages: this.transformMessages(params.messages),
|
|
938
1398
|
stream,
|
|
939
|
-
|
|
1399
|
+
options
|
|
940
1400
|
};
|
|
941
1401
|
if (this.think !== void 0) {
|
|
942
1402
|
body.think = this.think;
|
|
@@ -949,16 +1409,49 @@ var OllamaAdapter = class extends BaseModelAdapter {
|
|
|
949
1409
|
}
|
|
950
1410
|
return body;
|
|
951
1411
|
}
|
|
952
|
-
async fetch(path, body,
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
1412
|
+
async fetch(path, body, operation, params) {
|
|
1413
|
+
const requestLog = logModelRequestStart({
|
|
1414
|
+
provider: "ollama",
|
|
1415
|
+
model: this.model,
|
|
1416
|
+
path,
|
|
1417
|
+
operation,
|
|
1418
|
+
params
|
|
1419
|
+
}, body);
|
|
1420
|
+
try {
|
|
1421
|
+
const response = await globalThis.fetch(`${this.baseUrl}${path}`, {
|
|
1422
|
+
method: "POST",
|
|
1423
|
+
headers: {
|
|
1424
|
+
"Content-Type": "application/json"
|
|
1425
|
+
},
|
|
1426
|
+
body: JSON.stringify(body),
|
|
1427
|
+
signal: params.signal
|
|
1428
|
+
});
|
|
1429
|
+
logModelRequestEnd(
|
|
1430
|
+
{
|
|
1431
|
+
provider: "ollama",
|
|
1432
|
+
model: this.model,
|
|
1433
|
+
path,
|
|
1434
|
+
operation,
|
|
1435
|
+
params
|
|
1436
|
+
},
|
|
1437
|
+
requestLog,
|
|
1438
|
+
response
|
|
1439
|
+
);
|
|
1440
|
+
return response;
|
|
1441
|
+
} catch (error) {
|
|
1442
|
+
logModelRequestFailure(
|
|
1443
|
+
{
|
|
1444
|
+
provider: "ollama",
|
|
1445
|
+
model: this.model,
|
|
1446
|
+
path,
|
|
1447
|
+
operation,
|
|
1448
|
+
params
|
|
1449
|
+
},
|
|
1450
|
+
requestLog,
|
|
1451
|
+
error
|
|
1452
|
+
);
|
|
1453
|
+
throw error;
|
|
1454
|
+
}
|
|
962
1455
|
}
|
|
963
1456
|
};
|
|
964
1457
|
function createOllama(config) {
|
|
@@ -1007,6 +1500,6 @@ function createModel(modelConfig, agentEnv) {
|
|
|
1007
1500
|
throw new Error(`Unknown model provider: ${modelConfig.provider}`);
|
|
1008
1501
|
}
|
|
1009
1502
|
|
|
1010
|
-
export { AnthropicAdapter, OllamaAdapter, OpenAIAdapter, createAnthropic, createModel, createOllama, createOpenAI, mergeMcpStdioEnv, mergeProcessEnv, ollamaMessageContentToApiString, ollamaStreamChunksFromChatData };
|
|
1011
|
-
//# sourceMappingURL=chunk-
|
|
1012
|
-
//# sourceMappingURL=chunk-
|
|
1503
|
+
export { AnthropicAdapter, DEFAULT_ADAPTER_CAPABILITIES, OllamaAdapter, OpenAIAdapter, createAnthropic, createConsoleSDKLogger, createModel, createOllama, createOpenAI, emitSDKLog, formatSDKLog, mergeMcpStdioEnv, mergeProcessEnv, ollamaMessageContentToApiString, ollamaStreamChunksFromChatData };
|
|
1504
|
+
//# sourceMappingURL=chunk-D3UZNLZO.js.map
|
|
1505
|
+
//# sourceMappingURL=chunk-D3UZNLZO.js.map
|