@ddlqhd/agent-sdk 0.1.1 → 0.2.1

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