genesis-ai-cli 7.4.5
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/.env.example +78 -0
- package/README.md +282 -0
- package/dist/src/active-inference/actions.d.ts +75 -0
- package/dist/src/active-inference/actions.js +250 -0
- package/dist/src/active-inference/autonomous-loop.d.ts +103 -0
- package/dist/src/active-inference/autonomous-loop.js +289 -0
- package/dist/src/active-inference/core.d.ts +85 -0
- package/dist/src/active-inference/core.js +555 -0
- package/dist/src/active-inference/demo-autonomous-loop.d.ts +8 -0
- package/dist/src/active-inference/demo-autonomous-loop.js +338 -0
- package/dist/src/active-inference/demo-value-integration.d.ts +8 -0
- package/dist/src/active-inference/demo-value-integration.js +174 -0
- package/dist/src/active-inference/index.d.ts +32 -0
- package/dist/src/active-inference/index.js +88 -0
- package/dist/src/active-inference/integration.d.ts +114 -0
- package/dist/src/active-inference/integration.js +698 -0
- package/dist/src/active-inference/memory-integration.d.ts +51 -0
- package/dist/src/active-inference/memory-integration.js +232 -0
- package/dist/src/active-inference/observations.d.ts +67 -0
- package/dist/src/active-inference/observations.js +147 -0
- package/dist/src/active-inference/test-active-inference.d.ts +8 -0
- package/dist/src/active-inference/test-active-inference.js +320 -0
- package/dist/src/active-inference/test-value-integration.d.ts +6 -0
- package/dist/src/active-inference/test-value-integration.js +168 -0
- package/dist/src/active-inference/types.d.ts +150 -0
- package/dist/src/active-inference/types.js +59 -0
- package/dist/src/active-inference/value-integration.d.ts +164 -0
- package/dist/src/active-inference/value-integration.js +459 -0
- package/dist/src/agents/base-agent.d.ts +53 -0
- package/dist/src/agents/base-agent.js +178 -0
- package/dist/src/agents/builder.d.ts +67 -0
- package/dist/src/agents/builder.js +537 -0
- package/dist/src/agents/critic.d.ts +35 -0
- package/dist/src/agents/critic.js +322 -0
- package/dist/src/agents/ethicist.d.ts +54 -0
- package/dist/src/agents/ethicist.js +393 -0
- package/dist/src/agents/explorer.d.ts +26 -0
- package/dist/src/agents/explorer.js +216 -0
- package/dist/src/agents/feeling.d.ts +41 -0
- package/dist/src/agents/feeling.js +320 -0
- package/dist/src/agents/index.d.ts +111 -0
- package/dist/src/agents/index.js +222 -0
- package/dist/src/agents/memory.d.ts +69 -0
- package/dist/src/agents/memory.js +404 -0
- package/dist/src/agents/message-bus.d.ts +88 -0
- package/dist/src/agents/message-bus.js +267 -0
- package/dist/src/agents/narrator.d.ts +90 -0
- package/dist/src/agents/narrator.js +473 -0
- package/dist/src/agents/planner.d.ts +38 -0
- package/dist/src/agents/planner.js +341 -0
- package/dist/src/agents/predictor.d.ts +73 -0
- package/dist/src/agents/predictor.js +506 -0
- package/dist/src/agents/sensor.d.ts +88 -0
- package/dist/src/agents/sensor.js +377 -0
- package/dist/src/agents/test-agents.d.ts +6 -0
- package/dist/src/agents/test-agents.js +73 -0
- package/dist/src/agents/types.d.ts +194 -0
- package/dist/src/agents/types.js +7 -0
- package/dist/src/brain/index.d.ts +185 -0
- package/dist/src/brain/index.js +843 -0
- package/dist/src/brain/trace.d.ts +91 -0
- package/dist/src/brain/trace.js +327 -0
- package/dist/src/brain/types.d.ts +165 -0
- package/dist/src/brain/types.js +51 -0
- package/dist/src/cli/chat.d.ts +237 -0
- package/dist/src/cli/chat.js +1959 -0
- package/dist/src/cli/dispatcher.d.ts +182 -0
- package/dist/src/cli/dispatcher.js +718 -0
- package/dist/src/cli/human-loop.d.ts +170 -0
- package/dist/src/cli/human-loop.js +543 -0
- package/dist/src/cli/index.d.ts +12 -0
- package/dist/src/cli/index.js +28 -0
- package/dist/src/cli/interactive.d.ts +141 -0
- package/dist/src/cli/interactive.js +757 -0
- package/dist/src/cli/ui.d.ts +205 -0
- package/dist/src/cli/ui.js +632 -0
- package/dist/src/consciousness/attention-schema.d.ts +154 -0
- package/dist/src/consciousness/attention-schema.js +432 -0
- package/dist/src/consciousness/global-workspace.d.ts +149 -0
- package/dist/src/consciousness/global-workspace.js +422 -0
- package/dist/src/consciousness/index.d.ts +186 -0
- package/dist/src/consciousness/index.js +476 -0
- package/dist/src/consciousness/phi-calculator.d.ts +119 -0
- package/dist/src/consciousness/phi-calculator.js +445 -0
- package/dist/src/consciousness/phi-decisions.d.ts +169 -0
- package/dist/src/consciousness/phi-decisions.js +383 -0
- package/dist/src/consciousness/phi-monitor.d.ts +153 -0
- package/dist/src/consciousness/phi-monitor.js +465 -0
- package/dist/src/consciousness/types.d.ts +260 -0
- package/dist/src/consciousness/types.js +44 -0
- package/dist/src/daemon/dream-mode.d.ts +115 -0
- package/dist/src/daemon/dream-mode.js +470 -0
- package/dist/src/daemon/index.d.ts +162 -0
- package/dist/src/daemon/index.js +542 -0
- package/dist/src/daemon/maintenance.d.ts +139 -0
- package/dist/src/daemon/maintenance.js +549 -0
- package/dist/src/daemon/process.d.ts +82 -0
- package/dist/src/daemon/process.js +442 -0
- package/dist/src/daemon/scheduler.d.ts +90 -0
- package/dist/src/daemon/scheduler.js +494 -0
- package/dist/src/daemon/types.d.ts +213 -0
- package/dist/src/daemon/types.js +50 -0
- package/dist/src/epistemic/index.d.ts +74 -0
- package/dist/src/epistemic/index.js +225 -0
- package/dist/src/grounding/epistemic-stack.d.ts +100 -0
- package/dist/src/grounding/epistemic-stack.js +408 -0
- package/dist/src/grounding/feedback.d.ts +98 -0
- package/dist/src/grounding/feedback.js +276 -0
- package/dist/src/grounding/index.d.ts +123 -0
- package/dist/src/grounding/index.js +224 -0
- package/dist/src/grounding/verifier.d.ts +149 -0
- package/dist/src/grounding/verifier.js +484 -0
- package/dist/src/healing/detector.d.ts +110 -0
- package/dist/src/healing/detector.js +436 -0
- package/dist/src/healing/fixer.d.ts +138 -0
- package/dist/src/healing/fixer.js +572 -0
- package/dist/src/healing/index.d.ts +23 -0
- package/dist/src/healing/index.js +43 -0
- package/dist/src/hooks/index.d.ts +135 -0
- package/dist/src/hooks/index.js +317 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.js +1266 -0
- package/dist/src/kernel/index.d.ts +155 -0
- package/dist/src/kernel/index.js +795 -0
- package/dist/src/kernel/invariants.d.ts +153 -0
- package/dist/src/kernel/invariants.js +355 -0
- package/dist/src/kernel/test-kernel.d.ts +6 -0
- package/dist/src/kernel/test-kernel.js +108 -0
- package/dist/src/kernel/test-real-mcp.d.ts +10 -0
- package/dist/src/kernel/test-real-mcp.js +295 -0
- package/dist/src/llm/index.d.ts +146 -0
- package/dist/src/llm/index.js +428 -0
- package/dist/src/llm/router.d.ts +136 -0
- package/dist/src/llm/router.js +510 -0
- package/dist/src/mcp/index.d.ts +85 -0
- package/dist/src/mcp/index.js +657 -0
- package/dist/src/mcp/resilient.d.ts +139 -0
- package/dist/src/mcp/resilient.js +417 -0
- package/dist/src/memory/cache.d.ts +118 -0
- package/dist/src/memory/cache.js +356 -0
- package/dist/src/memory/cognitive-workspace.d.ts +231 -0
- package/dist/src/memory/cognitive-workspace.js +521 -0
- package/dist/src/memory/consolidation.d.ts +99 -0
- package/dist/src/memory/consolidation.js +443 -0
- package/dist/src/memory/episodic.d.ts +114 -0
- package/dist/src/memory/episodic.js +394 -0
- package/dist/src/memory/forgetting.d.ts +134 -0
- package/dist/src/memory/forgetting.js +324 -0
- package/dist/src/memory/index.d.ts +211 -0
- package/dist/src/memory/index.js +367 -0
- package/dist/src/memory/indexer.d.ts +123 -0
- package/dist/src/memory/indexer.js +479 -0
- package/dist/src/memory/procedural.d.ts +136 -0
- package/dist/src/memory/procedural.js +479 -0
- package/dist/src/memory/semantic.d.ts +132 -0
- package/dist/src/memory/semantic.js +497 -0
- package/dist/src/memory/types.d.ts +193 -0
- package/dist/src/memory/types.js +15 -0
- package/dist/src/orchestrator.d.ts +65 -0
- package/dist/src/orchestrator.js +317 -0
- package/dist/src/persistence/index.d.ts +257 -0
- package/dist/src/persistence/index.js +763 -0
- package/dist/src/pipeline/executor.d.ts +51 -0
- package/dist/src/pipeline/executor.js +695 -0
- package/dist/src/pipeline/index.d.ts +7 -0
- package/dist/src/pipeline/index.js +11 -0
- package/dist/src/self-production.d.ts +67 -0
- package/dist/src/self-production.js +205 -0
- package/dist/src/subagents/executor.d.ts +58 -0
- package/dist/src/subagents/executor.js +283 -0
- package/dist/src/subagents/index.d.ts +37 -0
- package/dist/src/subagents/index.js +53 -0
- package/dist/src/subagents/registry.d.ts +23 -0
- package/dist/src/subagents/registry.js +167 -0
- package/dist/src/subagents/types.d.ts +79 -0
- package/dist/src/subagents/types.js +14 -0
- package/dist/src/tools/bash.d.ts +139 -0
- package/dist/src/tools/bash.js +583 -0
- package/dist/src/tools/edit.d.ts +125 -0
- package/dist/src/tools/edit.js +424 -0
- package/dist/src/tools/git.d.ts +179 -0
- package/dist/src/tools/git.js +504 -0
- package/dist/src/tools/index.d.ts +21 -0
- package/dist/src/tools/index.js +163 -0
- package/dist/src/types.d.ts +145 -0
- package/dist/src/types.js +7 -0
- package/dist/src/world-model/decoder.d.ts +163 -0
- package/dist/src/world-model/decoder.js +517 -0
- package/dist/src/world-model/digital-twin.d.ts +219 -0
- package/dist/src/world-model/digital-twin.js +695 -0
- package/dist/src/world-model/encoder.d.ts +141 -0
- package/dist/src/world-model/encoder.js +564 -0
- package/dist/src/world-model/index.d.ts +221 -0
- package/dist/src/world-model/index.js +772 -0
- package/dist/src/world-model/predictor.d.ts +161 -0
- package/dist/src/world-model/predictor.js +681 -0
- package/dist/src/world-model/test-value-jepa.d.ts +8 -0
- package/dist/src/world-model/test-value-jepa.js +430 -0
- package/dist/src/world-model/types.d.ts +341 -0
- package/dist/src/world-model/types.js +69 -0
- package/dist/src/world-model/value-jepa.d.ts +247 -0
- package/dist/src/world-model/value-jepa.js +622 -0
- package/dist/test/brain.test.d.ts +11 -0
- package/dist/test/brain.test.js +358 -0
- package/dist/test/cli/dispatcher.test.d.ts +4 -0
- package/dist/test/cli/dispatcher.test.js +332 -0
- package/dist/test/cli/human-loop.test.d.ts +4 -0
- package/dist/test/cli/human-loop.test.js +270 -0
- package/dist/test/grounding/feedback.test.d.ts +4 -0
- package/dist/test/grounding/feedback.test.js +462 -0
- package/dist/test/grounding/verifier.test.d.ts +4 -0
- package/dist/test/grounding/verifier.test.js +442 -0
- package/dist/test/grounding.test.d.ts +6 -0
- package/dist/test/grounding.test.js +246 -0
- package/dist/test/healing/detector.test.d.ts +4 -0
- package/dist/test/healing/detector.test.js +266 -0
- package/dist/test/healing/fixer.test.d.ts +4 -0
- package/dist/test/healing/fixer.test.js +369 -0
- package/dist/test/integration.test.d.ts +5 -0
- package/dist/test/integration.test.js +290 -0
- package/dist/test/tools/bash.test.d.ts +4 -0
- package/dist/test/tools/bash.test.js +348 -0
- package/dist/test/tools/edit.test.d.ts +4 -0
- package/dist/test/tools/edit.test.js +350 -0
- package/dist/test/tools/git.test.d.ts +4 -0
- package/dist/test/tools/git.test.js +350 -0
- package/package.json +60 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genesis 6.0 - Human-in-the-Loop Module
|
|
3
|
+
*
|
|
4
|
+
* Enables human intervention at critical decision points:
|
|
5
|
+
* - Confirmation for destructive operations
|
|
6
|
+
* - Clarification when intent is unclear
|
|
7
|
+
* - Choice selection from options
|
|
8
|
+
* - Free-form input for open questions
|
|
9
|
+
*
|
|
10
|
+
* Follows the principle: "When in doubt, ask the human."
|
|
11
|
+
*/
|
|
12
|
+
import * as readline from 'readline';
|
|
13
|
+
export type QuestionType = 'confirm' | 'choice' | 'text' | 'multiChoice';
|
|
14
|
+
export interface Question {
|
|
15
|
+
/** Question type */
|
|
16
|
+
type: QuestionType;
|
|
17
|
+
/** Question text */
|
|
18
|
+
text: string;
|
|
19
|
+
/** Optional header/label */
|
|
20
|
+
header?: string;
|
|
21
|
+
/** Options for choice/multiChoice */
|
|
22
|
+
options?: QuestionOption[];
|
|
23
|
+
/** Default value */
|
|
24
|
+
default?: string | boolean | string[];
|
|
25
|
+
/** Whether this question is required */
|
|
26
|
+
required?: boolean;
|
|
27
|
+
/** Timeout in ms (0 = no timeout) */
|
|
28
|
+
timeout?: number;
|
|
29
|
+
/** Context for why we're asking */
|
|
30
|
+
context?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface QuestionOption {
|
|
33
|
+
/** Option value */
|
|
34
|
+
value: string;
|
|
35
|
+
/** Display label */
|
|
36
|
+
label: string;
|
|
37
|
+
/** Optional description */
|
|
38
|
+
description?: string;
|
|
39
|
+
/** Whether this is the recommended option */
|
|
40
|
+
recommended?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface Answer {
|
|
43
|
+
/** The question that was asked */
|
|
44
|
+
question: Question;
|
|
45
|
+
/** The answer value */
|
|
46
|
+
value: string | boolean | string[];
|
|
47
|
+
/** Whether the user responded (vs timeout/cancel) */
|
|
48
|
+
responded: boolean;
|
|
49
|
+
/** Time taken to respond in ms */
|
|
50
|
+
responseTime: number;
|
|
51
|
+
/** Was this a timeout? */
|
|
52
|
+
timedOut?: boolean;
|
|
53
|
+
/** Was this cancelled? */
|
|
54
|
+
cancelled?: boolean;
|
|
55
|
+
}
|
|
56
|
+
export interface HumanLoopConfig {
|
|
57
|
+
/** Default timeout for questions (0 = no timeout) */
|
|
58
|
+
defaultTimeout: number;
|
|
59
|
+
/** Whether to allow skipping questions */
|
|
60
|
+
allowSkip: boolean;
|
|
61
|
+
/** Callback when human responds */
|
|
62
|
+
onResponse?: (answer: Answer) => void;
|
|
63
|
+
/** Use colors in output */
|
|
64
|
+
useColors: boolean;
|
|
65
|
+
/** Custom readline interface */
|
|
66
|
+
rl?: readline.Interface;
|
|
67
|
+
}
|
|
68
|
+
export declare class HumanLoop {
|
|
69
|
+
private config;
|
|
70
|
+
private rl;
|
|
71
|
+
private ownRl;
|
|
72
|
+
private history;
|
|
73
|
+
constructor(config?: Partial<HumanLoopConfig>);
|
|
74
|
+
/**
|
|
75
|
+
* Initialize readline if needed
|
|
76
|
+
*/
|
|
77
|
+
private ensureRl;
|
|
78
|
+
/**
|
|
79
|
+
* Ask a question and wait for response
|
|
80
|
+
*/
|
|
81
|
+
ask(question: Question): Promise<Answer>;
|
|
82
|
+
/**
|
|
83
|
+
* Ask a yes/no confirmation
|
|
84
|
+
*/
|
|
85
|
+
private askConfirm;
|
|
86
|
+
/**
|
|
87
|
+
* Ask to choose one option
|
|
88
|
+
*/
|
|
89
|
+
private askChoice;
|
|
90
|
+
/**
|
|
91
|
+
* Ask to choose multiple options
|
|
92
|
+
*/
|
|
93
|
+
private askMultiChoice;
|
|
94
|
+
/**
|
|
95
|
+
* Ask for free-form text input
|
|
96
|
+
*/
|
|
97
|
+
private askText;
|
|
98
|
+
/**
|
|
99
|
+
* Quick confirmation
|
|
100
|
+
*/
|
|
101
|
+
confirm(text: string, defaultValue?: boolean): Promise<boolean>;
|
|
102
|
+
/**
|
|
103
|
+
* Quick choice
|
|
104
|
+
*/
|
|
105
|
+
choose(text: string, options: string[]): Promise<string>;
|
|
106
|
+
/**
|
|
107
|
+
* Quick text input
|
|
108
|
+
*/
|
|
109
|
+
input(text: string, defaultValue?: string): Promise<string>;
|
|
110
|
+
/**
|
|
111
|
+
* Ask for confirmation before destructive operation
|
|
112
|
+
*/
|
|
113
|
+
confirmDestructive(operation: string, details?: string): Promise<boolean>;
|
|
114
|
+
/**
|
|
115
|
+
* Ask for clarification
|
|
116
|
+
*/
|
|
117
|
+
clarify(context: string, options?: QuestionOption[]): Promise<string>;
|
|
118
|
+
/**
|
|
119
|
+
* Present implementation options
|
|
120
|
+
*/
|
|
121
|
+
chooseApproach(task: string, approaches: Array<{
|
|
122
|
+
name: string;
|
|
123
|
+
description: string;
|
|
124
|
+
recommended?: boolean;
|
|
125
|
+
}>): Promise<string>;
|
|
126
|
+
/**
|
|
127
|
+
* Get answer history
|
|
128
|
+
*/
|
|
129
|
+
getHistory(): Answer[];
|
|
130
|
+
/**
|
|
131
|
+
* Clear history
|
|
132
|
+
*/
|
|
133
|
+
clearHistory(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Get statistics
|
|
136
|
+
*/
|
|
137
|
+
stats(): {
|
|
138
|
+
totalQuestions: number;
|
|
139
|
+
responded: number;
|
|
140
|
+
timedOut: number;
|
|
141
|
+
cancelled: number;
|
|
142
|
+
avgResponseTime: number;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Close (cleanup readline if we created it)
|
|
146
|
+
*/
|
|
147
|
+
close(): void;
|
|
148
|
+
}
|
|
149
|
+
export declare function getHumanLoop(config?: Partial<HumanLoopConfig>): HumanLoop;
|
|
150
|
+
export declare function resetHumanLoop(): void;
|
|
151
|
+
/**
|
|
152
|
+
* Quick confirmation
|
|
153
|
+
*/
|
|
154
|
+
export declare function confirm(text: string, defaultValue?: boolean): Promise<boolean>;
|
|
155
|
+
/**
|
|
156
|
+
* Quick choice
|
|
157
|
+
*/
|
|
158
|
+
export declare function choose(text: string, options: string[]): Promise<string>;
|
|
159
|
+
/**
|
|
160
|
+
* Quick text input
|
|
161
|
+
*/
|
|
162
|
+
export declare function input(text: string, defaultValue?: string): Promise<string>;
|
|
163
|
+
/**
|
|
164
|
+
* Confirm destructive operation
|
|
165
|
+
*/
|
|
166
|
+
export declare function confirmDestructive(operation: string, details?: string): Promise<boolean>;
|
|
167
|
+
/**
|
|
168
|
+
* Ask for clarification
|
|
169
|
+
*/
|
|
170
|
+
export declare function clarify(context: string, options?: QuestionOption[]): Promise<string>;
|
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Genesis 6.0 - Human-in-the-Loop Module
|
|
4
|
+
*
|
|
5
|
+
* Enables human intervention at critical decision points:
|
|
6
|
+
* - Confirmation for destructive operations
|
|
7
|
+
* - Clarification when intent is unclear
|
|
8
|
+
* - Choice selection from options
|
|
9
|
+
* - Free-form input for open questions
|
|
10
|
+
*
|
|
11
|
+
* Follows the principle: "When in doubt, ask the human."
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.HumanLoop = void 0;
|
|
48
|
+
exports.getHumanLoop = getHumanLoop;
|
|
49
|
+
exports.resetHumanLoop = resetHumanLoop;
|
|
50
|
+
exports.confirm = confirm;
|
|
51
|
+
exports.choose = choose;
|
|
52
|
+
exports.input = input;
|
|
53
|
+
exports.confirmDestructive = confirmDestructive;
|
|
54
|
+
exports.clarify = clarify;
|
|
55
|
+
const readline = __importStar(require("readline"));
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Colors
|
|
58
|
+
// ============================================================================
|
|
59
|
+
const colors = {
|
|
60
|
+
reset: '\x1b[0m',
|
|
61
|
+
bold: '\x1b[1m',
|
|
62
|
+
dim: '\x1b[2m',
|
|
63
|
+
cyan: '\x1b[36m',
|
|
64
|
+
green: '\x1b[32m',
|
|
65
|
+
yellow: '\x1b[33m',
|
|
66
|
+
red: '\x1b[31m',
|
|
67
|
+
magenta: '\x1b[35m',
|
|
68
|
+
blue: '\x1b[34m',
|
|
69
|
+
};
|
|
70
|
+
function c(text, color, useColors) {
|
|
71
|
+
if (!useColors)
|
|
72
|
+
return text;
|
|
73
|
+
return `${colors[color]}${text}${colors.reset}`;
|
|
74
|
+
}
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// Default Config
|
|
77
|
+
// ============================================================================
|
|
78
|
+
const DEFAULT_CONFIG = {
|
|
79
|
+
defaultTimeout: 0,
|
|
80
|
+
allowSkip: true,
|
|
81
|
+
useColors: true,
|
|
82
|
+
};
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// HumanLoop Class
|
|
85
|
+
// ============================================================================
|
|
86
|
+
class HumanLoop {
|
|
87
|
+
config;
|
|
88
|
+
rl = null;
|
|
89
|
+
ownRl = false;
|
|
90
|
+
history = [];
|
|
91
|
+
constructor(config) {
|
|
92
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
93
|
+
if (config?.rl) {
|
|
94
|
+
this.rl = config.rl;
|
|
95
|
+
this.ownRl = false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Initialize readline if needed
|
|
100
|
+
*/
|
|
101
|
+
ensureRl() {
|
|
102
|
+
if (!this.rl) {
|
|
103
|
+
this.rl = readline.createInterface({
|
|
104
|
+
input: process.stdin,
|
|
105
|
+
output: process.stdout,
|
|
106
|
+
});
|
|
107
|
+
this.ownRl = true;
|
|
108
|
+
}
|
|
109
|
+
return this.rl;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Ask a question and wait for response
|
|
113
|
+
*/
|
|
114
|
+
async ask(question) {
|
|
115
|
+
const startTime = Date.now();
|
|
116
|
+
const rl = this.ensureRl();
|
|
117
|
+
// Print context if provided
|
|
118
|
+
if (question.context) {
|
|
119
|
+
console.log(c(`\n${question.context}`, 'dim', this.config.useColors));
|
|
120
|
+
}
|
|
121
|
+
// Route to appropriate handler
|
|
122
|
+
let answer;
|
|
123
|
+
switch (question.type) {
|
|
124
|
+
case 'confirm':
|
|
125
|
+
answer = await this.askConfirm(question, rl);
|
|
126
|
+
break;
|
|
127
|
+
case 'choice':
|
|
128
|
+
answer = await this.askChoice(question, rl);
|
|
129
|
+
break;
|
|
130
|
+
case 'multiChoice':
|
|
131
|
+
answer = await this.askMultiChoice(question, rl);
|
|
132
|
+
break;
|
|
133
|
+
case 'text':
|
|
134
|
+
default:
|
|
135
|
+
answer = await this.askText(question, rl);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
answer.responseTime = Date.now() - startTime;
|
|
139
|
+
this.history.push(answer);
|
|
140
|
+
// Callback
|
|
141
|
+
if (this.config.onResponse) {
|
|
142
|
+
this.config.onResponse(answer);
|
|
143
|
+
}
|
|
144
|
+
return answer;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Ask a yes/no confirmation
|
|
148
|
+
*/
|
|
149
|
+
askConfirm(question, rl) {
|
|
150
|
+
return new Promise((resolve) => {
|
|
151
|
+
const defaultStr = question.default === true ? 'Y/n' : 'y/N';
|
|
152
|
+
const prompt = `${c('?', 'yellow', this.config.useColors)} ${question.text} [${defaultStr}] `;
|
|
153
|
+
const timeout = question.timeout || this.config.defaultTimeout;
|
|
154
|
+
let timer = null;
|
|
155
|
+
if (timeout > 0) {
|
|
156
|
+
timer = setTimeout(() => {
|
|
157
|
+
console.log(c('\n(Timeout - using default)', 'dim', this.config.useColors));
|
|
158
|
+
resolve({
|
|
159
|
+
question,
|
|
160
|
+
value: question.default ?? false,
|
|
161
|
+
responded: false,
|
|
162
|
+
timedOut: true,
|
|
163
|
+
responseTime: timeout,
|
|
164
|
+
});
|
|
165
|
+
}, timeout);
|
|
166
|
+
}
|
|
167
|
+
rl.question(prompt, (input) => {
|
|
168
|
+
if (timer)
|
|
169
|
+
clearTimeout(timer);
|
|
170
|
+
const normalized = input.trim().toLowerCase();
|
|
171
|
+
let value;
|
|
172
|
+
if (normalized === '') {
|
|
173
|
+
value = question.default ?? false;
|
|
174
|
+
}
|
|
175
|
+
else if (normalized === 'y' || normalized === 'yes' || normalized === 'sì' || normalized === 'si') {
|
|
176
|
+
value = true;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
value = false;
|
|
180
|
+
}
|
|
181
|
+
resolve({
|
|
182
|
+
question,
|
|
183
|
+
value,
|
|
184
|
+
responded: true,
|
|
185
|
+
responseTime: 0,
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Ask to choose one option
|
|
192
|
+
*/
|
|
193
|
+
askChoice(question, rl) {
|
|
194
|
+
return new Promise((resolve) => {
|
|
195
|
+
const options = question.options || [];
|
|
196
|
+
// Print options
|
|
197
|
+
console.log(c(`\n${question.text}`, 'cyan', this.config.useColors));
|
|
198
|
+
for (let i = 0; i < options.length; i++) {
|
|
199
|
+
const opt = options[i];
|
|
200
|
+
const num = c(` ${i + 1}.`, 'bold', this.config.useColors);
|
|
201
|
+
const label = opt.recommended
|
|
202
|
+
? c(`${opt.label} (Recommended)`, 'green', this.config.useColors)
|
|
203
|
+
: opt.label;
|
|
204
|
+
const desc = opt.description
|
|
205
|
+
? c(` - ${opt.description}`, 'dim', this.config.useColors)
|
|
206
|
+
: '';
|
|
207
|
+
console.log(`${num} ${label}${desc}`);
|
|
208
|
+
}
|
|
209
|
+
if (this.config.allowSkip) {
|
|
210
|
+
console.log(c(` 0. Skip`, 'dim', this.config.useColors));
|
|
211
|
+
}
|
|
212
|
+
const defaultIdx = options.findIndex(o => o.value === question.default);
|
|
213
|
+
const defaultStr = defaultIdx >= 0 ? ` (default: ${defaultIdx + 1})` : '';
|
|
214
|
+
const prompt = `${c('>', 'yellow', this.config.useColors)} Choose${defaultStr}: `;
|
|
215
|
+
rl.question(prompt, (input) => {
|
|
216
|
+
const num = parseInt(input.trim(), 10);
|
|
217
|
+
if (isNaN(num) && defaultIdx >= 0) {
|
|
218
|
+
// Use default
|
|
219
|
+
resolve({
|
|
220
|
+
question,
|
|
221
|
+
value: options[defaultIdx].value,
|
|
222
|
+
responded: true,
|
|
223
|
+
responseTime: 0,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
else if (num === 0 && this.config.allowSkip) {
|
|
227
|
+
resolve({
|
|
228
|
+
question,
|
|
229
|
+
value: '',
|
|
230
|
+
responded: true,
|
|
231
|
+
cancelled: true,
|
|
232
|
+
responseTime: 0,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
else if (num >= 1 && num <= options.length) {
|
|
236
|
+
resolve({
|
|
237
|
+
question,
|
|
238
|
+
value: options[num - 1].value,
|
|
239
|
+
responded: true,
|
|
240
|
+
responseTime: 0,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
// Invalid, use first option
|
|
245
|
+
console.log(c('Invalid choice, using first option.', 'yellow', this.config.useColors));
|
|
246
|
+
resolve({
|
|
247
|
+
question,
|
|
248
|
+
value: options[0]?.value || '',
|
|
249
|
+
responded: true,
|
|
250
|
+
responseTime: 0,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Ask to choose multiple options
|
|
258
|
+
*/
|
|
259
|
+
askMultiChoice(question, rl) {
|
|
260
|
+
return new Promise((resolve) => {
|
|
261
|
+
const options = question.options || [];
|
|
262
|
+
// Print options
|
|
263
|
+
console.log(c(`\n${question.text}`, 'cyan', this.config.useColors));
|
|
264
|
+
console.log(c('(Enter comma-separated numbers, e.g., 1,3,4)', 'dim', this.config.useColors));
|
|
265
|
+
for (let i = 0; i < options.length; i++) {
|
|
266
|
+
const opt = options[i];
|
|
267
|
+
const num = c(` ${i + 1}.`, 'bold', this.config.useColors);
|
|
268
|
+
const label = opt.label;
|
|
269
|
+
const desc = opt.description
|
|
270
|
+
? c(` - ${opt.description}`, 'dim', this.config.useColors)
|
|
271
|
+
: '';
|
|
272
|
+
console.log(`${num} ${label}${desc}`);
|
|
273
|
+
}
|
|
274
|
+
const prompt = `${c('>', 'yellow', this.config.useColors)} Choose: `;
|
|
275
|
+
rl.question(prompt, (input) => {
|
|
276
|
+
const nums = input.split(',')
|
|
277
|
+
.map(s => parseInt(s.trim(), 10))
|
|
278
|
+
.filter(n => !isNaN(n) && n >= 1 && n <= options.length);
|
|
279
|
+
const values = nums.map(n => options[n - 1].value);
|
|
280
|
+
resolve({
|
|
281
|
+
question,
|
|
282
|
+
value: values,
|
|
283
|
+
responded: true,
|
|
284
|
+
responseTime: 0,
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Ask for free-form text input
|
|
291
|
+
*/
|
|
292
|
+
askText(question, rl) {
|
|
293
|
+
return new Promise((resolve) => {
|
|
294
|
+
const defaultStr = question.default ? ` (${question.default})` : '';
|
|
295
|
+
const prompt = `${c('?', 'yellow', this.config.useColors)} ${question.text}${defaultStr}: `;
|
|
296
|
+
rl.question(prompt, (input) => {
|
|
297
|
+
const value = input.trim() || question.default || '';
|
|
298
|
+
resolve({
|
|
299
|
+
question,
|
|
300
|
+
value,
|
|
301
|
+
responded: true,
|
|
302
|
+
responseTime: 0,
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
// ==========================================================================
|
|
308
|
+
// Convenience Methods
|
|
309
|
+
// ==========================================================================
|
|
310
|
+
/**
|
|
311
|
+
* Quick confirmation
|
|
312
|
+
*/
|
|
313
|
+
async confirm(text, defaultValue = false) {
|
|
314
|
+
const answer = await this.ask({
|
|
315
|
+
type: 'confirm',
|
|
316
|
+
text,
|
|
317
|
+
default: defaultValue,
|
|
318
|
+
});
|
|
319
|
+
return answer.value;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Quick choice
|
|
323
|
+
*/
|
|
324
|
+
async choose(text, options) {
|
|
325
|
+
const answer = await this.ask({
|
|
326
|
+
type: 'choice',
|
|
327
|
+
text,
|
|
328
|
+
options: options.map(o => ({ value: o, label: o })),
|
|
329
|
+
});
|
|
330
|
+
return answer.value;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Quick text input
|
|
334
|
+
*/
|
|
335
|
+
async input(text, defaultValue) {
|
|
336
|
+
const answer = await this.ask({
|
|
337
|
+
type: 'text',
|
|
338
|
+
text,
|
|
339
|
+
default: defaultValue,
|
|
340
|
+
});
|
|
341
|
+
return answer.value;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Ask for confirmation before destructive operation
|
|
345
|
+
*/
|
|
346
|
+
async confirmDestructive(operation, details) {
|
|
347
|
+
console.log(c('\n⚠️ DESTRUCTIVE OPERATION', 'red', this.config.useColors));
|
|
348
|
+
console.log(c(`Operation: ${operation}`, 'yellow', this.config.useColors));
|
|
349
|
+
if (details) {
|
|
350
|
+
console.log(c(`Details: ${details}`, 'dim', this.config.useColors));
|
|
351
|
+
}
|
|
352
|
+
return this.confirm('Are you sure you want to proceed?', false);
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Ask for clarification
|
|
356
|
+
*/
|
|
357
|
+
async clarify(context, options) {
|
|
358
|
+
if (options && options.length > 0) {
|
|
359
|
+
const answer = await this.ask({
|
|
360
|
+
type: 'choice',
|
|
361
|
+
text: 'Please clarify your intent:',
|
|
362
|
+
context,
|
|
363
|
+
options,
|
|
364
|
+
});
|
|
365
|
+
return answer.value;
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
const answer = await this.ask({
|
|
369
|
+
type: 'text',
|
|
370
|
+
text: 'Please provide more details:',
|
|
371
|
+
context,
|
|
372
|
+
});
|
|
373
|
+
return answer.value;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Present implementation options
|
|
378
|
+
*/
|
|
379
|
+
async chooseApproach(task, approaches) {
|
|
380
|
+
const answer = await this.ask({
|
|
381
|
+
type: 'choice',
|
|
382
|
+
text: `How would you like to approach: "${task}"?`,
|
|
383
|
+
options: approaches.map(a => ({
|
|
384
|
+
value: a.name,
|
|
385
|
+
label: a.name,
|
|
386
|
+
description: a.description,
|
|
387
|
+
recommended: a.recommended,
|
|
388
|
+
})),
|
|
389
|
+
});
|
|
390
|
+
return answer.value;
|
|
391
|
+
}
|
|
392
|
+
// ==========================================================================
|
|
393
|
+
// History & State
|
|
394
|
+
// ==========================================================================
|
|
395
|
+
/**
|
|
396
|
+
* Get answer history
|
|
397
|
+
*/
|
|
398
|
+
getHistory() {
|
|
399
|
+
return [...this.history];
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Clear history
|
|
403
|
+
*/
|
|
404
|
+
clearHistory() {
|
|
405
|
+
this.history = [];
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Get statistics
|
|
409
|
+
*/
|
|
410
|
+
stats() {
|
|
411
|
+
const responded = this.history.filter(a => a.responded && !a.cancelled && !a.timedOut).length;
|
|
412
|
+
const timedOut = this.history.filter(a => a.timedOut).length;
|
|
413
|
+
const cancelled = this.history.filter(a => a.cancelled).length;
|
|
414
|
+
const avgResponseTime = this.history.length > 0
|
|
415
|
+
? this.history.reduce((sum, a) => sum + a.responseTime, 0) / this.history.length
|
|
416
|
+
: 0;
|
|
417
|
+
return {
|
|
418
|
+
totalQuestions: this.history.length,
|
|
419
|
+
responded,
|
|
420
|
+
timedOut,
|
|
421
|
+
cancelled,
|
|
422
|
+
avgResponseTime,
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Close (cleanup readline if we created it)
|
|
427
|
+
*/
|
|
428
|
+
close() {
|
|
429
|
+
if (this.ownRl && this.rl) {
|
|
430
|
+
this.rl.close();
|
|
431
|
+
this.rl = null;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
exports.HumanLoop = HumanLoop;
|
|
436
|
+
// ============================================================================
|
|
437
|
+
// Singleton
|
|
438
|
+
// ============================================================================
|
|
439
|
+
let humanLoopInstance = null;
|
|
440
|
+
function getHumanLoop(config) {
|
|
441
|
+
if (!humanLoopInstance) {
|
|
442
|
+
humanLoopInstance = new HumanLoop(config);
|
|
443
|
+
}
|
|
444
|
+
return humanLoopInstance;
|
|
445
|
+
}
|
|
446
|
+
function resetHumanLoop() {
|
|
447
|
+
if (humanLoopInstance) {
|
|
448
|
+
humanLoopInstance.close();
|
|
449
|
+
humanLoopInstance = null;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
// ============================================================================
|
|
453
|
+
// Tool Registration
|
|
454
|
+
// ============================================================================
|
|
455
|
+
const index_js_1 = require("../tools/index.js");
|
|
456
|
+
/**
|
|
457
|
+
* AskUser tool - for LLM to request human input
|
|
458
|
+
*/
|
|
459
|
+
const askUserTool = {
|
|
460
|
+
name: 'ask_user',
|
|
461
|
+
description: 'Ask the user a question and wait for their response',
|
|
462
|
+
execute: async (params) => {
|
|
463
|
+
const humanLoop = getHumanLoop();
|
|
464
|
+
const type = params.type || 'text';
|
|
465
|
+
const text = params.text || params.question || 'Please respond:';
|
|
466
|
+
const options = params.options;
|
|
467
|
+
const context = params.context;
|
|
468
|
+
const defaultValue = params.default;
|
|
469
|
+
const answer = await humanLoop.ask({
|
|
470
|
+
type,
|
|
471
|
+
text,
|
|
472
|
+
options,
|
|
473
|
+
context,
|
|
474
|
+
default: defaultValue,
|
|
475
|
+
});
|
|
476
|
+
return {
|
|
477
|
+
success: answer.responded,
|
|
478
|
+
answer: answer.value,
|
|
479
|
+
cancelled: answer.cancelled,
|
|
480
|
+
timedOut: answer.timedOut,
|
|
481
|
+
};
|
|
482
|
+
},
|
|
483
|
+
validate: (params) => {
|
|
484
|
+
const text = params.text || params.question;
|
|
485
|
+
if (!text) {
|
|
486
|
+
return { valid: false, reason: 'Missing question text' };
|
|
487
|
+
}
|
|
488
|
+
return { valid: true };
|
|
489
|
+
},
|
|
490
|
+
};
|
|
491
|
+
/**
|
|
492
|
+
* Confirm tool - quick yes/no confirmation
|
|
493
|
+
*/
|
|
494
|
+
const confirmTool = {
|
|
495
|
+
name: 'confirm',
|
|
496
|
+
description: 'Ask the user for yes/no confirmation',
|
|
497
|
+
execute: async (params) => {
|
|
498
|
+
const humanLoop = getHumanLoop();
|
|
499
|
+
const text = params.text || params.question || 'Do you confirm?';
|
|
500
|
+
const defaultValue = params.default ?? false;
|
|
501
|
+
const confirmed = await humanLoop.confirm(text, defaultValue);
|
|
502
|
+
return {
|
|
503
|
+
success: true,
|
|
504
|
+
confirmed,
|
|
505
|
+
};
|
|
506
|
+
},
|
|
507
|
+
};
|
|
508
|
+
// Register tools
|
|
509
|
+
index_js_1.toolRegistry.set('ask_user', askUserTool);
|
|
510
|
+
index_js_1.toolRegistry.set('confirm', confirmTool);
|
|
511
|
+
// ============================================================================
|
|
512
|
+
// Convenience Functions
|
|
513
|
+
// ============================================================================
|
|
514
|
+
/**
|
|
515
|
+
* Quick confirmation
|
|
516
|
+
*/
|
|
517
|
+
async function confirm(text, defaultValue = false) {
|
|
518
|
+
return getHumanLoop().confirm(text, defaultValue);
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Quick choice
|
|
522
|
+
*/
|
|
523
|
+
async function choose(text, options) {
|
|
524
|
+
return getHumanLoop().choose(text, options);
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Quick text input
|
|
528
|
+
*/
|
|
529
|
+
async function input(text, defaultValue) {
|
|
530
|
+
return getHumanLoop().input(text, defaultValue);
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Confirm destructive operation
|
|
534
|
+
*/
|
|
535
|
+
async function confirmDestructive(operation, details) {
|
|
536
|
+
return getHumanLoop().confirmDestructive(operation, details);
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Ask for clarification
|
|
540
|
+
*/
|
|
541
|
+
async function clarify(context, options) {
|
|
542
|
+
return getHumanLoop().clarify(context, options);
|
|
543
|
+
}
|