@yuaone/core 0.1.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 +663 -0
- package/README.md +15 -0
- package/dist/__tests__/context-manager.test.d.ts +6 -0
- package/dist/__tests__/context-manager.test.d.ts.map +1 -0
- package/dist/__tests__/context-manager.test.js +220 -0
- package/dist/__tests__/context-manager.test.js.map +1 -0
- package/dist/__tests__/governor.test.d.ts +6 -0
- package/dist/__tests__/governor.test.d.ts.map +1 -0
- package/dist/__tests__/governor.test.js +210 -0
- package/dist/__tests__/governor.test.js.map +1 -0
- package/dist/__tests__/model-router.test.d.ts +6 -0
- package/dist/__tests__/model-router.test.d.ts.map +1 -0
- package/dist/__tests__/model-router.test.js +329 -0
- package/dist/__tests__/model-router.test.js.map +1 -0
- package/dist/agent-logger.d.ts +384 -0
- package/dist/agent-logger.d.ts.map +1 -0
- package/dist/agent-logger.js +820 -0
- package/dist/agent-logger.js.map +1 -0
- package/dist/agent-loop.d.ts +163 -0
- package/dist/agent-loop.d.ts.map +1 -0
- package/dist/agent-loop.js +609 -0
- package/dist/agent-loop.js.map +1 -0
- package/dist/agent-modes.d.ts +85 -0
- package/dist/agent-modes.d.ts.map +1 -0
- package/dist/agent-modes.js +418 -0
- package/dist/agent-modes.js.map +1 -0
- package/dist/approval.d.ts +137 -0
- package/dist/approval.d.ts.map +1 -0
- package/dist/approval.js +299 -0
- package/dist/approval.js.map +1 -0
- package/dist/async-completion-queue.d.ts +56 -0
- package/dist/async-completion-queue.d.ts.map +1 -0
- package/dist/async-completion-queue.js +77 -0
- package/dist/async-completion-queue.js.map +1 -0
- package/dist/auto-fix.d.ts +174 -0
- package/dist/auto-fix.d.ts.map +1 -0
- package/dist/auto-fix.js +319 -0
- package/dist/auto-fix.js.map +1 -0
- package/dist/codebase-context.d.ts +396 -0
- package/dist/codebase-context.d.ts.map +1 -0
- package/dist/codebase-context.js +1260 -0
- package/dist/codebase-context.js.map +1 -0
- package/dist/conflict-resolver.d.ts +191 -0
- package/dist/conflict-resolver.d.ts.map +1 -0
- package/dist/conflict-resolver.js +524 -0
- package/dist/conflict-resolver.js.map +1 -0
- package/dist/constants.d.ts +52 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +141 -0
- package/dist/constants.js.map +1 -0
- package/dist/context-budget.d.ts +435 -0
- package/dist/context-budget.d.ts.map +1 -0
- package/dist/context-budget.js +903 -0
- package/dist/context-budget.js.map +1 -0
- package/dist/context-compressor.d.ts +143 -0
- package/dist/context-compressor.d.ts.map +1 -0
- package/dist/context-compressor.js +511 -0
- package/dist/context-compressor.js.map +1 -0
- package/dist/context-manager.d.ts +112 -0
- package/dist/context-manager.d.ts.map +1 -0
- package/dist/context-manager.js +247 -0
- package/dist/context-manager.js.map +1 -0
- package/dist/continuous-reflection.d.ts +267 -0
- package/dist/continuous-reflection.d.ts.map +1 -0
- package/dist/continuous-reflection.js +338 -0
- package/dist/continuous-reflection.js.map +1 -0
- package/dist/cross-file-refactor.d.ts +352 -0
- package/dist/cross-file-refactor.d.ts.map +1 -0
- package/dist/cross-file-refactor.js +1544 -0
- package/dist/cross-file-refactor.js.map +1 -0
- package/dist/dag-orchestrator.d.ts +138 -0
- package/dist/dag-orchestrator.d.ts.map +1 -0
- package/dist/dag-orchestrator.js +379 -0
- package/dist/dag-orchestrator.js.map +1 -0
- package/dist/debate-orchestrator.d.ts +301 -0
- package/dist/debate-orchestrator.d.ts.map +1 -0
- package/dist/debate-orchestrator.js +719 -0
- package/dist/debate-orchestrator.js.map +1 -0
- package/dist/dependency-analyzer.d.ts +113 -0
- package/dist/dependency-analyzer.d.ts.map +1 -0
- package/dist/dependency-analyzer.js +444 -0
- package/dist/dependency-analyzer.js.map +1 -0
- package/dist/design-loop.d.ts +59 -0
- package/dist/design-loop.d.ts.map +1 -0
- package/dist/design-loop.js +344 -0
- package/dist/design-loop.js.map +1 -0
- package/dist/doc-intelligence.d.ts +383 -0
- package/dist/doc-intelligence.d.ts.map +1 -0
- package/dist/doc-intelligence.js +1307 -0
- package/dist/doc-intelligence.js.map +1 -0
- package/dist/dynamic-role-generator.d.ts +76 -0
- package/dist/dynamic-role-generator.d.ts.map +1 -0
- package/dist/dynamic-role-generator.js +194 -0
- package/dist/dynamic-role-generator.js.map +1 -0
- package/dist/errors.d.ts +69 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +102 -0
- package/dist/errors.js.map +1 -0
- package/dist/event-bus.d.ts +159 -0
- package/dist/event-bus.d.ts.map +1 -0
- package/dist/event-bus.js +305 -0
- package/dist/event-bus.js.map +1 -0
- package/dist/execution-engine.d.ts +425 -0
- package/dist/execution-engine.d.ts.map +1 -0
- package/dist/execution-engine.js +1555 -0
- package/dist/execution-engine.js.map +1 -0
- package/dist/git-intelligence.d.ts +306 -0
- package/dist/git-intelligence.d.ts.map +1 -0
- package/dist/git-intelligence.js +1099 -0
- package/dist/git-intelligence.js.map +1 -0
- package/dist/governor.d.ts +77 -0
- package/dist/governor.d.ts.map +1 -0
- package/dist/governor.js +161 -0
- package/dist/governor.js.map +1 -0
- package/dist/hierarchical-planner.d.ts +313 -0
- package/dist/hierarchical-planner.d.ts.map +1 -0
- package/dist/hierarchical-planner.js +981 -0
- package/dist/hierarchical-planner.js.map +1 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +123 -0
- package/dist/index.js.map +1 -0
- package/dist/intent-inference.d.ts +103 -0
- package/dist/intent-inference.d.ts.map +1 -0
- package/dist/intent-inference.js +605 -0
- package/dist/intent-inference.js.map +1 -0
- package/dist/interrupt-manager.d.ts +143 -0
- package/dist/interrupt-manager.d.ts.map +1 -0
- package/dist/interrupt-manager.js +196 -0
- package/dist/interrupt-manager.js.map +1 -0
- package/dist/kernel.d.ts +564 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +1419 -0
- package/dist/kernel.js.map +1 -0
- package/dist/language-support.d.ts +232 -0
- package/dist/language-support.d.ts.map +1 -0
- package/dist/language-support.js +1134 -0
- package/dist/language-support.js.map +1 -0
- package/dist/llm-client.d.ts +82 -0
- package/dist/llm-client.d.ts.map +1 -0
- package/dist/llm-client.js +475 -0
- package/dist/llm-client.js.map +1 -0
- package/dist/mcp-client.d.ts +232 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +718 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/memory-manager.d.ts +200 -0
- package/dist/memory-manager.d.ts.map +1 -0
- package/dist/memory-manager.js +568 -0
- package/dist/memory-manager.js.map +1 -0
- package/dist/memory.d.ts +87 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +341 -0
- package/dist/memory.js.map +1 -0
- package/dist/model-router.d.ts +245 -0
- package/dist/model-router.d.ts.map +1 -0
- package/dist/model-router.js +632 -0
- package/dist/model-router.js.map +1 -0
- package/dist/parallel-executor.d.ts +125 -0
- package/dist/parallel-executor.d.ts.map +1 -0
- package/dist/parallel-executor.js +201 -0
- package/dist/parallel-executor.js.map +1 -0
- package/dist/perf-optimizer.d.ts +212 -0
- package/dist/perf-optimizer.d.ts.map +1 -0
- package/dist/perf-optimizer.js +721 -0
- package/dist/perf-optimizer.js.map +1 -0
- package/dist/persona.d.ts +305 -0
- package/dist/persona.d.ts.map +1 -0
- package/dist/persona.js +887 -0
- package/dist/persona.js.map +1 -0
- package/dist/planner.d.ts +70 -0
- package/dist/planner.d.ts.map +1 -0
- package/dist/planner.js +264 -0
- package/dist/planner.js.map +1 -0
- package/dist/qa-pipeline.d.ts +365 -0
- package/dist/qa-pipeline.d.ts.map +1 -0
- package/dist/qa-pipeline.js +1352 -0
- package/dist/qa-pipeline.js.map +1 -0
- package/dist/reasoning-adapter.d.ts +116 -0
- package/dist/reasoning-adapter.d.ts.map +1 -0
- package/dist/reasoning-adapter.js +187 -0
- package/dist/reasoning-adapter.js.map +1 -0
- package/dist/role-registry.d.ts +55 -0
- package/dist/role-registry.d.ts.map +1 -0
- package/dist/role-registry.js +192 -0
- package/dist/role-registry.js.map +1 -0
- package/dist/sandbox-tiers.d.ts +327 -0
- package/dist/sandbox-tiers.d.ts.map +1 -0
- package/dist/sandbox-tiers.js +928 -0
- package/dist/sandbox-tiers.js.map +1 -0
- package/dist/security-scanner.d.ts +222 -0
- package/dist/security-scanner.d.ts.map +1 -0
- package/dist/security-scanner.js +1129 -0
- package/dist/security-scanner.js.map +1 -0
- package/dist/security.d.ts +93 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +393 -0
- package/dist/security.js.map +1 -0
- package/dist/self-reflection.d.ts +397 -0
- package/dist/self-reflection.d.ts.map +1 -0
- package/dist/self-reflection.js +908 -0
- package/dist/self-reflection.js.map +1 -0
- package/dist/session-persistence.d.ts +191 -0
- package/dist/session-persistence.d.ts.map +1 -0
- package/dist/session-persistence.js +395 -0
- package/dist/session-persistence.js.map +1 -0
- package/dist/speculative-executor.d.ts +210 -0
- package/dist/speculative-executor.d.ts.map +1 -0
- package/dist/speculative-executor.js +618 -0
- package/dist/speculative-executor.js.map +1 -0
- package/dist/state-machine.d.ts +289 -0
- package/dist/state-machine.d.ts.map +1 -0
- package/dist/state-machine.js +695 -0
- package/dist/state-machine.js.map +1 -0
- package/dist/sub-agent.d.ts +177 -0
- package/dist/sub-agent.d.ts.map +1 -0
- package/dist/sub-agent.js +303 -0
- package/dist/sub-agent.js.map +1 -0
- package/dist/system-prompt.d.ts +26 -0
- package/dist/system-prompt.d.ts.map +1 -0
- package/dist/system-prompt.js +84 -0
- package/dist/system-prompt.js.map +1 -0
- package/dist/test-intelligence.d.ts +439 -0
- package/dist/test-intelligence.d.ts.map +1 -0
- package/dist/test-intelligence.js +1165 -0
- package/dist/test-intelligence.js.map +1 -0
- package/dist/types.d.ts +632 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/vector-index.d.ts +314 -0
- package/dist/vector-index.d.ts.map +1 -0
- package/dist/vector-index.js +618 -0
- package/dist/vector-index.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module interrupt-manager
|
|
3
|
+
* @description 인터럽트 매니저 — 설계 문서 섹션 21.2 구현.
|
|
4
|
+
*
|
|
5
|
+
* CLI/Web/팀에서 에이전트에 전달되는 인터럽트를 처리한다.
|
|
6
|
+
*
|
|
7
|
+
* 인터럽트 유형:
|
|
8
|
+
* - soft: 현재 도구 실행 취소 + 피드백 주입 → 에이전트 루프 계속
|
|
9
|
+
* - hard: 모든 실행 즉시 중단 + 비상 체크포인트 + paused 상태
|
|
10
|
+
* - pause: 에이전트 루프 일시 정지 (상태 유지)
|
|
11
|
+
* - resume: 일시 정지된 에이전트 루프 재개
|
|
12
|
+
*
|
|
13
|
+
* EventEmitter를 확장하여 인터럽트 이벤트를 외부에 전파한다.
|
|
14
|
+
*/
|
|
15
|
+
import { EventEmitter } from "node:events";
|
|
16
|
+
import type { InterruptSignal } from "./types.js";
|
|
17
|
+
/** InterruptManager가 발행하는 이벤트 맵 */
|
|
18
|
+
export interface InterruptManagerEvents {
|
|
19
|
+
/** soft interrupt 발생 */
|
|
20
|
+
"interrupt:soft": [signal: InterruptSignal];
|
|
21
|
+
/** hard interrupt 발생 — 전체 중단 */
|
|
22
|
+
"interrupt:hard": [signal: InterruptSignal];
|
|
23
|
+
/** 일시 정지 */
|
|
24
|
+
"interrupt:pause": [signal: InterruptSignal];
|
|
25
|
+
/** 재개 */
|
|
26
|
+
"interrupt:resume": [signal: InterruptSignal];
|
|
27
|
+
/** 피드백 주입 요청 (agent loop이 수신) */
|
|
28
|
+
"interrupt:feedback": [feedback: string];
|
|
29
|
+
/** 비상 체크포인트 요청 (reflection/persistence가 수신) */
|
|
30
|
+
"interrupt:emergency_checkpoint": [];
|
|
31
|
+
/** 세션 상태 변경 요청 */
|
|
32
|
+
"interrupt:status_change": [status: "paused" | "running"];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 인터럽트 매니저.
|
|
36
|
+
*
|
|
37
|
+
* 에이전트 실행 중 외부(CLI/Web/팀)에서 전달되는 인터럽트를 처리한다.
|
|
38
|
+
* AbortController를 관리하여 현재 실행 중인 도구를 취소할 수 있다.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const im = new InterruptManager();
|
|
43
|
+
*
|
|
44
|
+
* // 도구 실행 시 AbortController 등록
|
|
45
|
+
* const ac = new AbortController();
|
|
46
|
+
* im.registerToolAbort(ac);
|
|
47
|
+
* await shellExec(cmd, { signal: ac.signal });
|
|
48
|
+
*
|
|
49
|
+
* // soft interrupt: 현재 도구 취소 + 피드백 주입
|
|
50
|
+
* im.interrupt({ type: "soft", feedback: "다른 방향으로", source: "cli" });
|
|
51
|
+
*
|
|
52
|
+
* // hard interrupt: 전체 중단
|
|
53
|
+
* im.interrupt({ type: "hard", source: "web" });
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare class InterruptManager extends EventEmitter {
|
|
57
|
+
/** 현재 실행 중인 도구의 AbortController */
|
|
58
|
+
private currentToolAbort;
|
|
59
|
+
/** 에이전트 루프 일시 정지 여부 */
|
|
60
|
+
private paused;
|
|
61
|
+
/** 인터럽트 히스토리 (디버깅/감사용, 최근 50개) */
|
|
62
|
+
private readonly history;
|
|
63
|
+
private static readonly MAX_HISTORY;
|
|
64
|
+
/**
|
|
65
|
+
* 인터럽트를 처리한다.
|
|
66
|
+
*
|
|
67
|
+
* @param signal - 인터럽트 시그널 (type, feedback, source, userId)
|
|
68
|
+
*/
|
|
69
|
+
interrupt(signal: InterruptSignal): void;
|
|
70
|
+
/**
|
|
71
|
+
* 현재 실행 중인 도구의 AbortController를 등록한다.
|
|
72
|
+
*
|
|
73
|
+
* 도구 실행 시작 시 호출하여, soft/hard interrupt 시
|
|
74
|
+
* 해당 도구를 취소할 수 있도록 한다.
|
|
75
|
+
*
|
|
76
|
+
* @param controller - 도구 실행에 사용되는 AbortController
|
|
77
|
+
*/
|
|
78
|
+
registerToolAbort(controller: AbortController): void;
|
|
79
|
+
/**
|
|
80
|
+
* 현재 등록된 AbortController를 해제한다.
|
|
81
|
+
*
|
|
82
|
+
* 도구 실행 완료 후 호출하여, 다음 도구와 혼선을 방지한다.
|
|
83
|
+
*/
|
|
84
|
+
clearToolAbort(): void;
|
|
85
|
+
/**
|
|
86
|
+
* 에이전트 루프가 일시 정지 상태인지 확인한다.
|
|
87
|
+
*
|
|
88
|
+
* 에이전트 루프는 매 iteration 시작 시 이 값을 확인하고,
|
|
89
|
+
* true이면 resume될 때까지 대기해야 한다.
|
|
90
|
+
*/
|
|
91
|
+
isPaused(): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* 인터럽트 히스토리를 반환한다 (디버깅/감사용).
|
|
94
|
+
*
|
|
95
|
+
* @returns 최근 인터럽트 기록 (최대 50개)
|
|
96
|
+
*/
|
|
97
|
+
getHistory(): ReadonlyArray<{
|
|
98
|
+
signal: InterruptSignal;
|
|
99
|
+
timestamp: number;
|
|
100
|
+
}>;
|
|
101
|
+
/**
|
|
102
|
+
* 상태를 초기화한다.
|
|
103
|
+
*
|
|
104
|
+
* 새 세션 시작 시 호출하여 이전 상태를 정리한다.
|
|
105
|
+
*/
|
|
106
|
+
reset(): void;
|
|
107
|
+
/**
|
|
108
|
+
* Soft interrupt 처리.
|
|
109
|
+
*
|
|
110
|
+
* 1. 현재 도구 실행 취소 (AbortController.abort())
|
|
111
|
+
* 2. 피드백이 있으면 에이전트 컨텍스트에 주입
|
|
112
|
+
* 3. 이벤트 발행 → 에이전트 루프는 계속 진행
|
|
113
|
+
*/
|
|
114
|
+
private handleSoftInterrupt;
|
|
115
|
+
/**
|
|
116
|
+
* Hard interrupt 처리.
|
|
117
|
+
*
|
|
118
|
+
* 1. 모든 실행 즉시 중단 (도구 취소)
|
|
119
|
+
* 2. 비상 체크포인트 요청 발행
|
|
120
|
+
* 3. 세션 상태 → paused
|
|
121
|
+
* 4. 이벤트 발행
|
|
122
|
+
*/
|
|
123
|
+
private handleHardInterrupt;
|
|
124
|
+
/**
|
|
125
|
+
* Pause 처리.
|
|
126
|
+
*
|
|
127
|
+
* 에이전트 루프를 일시 정지한다.
|
|
128
|
+
* 상태는 유지되며, 현재 진행 중인 도구 실행은 완료될 수 있다.
|
|
129
|
+
*/
|
|
130
|
+
private handlePause;
|
|
131
|
+
/**
|
|
132
|
+
* Resume 처리.
|
|
133
|
+
*
|
|
134
|
+
* 일시 정지된 에이전트 루프를 재개한다.
|
|
135
|
+
*/
|
|
136
|
+
private handleResume;
|
|
137
|
+
/**
|
|
138
|
+
* 인터럽트를 히스토리에 기록한다.
|
|
139
|
+
* 최대 MAX_HISTORY개까지 유지하며, 초과 시 오래된 것부터 제거.
|
|
140
|
+
*/
|
|
141
|
+
private recordHistory;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=interrupt-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interrupt-manager.d.ts","sourceRoot":"","sources":["../src/interrupt-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAA0C,MAAM,YAAY,CAAC;AAI1F,mCAAmC;AACnC,MAAM,WAAW,sBAAsB;IACrC,wBAAwB;IACxB,gBAAgB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C,gCAAgC;IAChC,gBAAgB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5C,YAAY;IACZ,iBAAiB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,SAAS;IACT,kBAAkB,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC9C,iCAAiC;IACjC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACzC,+CAA+C;IAC/C,gCAAgC,EAAE,EAAE,CAAC;IACrC,kBAAkB;IAClB,yBAAyB,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC;CAC3D;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,mCAAmC;IACnC,OAAO,CAAC,gBAAgB,CAAgC;IAExD,uBAAuB;IACvB,OAAO,CAAC,MAAM,CAAS;IAEvB,kCAAkC;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6D;IACrF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAM;IAEzC;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAuBxC;;;;;;;OAOG;IACH,iBAAiB,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IAIpD;;;;OAIG;IACH,cAAc,IAAI,IAAI;IAItB;;;;;OAKG;IACH,QAAQ,IAAI,OAAO;IAInB;;;;OAIG;IACH,UAAU,IAAI,aAAa,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAI3E;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAQb;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAgB3B;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAQnB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAQpB;;;OAGG;IACH,OAAO,CAAC,aAAa;CAMtB"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module interrupt-manager
|
|
3
|
+
* @description 인터럽트 매니저 — 설계 문서 섹션 21.2 구현.
|
|
4
|
+
*
|
|
5
|
+
* CLI/Web/팀에서 에이전트에 전달되는 인터럽트를 처리한다.
|
|
6
|
+
*
|
|
7
|
+
* 인터럽트 유형:
|
|
8
|
+
* - soft: 현재 도구 실행 취소 + 피드백 주입 → 에이전트 루프 계속
|
|
9
|
+
* - hard: 모든 실행 즉시 중단 + 비상 체크포인트 + paused 상태
|
|
10
|
+
* - pause: 에이전트 루프 일시 정지 (상태 유지)
|
|
11
|
+
* - resume: 일시 정지된 에이전트 루프 재개
|
|
12
|
+
*
|
|
13
|
+
* EventEmitter를 확장하여 인터럽트 이벤트를 외부에 전파한다.
|
|
14
|
+
*/
|
|
15
|
+
import { EventEmitter } from "node:events";
|
|
16
|
+
// ─── InterruptManager ────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* 인터럽트 매니저.
|
|
19
|
+
*
|
|
20
|
+
* 에이전트 실행 중 외부(CLI/Web/팀)에서 전달되는 인터럽트를 처리한다.
|
|
21
|
+
* AbortController를 관리하여 현재 실행 중인 도구를 취소할 수 있다.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const im = new InterruptManager();
|
|
26
|
+
*
|
|
27
|
+
* // 도구 실행 시 AbortController 등록
|
|
28
|
+
* const ac = new AbortController();
|
|
29
|
+
* im.registerToolAbort(ac);
|
|
30
|
+
* await shellExec(cmd, { signal: ac.signal });
|
|
31
|
+
*
|
|
32
|
+
* // soft interrupt: 현재 도구 취소 + 피드백 주입
|
|
33
|
+
* im.interrupt({ type: "soft", feedback: "다른 방향으로", source: "cli" });
|
|
34
|
+
*
|
|
35
|
+
* // hard interrupt: 전체 중단
|
|
36
|
+
* im.interrupt({ type: "hard", source: "web" });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export class InterruptManager extends EventEmitter {
|
|
40
|
+
/** 현재 실행 중인 도구의 AbortController */
|
|
41
|
+
currentToolAbort = null;
|
|
42
|
+
/** 에이전트 루프 일시 정지 여부 */
|
|
43
|
+
paused = false;
|
|
44
|
+
/** 인터럽트 히스토리 (디버깅/감사용, 최근 50개) */
|
|
45
|
+
history = [];
|
|
46
|
+
static MAX_HISTORY = 50;
|
|
47
|
+
/**
|
|
48
|
+
* 인터럽트를 처리한다.
|
|
49
|
+
*
|
|
50
|
+
* @param signal - 인터럽트 시그널 (type, feedback, source, userId)
|
|
51
|
+
*/
|
|
52
|
+
interrupt(signal) {
|
|
53
|
+
// 히스토리 기록
|
|
54
|
+
this.recordHistory(signal);
|
|
55
|
+
switch (signal.type) {
|
|
56
|
+
case "soft":
|
|
57
|
+
this.handleSoftInterrupt(signal);
|
|
58
|
+
break;
|
|
59
|
+
case "hard":
|
|
60
|
+
this.handleHardInterrupt(signal);
|
|
61
|
+
break;
|
|
62
|
+
case "pause":
|
|
63
|
+
this.handlePause(signal);
|
|
64
|
+
break;
|
|
65
|
+
case "resume":
|
|
66
|
+
this.handleResume(signal);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 현재 실행 중인 도구의 AbortController를 등록한다.
|
|
72
|
+
*
|
|
73
|
+
* 도구 실행 시작 시 호출하여, soft/hard interrupt 시
|
|
74
|
+
* 해당 도구를 취소할 수 있도록 한다.
|
|
75
|
+
*
|
|
76
|
+
* @param controller - 도구 실행에 사용되는 AbortController
|
|
77
|
+
*/
|
|
78
|
+
registerToolAbort(controller) {
|
|
79
|
+
this.currentToolAbort = controller;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 현재 등록된 AbortController를 해제한다.
|
|
83
|
+
*
|
|
84
|
+
* 도구 실행 완료 후 호출하여, 다음 도구와 혼선을 방지한다.
|
|
85
|
+
*/
|
|
86
|
+
clearToolAbort() {
|
|
87
|
+
this.currentToolAbort = null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 에이전트 루프가 일시 정지 상태인지 확인한다.
|
|
91
|
+
*
|
|
92
|
+
* 에이전트 루프는 매 iteration 시작 시 이 값을 확인하고,
|
|
93
|
+
* true이면 resume될 때까지 대기해야 한다.
|
|
94
|
+
*/
|
|
95
|
+
isPaused() {
|
|
96
|
+
return this.paused;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* 인터럽트 히스토리를 반환한다 (디버깅/감사용).
|
|
100
|
+
*
|
|
101
|
+
* @returns 최근 인터럽트 기록 (최대 50개)
|
|
102
|
+
*/
|
|
103
|
+
getHistory() {
|
|
104
|
+
return this.history;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 상태를 초기화한다.
|
|
108
|
+
*
|
|
109
|
+
* 새 세션 시작 시 호출하여 이전 상태를 정리한다.
|
|
110
|
+
*/
|
|
111
|
+
reset() {
|
|
112
|
+
this.currentToolAbort = null;
|
|
113
|
+
this.paused = false;
|
|
114
|
+
this.history.length = 0;
|
|
115
|
+
}
|
|
116
|
+
// ─── Private Handlers ────────────────────────────────────────
|
|
117
|
+
/**
|
|
118
|
+
* Soft interrupt 처리.
|
|
119
|
+
*
|
|
120
|
+
* 1. 현재 도구 실행 취소 (AbortController.abort())
|
|
121
|
+
* 2. 피드백이 있으면 에이전트 컨텍스트에 주입
|
|
122
|
+
* 3. 이벤트 발행 → 에이전트 루프는 계속 진행
|
|
123
|
+
*/
|
|
124
|
+
handleSoftInterrupt(signal) {
|
|
125
|
+
// 1. 현재 도구 실행 취소
|
|
126
|
+
if (this.currentToolAbort && !this.currentToolAbort.signal.aborted) {
|
|
127
|
+
this.currentToolAbort.abort();
|
|
128
|
+
}
|
|
129
|
+
this.currentToolAbort = null;
|
|
130
|
+
// 2. 피드백 주입 요청
|
|
131
|
+
if (signal.feedback) {
|
|
132
|
+
this.emit("interrupt:feedback", `[유저 Interrupt] ${signal.feedback}`);
|
|
133
|
+
}
|
|
134
|
+
// 3. 이벤트 발행
|
|
135
|
+
this.emit("interrupt:soft", signal);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Hard interrupt 처리.
|
|
139
|
+
*
|
|
140
|
+
* 1. 모든 실행 즉시 중단 (도구 취소)
|
|
141
|
+
* 2. 비상 체크포인트 요청 발행
|
|
142
|
+
* 3. 세션 상태 → paused
|
|
143
|
+
* 4. 이벤트 발행
|
|
144
|
+
*/
|
|
145
|
+
handleHardInterrupt(signal) {
|
|
146
|
+
// 1. 현재 도구 실행 취소
|
|
147
|
+
if (this.currentToolAbort && !this.currentToolAbort.signal.aborted) {
|
|
148
|
+
this.currentToolAbort.abort();
|
|
149
|
+
}
|
|
150
|
+
this.currentToolAbort = null;
|
|
151
|
+
// 2. paused 상태로 전환
|
|
152
|
+
this.paused = true;
|
|
153
|
+
// 3. 비상 체크포인트 요청
|
|
154
|
+
this.emit("interrupt:emergency_checkpoint");
|
|
155
|
+
// 4. 세션 상태 변경 요청
|
|
156
|
+
this.emit("interrupt:status_change", "paused");
|
|
157
|
+
// 5. 이벤트 발행
|
|
158
|
+
this.emit("interrupt:hard", signal);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Pause 처리.
|
|
162
|
+
*
|
|
163
|
+
* 에이전트 루프를 일시 정지한다.
|
|
164
|
+
* 상태는 유지되며, 현재 진행 중인 도구 실행은 완료될 수 있다.
|
|
165
|
+
*/
|
|
166
|
+
handlePause(signal) {
|
|
167
|
+
if (this.paused)
|
|
168
|
+
return; // 이미 정지 상태
|
|
169
|
+
this.paused = true;
|
|
170
|
+
this.emit("interrupt:status_change", "paused");
|
|
171
|
+
this.emit("interrupt:pause", signal);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Resume 처리.
|
|
175
|
+
*
|
|
176
|
+
* 일시 정지된 에이전트 루프를 재개한다.
|
|
177
|
+
*/
|
|
178
|
+
handleResume(signal) {
|
|
179
|
+
if (!this.paused)
|
|
180
|
+
return; // 이미 실행 중
|
|
181
|
+
this.paused = false;
|
|
182
|
+
this.emit("interrupt:status_change", "running");
|
|
183
|
+
this.emit("interrupt:resume", signal);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* 인터럽트를 히스토리에 기록한다.
|
|
187
|
+
* 최대 MAX_HISTORY개까지 유지하며, 초과 시 오래된 것부터 제거.
|
|
188
|
+
*/
|
|
189
|
+
recordHistory(signal) {
|
|
190
|
+
this.history.push({ signal, timestamp: Date.now() });
|
|
191
|
+
if (this.history.length > InterruptManager.MAX_HISTORY) {
|
|
192
|
+
this.history.shift();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=interrupt-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interrupt-manager.js","sourceRoot":"","sources":["../src/interrupt-manager.ts"],"names":[],"mappings":"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"}
|