mcp-subagents-opencode 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +602 -0
- package/build/config/timeouts.d.ts +9 -0
- package/build/config/timeouts.d.ts.map +1 -0
- package/build/config/timeouts.js +18 -0
- package/build/config/timeouts.js.map +1 -0
- package/build/helpers.d.ts +6 -0
- package/build/helpers.d.ts.map +1 -0
- package/build/helpers.js +47 -0
- package/build/helpers.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +245 -0
- package/build/index.js.map +1 -0
- package/build/models.d.ts +32 -0
- package/build/models.d.ts.map +1 -0
- package/build/models.js +58 -0
- package/build/models.js.map +1 -0
- package/build/server/register-notifications.d.ts +3 -0
- package/build/server/register-notifications.d.ts.map +1 -0
- package/build/server/register-notifications.js +77 -0
- package/build/server/register-notifications.js.map +1 -0
- package/build/server/register-resources.d.ts +3 -0
- package/build/server/register-resources.d.ts.map +1 -0
- package/build/server/register-resources.js +210 -0
- package/build/server/register-resources.js.map +1 -0
- package/build/server/register-retry-execution.d.ts +2 -0
- package/build/server/register-retry-execution.d.ts.map +1 -0
- package/build/server/register-retry-execution.js +28 -0
- package/build/server/register-retry-execution.js.map +1 -0
- package/build/server/register-tasks.d.ts +3 -0
- package/build/server/register-tasks.d.ts.map +1 -0
- package/build/server/register-tasks.js +52 -0
- package/build/server/register-tasks.js.map +1 -0
- package/build/server/register-tools.d.ts +3 -0
- package/build/server/register-tools.d.ts.map +1 -0
- package/build/server/register-tools.js +32 -0
- package/build/server/register-tools.js.map +1 -0
- package/build/server/resource-helpers.d.ts +21 -0
- package/build/server/resource-helpers.d.ts.map +1 -0
- package/build/server/resource-helpers.js +84 -0
- package/build/server/resource-helpers.js.map +1 -0
- package/build/services/account-manager.d.ts +88 -0
- package/build/services/account-manager.d.ts.map +1 -0
- package/build/services/account-manager.js +239 -0
- package/build/services/account-manager.js.map +1 -0
- package/build/services/claude-code-runner.d.ts +15 -0
- package/build/services/claude-code-runner.d.ts.map +1 -0
- package/build/services/claude-code-runner.js +475 -0
- package/build/services/claude-code-runner.js.map +1 -0
- package/build/services/client-context.d.ts +31 -0
- package/build/services/client-context.d.ts.map +1 -0
- package/build/services/client-context.js +44 -0
- package/build/services/client-context.js.map +1 -0
- package/build/services/exhaustion-fallback.d.ts +27 -0
- package/build/services/exhaustion-fallback.d.ts.map +1 -0
- package/build/services/exhaustion-fallback.js +30 -0
- package/build/services/exhaustion-fallback.js.map +1 -0
- package/build/services/fallback-orchestrator.d.ts +16 -0
- package/build/services/fallback-orchestrator.d.ts.map +1 -0
- package/build/services/fallback-orchestrator.js +48 -0
- package/build/services/fallback-orchestrator.js.map +1 -0
- package/build/services/opencode-client.d.ts +40 -0
- package/build/services/opencode-client.d.ts.map +1 -0
- package/build/services/opencode-client.js +147 -0
- package/build/services/opencode-client.js.map +1 -0
- package/build/services/opencode-spawner.d.ts +56 -0
- package/build/services/opencode-spawner.d.ts.map +1 -0
- package/build/services/opencode-spawner.js +426 -0
- package/build/services/opencode-spawner.js.map +1 -0
- package/build/services/output-file.d.ts +24 -0
- package/build/services/output-file.d.ts.map +1 -0
- package/build/services/output-file.js +90 -0
- package/build/services/output-file.js.map +1 -0
- package/build/services/progress-registry.d.ts +12 -0
- package/build/services/progress-registry.d.ts.map +1 -0
- package/build/services/progress-registry.js +97 -0
- package/build/services/progress-registry.js.map +1 -0
- package/build/services/question-registry.d.ts +79 -0
- package/build/services/question-registry.d.ts.map +1 -0
- package/build/services/question-registry.js +249 -0
- package/build/services/question-registry.js.map +1 -0
- package/build/services/retry-queue.d.ts +41 -0
- package/build/services/retry-queue.d.ts.map +1 -0
- package/build/services/retry-queue.js +195 -0
- package/build/services/retry-queue.js.map +1 -0
- package/build/services/sdk-client-manager.d.ts +149 -0
- package/build/services/sdk-client-manager.d.ts.map +1 -0
- package/build/services/sdk-client-manager.js +632 -0
- package/build/services/sdk-client-manager.js.map +1 -0
- package/build/services/sdk-session-adapter.d.ts +203 -0
- package/build/services/sdk-session-adapter.d.ts.map +1 -0
- package/build/services/sdk-session-adapter.js +1088 -0
- package/build/services/sdk-session-adapter.js.map +1 -0
- package/build/services/sdk-spawner.d.ts +42 -0
- package/build/services/sdk-spawner.d.ts.map +1 -0
- package/build/services/sdk-spawner.js +488 -0
- package/build/services/sdk-spawner.js.map +1 -0
- package/build/services/session-hooks.d.ts +24 -0
- package/build/services/session-hooks.d.ts.map +1 -0
- package/build/services/session-hooks.js +130 -0
- package/build/services/session-hooks.js.map +1 -0
- package/build/services/session-snapshot.d.ts +19 -0
- package/build/services/session-snapshot.d.ts.map +1 -0
- package/build/services/session-snapshot.js +203 -0
- package/build/services/session-snapshot.js.map +1 -0
- package/build/services/subscription-registry.d.ts +12 -0
- package/build/services/subscription-registry.d.ts.map +1 -0
- package/build/services/subscription-registry.js +27 -0
- package/build/services/subscription-registry.js.map +1 -0
- package/build/services/task-manager.d.ts +150 -0
- package/build/services/task-manager.d.ts.map +1 -0
- package/build/services/task-manager.js +765 -0
- package/build/services/task-manager.js.map +1 -0
- package/build/services/task-persistence.d.ts +29 -0
- package/build/services/task-persistence.d.ts.map +1 -0
- package/build/services/task-persistence.js +159 -0
- package/build/services/task-persistence.js.map +1 -0
- package/build/services/task-status-mapper.d.ts +21 -0
- package/build/services/task-status-mapper.d.ts.map +1 -0
- package/build/services/task-status-mapper.js +171 -0
- package/build/services/task-status-mapper.js.map +1 -0
- package/build/templates/index.d.ts +22 -0
- package/build/templates/index.d.ts.map +1 -0
- package/build/templates/index.js +147 -0
- package/build/templates/index.js.map +1 -0
- package/build/templates/overlays/coder-csharp.mdx +58 -0
- package/build/templates/overlays/coder-go.mdx +53 -0
- package/build/templates/overlays/coder-java.mdx +54 -0
- package/build/templates/overlays/coder-kotlin.mdx +56 -0
- package/build/templates/overlays/coder-nextjs.mdx +65 -0
- package/build/templates/overlays/coder-python.mdx +53 -0
- package/build/templates/overlays/coder-react.mdx +55 -0
- package/build/templates/overlays/coder-ruby.mdx +59 -0
- package/build/templates/overlays/coder-rust.mdx +48 -0
- package/build/templates/overlays/coder-supabase.mdx +268 -0
- package/build/templates/overlays/coder-supastarter.mdx +313 -0
- package/build/templates/overlays/coder-swift.mdx +56 -0
- package/build/templates/overlays/coder-tauri.mdx +566 -0
- package/build/templates/overlays/coder-triggerdev.mdx +296 -0
- package/build/templates/overlays/coder-typescript.mdx +45 -0
- package/build/templates/overlays/coder-vue.mdx +62 -0
- package/build/templates/overlays/planner-architecture.mdx +78 -0
- package/build/templates/overlays/planner-bugfix.mdx +36 -0
- package/build/templates/overlays/planner-feature.mdx +38 -0
- package/build/templates/overlays/planner-migration.mdx +50 -0
- package/build/templates/overlays/planner-refactor.mdx +57 -0
- package/build/templates/overlays/researcher-library.mdx +59 -0
- package/build/templates/overlays/researcher-performance.mdx +68 -0
- package/build/templates/overlays/researcher-security.mdx +86 -0
- package/build/templates/overlays/tester-graphql.mdx +191 -0
- package/build/templates/overlays/tester-playwright.mdx +621 -0
- package/build/templates/overlays/tester-rest.mdx +101 -0
- package/build/templates/overlays/tester-suite.mdx +177 -0
- package/build/templates/super-coder.mdx +529 -0
- package/build/templates/super-planner.mdx +568 -0
- package/build/templates/super-researcher.mdx +406 -0
- package/build/templates/super-tester.mdx +243 -0
- package/build/tools/answer-question.d.ts +30 -0
- package/build/tools/answer-question.d.ts.map +1 -0
- package/build/tools/answer-question.js +108 -0
- package/build/tools/answer-question.js.map +1 -0
- package/build/tools/cancel-task.d.ts +44 -0
- package/build/tools/cancel-task.d.ts.map +1 -0
- package/build/tools/cancel-task.js +144 -0
- package/build/tools/cancel-task.js.map +1 -0
- package/build/tools/send-message.d.ts +39 -0
- package/build/tools/send-message.d.ts.map +1 -0
- package/build/tools/send-message.js +124 -0
- package/build/tools/send-message.js.map +1 -0
- package/build/tools/shared-spawn.d.ts +56 -0
- package/build/tools/shared-spawn.d.ts.map +1 -0
- package/build/tools/shared-spawn.js +114 -0
- package/build/tools/shared-spawn.js.map +1 -0
- package/build/tools/spawn-agent.d.ts +85 -0
- package/build/tools/spawn-agent.d.ts.map +1 -0
- package/build/tools/spawn-agent.js +133 -0
- package/build/tools/spawn-agent.js.map +1 -0
- package/build/tools/spawn-coder.d.ts +70 -0
- package/build/tools/spawn-coder.d.ts.map +1 -0
- package/build/tools/spawn-coder.js +71 -0
- package/build/tools/spawn-coder.js.map +1 -0
- package/build/tools/spawn-planner.d.ts +70 -0
- package/build/tools/spawn-planner.d.ts.map +1 -0
- package/build/tools/spawn-planner.js +71 -0
- package/build/tools/spawn-planner.js.map +1 -0
- package/build/tools/spawn-researcher.d.ts +70 -0
- package/build/tools/spawn-researcher.d.ts.map +1 -0
- package/build/tools/spawn-researcher.js +70 -0
- package/build/tools/spawn-researcher.js.map +1 -0
- package/build/tools/spawn-task.d.ts +74 -0
- package/build/tools/spawn-task.d.ts.map +1 -0
- package/build/tools/spawn-task.js +107 -0
- package/build/tools/spawn-task.js.map +1 -0
- package/build/tools/spawn-tester.d.ts +70 -0
- package/build/tools/spawn-tester.d.ts.map +1 -0
- package/build/tools/spawn-tester.js +69 -0
- package/build/tools/spawn-tester.js.map +1 -0
- package/build/types.d.ts +101 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +28 -0
- package/build/types.js.map +1 -0
- package/build/utils/brief-validator.d.ts +30 -0
- package/build/utils/brief-validator.d.ts.map +1 -0
- package/build/utils/brief-validator.js +254 -0
- package/build/utils/brief-validator.js.map +1 -0
- package/build/utils/format.d.ts +34 -0
- package/build/utils/format.d.ts.map +1 -0
- package/build/utils/format.js +55 -0
- package/build/utils/format.js.map +1 -0
- package/build/utils/sanitize.d.ts +240 -0
- package/build/utils/sanitize.d.ts.map +1 -0
- package/build/utils/sanitize.js +89 -0
- package/build/utils/sanitize.js.map +1 -0
- package/build/utils/task-id-generator.d.ts +10 -0
- package/build/utils/task-id-generator.d.ts.map +1 -0
- package/build/utils/task-id-generator.js +22 -0
- package/build/utils/task-id-generator.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const THROTTLE_MS = 100;
|
|
2
|
+
class ProgressRegistry {
|
|
3
|
+
bindings = new Map();
|
|
4
|
+
register(taskId, progressToken, sendNotification) {
|
|
5
|
+
// Clean up any existing binding
|
|
6
|
+
this.unregister(taskId);
|
|
7
|
+
this.bindings.set(taskId.toLowerCase(), {
|
|
8
|
+
progressToken,
|
|
9
|
+
sendNotification,
|
|
10
|
+
progressCount: 0,
|
|
11
|
+
lastSendTime: 0,
|
|
12
|
+
pendingMessage: null,
|
|
13
|
+
pendingTotal: undefined,
|
|
14
|
+
flushTimer: null,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
unregister(taskId) {
|
|
18
|
+
const key = taskId.toLowerCase();
|
|
19
|
+
const binding = this.bindings.get(key);
|
|
20
|
+
if (binding) {
|
|
21
|
+
if (binding.flushTimer) {
|
|
22
|
+
clearTimeout(binding.flushTimer);
|
|
23
|
+
}
|
|
24
|
+
// Flush any pending message before unregistering
|
|
25
|
+
if (binding.pendingMessage) {
|
|
26
|
+
this.doSend(binding, binding.pendingMessage);
|
|
27
|
+
}
|
|
28
|
+
this.bindings.delete(key);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
has(taskId) {
|
|
32
|
+
return this.bindings.has(taskId.toLowerCase());
|
|
33
|
+
}
|
|
34
|
+
sendProgress(taskId, message, total) {
|
|
35
|
+
const binding = this.bindings.get(taskId.toLowerCase());
|
|
36
|
+
if (!binding)
|
|
37
|
+
return;
|
|
38
|
+
const now = Date.now();
|
|
39
|
+
const elapsed = now - binding.lastSendTime;
|
|
40
|
+
// Always update pendingTotal to the most recent value
|
|
41
|
+
if (total !== undefined) {
|
|
42
|
+
binding.pendingTotal = total;
|
|
43
|
+
}
|
|
44
|
+
if (elapsed >= THROTTLE_MS) {
|
|
45
|
+
// Send immediately
|
|
46
|
+
if (binding.flushTimer) {
|
|
47
|
+
clearTimeout(binding.flushTimer);
|
|
48
|
+
binding.flushTimer = null;
|
|
49
|
+
}
|
|
50
|
+
// If there was a pending message, prepend it
|
|
51
|
+
const fullMessage = binding.pendingMessage
|
|
52
|
+
? `${binding.pendingMessage}\n${message}`
|
|
53
|
+
: message;
|
|
54
|
+
binding.pendingMessage = null;
|
|
55
|
+
const sendTotal = binding.pendingTotal;
|
|
56
|
+
binding.pendingTotal = undefined;
|
|
57
|
+
this.doSend(binding, fullMessage, sendTotal);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// Buffer the message
|
|
61
|
+
binding.pendingMessage = binding.pendingMessage
|
|
62
|
+
? `${binding.pendingMessage}\n${message}`
|
|
63
|
+
: message;
|
|
64
|
+
// Schedule flush if not already scheduled
|
|
65
|
+
if (!binding.flushTimer) {
|
|
66
|
+
binding.flushTimer = setTimeout(() => {
|
|
67
|
+
binding.flushTimer = null;
|
|
68
|
+
if (binding.pendingMessage) {
|
|
69
|
+
const msg = binding.pendingMessage;
|
|
70
|
+
binding.pendingMessage = null;
|
|
71
|
+
const sendTotal = binding.pendingTotal;
|
|
72
|
+
binding.pendingTotal = undefined;
|
|
73
|
+
this.doSend(binding, msg, sendTotal);
|
|
74
|
+
}
|
|
75
|
+
}, THROTTLE_MS);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
doSend(binding, message, total) {
|
|
80
|
+
binding.progressCount++;
|
|
81
|
+
binding.lastSendTime = Date.now();
|
|
82
|
+
const notification = {
|
|
83
|
+
method: 'notifications/progress',
|
|
84
|
+
params: {
|
|
85
|
+
progressToken: binding.progressToken,
|
|
86
|
+
progress: binding.progressCount,
|
|
87
|
+
...(total !== undefined ? { total } : {}),
|
|
88
|
+
message,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
binding.sendNotification(notification).catch((err) => {
|
|
92
|
+
console.error(`[progress-registry] Failed to send progress for token ${binding.progressToken}:`, err);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export const progressRegistry = new ProgressRegistry();
|
|
97
|
+
//# sourceMappingURL=progress-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-registry.js","sourceRoot":"","sources":["../../src/services/progress-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Question Registry - Manages pending questions from the agent's ask_user tool.
|
|
3
|
+
*
|
|
4
|
+
* When the agent asks a question via ask_user, this registry:
|
|
5
|
+
* - Stores the question with Promise callbacks for resolution
|
|
6
|
+
* - Updates TaskState with pending question
|
|
7
|
+
* - Provides answer submission with validation
|
|
8
|
+
* - Handles timeouts (30 min default)
|
|
9
|
+
* - Sends MCP notifications when questions arrive
|
|
10
|
+
*/
|
|
11
|
+
import type { PendingQuestion } from '../types.js';
|
|
12
|
+
/** User input response shape. */
|
|
13
|
+
interface UserInputResponse {
|
|
14
|
+
answer: string;
|
|
15
|
+
wasFreeform: boolean;
|
|
16
|
+
}
|
|
17
|
+
type QuestionNotificationCallback = (taskId: string, question: PendingQuestion) => void;
|
|
18
|
+
declare class QuestionRegistry {
|
|
19
|
+
private bindings;
|
|
20
|
+
private notificationCallback?;
|
|
21
|
+
/**
|
|
22
|
+
* Set callback for MCP notifications when questions arrive.
|
|
23
|
+
*/
|
|
24
|
+
onQuestionAsked(callback: QuestionNotificationCallback): void;
|
|
25
|
+
/**
|
|
26
|
+
* Register a pending question and return a Promise that resolves when answered.
|
|
27
|
+
* This is called when a session asks for user input.
|
|
28
|
+
*/
|
|
29
|
+
register(taskId: string, sessionId: string, question: string, choices?: string[], allowFreeform?: boolean): Promise<UserInputResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Submit an answer for a pending question.
|
|
32
|
+
* Validates the answer format and resolves the Promise.
|
|
33
|
+
*/
|
|
34
|
+
submitAnswer(taskId: string, answer: string): {
|
|
35
|
+
success: boolean;
|
|
36
|
+
error?: string;
|
|
37
|
+
resolvedAnswer?: string;
|
|
38
|
+
wasFreeform?: boolean;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Parse and validate an answer.
|
|
42
|
+
* Supports: "1", "2", "3" (choice index), "CUSTOM: text", or direct text.
|
|
43
|
+
*/
|
|
44
|
+
private parseAnswer;
|
|
45
|
+
/**
|
|
46
|
+
* Handle question timeout.
|
|
47
|
+
*/
|
|
48
|
+
private handleTimeout;
|
|
49
|
+
/**
|
|
50
|
+
* Clear a pending question for a task.
|
|
51
|
+
*/
|
|
52
|
+
clearQuestion(taskId: string, reason?: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get the pending question for a task.
|
|
55
|
+
*/
|
|
56
|
+
getQuestion(taskId: string): PendingQuestion | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a task has a pending question.
|
|
59
|
+
*/
|
|
60
|
+
hasPendingQuestion(taskId: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Get all tasks with pending questions.
|
|
63
|
+
*/
|
|
64
|
+
getAllPendingQuestions(): Map<string, PendingQuestion>;
|
|
65
|
+
/**
|
|
66
|
+
* Clean up all pending questions (e.g., on server shutdown).
|
|
67
|
+
*/
|
|
68
|
+
cleanup(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get statistics.
|
|
71
|
+
*/
|
|
72
|
+
getStats(): {
|
|
73
|
+
pendingCount: number;
|
|
74
|
+
oldestQuestionAge?: number;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export declare const questionRegistry: QuestionRegistry;
|
|
78
|
+
export {};
|
|
79
|
+
//# sourceMappingURL=question-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"question-registry.d.ts","sourceRoot":"","sources":["../../src/services/question-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,iCAAiC;AACjC,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;CACtB;AAiBD,KAAK,4BAA4B,GAAG,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,eAAe,KACtB,IAAI,CAAC;AAEV,cAAM,gBAAgB;IACpB,OAAO,CAAC,QAAQ,CAA2C;IAC3D,OAAO,CAAC,oBAAoB,CAAC,CAA+B;IAE5D;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,4BAA4B,GAAG,IAAI;IAI7D;;;OAGG;IACH,QAAQ,CACN,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAAE,EAClB,aAAa,GAAE,OAAc,GAC5B,OAAO,CAAC,iBAAiB,CAAC;IA0D7B;;;OAGG;IACH,YAAY,CACV,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE;IAwCvF;;;OAGG;IACH,OAAO,CAAC,WAAW;IAyDnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAgBrB;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAkB,GAAG,IAAI;IAgB/D;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAaxD;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAI3C;;OAEG;IACH,sBAAsB,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAgBtD;;OAEG;IACH,OAAO,IAAI,IAAI;IASf;;OAEG;IACH,QAAQ,IAAI;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE;CAgBjE;AAED,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Question Registry - Manages pending questions from the agent's ask_user tool.
|
|
3
|
+
*
|
|
4
|
+
* When the agent asks a question via ask_user, this registry:
|
|
5
|
+
* - Stores the question with Promise callbacks for resolution
|
|
6
|
+
* - Updates TaskState with pending question
|
|
7
|
+
* - Provides answer submission with validation
|
|
8
|
+
* - Handles timeouts (30 min default)
|
|
9
|
+
* - Sends MCP notifications when questions arrive
|
|
10
|
+
*/
|
|
11
|
+
import { taskManager } from './task-manager.js';
|
|
12
|
+
const QUESTION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
|
|
13
|
+
class QuestionRegistry {
|
|
14
|
+
bindings = new Map();
|
|
15
|
+
notificationCallback;
|
|
16
|
+
/**
|
|
17
|
+
* Set callback for MCP notifications when questions arrive.
|
|
18
|
+
*/
|
|
19
|
+
onQuestionAsked(callback) {
|
|
20
|
+
this.notificationCallback = callback;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register a pending question and return a Promise that resolves when answered.
|
|
24
|
+
* This is called when a session asks for user input.
|
|
25
|
+
*/
|
|
26
|
+
register(taskId, sessionId, question, choices, allowFreeform = true) {
|
|
27
|
+
// Clean up any existing question for this task
|
|
28
|
+
this.clearQuestion(taskId, 'new question asked');
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const askedAt = new Date();
|
|
31
|
+
// Set timeout for question
|
|
32
|
+
const timeoutId = setTimeout(() => {
|
|
33
|
+
this.handleTimeout(taskId);
|
|
34
|
+
}, QUESTION_TIMEOUT_MS);
|
|
35
|
+
const binding = {
|
|
36
|
+
taskId,
|
|
37
|
+
sessionId,
|
|
38
|
+
question,
|
|
39
|
+
choices,
|
|
40
|
+
allowFreeform,
|
|
41
|
+
askedAt,
|
|
42
|
+
timeoutId,
|
|
43
|
+
resolve,
|
|
44
|
+
reject,
|
|
45
|
+
};
|
|
46
|
+
this.bindings.set(taskId.toLowerCase(), binding);
|
|
47
|
+
// Update task state with pending question
|
|
48
|
+
const pendingQuestion = {
|
|
49
|
+
question,
|
|
50
|
+
choices,
|
|
51
|
+
allowFreeform,
|
|
52
|
+
askedAt: askedAt.toISOString(),
|
|
53
|
+
sessionId,
|
|
54
|
+
};
|
|
55
|
+
taskManager.updateTask(taskId, { pendingQuestion });
|
|
56
|
+
taskManager.appendOutput(taskId, `\n[question] Agent is asking: ${question}`);
|
|
57
|
+
if (choices && choices.length > 0) {
|
|
58
|
+
const choiceList = choices.map((c, i) => ` ${i + 1}. ${c}`).join('\n');
|
|
59
|
+
taskManager.appendOutput(taskId, `[question] Options:\n${choiceList}`);
|
|
60
|
+
}
|
|
61
|
+
if (allowFreeform) {
|
|
62
|
+
taskManager.appendOutput(taskId, `[question] Custom answers are allowed.`);
|
|
63
|
+
}
|
|
64
|
+
taskManager.appendOutput(taskId, `[question] Task paused. Use answer_question tool to respond.`);
|
|
65
|
+
console.error(`[question-registry] Question registered for task ${taskId}: "${question}"`);
|
|
66
|
+
// Send MCP notification
|
|
67
|
+
if (this.notificationCallback) {
|
|
68
|
+
this.notificationCallback(taskId, pendingQuestion);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Submit an answer for a pending question.
|
|
74
|
+
* Validates the answer format and resolves the Promise.
|
|
75
|
+
*/
|
|
76
|
+
submitAnswer(taskId, answer) {
|
|
77
|
+
const normalizedId = taskId.toLowerCase();
|
|
78
|
+
const binding = this.bindings.get(normalizedId);
|
|
79
|
+
if (!binding) {
|
|
80
|
+
return { success: false, error: 'No pending question for this task' };
|
|
81
|
+
}
|
|
82
|
+
// Parse and validate the answer
|
|
83
|
+
const parseResult = this.parseAnswer(answer, binding.choices, binding.allowFreeform);
|
|
84
|
+
if (!parseResult.valid) {
|
|
85
|
+
return { success: false, error: parseResult.error };
|
|
86
|
+
}
|
|
87
|
+
// Clear timeout
|
|
88
|
+
clearTimeout(binding.timeoutId);
|
|
89
|
+
// Resolve the Promise
|
|
90
|
+
binding.resolve({
|
|
91
|
+
answer: parseResult.answer,
|
|
92
|
+
wasFreeform: parseResult.wasFreeform,
|
|
93
|
+
});
|
|
94
|
+
// Clear the pending question from task state
|
|
95
|
+
taskManager.updateTask(taskId, { pendingQuestion: undefined });
|
|
96
|
+
taskManager.appendOutput(taskId, `[question] Answer submitted: ${parseResult.answer}`);
|
|
97
|
+
// Remove from registry
|
|
98
|
+
this.bindings.delete(normalizedId);
|
|
99
|
+
console.error(`[question-registry] Answer submitted for task ${taskId}: "${parseResult.answer}" (freeform: ${parseResult.wasFreeform})`);
|
|
100
|
+
return {
|
|
101
|
+
success: true,
|
|
102
|
+
resolvedAnswer: parseResult.answer,
|
|
103
|
+
wasFreeform: parseResult.wasFreeform,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Parse and validate an answer.
|
|
108
|
+
* Supports: "1", "2", "3" (choice index), "CUSTOM: text", or direct text.
|
|
109
|
+
*/
|
|
110
|
+
parseAnswer(answer, choices, allowFreeform = true) {
|
|
111
|
+
const trimmedAnswer = answer.trim();
|
|
112
|
+
// Check for CUSTOM: prefix
|
|
113
|
+
if (trimmedAnswer.toUpperCase().startsWith('CUSTOM:')) {
|
|
114
|
+
if (!allowFreeform) {
|
|
115
|
+
return { valid: false, error: 'Custom answers not allowed. Please select from the choices.' };
|
|
116
|
+
}
|
|
117
|
+
const customText = trimmedAnswer.slice(7).trim();
|
|
118
|
+
if (!customText) {
|
|
119
|
+
return { valid: false, error: 'Custom answer cannot be empty.' };
|
|
120
|
+
}
|
|
121
|
+
return { valid: true, answer: customText, wasFreeform: true };
|
|
122
|
+
}
|
|
123
|
+
// Check for numeric choice (1-indexed)
|
|
124
|
+
if (choices && choices.length > 0 && /^\d+$/.test(trimmedAnswer)) {
|
|
125
|
+
const index = parseInt(trimmedAnswer, 10) - 1; // Convert to 0-indexed
|
|
126
|
+
if (index >= 0 && index < choices.length) {
|
|
127
|
+
return { valid: true, answer: choices[index], wasFreeform: false };
|
|
128
|
+
}
|
|
129
|
+
return { valid: false, error: `Invalid choice. Please enter 1-${choices.length}.` };
|
|
130
|
+
}
|
|
131
|
+
// Check if answer matches a choice exactly
|
|
132
|
+
if (choices && choices.length > 0) {
|
|
133
|
+
const matchIndex = choices.findIndex(c => c.toLowerCase() === trimmedAnswer.toLowerCase());
|
|
134
|
+
if (matchIndex >= 0) {
|
|
135
|
+
return { valid: true, answer: choices[matchIndex], wasFreeform: false };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Freeform answer
|
|
139
|
+
if (allowFreeform) {
|
|
140
|
+
if (!trimmedAnswer) {
|
|
141
|
+
return { valid: false, error: 'Answer cannot be empty.' };
|
|
142
|
+
}
|
|
143
|
+
return { valid: true, answer: trimmedAnswer, wasFreeform: true };
|
|
144
|
+
}
|
|
145
|
+
// Not allowed
|
|
146
|
+
if (choices && choices.length > 0) {
|
|
147
|
+
return {
|
|
148
|
+
valid: false,
|
|
149
|
+
error: `Invalid answer. Please select a choice (1-${choices.length}) or use "CUSTOM: your answer" if freeform is enabled.`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return { valid: false, error: 'Cannot submit answer.' };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Handle question timeout.
|
|
156
|
+
*/
|
|
157
|
+
handleTimeout(taskId) {
|
|
158
|
+
const normalizedId = taskId.toLowerCase();
|
|
159
|
+
const binding = this.bindings.get(normalizedId);
|
|
160
|
+
if (binding) {
|
|
161
|
+
binding.reject(new Error('Question timed out after 30 minutes'));
|
|
162
|
+
taskManager.updateTask(taskId, { pendingQuestion: undefined });
|
|
163
|
+
taskManager.appendOutput(taskId, `[question] Question timed out after 30 minutes. Task may fail.`);
|
|
164
|
+
this.bindings.delete(normalizedId);
|
|
165
|
+
console.error(`[question-registry] Question timed out for task ${taskId}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Clear a pending question for a task.
|
|
170
|
+
*/
|
|
171
|
+
clearQuestion(taskId, reason = 'cleared') {
|
|
172
|
+
const normalizedId = taskId.toLowerCase();
|
|
173
|
+
const binding = this.bindings.get(normalizedId);
|
|
174
|
+
if (binding) {
|
|
175
|
+
clearTimeout(binding.timeoutId);
|
|
176
|
+
binding.reject(new Error(`Question cleared: ${reason}`));
|
|
177
|
+
taskManager.updateTask(taskId, { pendingQuestion: undefined });
|
|
178
|
+
this.bindings.delete(normalizedId);
|
|
179
|
+
console.error(`[question-registry] Question cleared for task ${taskId}: ${reason}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get the pending question for a task.
|
|
184
|
+
*/
|
|
185
|
+
getQuestion(taskId) {
|
|
186
|
+
const binding = this.bindings.get(taskId.toLowerCase());
|
|
187
|
+
if (!binding)
|
|
188
|
+
return undefined;
|
|
189
|
+
return {
|
|
190
|
+
question: binding.question,
|
|
191
|
+
choices: binding.choices,
|
|
192
|
+
allowFreeform: binding.allowFreeform,
|
|
193
|
+
askedAt: binding.askedAt.toISOString(),
|
|
194
|
+
sessionId: binding.sessionId,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Check if a task has a pending question.
|
|
199
|
+
*/
|
|
200
|
+
hasPendingQuestion(taskId) {
|
|
201
|
+
return this.bindings.has(taskId.toLowerCase());
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get all tasks with pending questions.
|
|
205
|
+
*/
|
|
206
|
+
getAllPendingQuestions() {
|
|
207
|
+
const result = new Map();
|
|
208
|
+
for (const [taskId, binding] of this.bindings) {
|
|
209
|
+
result.set(taskId, {
|
|
210
|
+
question: binding.question,
|
|
211
|
+
choices: binding.choices,
|
|
212
|
+
allowFreeform: binding.allowFreeform,
|
|
213
|
+
askedAt: binding.askedAt.toISOString(),
|
|
214
|
+
sessionId: binding.sessionId,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Clean up all pending questions (e.g., on server shutdown).
|
|
221
|
+
*/
|
|
222
|
+
cleanup() {
|
|
223
|
+
for (const [taskId, binding] of this.bindings) {
|
|
224
|
+
clearTimeout(binding.timeoutId);
|
|
225
|
+
binding.reject(new Error('Server shutdown'));
|
|
226
|
+
}
|
|
227
|
+
this.bindings.clear();
|
|
228
|
+
console.error(`[question-registry] Cleaned up all pending questions`);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Get statistics.
|
|
232
|
+
*/
|
|
233
|
+
getStats() {
|
|
234
|
+
const now = Date.now();
|
|
235
|
+
let oldestAge;
|
|
236
|
+
for (const binding of this.bindings.values()) {
|
|
237
|
+
const age = now - binding.askedAt.getTime();
|
|
238
|
+
if (oldestAge === undefined || age > oldestAge) {
|
|
239
|
+
oldestAge = age;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
pendingCount: this.bindings.size,
|
|
244
|
+
oldestQuestionAge: oldestAge,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
export const questionRegistry = new QuestionRegistry();
|
|
249
|
+
//# sourceMappingURL=question-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"question-registry.js","sourceRoot":"","sources":["../../src/services/question-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { TaskState, RetryInfo } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Check if an error/output indicates rate limiting.
|
|
4
|
+
* Prefers structured failureContext over string parsing when available.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isRateLimitError(output: string[], error?: string, task?: TaskState): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Extract rate limit wait time from error message if present.
|
|
9
|
+
* Returns milliseconds or null if not found.
|
|
10
|
+
* Prefers quotaInfo.resetDate for precise timing when available.
|
|
11
|
+
*/
|
|
12
|
+
export declare function extractWaitTime(output: string[], error?: string, task?: TaskState): number | null;
|
|
13
|
+
/**
|
|
14
|
+
* Calculate next retry time based on retry count and task data.
|
|
15
|
+
* Uses quotaInfo.resetDate when available for precise timing.
|
|
16
|
+
*/
|
|
17
|
+
export declare function calculateNextRetryTime(retryCount: number, suggestedWaitMs?: number | null, task?: TaskState): string;
|
|
18
|
+
/**
|
|
19
|
+
* Create retry info for a rate-limited task.
|
|
20
|
+
* Uses structured task data for better timing when available.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createRetryInfo(task: TaskState, reason: string, existingRetryInfo?: RetryInfo): RetryInfo;
|
|
23
|
+
/**
|
|
24
|
+
* Check if a task should be retried now.
|
|
25
|
+
* Considers quota info when deciding whether to retry.
|
|
26
|
+
*/
|
|
27
|
+
export declare function shouldRetryNow(task: TaskState): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a task has exceeded max retries.
|
|
30
|
+
*/
|
|
31
|
+
export declare function hasExceededMaxRetries(task: TaskState): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Check if handoff is recommended instead of retry.
|
|
34
|
+
* Uses task data to make intelligent recommendations.
|
|
35
|
+
*/
|
|
36
|
+
export declare function shouldRecommendHandoff(task: TaskState): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Get recommended action for a rate-limited task.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getRecommendedAction(task: TaskState): 'retry' | 'handoff' | 'wait' | 'give_up';
|
|
41
|
+
//# sourceMappingURL=retry-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-queue.d.ts","sourceRoot":"","sources":["../../src/services/retry-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAc,SAAS,EAAE,MAAM,aAAa,CAAC;AAsB/D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAc5F;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CA8BjG;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,IAAI,CAAC,EAAE,SAAS,GACf,MAAM,CAyBR;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,MAAM,EACd,iBAAiB,CAAC,EAAE,SAAS,GAC5B,SAAS,CAwBX;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAuBvD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAK9D;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAiB/D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAkB9F"}
|