@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.
Files changed (39) hide show
  1. package/dist/{chunk-AJD3DTL7.cjs → chunk-6X7EYQLS.cjs} +742 -103
  2. package/dist/chunk-6X7EYQLS.cjs.map +1 -0
  3. package/dist/{chunk-742JTNYI.js → chunk-D3UZNLZO.js} +570 -77
  4. package/dist/chunk-D3UZNLZO.js.map +1 -0
  5. package/dist/{chunk-DXMVWGLJ.js → chunk-EQ5CXH44.js} +730 -96
  6. package/dist/chunk-EQ5CXH44.js.map +1 -0
  7. package/dist/{chunk-THKEF32L.js → chunk-MEJHTQJM.js} +82 -112
  8. package/dist/chunk-MEJHTQJM.js.map +1 -0
  9. package/dist/{chunk-DQFTAD3I.cjs → chunk-NYZD3THB.cjs} +573 -76
  10. package/dist/chunk-NYZD3THB.cjs.map +1 -0
  11. package/dist/{chunk-Q3L4GIBG.cjs → chunk-Z45DHTDX.cjs} +83 -115
  12. package/dist/chunk-Z45DHTDX.cjs.map +1 -0
  13. package/dist/cli/index.cjs +40 -31
  14. package/dist/cli/index.cjs.map +1 -1
  15. package/dist/cli/index.js +14 -5
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/{index-DGPDMbW5.d.cts → index-Cw3SfEAB.d.ts} +13 -14
  18. package/dist/{index-nEfayAzD.d.ts → index-D2Qntkn_.d.cts} +13 -14
  19. package/dist/index.cjs +115 -91
  20. package/dist/index.d.cts +42 -22
  21. package/dist/index.d.ts +42 -22
  22. package/dist/index.js +3 -3
  23. package/dist/models/index.cjs +14 -10
  24. package/dist/models/index.d.cts +7 -2
  25. package/dist/models/index.d.ts +7 -2
  26. package/dist/models/index.js +1 -1
  27. package/dist/tools/index.cjs +52 -60
  28. package/dist/tools/index.d.cts +3 -3
  29. package/dist/tools/index.d.ts +3 -3
  30. package/dist/tools/index.js +1 -1
  31. package/dist/{types-BLf9IqRs.d.cts → types-CWPAYWzr.d.cts} +274 -13
  32. package/dist/{types-BLf9IqRs.d.ts → types-CWPAYWzr.d.ts} +274 -13
  33. package/package.json +11 -11
  34. package/dist/chunk-742JTNYI.js.map +0 -1
  35. package/dist/chunk-AJD3DTL7.cjs.map +0 -1
  36. package/dist/chunk-DQFTAD3I.cjs.map +0 -1
  37. package/dist/chunk-DXMVWGLJ.js.map +0 -1
  38. package/dist/chunk-Q3L4GIBG.cjs.map +0 -1
  39. 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/request-debug.ts
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
- function isModelRequestDebugEnabled() {
7
- const raw = process.env.AGENT_SDK_DEBUG_MODEL_REQUEST;
8
- if (raw === void 0 || raw === "") {
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
- return TRUTHY.test(String(raw).trim());
113
+ const normalized = key.toLowerCase();
114
+ return redaction.redactKeys.some((candidate) => candidate.toLowerCase() === normalized);
12
115
  }
13
- function debugLogModelRequestBody(provider, path, body) {
14
- if (!isModelRequestDebugEnabled()) {
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 prefix = `[agent-sdk][model-request][${provider}] ${path}`;
18
- try {
19
- const json = body !== null && typeof body === "object" ? JSON.stringify(body, null, 2) : JSON.stringify(body);
20
- console.error(`${prefix}
21
- ${json}`);
22
- } catch {
23
- console.error(prefix, body);
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 ?? OPENAI_CAPABILITIES[this.model] ?? { contextLength: 128e3, maxOutputTokens: 4096 };
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.signal);
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
- ...params.maxTokens !== void 0 && { max_tokens: params.maxTokens },
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, signal) {
225
- debugLogModelRequestBody("openai", path, body);
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
- return globalThis.fetch(`${this.baseUrl}${path}`, {
234
- method: "POST",
235
- headers,
236
- body: JSON.stringify(body),
237
- signal
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 ?? ANTHROPIC_CAPABILITIES[this.model] ?? { contextLength: 2e5, maxOutputTokens: 4096 };
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.signal);
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 || 4096,
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, signal) {
669
- debugLogModelRequestBody("anthropic", path, body);
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
- if (signal?.aborted) {
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 ?? OLLAMA_CAPABILITIES[this.model] ?? { contextLength: 4096, maxOutputTokens: 2048 };
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.signal);
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
- ...params.temperature !== void 0 && { options: { temperature: params.temperature } }
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, signal) {
953
- debugLogModelRequestBody("ollama", path, body);
954
- return globalThis.fetch(`${this.baseUrl}${path}`, {
955
- method: "POST",
956
- headers: {
957
- "Content-Type": "application/json"
958
- },
959
- body: JSON.stringify(body),
960
- signal
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-742JTNYI.js.map
1012
- //# sourceMappingURL=chunk-742JTNYI.js.map
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