@shareai-lab/kode-sdk 2.7.1 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/core/agent/breakpoint-manager.js +36 -0
  2. package/dist/core/agent/message-queue.js +57 -0
  3. package/dist/core/agent/permission-manager.js +32 -0
  4. package/dist/core/agent/todo-manager.js +91 -0
  5. package/dist/core/agent/tool-runner.js +45 -0
  6. package/dist/core/agent.js +2035 -0
  7. package/dist/core/config.js +2 -0
  8. package/dist/core/context-manager.js +241 -0
  9. package/dist/core/errors.js +49 -0
  10. package/dist/core/events.js +329 -0
  11. package/dist/core/file-pool.d.ts +2 -0
  12. package/dist/core/file-pool.js +125 -0
  13. package/dist/core/hooks.js +71 -0
  14. package/dist/core/permission-modes.js +61 -0
  15. package/dist/core/pool.js +301 -0
  16. package/dist/core/room.js +57 -0
  17. package/dist/core/scheduler.js +58 -0
  18. package/dist/core/skills/index.js +20 -0
  19. package/dist/core/skills/management-manager.js +557 -0
  20. package/dist/core/skills/manager.js +243 -0
  21. package/dist/core/skills/operation-queue.js +113 -0
  22. package/dist/core/skills/sandbox-file-manager.js +183 -0
  23. package/dist/core/skills/types.js +9 -0
  24. package/dist/core/skills/xml-generator.js +70 -0
  25. package/dist/core/template.js +35 -0
  26. package/dist/core/time-bridge.js +100 -0
  27. package/dist/core/todo.js +89 -0
  28. package/dist/core/types.js +3 -0
  29. package/dist/index.js +148 -60461
  30. package/dist/infra/db/postgres/postgres-store.js +1073 -0
  31. package/dist/infra/db/sqlite/sqlite-store.js +800 -0
  32. package/dist/infra/e2b/e2b-fs.js +128 -0
  33. package/dist/infra/e2b/e2b-sandbox.js +156 -0
  34. package/dist/infra/e2b/e2b-template.js +105 -0
  35. package/dist/infra/e2b/index.js +9 -0
  36. package/dist/infra/e2b/types.js +2 -0
  37. package/dist/infra/provider.js +67 -0
  38. package/dist/infra/providers/anthropic.js +308 -0
  39. package/dist/infra/providers/core/errors.js +353 -0
  40. package/dist/infra/providers/core/fork.js +418 -0
  41. package/dist/infra/providers/core/index.js +76 -0
  42. package/dist/infra/providers/core/logger.js +191 -0
  43. package/dist/infra/providers/core/retry.js +189 -0
  44. package/dist/infra/providers/core/usage.js +376 -0
  45. package/dist/infra/providers/gemini.js +493 -0
  46. package/dist/infra/providers/index.js +83 -0
  47. package/dist/infra/providers/openai.js +662 -0
  48. package/dist/infra/providers/types.js +20 -0
  49. package/dist/infra/providers/utils.js +400 -0
  50. package/dist/infra/sandbox-factory.js +30 -0
  51. package/dist/infra/sandbox.js +243 -0
  52. package/dist/infra/store/factory.js +80 -0
  53. package/dist/infra/store/index.js +26 -0
  54. package/dist/infra/store/json-store.js +606 -0
  55. package/dist/infra/store/types.js +2 -0
  56. package/dist/infra/store.js +29 -0
  57. package/dist/tools/bash_kill/index.js +35 -0
  58. package/dist/tools/bash_kill/prompt.js +14 -0
  59. package/dist/tools/bash_logs/index.js +40 -0
  60. package/dist/tools/bash_logs/prompt.js +14 -0
  61. package/dist/tools/bash_run/index.js +61 -0
  62. package/dist/tools/bash_run/prompt.js +18 -0
  63. package/dist/tools/builtin.js +26 -0
  64. package/dist/tools/define.js +214 -0
  65. package/dist/tools/fs_edit/index.js +62 -0
  66. package/dist/tools/fs_edit/prompt.js +15 -0
  67. package/dist/tools/fs_glob/index.js +40 -0
  68. package/dist/tools/fs_glob/prompt.js +15 -0
  69. package/dist/tools/fs_grep/index.js +66 -0
  70. package/dist/tools/fs_grep/prompt.js +16 -0
  71. package/dist/tools/fs_multi_edit/index.js +106 -0
  72. package/dist/tools/fs_multi_edit/prompt.js +16 -0
  73. package/dist/tools/fs_read/index.js +40 -0
  74. package/dist/tools/fs_read/prompt.js +16 -0
  75. package/dist/tools/fs_write/index.js +40 -0
  76. package/dist/tools/fs_write/prompt.js +15 -0
  77. package/dist/tools/index.js +61 -0
  78. package/dist/tools/mcp.js +185 -0
  79. package/dist/tools/registry.js +26 -0
  80. package/dist/tools/scripts.js +205 -0
  81. package/dist/tools/skills.js +115 -0
  82. package/dist/tools/task_run/index.js +58 -0
  83. package/dist/tools/task_run/prompt.js +25 -0
  84. package/dist/tools/todo_read/index.js +29 -0
  85. package/dist/tools/todo_read/prompt.js +18 -0
  86. package/dist/tools/todo_write/index.js +42 -0
  87. package/dist/tools/todo_write/prompt.js +23 -0
  88. package/dist/tools/tool.js +211 -0
  89. package/dist/tools/toolkit.js +98 -0
  90. package/dist/tools/type-inference.js +207 -0
  91. package/dist/utils/agent-id.js +28 -0
  92. package/dist/utils/logger.js +44 -0
  93. package/dist/utils/session-id.js +64 -0
  94. package/package.json +7 -38
  95. package/dist/index.js.map +0 -7
  96. package/dist/index.mjs +0 -60385
  97. package/dist/index.mjs.map +0 -7
