attocode 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -1
- package/README.md +180 -0
- package/dist/src/agent.d.ts +78 -1
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +639 -36
- package/dist/src/agent.js.map +1 -1
- package/dist/src/analysis/feedback-loop.d.ts +115 -0
- package/dist/src/analysis/feedback-loop.d.ts.map +1 -0
- package/dist/src/analysis/feedback-loop.js +226 -0
- package/dist/src/analysis/feedback-loop.js.map +1 -0
- package/dist/src/analysis/index.d.ts +9 -0
- package/dist/src/analysis/index.d.ts.map +1 -0
- package/dist/src/analysis/index.js +9 -0
- package/dist/src/analysis/index.js.map +1 -0
- package/dist/src/analysis/prompt-templates.d.ts +36 -0
- package/dist/src/analysis/prompt-templates.d.ts.map +1 -0
- package/dist/src/analysis/prompt-templates.js +198 -0
- package/dist/src/analysis/prompt-templates.js.map +1 -0
- package/dist/src/analysis/trace-summary.d.ts +56 -0
- package/dist/src/analysis/trace-summary.d.ts.map +1 -0
- package/dist/src/analysis/trace-summary.js +261 -0
- package/dist/src/analysis/trace-summary.js.map +1 -0
- package/dist/src/commands/agents-commands.d.ts +24 -0
- package/dist/src/commands/agents-commands.d.ts.map +1 -0
- package/dist/src/commands/agents-commands.js +284 -0
- package/dist/src/commands/agents-commands.js.map +1 -0
- package/dist/src/commands/handler.d.ts.map +1 -1
- package/dist/src/commands/handler.js +329 -21
- package/dist/src/commands/handler.js.map +1 -1
- package/dist/src/commands/init-commands.d.ts +35 -0
- package/dist/src/commands/init-commands.d.ts.map +1 -0
- package/dist/src/commands/init-commands.js +187 -0
- package/dist/src/commands/init-commands.js.map +1 -0
- package/dist/src/commands/skills-commands.d.ts +26 -0
- package/dist/src/commands/skills-commands.d.ts.map +1 -0
- package/dist/src/commands/skills-commands.js +309 -0
- package/dist/src/commands/skills-commands.js.map +1 -0
- package/dist/src/commands/types.d.ts +13 -2
- package/dist/src/commands/types.d.ts.map +1 -1
- package/dist/src/config.d.ts +3 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js.map +1 -1
- package/dist/src/defaults.d.ts +31 -2
- package/dist/src/defaults.d.ts.map +1 -1
- package/dist/src/defaults.js +69 -2
- package/dist/src/defaults.js.map +1 -1
- package/dist/src/errors/index.d.ts +233 -0
- package/dist/src/errors/index.d.ts.map +1 -0
- package/dist/src/errors/index.js +427 -0
- package/dist/src/errors/index.js.map +1 -0
- package/dist/src/integrations/agent-registry.d.ts +68 -2
- package/dist/src/integrations/agent-registry.d.ts.map +1 -1
- package/dist/src/integrations/agent-registry.js +230 -23
- package/dist/src/integrations/agent-registry.js.map +1 -1
- package/dist/src/integrations/auto-compaction.d.ts +33 -0
- package/dist/src/integrations/auto-compaction.d.ts.map +1 -1
- package/dist/src/integrations/auto-compaction.js +47 -3
- package/dist/src/integrations/auto-compaction.js.map +1 -1
- package/dist/src/integrations/cancellation.d.ts +5 -0
- package/dist/src/integrations/cancellation.d.ts.map +1 -1
- package/dist/src/integrations/cancellation.js +7 -0
- package/dist/src/integrations/cancellation.js.map +1 -1
- package/dist/src/integrations/capabilities.d.ts +160 -0
- package/dist/src/integrations/capabilities.d.ts.map +1 -0
- package/dist/src/integrations/capabilities.js +426 -0
- package/dist/src/integrations/capabilities.js.map +1 -0
- package/dist/src/integrations/context-engineering.d.ts +6 -1
- package/dist/src/integrations/context-engineering.d.ts.map +1 -1
- package/dist/src/integrations/context-engineering.js +7 -0
- package/dist/src/integrations/context-engineering.js.map +1 -1
- package/dist/src/integrations/dead-letter-queue.d.ts +208 -0
- package/dist/src/integrations/dead-letter-queue.d.ts.map +1 -0
- package/dist/src/integrations/dead-letter-queue.js +458 -0
- package/dist/src/integrations/dead-letter-queue.js.map +1 -0
- package/dist/src/integrations/health-check.d.ts +218 -0
- package/dist/src/integrations/health-check.d.ts.map +1 -0
- package/dist/src/integrations/health-check.js +400 -0
- package/dist/src/integrations/health-check.js.map +1 -0
- package/dist/src/integrations/index.d.ts +11 -2
- package/dist/src/integrations/index.d.ts.map +1 -1
- package/dist/src/integrations/index.js +19 -2
- package/dist/src/integrations/index.js.map +1 -1
- package/dist/src/integrations/mcp-client.d.ts +9 -0
- package/dist/src/integrations/mcp-client.d.ts.map +1 -1
- package/dist/src/integrations/mcp-client.js +49 -7
- package/dist/src/integrations/mcp-client.js.map +1 -1
- package/dist/src/integrations/openrouter-pricing.d.ts +28 -3
- package/dist/src/integrations/openrouter-pricing.d.ts.map +1 -1
- package/dist/src/integrations/openrouter-pricing.js +57 -16
- package/dist/src/integrations/openrouter-pricing.js.map +1 -1
- package/dist/src/integrations/retry.d.ts +131 -0
- package/dist/src/integrations/retry.d.ts.map +1 -0
- package/dist/src/integrations/retry.js +233 -0
- package/dist/src/integrations/retry.js.map +1 -0
- package/dist/src/integrations/skill-executor.d.ts +113 -0
- package/dist/src/integrations/skill-executor.d.ts.map +1 -0
- package/dist/src/integrations/skill-executor.js +270 -0
- package/dist/src/integrations/skill-executor.js.map +1 -0
- package/dist/src/integrations/skills.d.ts +98 -7
- package/dist/src/integrations/skills.d.ts.map +1 -1
- package/dist/src/integrations/skills.js +210 -11
- package/dist/src/integrations/skills.js.map +1 -1
- package/dist/src/integrations/sqlite-store.d.ts +42 -0
- package/dist/src/integrations/sqlite-store.d.ts.map +1 -1
- package/dist/src/integrations/sqlite-store.js +111 -0
- package/dist/src/integrations/sqlite-store.js.map +1 -1
- package/dist/src/main.js +88 -7
- package/dist/src/main.js.map +1 -1
- package/dist/src/modes/repl.d.ts.map +1 -1
- package/dist/src/modes/repl.js +37 -1
- package/dist/src/modes/repl.js.map +1 -1
- package/dist/src/modes/tui.d.ts.map +1 -1
- package/dist/src/modes/tui.js +46 -5
- package/dist/src/modes/tui.js.map +1 -1
- package/dist/src/modes.d.ts.map +1 -1
- package/dist/src/modes.js +10 -3
- package/dist/src/modes.js.map +1 -1
- package/dist/src/persistence/schema.d.ts +4 -0
- package/dist/src/persistence/schema.d.ts.map +1 -1
- package/dist/src/persistence/schema.js +49 -0
- package/dist/src/persistence/schema.js.map +1 -1
- package/dist/src/providers/adapters/anthropic.d.ts +24 -2
- package/dist/src/providers/adapters/anthropic.d.ts.map +1 -1
- package/dist/src/providers/adapters/anthropic.js +184 -0
- package/dist/src/providers/adapters/anthropic.js.map +1 -1
- package/dist/src/tools/bash.d.ts.map +1 -1
- package/dist/src/tools/bash.js +7 -4
- package/dist/src/tools/bash.js.map +1 -1
- package/dist/src/tools/file.d.ts.map +1 -1
- package/dist/src/tools/file.js +31 -10
- package/dist/src/tools/file.js.map +1 -1
- package/dist/src/tools/permission.d.ts +12 -0
- package/dist/src/tools/permission.d.ts.map +1 -1
- package/dist/src/tools/permission.js +136 -0
- package/dist/src/tools/permission.js.map +1 -1
- package/dist/src/tools/registry.d.ts +23 -1
- package/dist/src/tools/registry.d.ts.map +1 -1
- package/dist/src/tools/registry.js +77 -17
- package/dist/src/tools/registry.js.map +1 -1
- package/dist/src/tools/standard.d.ts.map +1 -1
- package/dist/src/tools/standard.js +8 -0
- package/dist/src/tools/standard.js.map +1 -1
- package/dist/src/tools/types.d.ts +20 -1
- package/dist/src/tools/types.d.ts.map +1 -1
- package/dist/src/tools/types.js.map +1 -1
- package/dist/src/tracing/trace-collector.d.ts +198 -2
- package/dist/src/tracing/trace-collector.d.ts.map +1 -1
- package/dist/src/tracing/trace-collector.js +315 -3
- package/dist/src/tracing/trace-collector.js.map +1 -1
- package/dist/src/tracing/types.d.ts +470 -2
- package/dist/src/tracing/types.d.ts.map +1 -1
- package/dist/src/tracing/types.js +25 -0
- package/dist/src/tracing/types.js.map +1 -1
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +292 -18
- package/dist/src/tui/app.js.map +1 -1
- package/dist/src/tui/index.d.ts +1 -0
- package/dist/src/tui/index.d.ts.map +1 -1
- package/dist/src/tui/index.js +2 -0
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/transparency-aggregator.d.ts +100 -0
- package/dist/src/tui/transparency-aggregator.d.ts.map +1 -0
- package/dist/src/tui/transparency-aggregator.js +234 -0
- package/dist/src/tui/transparency-aggregator.js.map +1 -0
- package/dist/src/types.d.ts +129 -0
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +6 -3
- package/dist/src/hello.d.ts +0 -2
- package/dist/src/hello.d.ts.map +0 -1
- package/dist/src/hello.js +0 -4
- package/dist/src/hello.js.map +0 -1
- package/dist/src/test-sqlite.d.ts +0 -2
- package/dist/src/test-sqlite.d.ts.map +0 -1
- package/dist/src/test-sqlite.js +0 -114
- package/dist/src/test-sqlite.js.map +0 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dead Letter Queue
|
|
3
|
+
*
|
|
4
|
+
* Persists failed operations for later retry or manual intervention.
|
|
5
|
+
* Integrates with SQLite store for durability across sessions.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const dlq = createDeadLetterQueue(db);
|
|
10
|
+
*
|
|
11
|
+
* // On failure, add to DLQ
|
|
12
|
+
* await dlq.add({
|
|
13
|
+
* operation: 'tool:bash',
|
|
14
|
+
* args: { command: 'npm install' },
|
|
15
|
+
* error: new Error('ETIMEDOUT'),
|
|
16
|
+
* sessionId: 'session-123',
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // At session start, drain pending items
|
|
20
|
+
* const pending = await dlq.getPending();
|
|
21
|
+
* for (const item of pending) {
|
|
22
|
+
* const success = await retry(item);
|
|
23
|
+
* if (success) await dlq.resolve(item.id);
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
import type Database from 'better-sqlite3';
|
|
28
|
+
import { ErrorCategory, type AgentError } from '../errors/index.js';
|
|
29
|
+
/**
|
|
30
|
+
* Status of a dead letter item.
|
|
31
|
+
*/
|
|
32
|
+
export type DeadLetterStatus = 'pending' | 'retrying' | 'resolved' | 'abandoned';
|
|
33
|
+
/**
|
|
34
|
+
* A failed operation stored in the dead letter queue.
|
|
35
|
+
*/
|
|
36
|
+
export interface DeadLetterItem {
|
|
37
|
+
/** Unique ID */
|
|
38
|
+
id: string;
|
|
39
|
+
/** Session ID (if associated with a session) */
|
|
40
|
+
sessionId?: string;
|
|
41
|
+
/** Operation type (e.g., 'tool:bash', 'mcp:playwright:click') */
|
|
42
|
+
operation: string;
|
|
43
|
+
/** Operation arguments (serialized JSON) */
|
|
44
|
+
args: string;
|
|
45
|
+
/** Error message */
|
|
46
|
+
error: string;
|
|
47
|
+
/** Error category for recovery decisions */
|
|
48
|
+
category: ErrorCategory;
|
|
49
|
+
/** Number of retry attempts made */
|
|
50
|
+
attempts: number;
|
|
51
|
+
/** Maximum retry attempts before abandoning */
|
|
52
|
+
maxAttempts: number;
|
|
53
|
+
/** Timestamp of last retry attempt */
|
|
54
|
+
lastAttempt: Date;
|
|
55
|
+
/** Timestamp for next retry (if scheduled) */
|
|
56
|
+
nextRetry?: Date;
|
|
57
|
+
/** Additional metadata */
|
|
58
|
+
metadata?: Record<string, unknown>;
|
|
59
|
+
/** Current status */
|
|
60
|
+
status: DeadLetterStatus;
|
|
61
|
+
/** When the item was created */
|
|
62
|
+
createdAt: Date;
|
|
63
|
+
/** When the item was resolved (if resolved) */
|
|
64
|
+
resolvedAt?: Date;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Input for adding a dead letter.
|
|
68
|
+
*/
|
|
69
|
+
export interface AddDeadLetterInput {
|
|
70
|
+
/** Operation type */
|
|
71
|
+
operation: string;
|
|
72
|
+
/** Operation arguments */
|
|
73
|
+
args: unknown;
|
|
74
|
+
/** Error that caused the failure */
|
|
75
|
+
error: Error | AgentError;
|
|
76
|
+
/** Associated session ID */
|
|
77
|
+
sessionId?: string;
|
|
78
|
+
/** Maximum retry attempts (default: 3) */
|
|
79
|
+
maxAttempts?: number;
|
|
80
|
+
/** Additional metadata */
|
|
81
|
+
metadata?: Record<string, unknown>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Options for querying the dead letter queue.
|
|
85
|
+
*/
|
|
86
|
+
export interface DeadLetterQueryOptions {
|
|
87
|
+
/** Filter by status */
|
|
88
|
+
status?: DeadLetterStatus;
|
|
89
|
+
/** Filter by operation type */
|
|
90
|
+
operation?: string;
|
|
91
|
+
/** Filter by session ID */
|
|
92
|
+
sessionId?: string;
|
|
93
|
+
/** Only items ready for retry (nextRetry <= now) */
|
|
94
|
+
readyForRetry?: boolean;
|
|
95
|
+
/** Limit number of results */
|
|
96
|
+
limit?: number;
|
|
97
|
+
/** Order by field */
|
|
98
|
+
orderBy?: 'createdAt' | 'lastAttempt' | 'nextRetry';
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Dead letter queue statistics.
|
|
102
|
+
*/
|
|
103
|
+
export interface DeadLetterStats {
|
|
104
|
+
total: number;
|
|
105
|
+
pending: number;
|
|
106
|
+
retrying: number;
|
|
107
|
+
resolved: number;
|
|
108
|
+
abandoned: number;
|
|
109
|
+
byOperation: Record<string, number>;
|
|
110
|
+
byCategory: Record<string, number>;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Dead letter queue event types.
|
|
114
|
+
*/
|
|
115
|
+
export type DeadLetterEvent = {
|
|
116
|
+
type: 'item.added';
|
|
117
|
+
item: DeadLetterItem;
|
|
118
|
+
} | {
|
|
119
|
+
type: 'item.retrying';
|
|
120
|
+
item: DeadLetterItem;
|
|
121
|
+
} | {
|
|
122
|
+
type: 'item.resolved';
|
|
123
|
+
item: DeadLetterItem;
|
|
124
|
+
} | {
|
|
125
|
+
type: 'item.abandoned';
|
|
126
|
+
item: DeadLetterItem;
|
|
127
|
+
} | {
|
|
128
|
+
type: 'item.deleted';
|
|
129
|
+
id: string;
|
|
130
|
+
};
|
|
131
|
+
export type DeadLetterEventListener = (event: DeadLetterEvent) => void;
|
|
132
|
+
/**
|
|
133
|
+
* Dead letter queue backed by SQLite.
|
|
134
|
+
*/
|
|
135
|
+
export declare class DeadLetterQueue {
|
|
136
|
+
private db;
|
|
137
|
+
private listeners;
|
|
138
|
+
private stmts?;
|
|
139
|
+
constructor(db: Database.Database);
|
|
140
|
+
private prepareStatements;
|
|
141
|
+
/**
|
|
142
|
+
* Check if DLQ is available (table exists).
|
|
143
|
+
*/
|
|
144
|
+
isAvailable(): boolean;
|
|
145
|
+
/**
|
|
146
|
+
* Add a failed operation to the dead letter queue.
|
|
147
|
+
*/
|
|
148
|
+
add(input: AddDeadLetterInput): Promise<DeadLetterItem>;
|
|
149
|
+
/**
|
|
150
|
+
* Get a dead letter item by ID.
|
|
151
|
+
*/
|
|
152
|
+
get(id: string): DeadLetterItem | null;
|
|
153
|
+
/**
|
|
154
|
+
* Get pending items ready for retry.
|
|
155
|
+
*/
|
|
156
|
+
getPending(options?: DeadLetterQueryOptions): DeadLetterItem[];
|
|
157
|
+
/**
|
|
158
|
+
* Query dead letters with filters.
|
|
159
|
+
*/
|
|
160
|
+
query(options?: DeadLetterQueryOptions): DeadLetterItem[];
|
|
161
|
+
/**
|
|
162
|
+
* Mark an item as being retried.
|
|
163
|
+
*/
|
|
164
|
+
markRetrying(id: string): void;
|
|
165
|
+
/**
|
|
166
|
+
* Mark an item as resolved (successful retry).
|
|
167
|
+
*/
|
|
168
|
+
resolve(id: string): void;
|
|
169
|
+
/**
|
|
170
|
+
* Mark an item as abandoned (max retries exceeded or non-recoverable).
|
|
171
|
+
*/
|
|
172
|
+
abandon(id: string): void;
|
|
173
|
+
/**
|
|
174
|
+
* Return an item to pending status after a failed retry.
|
|
175
|
+
*/
|
|
176
|
+
returnToPending(id: string): void;
|
|
177
|
+
/**
|
|
178
|
+
* Delete an item from the queue.
|
|
179
|
+
*/
|
|
180
|
+
delete(id: string): void;
|
|
181
|
+
/**
|
|
182
|
+
* Get queue statistics.
|
|
183
|
+
*/
|
|
184
|
+
getStats(): DeadLetterStats;
|
|
185
|
+
/**
|
|
186
|
+
* Cleanup old resolved/abandoned items.
|
|
187
|
+
*/
|
|
188
|
+
cleanup(olderThanDays?: number): number;
|
|
189
|
+
/**
|
|
190
|
+
* Add an event listener.
|
|
191
|
+
*/
|
|
192
|
+
on(listener: DeadLetterEventListener): () => void;
|
|
193
|
+
private emit;
|
|
194
|
+
/**
|
|
195
|
+
* Calculate next retry time based on attempts and error category.
|
|
196
|
+
*/
|
|
197
|
+
private calculateNextRetry;
|
|
198
|
+
private rowToItem;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Create a dead letter queue instance.
|
|
202
|
+
*/
|
|
203
|
+
export declare function createDeadLetterQueue(db: Database.Database): DeadLetterQueue;
|
|
204
|
+
/**
|
|
205
|
+
* Format dead letter stats for display.
|
|
206
|
+
*/
|
|
207
|
+
export declare function formatDeadLetterStats(stats: DeadLetterStats): string;
|
|
208
|
+
//# sourceMappingURL=dead-letter-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dead-letter-queue.d.ts","sourceRoot":"","sources":["../../../src/integrations/dead-letter-queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dead Letter Queue
|
|
3
|
+
*
|
|
4
|
+
* Persists failed operations for later retry or manual intervention.
|
|
5
|
+
* Integrates with SQLite store for durability across sessions.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const dlq = createDeadLetterQueue(db);
|
|
10
|
+
*
|
|
11
|
+
* // On failure, add to DLQ
|
|
12
|
+
* await dlq.add({
|
|
13
|
+
* operation: 'tool:bash',
|
|
14
|
+
* args: { command: 'npm install' },
|
|
15
|
+
* error: new Error('ETIMEDOUT'),
|
|
16
|
+
* sessionId: 'session-123',
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // At session start, drain pending items
|
|
20
|
+
* const pending = await dlq.getPending();
|
|
21
|
+
* for (const item of pending) {
|
|
22
|
+
* const success = await retry(item);
|
|
23
|
+
* if (success) await dlq.resolve(item.id);
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
import { randomUUID } from 'node:crypto';
|
|
28
|
+
import { ErrorCategory, categorizeError } from '../errors/index.js';
|
|
29
|
+
// =============================================================================
|
|
30
|
+
// DEAD LETTER QUEUE IMPLEMENTATION
|
|
31
|
+
// =============================================================================
|
|
32
|
+
/**
|
|
33
|
+
* Dead letter queue backed by SQLite.
|
|
34
|
+
*/
|
|
35
|
+
export class DeadLetterQueue {
|
|
36
|
+
db;
|
|
37
|
+
listeners = new Set();
|
|
38
|
+
stmts;
|
|
39
|
+
constructor(db) {
|
|
40
|
+
this.db = db;
|
|
41
|
+
this.prepareStatements();
|
|
42
|
+
}
|
|
43
|
+
prepareStatements() {
|
|
44
|
+
// Check if table exists
|
|
45
|
+
const tableExists = this.db
|
|
46
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='dead_letters'")
|
|
47
|
+
.get();
|
|
48
|
+
if (!tableExists) {
|
|
49
|
+
return; // Table not yet created - will be available after migration
|
|
50
|
+
}
|
|
51
|
+
this.stmts = {
|
|
52
|
+
insert: this.db.prepare(`
|
|
53
|
+
INSERT INTO dead_letters (
|
|
54
|
+
id, session_id, operation, args, error, category,
|
|
55
|
+
attempts, max_attempts, last_attempt, next_retry,
|
|
56
|
+
metadata, status, created_at
|
|
57
|
+
) VALUES (
|
|
58
|
+
@id, @sessionId, @operation, @args, @error, @category,
|
|
59
|
+
@attempts, @maxAttempts, @lastAttempt, @nextRetry,
|
|
60
|
+
@metadata, @status, @createdAt
|
|
61
|
+
)
|
|
62
|
+
`),
|
|
63
|
+
update: this.db.prepare(`
|
|
64
|
+
UPDATE dead_letters SET
|
|
65
|
+
attempts = @attempts,
|
|
66
|
+
last_attempt = @lastAttempt,
|
|
67
|
+
next_retry = @nextRetry,
|
|
68
|
+
status = @status,
|
|
69
|
+
resolved_at = @resolvedAt
|
|
70
|
+
WHERE id = @id
|
|
71
|
+
`),
|
|
72
|
+
get: this.db.prepare('SELECT * FROM dead_letters WHERE id = ?'),
|
|
73
|
+
delete: this.db.prepare('DELETE FROM dead_letters WHERE id = ?'),
|
|
74
|
+
list: this.db.prepare('SELECT * FROM dead_letters ORDER BY created_at DESC'),
|
|
75
|
+
stats: this.db.prepare(`
|
|
76
|
+
SELECT
|
|
77
|
+
status,
|
|
78
|
+
operation,
|
|
79
|
+
category,
|
|
80
|
+
COUNT(*) as count
|
|
81
|
+
FROM dead_letters
|
|
82
|
+
GROUP BY status, operation, category
|
|
83
|
+
`),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Check if DLQ is available (table exists).
|
|
88
|
+
*/
|
|
89
|
+
isAvailable() {
|
|
90
|
+
return this.stmts !== undefined;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Add a failed operation to the dead letter queue.
|
|
94
|
+
*/
|
|
95
|
+
async add(input) {
|
|
96
|
+
if (!this.stmts) {
|
|
97
|
+
throw new Error('Dead letter queue not available - migration required');
|
|
98
|
+
}
|
|
99
|
+
const { category } = input.error instanceof Error
|
|
100
|
+
? categorizeError(input.error)
|
|
101
|
+
: { category: ErrorCategory.INTERNAL };
|
|
102
|
+
const item = {
|
|
103
|
+
id: randomUUID(),
|
|
104
|
+
sessionId: input.sessionId,
|
|
105
|
+
operation: input.operation,
|
|
106
|
+
args: JSON.stringify(input.args),
|
|
107
|
+
error: input.error.message,
|
|
108
|
+
category,
|
|
109
|
+
attempts: 1,
|
|
110
|
+
maxAttempts: input.maxAttempts ?? 3,
|
|
111
|
+
lastAttempt: new Date(),
|
|
112
|
+
nextRetry: this.calculateNextRetry(1, category),
|
|
113
|
+
metadata: input.metadata,
|
|
114
|
+
status: 'pending',
|
|
115
|
+
createdAt: new Date(),
|
|
116
|
+
};
|
|
117
|
+
this.stmts.insert.run({
|
|
118
|
+
id: item.id,
|
|
119
|
+
sessionId: item.sessionId ?? null,
|
|
120
|
+
operation: item.operation,
|
|
121
|
+
args: item.args,
|
|
122
|
+
error: item.error,
|
|
123
|
+
category: item.category,
|
|
124
|
+
attempts: item.attempts,
|
|
125
|
+
maxAttempts: item.maxAttempts,
|
|
126
|
+
lastAttempt: item.lastAttempt.toISOString(),
|
|
127
|
+
nextRetry: item.nextRetry?.toISOString() ?? null,
|
|
128
|
+
metadata: item.metadata ? JSON.stringify(item.metadata) : null,
|
|
129
|
+
status: item.status,
|
|
130
|
+
createdAt: item.createdAt.toISOString(),
|
|
131
|
+
});
|
|
132
|
+
this.emit({ type: 'item.added', item });
|
|
133
|
+
return item;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Get a dead letter item by ID.
|
|
137
|
+
*/
|
|
138
|
+
get(id) {
|
|
139
|
+
if (!this.stmts)
|
|
140
|
+
return null;
|
|
141
|
+
const row = this.stmts.get.get(id);
|
|
142
|
+
return row ? this.rowToItem(row) : null;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get pending items ready for retry.
|
|
146
|
+
*/
|
|
147
|
+
getPending(options = {}) {
|
|
148
|
+
if (!this.stmts)
|
|
149
|
+
return [];
|
|
150
|
+
const conditions = ["status = 'pending'"];
|
|
151
|
+
const params = {};
|
|
152
|
+
if (options.operation) {
|
|
153
|
+
conditions.push('operation = @operation');
|
|
154
|
+
params.operation = options.operation;
|
|
155
|
+
}
|
|
156
|
+
if (options.sessionId) {
|
|
157
|
+
conditions.push('session_id = @sessionId');
|
|
158
|
+
params.sessionId = options.sessionId;
|
|
159
|
+
}
|
|
160
|
+
if (options.readyForRetry !== false) {
|
|
161
|
+
conditions.push('(next_retry IS NULL OR next_retry <= @now)');
|
|
162
|
+
params.now = new Date().toISOString();
|
|
163
|
+
}
|
|
164
|
+
const orderBy = options.orderBy ?? 'createdAt';
|
|
165
|
+
const orderCol = orderBy === 'createdAt' ? 'created_at'
|
|
166
|
+
: orderBy === 'lastAttempt' ? 'last_attempt'
|
|
167
|
+
: 'next_retry';
|
|
168
|
+
const limit = options.limit ?? 100;
|
|
169
|
+
const sql = `
|
|
170
|
+
SELECT * FROM dead_letters
|
|
171
|
+
WHERE ${conditions.join(' AND ')}
|
|
172
|
+
ORDER BY ${orderCol} ASC
|
|
173
|
+
LIMIT ${limit}
|
|
174
|
+
`;
|
|
175
|
+
const rows = this.db.prepare(sql).all(params);
|
|
176
|
+
return rows.map(row => this.rowToItem(row));
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Query dead letters with filters.
|
|
180
|
+
*/
|
|
181
|
+
query(options = {}) {
|
|
182
|
+
if (!this.stmts)
|
|
183
|
+
return [];
|
|
184
|
+
const conditions = [];
|
|
185
|
+
const params = {};
|
|
186
|
+
if (options.status) {
|
|
187
|
+
conditions.push('status = @status');
|
|
188
|
+
params.status = options.status;
|
|
189
|
+
}
|
|
190
|
+
if (options.operation) {
|
|
191
|
+
conditions.push('operation = @operation');
|
|
192
|
+
params.operation = options.operation;
|
|
193
|
+
}
|
|
194
|
+
if (options.sessionId) {
|
|
195
|
+
conditions.push('session_id = @sessionId');
|
|
196
|
+
params.sessionId = options.sessionId;
|
|
197
|
+
}
|
|
198
|
+
if (options.readyForRetry) {
|
|
199
|
+
conditions.push("status = 'pending' AND (next_retry IS NULL OR next_retry <= @now)");
|
|
200
|
+
params.now = new Date().toISOString();
|
|
201
|
+
}
|
|
202
|
+
const orderBy = options.orderBy ?? 'createdAt';
|
|
203
|
+
const orderCol = orderBy === 'createdAt' ? 'created_at'
|
|
204
|
+
: orderBy === 'lastAttempt' ? 'last_attempt'
|
|
205
|
+
: 'next_retry';
|
|
206
|
+
const limit = options.limit ?? 100;
|
|
207
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
208
|
+
const sql = `
|
|
209
|
+
SELECT * FROM dead_letters
|
|
210
|
+
${whereClause}
|
|
211
|
+
ORDER BY ${orderCol} DESC
|
|
212
|
+
LIMIT ${limit}
|
|
213
|
+
`;
|
|
214
|
+
const rows = this.db.prepare(sql).all(params);
|
|
215
|
+
return rows.map(row => this.rowToItem(row));
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Mark an item as being retried.
|
|
219
|
+
*/
|
|
220
|
+
markRetrying(id) {
|
|
221
|
+
if (!this.stmts)
|
|
222
|
+
return;
|
|
223
|
+
const item = this.get(id);
|
|
224
|
+
if (!item)
|
|
225
|
+
return;
|
|
226
|
+
const now = new Date();
|
|
227
|
+
this.stmts.update.run({
|
|
228
|
+
id,
|
|
229
|
+
attempts: item.attempts + 1,
|
|
230
|
+
lastAttempt: now.toISOString(),
|
|
231
|
+
nextRetry: this.calculateNextRetry(item.attempts + 1, item.category)?.toISOString() ?? null,
|
|
232
|
+
status: 'retrying',
|
|
233
|
+
resolvedAt: null,
|
|
234
|
+
});
|
|
235
|
+
this.emit({ type: 'item.retrying', item: { ...item, status: 'retrying' } });
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Mark an item as resolved (successful retry).
|
|
239
|
+
*/
|
|
240
|
+
resolve(id) {
|
|
241
|
+
if (!this.stmts)
|
|
242
|
+
return;
|
|
243
|
+
const item = this.get(id);
|
|
244
|
+
if (!item)
|
|
245
|
+
return;
|
|
246
|
+
const now = new Date();
|
|
247
|
+
this.stmts.update.run({
|
|
248
|
+
id,
|
|
249
|
+
attempts: item.attempts,
|
|
250
|
+
lastAttempt: item.lastAttempt.toISOString(),
|
|
251
|
+
nextRetry: null,
|
|
252
|
+
status: 'resolved',
|
|
253
|
+
resolvedAt: now.toISOString(),
|
|
254
|
+
});
|
|
255
|
+
this.emit({ type: 'item.resolved', item: { ...item, status: 'resolved', resolvedAt: now } });
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Mark an item as abandoned (max retries exceeded or non-recoverable).
|
|
259
|
+
*/
|
|
260
|
+
abandon(id) {
|
|
261
|
+
if (!this.stmts)
|
|
262
|
+
return;
|
|
263
|
+
const item = this.get(id);
|
|
264
|
+
if (!item)
|
|
265
|
+
return;
|
|
266
|
+
this.stmts.update.run({
|
|
267
|
+
id,
|
|
268
|
+
attempts: item.attempts,
|
|
269
|
+
lastAttempt: item.lastAttempt.toISOString(),
|
|
270
|
+
nextRetry: null,
|
|
271
|
+
status: 'abandoned',
|
|
272
|
+
resolvedAt: new Date().toISOString(),
|
|
273
|
+
});
|
|
274
|
+
this.emit({ type: 'item.abandoned', item: { ...item, status: 'abandoned' } });
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Return an item to pending status after a failed retry.
|
|
278
|
+
*/
|
|
279
|
+
returnToPending(id) {
|
|
280
|
+
if (!this.stmts)
|
|
281
|
+
return;
|
|
282
|
+
const item = this.get(id);
|
|
283
|
+
if (!item)
|
|
284
|
+
return;
|
|
285
|
+
// Check if max attempts reached
|
|
286
|
+
if (item.attempts >= item.maxAttempts) {
|
|
287
|
+
this.abandon(id);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const now = new Date();
|
|
291
|
+
this.stmts.update.run({
|
|
292
|
+
id,
|
|
293
|
+
attempts: item.attempts,
|
|
294
|
+
lastAttempt: now.toISOString(),
|
|
295
|
+
nextRetry: this.calculateNextRetry(item.attempts, item.category)?.toISOString() ?? null,
|
|
296
|
+
status: 'pending',
|
|
297
|
+
resolvedAt: null,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Delete an item from the queue.
|
|
302
|
+
*/
|
|
303
|
+
delete(id) {
|
|
304
|
+
if (!this.stmts)
|
|
305
|
+
return;
|
|
306
|
+
this.stmts.delete.run(id);
|
|
307
|
+
this.emit({ type: 'item.deleted', id });
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Get queue statistics.
|
|
311
|
+
*/
|
|
312
|
+
getStats() {
|
|
313
|
+
if (!this.stmts) {
|
|
314
|
+
return {
|
|
315
|
+
total: 0,
|
|
316
|
+
pending: 0,
|
|
317
|
+
retrying: 0,
|
|
318
|
+
resolved: 0,
|
|
319
|
+
abandoned: 0,
|
|
320
|
+
byOperation: {},
|
|
321
|
+
byCategory: {},
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
const rows = this.stmts.stats.all();
|
|
325
|
+
const stats = {
|
|
326
|
+
total: 0,
|
|
327
|
+
pending: 0,
|
|
328
|
+
retrying: 0,
|
|
329
|
+
resolved: 0,
|
|
330
|
+
abandoned: 0,
|
|
331
|
+
byOperation: {},
|
|
332
|
+
byCategory: {},
|
|
333
|
+
};
|
|
334
|
+
for (const row of rows) {
|
|
335
|
+
const count = row.count;
|
|
336
|
+
stats.total += count;
|
|
337
|
+
// Count by status
|
|
338
|
+
if (row.status === 'pending')
|
|
339
|
+
stats.pending += count;
|
|
340
|
+
else if (row.status === 'retrying')
|
|
341
|
+
stats.retrying += count;
|
|
342
|
+
else if (row.status === 'resolved')
|
|
343
|
+
stats.resolved += count;
|
|
344
|
+
else if (row.status === 'abandoned')
|
|
345
|
+
stats.abandoned += count;
|
|
346
|
+
// Count by operation
|
|
347
|
+
stats.byOperation[row.operation] = (stats.byOperation[row.operation] || 0) + count;
|
|
348
|
+
// Count by category
|
|
349
|
+
stats.byCategory[row.category] = (stats.byCategory[row.category] || 0) + count;
|
|
350
|
+
}
|
|
351
|
+
return stats;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Cleanup old resolved/abandoned items.
|
|
355
|
+
*/
|
|
356
|
+
cleanup(olderThanDays = 7) {
|
|
357
|
+
if (!this.stmts)
|
|
358
|
+
return 0;
|
|
359
|
+
const cutoff = new Date();
|
|
360
|
+
cutoff.setDate(cutoff.getDate() - olderThanDays);
|
|
361
|
+
const result = this.db.prepare(`
|
|
362
|
+
DELETE FROM dead_letters
|
|
363
|
+
WHERE status IN ('resolved', 'abandoned')
|
|
364
|
+
AND resolved_at < ?
|
|
365
|
+
`).run(cutoff.toISOString());
|
|
366
|
+
return result.changes;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Add an event listener.
|
|
370
|
+
*/
|
|
371
|
+
on(listener) {
|
|
372
|
+
this.listeners.add(listener);
|
|
373
|
+
return () => this.listeners.delete(listener);
|
|
374
|
+
}
|
|
375
|
+
emit(event) {
|
|
376
|
+
for (const listener of this.listeners) {
|
|
377
|
+
try {
|
|
378
|
+
listener(event);
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
// Ignore listener errors
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Calculate next retry time based on attempts and error category.
|
|
387
|
+
*/
|
|
388
|
+
calculateNextRetry(attempts, category) {
|
|
389
|
+
// Don't retry permanent errors
|
|
390
|
+
if (category === ErrorCategory.PERMANENT || category === ErrorCategory.VALIDATION) {
|
|
391
|
+
return undefined;
|
|
392
|
+
}
|
|
393
|
+
// Exponential backoff: 1min, 5min, 15min, 30min, 1hr
|
|
394
|
+
const delays = [60, 300, 900, 1800, 3600]; // seconds
|
|
395
|
+
const delaySeconds = delays[Math.min(attempts - 1, delays.length - 1)];
|
|
396
|
+
const nextRetry = new Date();
|
|
397
|
+
nextRetry.setSeconds(nextRetry.getSeconds() + delaySeconds);
|
|
398
|
+
return nextRetry;
|
|
399
|
+
}
|
|
400
|
+
rowToItem(row) {
|
|
401
|
+
return {
|
|
402
|
+
id: row.id,
|
|
403
|
+
sessionId: row.session_id,
|
|
404
|
+
operation: row.operation,
|
|
405
|
+
args: row.args,
|
|
406
|
+
error: row.error,
|
|
407
|
+
category: row.category,
|
|
408
|
+
attempts: row.attempts,
|
|
409
|
+
maxAttempts: row.max_attempts,
|
|
410
|
+
lastAttempt: new Date(row.last_attempt),
|
|
411
|
+
nextRetry: row.next_retry ? new Date(row.next_retry) : undefined,
|
|
412
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined,
|
|
413
|
+
status: row.status,
|
|
414
|
+
createdAt: new Date(row.created_at),
|
|
415
|
+
resolvedAt: row.resolved_at ? new Date(row.resolved_at) : undefined,
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// =============================================================================
|
|
420
|
+
// FACTORY FUNCTIONS
|
|
421
|
+
// =============================================================================
|
|
422
|
+
/**
|
|
423
|
+
* Create a dead letter queue instance.
|
|
424
|
+
*/
|
|
425
|
+
export function createDeadLetterQueue(db) {
|
|
426
|
+
return new DeadLetterQueue(db);
|
|
427
|
+
}
|
|
428
|
+
// =============================================================================
|
|
429
|
+
// FORMATTING
|
|
430
|
+
// =============================================================================
|
|
431
|
+
/**
|
|
432
|
+
* Format dead letter stats for display.
|
|
433
|
+
*/
|
|
434
|
+
export function formatDeadLetterStats(stats) {
|
|
435
|
+
const lines = [];
|
|
436
|
+
lines.push(`Dead Letter Queue Statistics`);
|
|
437
|
+
lines.push(` Total: ${stats.total}`);
|
|
438
|
+
lines.push(` Pending: ${stats.pending}`);
|
|
439
|
+
lines.push(` Retrying: ${stats.retrying}`);
|
|
440
|
+
lines.push(` Resolved: ${stats.resolved}`);
|
|
441
|
+
lines.push(` Abandoned: ${stats.abandoned}`);
|
|
442
|
+
if (Object.keys(stats.byOperation).length > 0) {
|
|
443
|
+
lines.push('');
|
|
444
|
+
lines.push(' By Operation:');
|
|
445
|
+
for (const [op, count] of Object.entries(stats.byOperation)) {
|
|
446
|
+
lines.push(` ${op}: ${count}`);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
if (Object.keys(stats.byCategory).length > 0) {
|
|
450
|
+
lines.push('');
|
|
451
|
+
lines.push(' By Category:');
|
|
452
|
+
for (const [cat, count] of Object.entries(stats.byCategory)) {
|
|
453
|
+
lines.push(` ${cat}: ${count}`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return lines.join('\n');
|
|
457
|
+
}
|
|
458
|
+
//# sourceMappingURL=dead-letter-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dead-letter-queue.js","sourceRoot":"","sources":["../../../src/integrations/dead-letter-queue.ts"],"names":[],"mappings":"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"}
|