@@ -0,0 +1,418 @@
1
+ "use strict";
2
+ /**
3
+ * Fork Point Detection and Resume Support
4
+ *
5
+ * Provides utilities for detecting safe fork points in message history
6
+ * and preparing messages for resume across different providers.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.geminiResumeHandler = exports.openaiResponsesResumeHandler = exports.openaiChatResumeHandler = exports.qwenResumeHandler = exports.deepseekResumeHandler = exports.anthropicResumeHandler = void 0;
10
+ exports.findSafeForkPoints = findSafeForkPoints;
11
+ exports.getLastSafeForkPoint = getLastSafeForkPoint;
12
+ exports.serializeForResume = serializeForResume;
13
+ exports.getResumeHandler = getResumeHandler;
14
+ exports.prepareMessagesForResume = prepareMessagesForResume;
15
+ exports.validateMessagesForResume = validateMessagesForResume;
16
+ exports.canForkAt = canForkAt;
17
+ exports.forkAt = forkAt;
18
+ /**
19
+ * Find all safe fork points in a message sequence.
20
+ *
21
+ * Safe fork points are:
22
+ * 1. User messages
23
+ * 2. Assistant messages without tool_use
24
+ * 3. After a user message containing all tool_results for preceding tool_uses
25
+ */
26
+ function findSafeForkPoints(messages) {
27
+ const points = [];
28
+ for (let i = 0; i < messages.length; i++) {
29
+ const msg = messages[i];
30
+ const point = analyzeForkSafety(msg, i, messages);
31
+ points.push(point);
32
+ }
33
+ return points;
34
+ }
35
+ /**
36
+ * Analyze if a specific message index is a safe fork point.
37
+ */
38
+ function analyzeForkSafety(msg, index, messages) {
39
+ // User messages are always safe fork points
40
+ if (msg.role === 'user') {
41
+ // But check if this user message contains incomplete tool results
42
+ const prevMsg = messages[index - 1];
43
+ if (prevMsg?.role === 'assistant') {
44
+ const toolUseIds = getToolUseIds(prevMsg);
45
+ if (toolUseIds.length > 0) {
46
+ const resultIds = getToolResultIds(msg);
47
+ const allHaveResults = toolUseIds.every(id => resultIds.includes(id));
48
+ if (!allHaveResults) {
49
+ return {
50
+ messageIndex: index,
51
+ isSafe: false,
52
+ reason: 'User message does not contain all required tool_results',
53
+ };
54
+ }
55
+ }
56
+ }
57
+ return { messageIndex: index, isSafe: true };
58
+ }
59
+ // Assistant messages without tool_use are safe
60
+ if (msg.role === 'assistant') {
61
+ const hasToolUse = msg.content.some(b => b.type === 'tool_use');
62
+ if (!hasToolUse) {
63
+ return { messageIndex: index, isSafe: true };
64
+ }
65
+ // Check if all tool calls have results in the next message
66
+ const toolUseIds = getToolUseIds(msg);
67
+ const nextMsg = messages[index + 1];
68
+ if (nextMsg?.role === 'user') {
69
+ const resultIds = getToolResultIds(nextMsg);
70
+ const allHaveResults = toolUseIds.every(id => resultIds.includes(id));
71
+ if (allHaveResults) {
72
+ // The next user message (index + 1) is the safe fork point
73
+ return {
74
+ messageIndex: index,
75
+ isSafe: false,
76
+ reason: 'Fork at next message (after tool results)',
77
+ };
78
+ }
79
+ }
80
+ return {
81
+ messageIndex: index,
82
+ isSafe: false,
83
+ reason: 'Pending tool calls without results',
84
+ };
85
+ }
86
+ // System messages
87
+ if (msg.role === 'system') {
88
+ return { messageIndex: index, isSafe: true };
89
+ }
90
+ return { messageIndex: index, isSafe: false, reason: 'Unknown message role' };
91
+ }
92
+ /**
93
+ * Get the last safe fork point index.
94
+ */
95
+ function getLastSafeForkPoint(messages) {
96
+ const points = findSafeForkPoints(messages);
97
+ for (let i = points.length - 1; i >= 0; i--) {
98
+ if (points[i].isSafe) {
99
+ return points[i].messageIndex;
100
+ }
101
+ }
102
+ return -1; // No safe fork point found
103
+ }
104
+ /**
105
+ * Extract tool_use IDs from a message.
106
+ */
107
+ function getToolUseIds(msg) {
108
+ return msg.content
109
+ .filter((b) => b.type === 'tool_use')
110
+ .map(b => b.id);
111
+ }
112
+ /**
113
+ * Extract tool_result IDs from a message.
114
+ */
115
+ function getToolResultIds(msg) {
116
+ return msg.content
117
+ .filter((b) => b.type === 'tool_result')
118
+ .map(b => b.tool_use_id);
119
+ }
120
+ /**
121
+ * Serialize messages for persistence.
122
+ */
123
+ function serializeForResume(messages, options) {
124
+ return messages.map(msg => serializeMessage(msg, options));
125
+ }
126
+ /**
127
+ * Serialize a single message.
128
+ */
129
+ function serializeMessage(msg, options) {
130
+ const serialized = {
131
+ role: msg.role,
132
+ content: [],
133
+ metadata: msg.metadata,
134
+ };
135
+ for (const block of msg.content) {
136
+ const serializedBlock = serializeBlock(block, options);
137
+ if (serializedBlock) {
138
+ serialized.content.push(serializedBlock);
139
+ }
140
+ }
141
+ return serialized;
142
+ }
143
+ /**
144
+ * Serialize a content block based on options.
145
+ */
146
+ function serializeBlock(block, options) {
147
+ // Handle reasoning blocks based on transport
148
+ if (block.type === 'reasoning') {
149
+ switch (options.reasoningTransport) {
150
+ case 'provider':
151
+ // Keep as-is for providers that support it
152
+ return block;
153
+ case 'text':
154
+ // Convert to text block with <think> tags
155
+ return {
156
+ type: 'text',
157
+ text: `<think>${block.reasoning}</think>`,
158
+ };
159
+ case 'omit':
160
+ // Exclude from serialized output
161
+ return null;
162
+ }
163
+ }
164
+ // All other blocks pass through
165
+ return block;
166
+ }
167
+ // ============================================================================
168
+ // Provider-Specific Resume Handlers
169
+ // ============================================================================
170
+ /**
171
+ * Anthropic resume handler.
172
+ * Preserves thinking blocks with signatures for Claude 4+.
173
+ */
174
+ exports.anthropicResumeHandler = {
175
+ prepareForResume(messages) {
176
+ // Anthropic requires thinking blocks with signatures for Claude 4+
177
+ // Blocks without signatures will be ignored by the API
178
+ return messages.map(msg => {
179
+ if (msg.role !== 'assistant')
180
+ return msg;
181
+ // Keep all blocks, including reasoning
182
+ // The API will verify signatures and ignore invalid ones
183
+ return msg;
184
+ });
185
+ },
186
+ validateForResume(messages) {
187
+ const errors = [];
188
+ const warnings = [];
189
+ for (let i = 0; i < messages.length; i++) {
190
+ const msg = messages[i];
191
+ // Check tool_use has corresponding tool_result
192
+ if (msg.role === 'assistant') {
193
+ const toolUses = msg.content.filter(b => b.type === 'tool_use');
194
+ if (toolUses.length > 0 && i < messages.length - 1) {
195
+ const nextMsg = messages[i + 1];
196
+ if (nextMsg.role !== 'user') {
197
+ errors.push(`Tool use at index ${i} not followed by user message`);
198
+ }
199
+ else {
200
+ const resultIds = getToolResultIds(nextMsg);
201
+ const toolUseIds = getToolUseIds(msg);
202
+ const missing = toolUseIds.filter(id => !resultIds.includes(id));
203
+ if (missing.length > 0) {
204
+ errors.push(`Missing tool_results for tool_use IDs: ${missing.join(', ')}`);
205
+ }
206
+ }
207
+ }
208
+ }
209
+ // Check for reasoning without signatures
210
+ if (msg.role === 'assistant') {
211
+ const reasoningBlocks = msg.content.filter(b => b.type === 'reasoning');
212
+ for (const block of reasoningBlocks) {
213
+ if (block.type === 'reasoning' && !block.meta?.signature) {
214
+ warnings.push(`Reasoning block at index ${i} has no signature (may be ignored)`);
215
+ }
216
+ }
217
+ }
218
+ }
219
+ return {
220
+ valid: errors.length === 0,
221
+ errors,
222
+ warnings,
223
+ };
224
+ },
225
+ };
226
+ /**
227
+ * DeepSeek resume handler.
228
+ * CRITICAL: Must NOT include reasoning_content in message history.
229
+ */
230
+ exports.deepseekResumeHandler = {
231
+ prepareForResume(messages) {
232
+ // DeepSeek returns 400 if reasoning_content is included in next turn
233
+ // Only include content field (text blocks)
234
+ return messages.map(msg => {
235
+ if (msg.role !== 'assistant')
236
+ return msg;
237
+ // Filter out reasoning blocks entirely
238
+ const filteredBlocks = msg.content.filter(b => b.type !== 'reasoning');
239
+ return { ...msg, content: filteredBlocks };
240
+ });
241
+ },
242
+ validateForResume(messages) {
243
+ const errors = [];
244
+ // Check that reasoning is not included in non-last messages
245
+ for (let i = 0; i < messages.length - 1; i++) {
246
+ const msg = messages[i];
247
+ if (msg.role === 'assistant') {
248
+ const hasReasoning = msg.content.some(b => b.type === 'reasoning');
249
+ if (hasReasoning) {
250
+ errors.push(`DeepSeek: reasoning_content must not be included at index ${i} (returns 400 error)`);
251
+ }
252
+ }
253
+ }
254
+ return {
255
+ valid: errors.length === 0,
256
+ errors,
257
+ };
258
+ },
259
+ };
260
+ /**
261
+ * Qwen resume handler.
262
+ * Similar to DeepSeek - reasoning should be omitted.
263
+ */
264
+ exports.qwenResumeHandler = {
265
+ prepareForResume(messages) {
266
+ // Qwen: Similar to DeepSeek, reasoning_content should be omitted
267
+ return messages.map(msg => {
268
+ if (msg.role !== 'assistant')
269
+ return msg;
270
+ const filteredBlocks = msg.content.filter(b => b.type !== 'reasoning');
271
+ return { ...msg, content: filteredBlocks };
272
+ });
273
+ },
274
+ validateForResume(messages) {
275
+ // Less strict than DeepSeek, but still recommend omitting
276
+ return { valid: true, errors: [] };
277
+ },
278
+ };
279
+ /**
280
+ * OpenAI Chat resume handler.
281
+ * Reasoning is converted to text with <think> tags.
282
+ */
283
+ exports.openaiChatResumeHandler = {
284
+ prepareForResume(messages) {
285
+ return messages.map(msg => {
286
+ if (msg.role !== 'assistant')
287
+ return msg;
288
+ // Convert reasoning to text with <think> tags
289
+ const convertedBlocks = msg.content.map(block => {
290
+ if (block.type === 'reasoning') {
291
+ return {
292
+ type: 'text',
293
+ text: `<think>${block.reasoning}</think>`,
294
+ };
295
+ }
296
+ return block;
297
+ });
298
+ return { ...msg, content: convertedBlocks };
299
+ });
300
+ },
301
+ validateForResume(messages) {
302
+ return { valid: true, errors: [] };
303
+ },
304
+ };
305
+ /**
306
+ * OpenAI Responses API resume handler.
307
+ * Uses previous_response_id for state persistence.
308
+ */
309
+ exports.openaiResponsesResumeHandler = {
310
+ prepareForResume(messages) {
311
+ // Responses API handles state via previous_response_id
312
+ // Messages are passed normally
313
+ return messages;
314
+ },
315
+ validateForResume(messages) {
316
+ // Responses API manages state via previous_response_id
317
+ // This is typically passed in options, not in message metadata
318
+ return { valid: true, errors: [] };
319
+ },
320
+ };
321
+ /**
322
+ * Gemini resume handler.
323
+ * Preserves thoughtSignature for function calls.
324
+ */
325
+ exports.geminiResumeHandler = {
326
+ prepareForResume(messages) {
327
+ // Gemini: Preserve thoughtSignature for function call continuation
328
+ return messages.map(msg => {
329
+ if (msg.role !== 'assistant')
330
+ return msg;
331
+ // Keep reasoning blocks that have thoughtSignature
332
+ // Others can be omitted or converted
333
+ const processedBlocks = msg.content.map(block => {
334
+ if (block.type === 'reasoning') {
335
+ // Keep if has signature, otherwise omit
336
+ if (block.meta?.thoughtSignature) {
337
+ return block;
338
+ }
339
+ return null;
340
+ }
341
+ return block;
342
+ }).filter((b) => b !== null);
343
+ return { ...msg, content: processedBlocks };
344
+ });
345
+ },
346
+ validateForResume(messages) {
347
+ return { valid: true, errors: [] };
348
+ },
349
+ };
350
+ /**
351
+ * Get resume handler for a provider.
352
+ */
353
+ function getResumeHandler(provider) {
354
+ switch (provider) {
355
+ case 'anthropic':
356
+ return exports.anthropicResumeHandler;
357
+ case 'deepseek':
358
+ return exports.deepseekResumeHandler;
359
+ case 'qwen':
360
+ return exports.qwenResumeHandler;
361
+ case 'openai':
362
+ case 'openai-chat':
363
+ return exports.openaiChatResumeHandler;
364
+ case 'openai-responses':
365
+ return exports.openaiResponsesResumeHandler;
366
+ case 'gemini':
367
+ return exports.geminiResumeHandler;
368
+ default:
369
+ // Default handler - omit reasoning to be safe
370
+ return {
371
+ prepareForResume(messages) {
372
+ return messages.map(msg => {
373
+ if (msg.role !== 'assistant')
374
+ return msg;
375
+ const filtered = msg.content.filter(b => b.type !== 'reasoning');
376
+ return { ...msg, content: filtered };
377
+ });
378
+ },
379
+ validateForResume() {
380
+ return { valid: true, errors: [] };
381
+ },
382
+ };
383
+ }
384
+ }
385
+ /**
386
+ * Prepare messages for resume with a specific provider.
387
+ */
388
+ function prepareMessagesForResume(messages, provider) {
389
+ const handler = getResumeHandler(provider);
390
+ return handler.prepareForResume(messages);
391
+ }
392
+ /**
393
+ * Validate messages for resume with a specific provider.
394
+ */
395
+ function validateMessagesForResume(messages, provider) {
396
+ const handler = getResumeHandler(provider);
397
+ return handler.validateForResume(messages);
398
+ }
399
+ /**
400
+ * Check if a message sequence can be safely forked at a given index.
401
+ */
402
+ function canForkAt(messages, index) {
403
+ if (index < 0 || index >= messages.length) {
404
+ return false;
405
+ }
406
+ const points = findSafeForkPoints(messages);
407
+ return points[index]?.isSafe ?? false;
408
+ }
409
+ /**
410
+ * Fork messages at a given index.
411
+ * Returns messages up to and including the fork point.
412
+ */
413
+ function forkAt(messages, index) {
414
+ if (!canForkAt(messages, index)) {
415
+ throw new Error(`Cannot fork at index ${index} - not a safe fork point`);
416
+ }
417
+ return messages.slice(0, index + 1);
418
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ /**
3
+ * Core Provider Module
4
+ *
5
+ * Re-exports all core utilities for provider implementations.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.openaiChatResumeHandler = exports.qwenResumeHandler = exports.deepseekResumeHandler = exports.anthropicResumeHandler = exports.serializeForResume = exports.getLastSafeForkPoint = exports.findSafeForkPoints = exports.generateAuditId = exports.truncateContent = exports.redactSensitive = exports.createProviderLogger = exports.createConsoleLogger = exports.DEFAULT_DEBUG_CONFIG = exports.getRetryDelay = exports.shouldRetry = exports.createRetryWrapper = exports.withRetryAndTimeout = exports.withRetry = exports.AGGRESSIVE_RETRY_CONFIG = exports.DEFAULT_RETRY_CONFIG = exports.formatUsageString = exports.aggregateUsage = exports.normalizeDeepSeekUsage = exports.normalizeGeminiUsage = exports.normalizeOpenAIUsage = exports.normalizeAnthropicUsage = exports.calculateCost = exports.createEmptyUsage = exports.PROVIDER_PRICING = exports.isContentFilterError = exports.isContextLengthError = exports.isAuthError = exports.isRateLimitError = exports.isRetryableError = exports.parseProviderError = exports.ParseError = exports.StreamError = exports.ThinkingSignatureError = exports.ServiceUnavailableError = exports.QuotaExceededError = exports.ModelNotFoundError = exports.ContentFilterError = exports.NetworkError = exports.TimeoutError = exports.ServerError = exports.InvalidRequestError = exports.ContextLengthError = exports.AuthenticationError = exports.RateLimitError = exports.ProviderError = void 0;
9
+ exports.forkAt = exports.canForkAt = exports.validateMessagesForResume = exports.prepareMessagesForResume = exports.getResumeHandler = exports.geminiResumeHandler = exports.openaiResponsesResumeHandler = void 0;
10
+ // Error types and utilities
11
+ var errors_1 = require("./errors");
12
+ Object.defineProperty(exports, "ProviderError", { enumerable: true, get: function () { return errors_1.ProviderError; } });
13
+ Object.defineProperty(exports, "RateLimitError", { enumerable: true, get: function () { return errors_1.RateLimitError; } });
14
+ Object.defineProperty(exports, "AuthenticationError", { enumerable: true, get: function () { return errors_1.AuthenticationError; } });
15
+ Object.defineProperty(exports, "ContextLengthError", { enumerable: true, get: function () { return errors_1.ContextLengthError; } });
16
+ Object.defineProperty(exports, "InvalidRequestError", { enumerable: true, get: function () { return errors_1.InvalidRequestError; } });
17
+ Object.defineProperty(exports, "ServerError", { enumerable: true, get: function () { return errors_1.ServerError; } });
18
+ Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return errors_1.TimeoutError; } });
19
+ Object.defineProperty(exports, "NetworkError", { enumerable: true, get: function () { return errors_1.NetworkError; } });
20
+ Object.defineProperty(exports, "ContentFilterError", { enumerable: true, get: function () { return errors_1.ContentFilterError; } });
21
+ Object.defineProperty(exports, "ModelNotFoundError", { enumerable: true, get: function () { return errors_1.ModelNotFoundError; } });
22
+ Object.defineProperty(exports, "QuotaExceededError", { enumerable: true, get: function () { return errors_1.QuotaExceededError; } });
23
+ Object.defineProperty(exports, "ServiceUnavailableError", { enumerable: true, get: function () { return errors_1.ServiceUnavailableError; } });
24
+ Object.defineProperty(exports, "ThinkingSignatureError", { enumerable: true, get: function () { return errors_1.ThinkingSignatureError; } });
25
+ Object.defineProperty(exports, "StreamError", { enumerable: true, get: function () { return errors_1.StreamError; } });
26
+ Object.defineProperty(exports, "ParseError", { enumerable: true, get: function () { return errors_1.ParseError; } });
27
+ Object.defineProperty(exports, "parseProviderError", { enumerable: true, get: function () { return errors_1.parseProviderError; } });
28
+ Object.defineProperty(exports, "isRetryableError", { enumerable: true, get: function () { return errors_1.isRetryableError; } });
29
+ Object.defineProperty(exports, "isRateLimitError", { enumerable: true, get: function () { return errors_1.isRateLimitError; } });
30
+ Object.defineProperty(exports, "isAuthError", { enumerable: true, get: function () { return errors_1.isAuthError; } });
31
+ Object.defineProperty(exports, "isContextLengthError", { enumerable: true, get: function () { return errors_1.isContextLengthError; } });
32
+ Object.defineProperty(exports, "isContentFilterError", { enumerable: true, get: function () { return errors_1.isContentFilterError; } });
33
+ // Usage statistics and cost calculation
34
+ var usage_1 = require("./usage");
35
+ Object.defineProperty(exports, "PROVIDER_PRICING", { enumerable: true, get: function () { return usage_1.PROVIDER_PRICING; } });
36
+ Object.defineProperty(exports, "createEmptyUsage", { enumerable: true, get: function () { return usage_1.createEmptyUsage; } });
37
+ Object.defineProperty(exports, "calculateCost", { enumerable: true, get: function () { return usage_1.calculateCost; } });
38
+ Object.defineProperty(exports, "normalizeAnthropicUsage", { enumerable: true, get: function () { return usage_1.normalizeAnthropicUsage; } });
39
+ Object.defineProperty(exports, "normalizeOpenAIUsage", { enumerable: true, get: function () { return usage_1.normalizeOpenAIUsage; } });
40
+ Object.defineProperty(exports, "normalizeGeminiUsage", { enumerable: true, get: function () { return usage_1.normalizeGeminiUsage; } });
41
+ Object.defineProperty(exports, "normalizeDeepSeekUsage", { enumerable: true, get: function () { return usage_1.normalizeDeepSeekUsage; } });
42
+ Object.defineProperty(exports, "aggregateUsage", { enumerable: true, get: function () { return usage_1.aggregateUsage; } });
43
+ Object.defineProperty(exports, "formatUsageString", { enumerable: true, get: function () { return usage_1.formatUsageString; } });
44
+ // Retry strategy
45
+ var retry_1 = require("./retry");
46
+ Object.defineProperty(exports, "DEFAULT_RETRY_CONFIG", { enumerable: true, get: function () { return retry_1.DEFAULT_RETRY_CONFIG; } });
47
+ Object.defineProperty(exports, "AGGRESSIVE_RETRY_CONFIG", { enumerable: true, get: function () { return retry_1.AGGRESSIVE_RETRY_CONFIG; } });
48
+ Object.defineProperty(exports, "withRetry", { enumerable: true, get: function () { return retry_1.withRetry; } });
49
+ Object.defineProperty(exports, "withRetryAndTimeout", { enumerable: true, get: function () { return retry_1.withRetryAndTimeout; } });
50
+ Object.defineProperty(exports, "createRetryWrapper", { enumerable: true, get: function () { return retry_1.createRetryWrapper; } });
51
+ Object.defineProperty(exports, "shouldRetry", { enumerable: true, get: function () { return retry_1.shouldRetry; } });
52
+ Object.defineProperty(exports, "getRetryDelay", { enumerable: true, get: function () { return retry_1.getRetryDelay; } });
53
+ // Logging and debugging
54
+ var logger_1 = require("./logger");
55
+ Object.defineProperty(exports, "DEFAULT_DEBUG_CONFIG", { enumerable: true, get: function () { return logger_1.DEFAULT_DEBUG_CONFIG; } });
56
+ Object.defineProperty(exports, "createConsoleLogger", { enumerable: true, get: function () { return logger_1.createConsoleLogger; } });
57
+ Object.defineProperty(exports, "createProviderLogger", { enumerable: true, get: function () { return logger_1.createProviderLogger; } });
58
+ Object.defineProperty(exports, "redactSensitive", { enumerable: true, get: function () { return logger_1.redactSensitive; } });
59
+ Object.defineProperty(exports, "truncateContent", { enumerable: true, get: function () { return logger_1.truncateContent; } });
60
+ Object.defineProperty(exports, "generateAuditId", { enumerable: true, get: function () { return logger_1.generateAuditId; } });
61
+ // Fork point detection and resume
62
+ var fork_1 = require("./fork");
63
+ Object.defineProperty(exports, "findSafeForkPoints", { enumerable: true, get: function () { return fork_1.findSafeForkPoints; } });
64
+ Object.defineProperty(exports, "getLastSafeForkPoint", { enumerable: true, get: function () { return fork_1.getLastSafeForkPoint; } });
65
+ Object.defineProperty(exports, "serializeForResume", { enumerable: true, get: function () { return fork_1.serializeForResume; } });
66
+ Object.defineProperty(exports, "anthropicResumeHandler", { enumerable: true, get: function () { return fork_1.anthropicResumeHandler; } });
67
+ Object.defineProperty(exports, "deepseekResumeHandler", { enumerable: true, get: function () { return fork_1.deepseekResumeHandler; } });
68
+ Object.defineProperty(exports, "qwenResumeHandler", { enumerable: true, get: function () { return fork_1.qwenResumeHandler; } });
69
+ Object.defineProperty(exports, "openaiChatResumeHandler", { enumerable: true, get: function () { return fork_1.openaiChatResumeHandler; } });
70
+ Object.defineProperty(exports, "openaiResponsesResumeHandler", { enumerable: true, get: function () { return fork_1.openaiResponsesResumeHandler; } });
71
+ Object.defineProperty(exports, "geminiResumeHandler", { enumerable: true, get: function () { return fork_1.geminiResumeHandler; } });
72
+ Object.defineProperty(exports, "getResumeHandler", { enumerable: true, get: function () { return fork_1.getResumeHandler; } });
73
+ Object.defineProperty(exports, "prepareMessagesForResume", { enumerable: true, get: function () { return fork_1.prepareMessagesForResume; } });
74
+ Object.defineProperty(exports, "validateMessagesForResume", { enumerable: true, get: function () { return fork_1.validateMessagesForResume; } });
75
+ Object.defineProperty(exports, "canForkAt", { enumerable: true, get: function () { return fork_1.canForkAt; } });
76
+ Object.defineProperty(exports, "forkAt", { enumerable: true, get: function () { return fork_1.forkAt; } });
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ /**
3
+ * Logging and Debugging Module
4
+ *
5
+ * Unified logging interfaces for provider operations,
6
+ * request/response tracking, and audit trail.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.DEFAULT_DEBUG_CONFIG = void 0;
10
+ exports.createConsoleLogger = createConsoleLogger;
11
+ exports.createProviderLogger = createProviderLogger;
12
+ exports.redactSensitive = redactSensitive;
13
+ exports.truncateContent = truncateContent;
14
+ exports.generateAuditId = generateAuditId;
15
+ /**
16
+ * Default debug configuration.
17
+ */
18
+ exports.DEFAULT_DEBUG_CONFIG = {
19
+ verbose: false,
20
+ logRawRequests: false,
21
+ logRawResponses: false,
22
+ logThinking: false,
23
+ logTokenUsage: true,
24
+ logCache: true,
25
+ logRetries: true,
26
+ redactSensitive: true,
27
+ maxContentLength: 500,
28
+ };
29
+ /**
30
+ * Create a console-based logger.
31
+ */
32
+ function createConsoleLogger(context = {}, debugConfig = {}) {
33
+ const config = { ...exports.DEFAULT_DEBUG_CONFIG, ...debugConfig };
34
+ const log = (level, message, ctx) => {
35
+ if (!config.verbose && level === 'debug')
36
+ return;
37
+ const entry = {
38
+ level,
39
+ message,
40
+ timestamp: Date.now(),
41
+ context: { ...context, ...ctx },
42
+ };
43
+ const prefix = `[${level.toUpperCase()}]`;
44
+ const contextStr = Object.keys(entry.context || {}).length > 0
45
+ ? ` ${JSON.stringify(entry.context)}`
46
+ : '';
47
+ const output = `${prefix} ${message}${contextStr}`;
48
+ switch (level) {
49
+ case 'debug':
50
+ console.debug(output);
51
+ break;
52
+ case 'info':
53
+ console.info(output);
54
+ break;
55
+ case 'warn':
56
+ console.warn(output);
57
+ break;
58
+ case 'error':
59
+ console.error(output);
60
+ break;
61
+ }
62
+ };
63
+ return {
64
+ debug: (message, ctx) => log('debug', message, ctx),
65
+ info: (message, ctx) => log('info', message, ctx),
66
+ warn: (message, ctx) => log('warn', message, ctx),
67
+ error: (message, ctx) => log('error', message, ctx),
68
+ child: (childContext) => createConsoleLogger({ ...context, ...childContext }, debugConfig),
69
+ };
70
+ }
71
+ /**
72
+ * Create a provider logger with request/response tracking.
73
+ */
74
+ function createProviderLogger(provider, debugConfig = {}) {
75
+ const config = { ...exports.DEFAULT_DEBUG_CONFIG, ...debugConfig };
76
+ const base = createConsoleLogger({ provider }, debugConfig);
77
+ return {
78
+ ...base,
79
+ logRequest(request) {
80
+ if (!config.verbose)
81
+ return;
82
+ base.info('Provider request', {
83
+ model: request.model,
84
+ requestId: request.requestId,
85
+ messageCount: request.messageCount,
86
+ estimatedTokens: request.estimatedTokens,
87
+ streaming: request.streaming,
88
+ toolCount: request.toolCount,
89
+ });
90
+ },
91
+ logResponse(response, durationMs) {
92
+ if (config.logTokenUsage) {
93
+ base.info('Provider response', {
94
+ model: response.model,
95
+ requestId: response.requestId,
96
+ inputTokens: response.usage.inputTokens,
97
+ outputTokens: response.usage.outputTokens,
98
+ durationMs,
99
+ stopReason: response.stopReason,
100
+ });
101
+ }
102
+ },
103
+ logError(error) {
104
+ base.error('Provider error', {
105
+ code: error.code,
106
+ requestId: error.requestId,
107
+ retryable: error.retryable,
108
+ });
109
+ },
110
+ logStreamStart(requestId) {
111
+ if (config.verbose) {
112
+ base.debug('Stream started', { requestId });
113
+ }
114
+ },
115
+ logStreamChunk(requestId, chunkSize) {
116
+ if (config.verbose) {
117
+ base.debug('Stream chunk', { requestId, chunkSize });
118
+ }
119
+ },
120
+ logStreamEnd(requestId, totalChunks) {
121
+ if (config.verbose) {
122
+ base.debug('Stream ended', { requestId, totalChunks });
123
+ }
124
+ },
125
+ logCacheHit(tokens) {
126
+ if (config.logCache) {
127
+ base.info('Cache hit', { tokens });
128
+ }
129
+ },
130
+ logCacheWrite(tokens, ttl) {
131
+ if (config.logCache) {
132
+ base.info('Cache write', { tokens, ttl });
133
+ }
134
+ },
135
+ logRetry(attempt, delayMs, error) {
136
+ if (config.logRetries) {
137
+ base.warn('Retrying request', {
138
+ attempt,
139
+ delayMs,
140
+ errorCode: error.code,
141
+ });
142
+ }
143
+ },
144
+ child(childContext) {
145
+ return createProviderLogger(provider, debugConfig);
146
+ },
147
+ };
148
+ }
149
+ /**
150
+ * Redact sensitive data from an object.
151
+ */
152
+ function redactSensitive(obj) {
153
+ const sensitiveKeys = [
154
+ 'apiKey',
155
+ 'api_key',
156
+ 'authorization',
157
+ 'Authorization',
158
+ 'token',
159
+ 'secret',
160
+ 'password',
161
+ 'credential',
162
+ ];
163
+ const redacted = {};
164
+ for (const [key, value] of Object.entries(obj)) {
165
+ if (sensitiveKeys.some(k => key.toLowerCase().includes(k.toLowerCase()))) {
166
+ redacted[key] = '[REDACTED]';
167
+ }
168
+ else if (typeof value === 'object' && value !== null) {
169
+ redacted[key] = redactSensitive(value);
170
+ }
171
+ else {
172
+ redacted[key] = value;
173
+ }
174
+ }
175
+ return redacted;
176
+ }
177
+ /**
178
+ * Truncate content for logging.
179
+ */
180
+ function truncateContent(content, maxLength) {
181
+ if (content.length <= maxLength) {
182
+ return content;
183
+ }
184
+ return content.slice(0, maxLength) + `... [truncated, ${content.length - maxLength} more chars]`;
185
+ }
186
+ /**
187
+ * Generate unique audit ID.
188
+ */
189
+ function generateAuditId() {
190
+ return `audit_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
191
+ }