laohuang 0.4.2 → 0.5.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.
Files changed (113) hide show
  1. package/README.md +10 -6
  2. package/dist/agent.d.ts +7 -27
  3. package/dist/agent.js +53 -567
  4. package/dist/agent.js.map +1 -1
  5. package/dist/capabilities.d.ts +19 -0
  6. package/dist/capabilities.js +29 -0
  7. package/dist/capabilities.js.map +1 -0
  8. package/dist/cli.d.ts +9 -6
  9. package/dist/cli.js +83 -70
  10. package/dist/cli.js.map +1 -1
  11. package/dist/commands.d.ts +20 -3
  12. package/dist/commands.js +39 -38
  13. package/dist/commands.js.map +1 -1
  14. package/dist/keybindings/default-keybindings.d.ts +2 -0
  15. package/dist/keybindings/default-keybindings.js +10 -0
  16. package/dist/keybindings/default-keybindings.js.map +1 -0
  17. package/dist/keybindings/hints.d.ts +3 -0
  18. package/dist/keybindings/hints.js +7 -0
  19. package/dist/keybindings/hints.js.map +1 -0
  20. package/dist/keybindings/key-id.d.ts +20 -0
  21. package/dist/keybindings/key-id.js +11 -0
  22. package/dist/keybindings/key-id.js.map +1 -0
  23. package/dist/keybindings/key-parser.d.ts +7 -0
  24. package/dist/keybindings/key-parser.js +92 -0
  25. package/dist/keybindings/key-parser.js.map +1 -0
  26. package/dist/keybindings/keybindings.d.ts +21 -0
  27. package/dist/keybindings/keybindings.js +65 -0
  28. package/dist/keybindings/keybindings.js.map +1 -0
  29. package/dist/routing.d.ts +2 -57
  30. package/dist/routing.js +3 -161
  31. package/dist/routing.js.map +1 -1
  32. package/dist/runtime/agent-step-runner.d.ts +51 -0
  33. package/dist/runtime/agent-step-runner.js +361 -0
  34. package/dist/runtime/agent-step-runner.js.map +1 -0
  35. package/dist/runtime/agent-turn-loop.d.ts +36 -0
  36. package/dist/runtime/agent-turn-loop.js +71 -0
  37. package/dist/runtime/agent-turn-loop.js.map +1 -0
  38. package/dist/runtime/guard-policy.d.ts +21 -0
  39. package/dist/runtime/guard-policy.js +93 -0
  40. package/dist/runtime/guard-policy.js.map +1 -0
  41. package/dist/runtime/history-committer.d.ts +34 -0
  42. package/dist/runtime/history-committer.js +77 -0
  43. package/dist/runtime/history-committer.js.map +1 -0
  44. package/dist/runtime/human-intent-router.d.ts +5 -0
  45. package/dist/runtime/human-intent-router.js +38 -0
  46. package/dist/runtime/human-intent-router.js.map +1 -0
  47. package/dist/runtime/model-runtime.d.ts +33 -0
  48. package/dist/runtime/model-runtime.js +70 -0
  49. package/dist/runtime/model-runtime.js.map +1 -0
  50. package/dist/runtime/queue-bridge.d.ts +11 -0
  51. package/dist/runtime/queue-bridge.js +2 -0
  52. package/dist/runtime/queue-bridge.js.map +1 -0
  53. package/dist/runtime/queue-dispatcher.d.ts +45 -0
  54. package/dist/runtime/queue-dispatcher.js +120 -0
  55. package/dist/runtime/queue-dispatcher.js.map +1 -0
  56. package/dist/runtime/runtime-events.d.ts +26 -0
  57. package/dist/runtime/runtime-events.js +21 -0
  58. package/dist/runtime/runtime-events.js.map +1 -0
  59. package/dist/runtime/session-action-protocol.d.ts +10 -0
  60. package/dist/runtime/session-action-protocol.js +64 -0
  61. package/dist/runtime/session-action-protocol.js.map +1 -0
  62. package/dist/runtime/session-action.d.ts +42 -0
  63. package/dist/runtime/session-action.js +3 -0
  64. package/dist/runtime/session-action.js.map +1 -0
  65. package/dist/runtime/task-lifecycle.d.ts +73 -0
  66. package/dist/runtime/task-lifecycle.js +267 -0
  67. package/dist/runtime/task-lifecycle.js.map +1 -0
  68. package/dist/runtime/tool-runtime.d.ts +33 -0
  69. package/dist/runtime/tool-runtime.js +89 -0
  70. package/dist/runtime/tool-runtime.js.map +1 -0
  71. package/dist/runtime/user-intent.d.ts +48 -0
  72. package/dist/runtime/user-intent.js +17 -0
  73. package/dist/runtime/user-intent.js.map +1 -0
  74. package/dist/session.d.ts +19 -9
  75. package/dist/session.js +119 -169
  76. package/dist/session.js.map +1 -1
  77. package/dist/terminal/editor.d.ts +16 -5
  78. package/dist/terminal/editor.js +99 -4
  79. package/dist/terminal/editor.js.map +1 -1
  80. package/dist/terminal/input.d.ts +2 -0
  81. package/dist/terminal/input.js +32 -7
  82. package/dist/terminal/input.js.map +1 -1
  83. package/dist/terminal/ui.d.ts +32 -21
  84. package/dist/terminal/ui.js +413 -252
  85. package/dist/terminal/ui.js.map +1 -1
  86. package/dist/tools.d.ts +7 -0
  87. package/dist/tools.js.map +1 -1
  88. package/dist/tui/components.d.ts +5 -0
  89. package/dist/tui/components.js +12 -0
  90. package/dist/tui/components.js.map +1 -0
  91. package/dist/tui/focus-manager.d.ts +7 -0
  92. package/dist/tui/focus-manager.js +13 -0
  93. package/dist/tui/focus-manager.js.map +1 -0
  94. package/dist/tui/overlay-manager.d.ts +12 -0
  95. package/dist/tui/overlay-manager.js +27 -0
  96. package/dist/tui/overlay-manager.js.map +1 -0
  97. package/dist/ui/display-actions.d.ts +23 -0
  98. package/dist/ui/display-actions.js +15 -0
  99. package/dist/ui/display-actions.js.map +1 -0
  100. package/dist/ui/display-policy.d.ts +38 -0
  101. package/dist/ui/display-policy.js +97 -0
  102. package/dist/ui/display-policy.js.map +1 -0
  103. package/dist/ui/frame-builder.d.ts +39 -0
  104. package/dist/ui/frame-builder.js +111 -0
  105. package/dist/ui/frame-builder.js.map +1 -0
  106. package/dist/ui/transcript-store.d.ts +35 -0
  107. package/dist/ui/transcript-store.js +172 -0
  108. package/dist/ui/transcript-store.js.map +1 -0
  109. package/dist/ui-state.js +6 -6
  110. package/dist/ui-state.js.map +1 -1
  111. package/dist/web.js +14 -1
  112. package/dist/web.js.map +1 -1
  113. package/package.json +2 -2
@@ -0,0 +1,73 @@
1
+ import { CancelToken } from "../cancellation.ts";
2
+ import { type EventBus } from "../events.ts";
3
+ export declare const TaskState: {
4
+ readonly RunningModel: "running_model";
5
+ readonly RunningTools: "running_tools";
6
+ readonly Cancelling: "cancelling";
7
+ readonly Cancelled: "cancelled";
8
+ readonly Completed: "completed";
9
+ readonly Failed: "failed";
10
+ };
11
+ export type TaskState = (typeof TaskState)[keyof typeof TaskState];
12
+ export interface TaskRecord {
13
+ readonly taskId: string;
14
+ readonly state: TaskState;
15
+ readonly cancelToken: CancelToken;
16
+ readonly result: string | null;
17
+ readonly error: string | null;
18
+ }
19
+ export interface RegisterTaskOptions {
20
+ state?: TaskState;
21
+ cancelToken?: CancelToken;
22
+ activate?: boolean;
23
+ }
24
+ export interface TransitionOptions {
25
+ result?: string;
26
+ error?: string;
27
+ }
28
+ export declare function isTerminalTaskState(state: TaskState): boolean;
29
+ /** Task records with at most one active task. */
30
+ export declare class TaskRegistry {
31
+ private readonly tasks;
32
+ private activeTaskIdValue;
33
+ get activeTaskId(): string | null;
34
+ register(taskId: string, options?: RegisterTaskOptions): TaskRecord;
35
+ get(taskId: string): TaskRecord | null;
36
+ active(): TaskRecord | null;
37
+ transition(taskId: string, state: TaskState, options?: TransitionOptions): TaskRecord;
38
+ records(): TaskRecord[];
39
+ }
40
+ export interface TaskLifecycleOptions {
41
+ readonly eventBus: EventBus;
42
+ readonly sessionId: string;
43
+ readonly taskRegistry?: TaskRegistry;
44
+ readonly queueCounts?: () => {
45
+ readonly pending: number;
46
+ readonly held: number;
47
+ };
48
+ readonly onCancelling?: (taskId: string) => void;
49
+ }
50
+ export interface CreateTaskOptions {
51
+ readonly cancelToken?: CancelToken;
52
+ readonly correlationId?: string | null;
53
+ }
54
+ /** Owns task state changes and their canonical lifecycle events. */
55
+ export declare class TaskLifecycle {
56
+ readonly taskRegistry: TaskRegistry;
57
+ private readonly eventBus;
58
+ private readonly sessionId;
59
+ private readonly queueCounts;
60
+ private readonly onCancelling;
61
+ constructor(options: TaskLifecycleOptions);
62
+ active(): TaskRecord | null;
63
+ createTask(taskId: string, options?: CreateTaskOptions): TaskRecord;
64
+ markModelRunning(taskId: string): boolean;
65
+ markToolsRunning(taskId: string): boolean;
66
+ requestCancel(taskId: string, reason?: string): boolean;
67
+ completeTask(taskId: string, result: string | null): boolean;
68
+ finishCancelled(taskId: string): boolean;
69
+ failTask(taskId: string, error: string): boolean;
70
+ publishCurrentState(taskId: string): boolean;
71
+ private markRunning;
72
+ private publishState;
73
+ }
@@ -0,0 +1,267 @@
1
+ import { CancelToken } from "../cancellation.js";
2
+ import { EventKind, EventSource } from "../events.js";
3
+ export const TaskState = {
4
+ RunningModel: "running_model",
5
+ RunningTools: "running_tools",
6
+ Cancelling: "cancelling",
7
+ Cancelled: "cancelled",
8
+ Completed: "completed",
9
+ Failed: "failed",
10
+ };
11
+ const TERMINAL_TASK_STATES = new Set([
12
+ TaskState.Cancelled,
13
+ TaskState.Completed,
14
+ TaskState.Failed,
15
+ ]);
16
+ const ALLOWED_TASK_TRANSITIONS = new Map([
17
+ [
18
+ TaskState.RunningModel,
19
+ new Set([
20
+ TaskState.RunningTools,
21
+ TaskState.Cancelling,
22
+ TaskState.Completed,
23
+ TaskState.Failed,
24
+ ]),
25
+ ],
26
+ [
27
+ TaskState.RunningTools,
28
+ new Set([
29
+ TaskState.RunningModel,
30
+ TaskState.Cancelling,
31
+ TaskState.Completed,
32
+ TaskState.Failed,
33
+ ]),
34
+ ],
35
+ [TaskState.Cancelling, new Set([TaskState.Cancelled])],
36
+ [TaskState.Cancelled, new Set()],
37
+ [TaskState.Completed, new Set()],
38
+ [TaskState.Failed, new Set()],
39
+ ]);
40
+ export function isTerminalTaskState(state) {
41
+ return TERMINAL_TASK_STATES.has(state);
42
+ }
43
+ /** Task records with at most one active task. */
44
+ export class TaskRegistry {
45
+ tasks = new Map();
46
+ activeTaskIdValue = null;
47
+ get activeTaskId() {
48
+ return this.activeTaskIdValue;
49
+ }
50
+ register(taskId, options = {}) {
51
+ const state = options.state ?? TaskState.RunningModel;
52
+ const activate = options.activate ?? true;
53
+ if (this.tasks.has(taskId)) {
54
+ throw new Error(`task already exists: ${taskId}`);
55
+ }
56
+ if (activate && this.activeTaskIdValue !== null) {
57
+ throw new Error("another task is already active");
58
+ }
59
+ const record = {
60
+ taskId,
61
+ state,
62
+ cancelToken: options.cancelToken ?? new CancelToken(),
63
+ result: null,
64
+ error: null,
65
+ };
66
+ this.tasks.set(taskId, record);
67
+ if (activate && !isTerminalTaskState(state)) {
68
+ this.activeTaskIdValue = taskId;
69
+ }
70
+ return { ...record };
71
+ }
72
+ get(taskId) {
73
+ const record = this.tasks.get(taskId);
74
+ return record === undefined ? null : { ...record };
75
+ }
76
+ active() {
77
+ if (this.activeTaskIdValue === null) {
78
+ return null;
79
+ }
80
+ const record = this.tasks.get(this.activeTaskIdValue);
81
+ return record === undefined ? null : { ...record };
82
+ }
83
+ transition(taskId, state, options = {}) {
84
+ const record = this.tasks.get(taskId);
85
+ if (record === undefined) {
86
+ throw new Error(`unknown task: ${taskId}`);
87
+ }
88
+ if (state !== record.state &&
89
+ !ALLOWED_TASK_TRANSITIONS.get(record.state)?.has(state)) {
90
+ throw new Error(`invalid task transition: ${record.state} -> ${state}`);
91
+ }
92
+ const next = {
93
+ ...record,
94
+ state,
95
+ result: options.result !== undefined ? options.result : record.result,
96
+ error: options.error !== undefined ? options.error : record.error,
97
+ };
98
+ if (isTerminalTaskState(state)) {
99
+ if (this.activeTaskIdValue === taskId) {
100
+ this.activeTaskIdValue = null;
101
+ }
102
+ }
103
+ else {
104
+ const active = this.activeTaskIdValue;
105
+ if (active !== null && active !== taskId) {
106
+ throw new Error("another task is already active");
107
+ }
108
+ this.activeTaskIdValue = taskId;
109
+ }
110
+ this.tasks.set(taskId, next);
111
+ return { ...next };
112
+ }
113
+ records() {
114
+ return [...this.tasks.values()].map((record) => ({ ...record }));
115
+ }
116
+ }
117
+ /** Owns task state changes and their canonical lifecycle events. */
118
+ export class TaskLifecycle {
119
+ taskRegistry;
120
+ eventBus;
121
+ sessionId;
122
+ queueCounts;
123
+ onCancelling;
124
+ constructor(options) {
125
+ this.eventBus = options.eventBus;
126
+ this.sessionId = options.sessionId;
127
+ this.taskRegistry = options.taskRegistry ?? new TaskRegistry();
128
+ this.queueCounts = options.queueCounts ?? (() => ({ pending: 0, held: 0 }));
129
+ this.onCancelling = options.onCancelling ?? (() => { });
130
+ }
131
+ active() {
132
+ return this.taskRegistry.active();
133
+ }
134
+ createTask(taskId, options = {}) {
135
+ const record = this.taskRegistry.register(taskId, {
136
+ cancelToken: options.cancelToken,
137
+ });
138
+ const counts = this.queueCounts();
139
+ this.eventBus.publish(EventKind.TaskStarted, {
140
+ source: EventSource.Session,
141
+ session_id: this.sessionId,
142
+ task_id: taskId,
143
+ correlation_id: options.correlationId ?? null,
144
+ payload: {
145
+ pending_count: counts.pending,
146
+ held_count: counts.held,
147
+ },
148
+ });
149
+ return record;
150
+ }
151
+ markModelRunning(taskId) {
152
+ return this.markRunning(taskId, TaskState.RunningModel);
153
+ }
154
+ markToolsRunning(taskId) {
155
+ return this.markRunning(taskId, TaskState.RunningTools);
156
+ }
157
+ requestCancel(taskId, reason = "cancelled by user") {
158
+ const record = this.taskRegistry.get(taskId);
159
+ if (record === null || isTerminalTaskState(record.state)) {
160
+ return false;
161
+ }
162
+ if (record.state === TaskState.Cancelling) {
163
+ return true;
164
+ }
165
+ this.taskRegistry.transition(taskId, TaskState.Cancelling);
166
+ this.onCancelling(taskId);
167
+ this.publishState(taskId, TaskState.Cancelling);
168
+ return record.cancelToken.cancel(reason);
169
+ }
170
+ completeTask(taskId, result) {
171
+ const record = this.taskRegistry.get(taskId);
172
+ if (record === null ||
173
+ record.state === TaskState.Cancelling ||
174
+ isTerminalTaskState(record.state)) {
175
+ return false;
176
+ }
177
+ this.taskRegistry.transition(taskId, TaskState.Completed, result === null ? {} : { result });
178
+ const counts = this.queueCounts();
179
+ this.eventBus.publish(EventKind.TaskCompleted, {
180
+ source: EventSource.Session,
181
+ session_id: this.sessionId,
182
+ task_id: taskId,
183
+ payload: {
184
+ result: result ?? "",
185
+ pending_count: counts.pending,
186
+ held_count: counts.held,
187
+ },
188
+ });
189
+ return true;
190
+ }
191
+ finishCancelled(taskId) {
192
+ const record = this.taskRegistry.get(taskId);
193
+ if (record === null || record.state !== TaskState.Cancelling) {
194
+ return false;
195
+ }
196
+ this.taskRegistry.transition(taskId, TaskState.Cancelled);
197
+ const counts = this.queueCounts();
198
+ this.eventBus.publish(EventKind.TaskCancelled, {
199
+ source: EventSource.Session,
200
+ session_id: this.sessionId,
201
+ task_id: taskId,
202
+ payload: {
203
+ reason: record.cancelToken.reason ?? "cancelled",
204
+ pending_count: counts.pending,
205
+ held_count: counts.held,
206
+ },
207
+ });
208
+ return true;
209
+ }
210
+ failTask(taskId, error) {
211
+ const record = this.taskRegistry.get(taskId);
212
+ if (record === null ||
213
+ record.state === TaskState.Cancelling ||
214
+ isTerminalTaskState(record.state)) {
215
+ return false;
216
+ }
217
+ this.taskRegistry.transition(taskId, TaskState.Failed, { error });
218
+ const counts = this.queueCounts();
219
+ this.eventBus.publish(EventKind.TaskFailed, {
220
+ source: EventSource.Session,
221
+ session_id: this.sessionId,
222
+ task_id: taskId,
223
+ payload: {
224
+ error,
225
+ pending_count: counts.pending,
226
+ held_count: counts.held,
227
+ },
228
+ });
229
+ return true;
230
+ }
231
+ publishCurrentState(taskId) {
232
+ const record = this.taskRegistry.get(taskId);
233
+ if (record === null) {
234
+ return false;
235
+ }
236
+ this.publishState(taskId, record.state);
237
+ return true;
238
+ }
239
+ markRunning(taskId, state) {
240
+ const record = this.taskRegistry.get(taskId);
241
+ if (record === null ||
242
+ record.state === TaskState.Cancelling ||
243
+ isTerminalTaskState(record.state)) {
244
+ return false;
245
+ }
246
+ if (record.state !== state) {
247
+ this.taskRegistry.transition(taskId, state);
248
+ this.publishState(taskId, state);
249
+ }
250
+ return true;
251
+ }
252
+ publishState(taskId, state) {
253
+ const counts = this.queueCounts();
254
+ this.eventBus.publish(EventKind.TaskStateChanged, {
255
+ source: EventSource.Session,
256
+ session_id: this.sessionId,
257
+ task_id: taskId,
258
+ payload: {
259
+ state,
260
+ state_name: state.toUpperCase(),
261
+ pending_count: counts.pending,
262
+ held_count: counts.held,
263
+ },
264
+ });
265
+ }
266
+ }
267
+ //# sourceMappingURL=task-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-lifecycle.js","sourceRoot":"","sources":["../../src/runtime/task-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { CancelToken } from "../cancellation.ts";
2
+ import type { AssembledToolCall } from "../model-stream.ts";
3
+ import type { ToolExecutionContextLike, ToolExecutionMode, ToolRegistryLike, ToolResult } from "../tools.ts";
4
+ export interface ToolRuntimeRequest {
5
+ toolCalls: readonly AssembledToolCall[];
6
+ executionMode: ToolExecutionMode;
7
+ cancelToken: CancelToken | null;
8
+ onToolStart?: ((event: ToolRuntimeToolEvent) => void) | null;
9
+ onToolResult?: ((event: ToolRuntimeToolResultEvent) => void) | null;
10
+ }
11
+ export interface ToolRuntimeToolEvent {
12
+ readonly index: number;
13
+ readonly batchSize: number;
14
+ readonly toolCall: AssembledToolCall;
15
+ readonly args: Record<string, unknown>;
16
+ }
17
+ export interface ToolRuntimeToolResultEvent extends ToolRuntimeToolEvent {
18
+ readonly result: ToolResult;
19
+ }
20
+ /** Tool results are always in source order, even when execution is parallel. */
21
+ export interface ToolBatchResult {
22
+ readonly results: readonly ToolResult[];
23
+ }
24
+ export type ToolExecutionContextFactory = (toolCallId: string, cancelToken: CancelToken | null) => ToolExecutionContextLike;
25
+ /** Owns tool-call argument decoding, scheduling, and cooperative cancellation. */
26
+ export declare class ToolRuntime {
27
+ private readonly tools;
28
+ private readonly createExecutionContext;
29
+ constructor(tools: ToolRegistryLike, options?: {
30
+ createExecutionContext?: ToolExecutionContextFactory;
31
+ });
32
+ execute(request: ToolRuntimeRequest): Promise<ToolBatchResult>;
33
+ }
@@ -0,0 +1,89 @@
1
+ import { ToolExecutionContext } from "../bash-runner.js";
2
+ /** Owns tool-call argument decoding, scheduling, and cooperative cancellation. */
3
+ export class ToolRuntime {
4
+ tools;
5
+ createExecutionContext;
6
+ constructor(tools, options = {}) {
7
+ this.tools = tools;
8
+ this.createExecutionContext = options.createExecutionContext ??
9
+ ((toolCallId, cancelToken) => new ToolExecutionContext({ toolCallId, cancelToken }));
10
+ }
11
+ async execute(request) {
12
+ const results = new Array(request.toolCalls.length).fill(undefined);
13
+ const prepared = [];
14
+ for (let offset = 0; offset < request.toolCalls.length; offset += 1) {
15
+ const toolCall = request.toolCalls[offset];
16
+ if (toolCall === undefined) {
17
+ continue;
18
+ }
19
+ let args;
20
+ let result;
21
+ try {
22
+ const decoded = JSON.parse(toolCall.function.arguments);
23
+ if (typeof decoded !== "object" || decoded === null || Array.isArray(decoded)) {
24
+ throw new Error("Tool arguments must be a JSON object");
25
+ }
26
+ args = decoded;
27
+ }
28
+ catch (error) {
29
+ args = { _raw: toolCall.function.arguments };
30
+ result = { ok: false, error: errorMessage(error) };
31
+ }
32
+ const event = {
33
+ index: offset + 1,
34
+ batchSize: request.toolCalls.length,
35
+ toolCall,
36
+ args,
37
+ };
38
+ request.onToolStart?.(event);
39
+ if (result === undefined) {
40
+ prepared.push(event);
41
+ }
42
+ else {
43
+ results[offset] = result;
44
+ request.onToolResult?.({ ...event, result });
45
+ }
46
+ }
47
+ const sequentialBatch = request.executionMode === "sequential" ||
48
+ request.toolCalls.some((toolCall) => this.tools.executionMode(toolCall.function.name) === "sequential") ||
49
+ request.toolCalls.some((toolCall) => toolCall.function.name === "write" || toolCall.function.name === "edit");
50
+ const runOne = async (event) => {
51
+ let result;
52
+ if (isCancelled(request.cancelToken)) {
53
+ result = cancelledToolResult(request.cancelToken);
54
+ }
55
+ else {
56
+ try {
57
+ result = await this.tools.execute(event.toolCall.function.name, event.args, this.createExecutionContext(event.toolCall.id, request.cancelToken));
58
+ }
59
+ catch (error) {
60
+ result = { ok: false, error: errorMessage(error) };
61
+ }
62
+ }
63
+ const offset = event.index - 1;
64
+ results[offset] = result;
65
+ request.onToolResult?.({ ...event, result });
66
+ };
67
+ if (sequentialBatch || prepared.length === 1) {
68
+ for (const event of prepared) {
69
+ await runOne(event);
70
+ }
71
+ }
72
+ else if (prepared.length > 0) {
73
+ await Promise.all(prepared.map((event) => runOne(event)));
74
+ }
75
+ return {
76
+ results: results.map((result) => result ?? { ok: false, error: "Tool execution produced no result" }),
77
+ };
78
+ }
79
+ }
80
+ function isCancelled(token) {
81
+ return token !== null && token.isCancelled();
82
+ }
83
+ function cancelledToolResult(token) {
84
+ return { ok: false, status: "cancelled", error: token?.reason || "cancelled" };
85
+ }
86
+ function errorMessage(error) {
87
+ return error instanceof Error ? error.message : String(error);
88
+ }
89
+ //# sourceMappingURL=tool-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-runtime.js","sourceRoot":"","sources":["../../src/runtime/tool-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /** User-level input before it is routed to a session action. */
2
+ export type UserIntent = {
3
+ readonly type: "prompt";
4
+ readonly text: string;
5
+ readonly source: string;
6
+ } | {
7
+ readonly type: "command";
8
+ readonly name: string;
9
+ readonly arguments: readonly string[];
10
+ readonly source: string;
11
+ } | {
12
+ readonly type: "steer";
13
+ readonly text: string;
14
+ readonly source: string;
15
+ } | {
16
+ readonly type: "follow_up";
17
+ readonly text: string;
18
+ readonly source: string;
19
+ } | {
20
+ readonly type: "cancel";
21
+ readonly reason: string;
22
+ readonly source: string;
23
+ } | {
24
+ readonly type: "approval";
25
+ readonly text: string;
26
+ readonly source: string;
27
+ } | {
28
+ readonly type: "answer";
29
+ readonly text: string;
30
+ readonly source: string;
31
+ } | {
32
+ readonly type: "exit";
33
+ readonly source: string;
34
+ };
35
+ export type HumanIntentDecision = {
36
+ readonly accepted: true;
37
+ readonly intent: UserIntent;
38
+ readonly reason?: string;
39
+ } | {
40
+ readonly accepted: false;
41
+ readonly intent: null;
42
+ readonly reason: string;
43
+ };
44
+ export declare function makePromptIntent(text: string, source: string): UserIntent;
45
+ export declare function makeFollowUpIntent(text: string, source: string): UserIntent;
46
+ export declare function makeCancelIntent(reason: string, source: string): UserIntent;
47
+ export declare function makeApprovalIntent(text: string, source: string): UserIntent;
48
+ export declare function makeAnswerIntent(text: string, source: string): UserIntent;
@@ -0,0 +1,17 @@
1
+ /** User-level input before it is routed to a session action. */
2
+ export function makePromptIntent(text, source) {
3
+ return { type: "prompt", text, source };
4
+ }
5
+ export function makeFollowUpIntent(text, source) {
6
+ return { type: "follow_up", text, source };
7
+ }
8
+ export function makeCancelIntent(reason, source) {
9
+ return { type: "cancel", reason, source };
10
+ }
11
+ export function makeApprovalIntent(text, source) {
12
+ return { type: "approval", text, source };
13
+ }
14
+ export function makeAnswerIntent(text, source) {
15
+ return { type: "answer", text, source };
16
+ }
17
+ //# sourceMappingURL=user-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-intent.js","sourceRoot":"","sources":["../../src/runtime/user-intent.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAwDhE,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,MAAc;IAC3D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,MAAc;IAC7D,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,MAAc;IAC7D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,MAAc;IAC7D,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,MAAc;IAC3D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1C,CAAC"}
package/dist/session.d.ts CHANGED
@@ -1,8 +1,12 @@
1
1
  /** Single-active-task runtime coordination for laoHuangCode. */
2
- import { type CancelToken } from "./cancellation.ts";
3
- import type { QueueStatus } from "./commands.ts";
2
+ import type { CancelToken } from "./cancellation.ts";
3
+ import type { CommandResult, QueueStatus } from "./commands.ts";
4
4
  import { EventBus, EventKind, EventSource, type AnyEventEnvelope, type EventEnvelope } from "./events.ts";
5
- import { DeadLetterQueue, EventRouter, HeldQueue, PendingQueue, Scheduler, TaskRegistry, TaskState, type RoutedEvent, type SafetyPolicy, type SemanticClassifier, type TaskRecord } from "./routing.ts";
5
+ import { DeadLetterQueue, EventRouter, HeldQueue, PendingQueue, type RoutedEvent, type SafetyPolicy, type SemanticClassifier } from "./routing.ts";
6
+ import { QueueDispatcher } from "./runtime/queue-dispatcher.ts";
7
+ import type { QueueInputBatch } from "./runtime/queue-bridge.ts";
8
+ import type { SessionAction } from "./runtime/session-action.ts";
9
+ import { TaskLifecycle, TaskRegistry, TaskState, type TaskRecord } from "./runtime/task-lifecycle.ts";
6
10
  export declare const SessionState: {
7
11
  readonly Idle: "idle";
8
12
  readonly Running: "running";
@@ -11,7 +15,7 @@ export declare const SessionState: {
11
15
  };
12
16
  export type SessionState = (typeof SessionState)[keyof typeof SessionState];
13
17
  /** One compatible batch of pending input claimed at a safe point. */
14
- export interface PendingInputBatch {
18
+ export interface PendingInputBatch extends QueueInputBatch {
15
19
  readonly events: readonly RoutedEvent[];
16
20
  readonly content: string;
17
21
  readonly eventIds: readonly string[];
@@ -36,6 +40,7 @@ export interface AgentRunnerLike {
36
40
  run(userInput: string, context: TaskContext): TaskRunnerResult;
37
41
  }
38
42
  export type TaskRunner = ((content: string, context: TaskContext) => TaskRunnerResult) | AgentRunnerLike;
43
+ export type CommandDispatcher = (command: string) => CommandResult | Promise<CommandResult>;
39
44
  /** Capabilities exposed to one model/tool worker invocation. */
40
45
  export declare class TaskContext {
41
46
  #private;
@@ -64,7 +69,7 @@ export declare class TaskContext {
64
69
  /** Atomically take one compatible pending batch for this task. */
65
70
  safePoint(): PendingInputBatch;
66
71
  /** @internal Used by the session worker around each runner invocation. */
67
- setClaimedInput(batch: PendingInputBatch | null): void;
72
+ setClaimedInput(batch: QueueInputBatch | null): void;
68
73
  commitInput(callback: () => void, rollback?: () => void): boolean;
69
74
  commitPending(batch: PendingInputBatch, callback: () => void, rollback?: () => void): boolean;
70
75
  /** Atomically reject history commits once cancellation has won. */
@@ -76,6 +81,7 @@ export interface AgentSessionOptions {
76
81
  taskRegistry?: TaskRegistry;
77
82
  semanticClassifier?: SemanticClassifier | null;
78
83
  safetyPolicy?: SafetyPolicy | null;
84
+ commandDispatcher?: CommandDispatcher | null;
79
85
  }
80
86
  export interface CloseOptions {
81
87
  wait?: boolean;
@@ -94,11 +100,12 @@ export declare class AgentSession {
94
100
  #private;
95
101
  readonly sessionId: string;
96
102
  readonly eventBus: EventBus;
103
+ readonly taskLifecycle: TaskLifecycle;
97
104
  readonly taskRegistry: TaskRegistry;
98
105
  readonly pending: PendingQueue;
99
106
  readonly held: HeldQueue;
100
107
  readonly deadLetters: DeadLetterQueue;
101
- readonly scheduler: Scheduler;
108
+ readonly queueDispatcher: QueueDispatcher;
102
109
  readonly router: EventRouter;
103
110
  readonly runner: TaskRunner;
104
111
  constructor(runner: TaskRunner, options?: AgentSessionOptions);
@@ -106,9 +113,14 @@ export declare class AgentSession {
106
113
  get activeTask(): TaskRecord | null;
107
114
  get pendingCount(): number;
108
115
  get heldCount(): number;
116
+ /**
117
+ * Compatibility API for existing callers while they migrate to submitAction.
118
+ */
109
119
  submitInput(content: string, options?: {
110
120
  strategy?: string;
111
121
  }): Promise<Submission>;
122
+ /** Compatibility bridge from neutral actions to the existing session API. */
123
+ submitAction(action: SessionAction): Promise<Submission | CommandResult | boolean>;
112
124
  /** Repair a decision if task state changed during semantic routing. */
113
125
  private refreshRouteForCurrentTask;
114
126
  requestCancel(reason?: string): boolean;
@@ -142,10 +154,8 @@ export declare class AgentSession {
142
154
  private settleWorker;
143
155
  /** @internal Test hook mirroring Python's ``_settle_worker``. */
144
156
  _settleWorker(workerKey: object): void;
145
- private finishCancelled;
146
157
  /** Rollback and preserve every unacknowledged input for a task. */
147
158
  private holdTaskInputs;
148
- private invokeRunner;
149
159
  /** @internal Used by {@link TaskContext}. */
150
160
  setRunningState(taskId: string, state: TaskState): boolean;
151
161
  /** @internal Used by {@link TaskContext}. */
@@ -154,9 +164,9 @@ export declare class AgentSession {
154
164
  commitClaimedInput(taskId: string, eventIds: readonly string[], callback: () => void, rollback: () => void): boolean;
155
165
  /** @internal Used by {@link TaskContext} and the worker loop. */
156
166
  ackClaimedInput(taskId: string, eventIds: readonly string[]): boolean;
157
- private publishTaskState;
158
167
  /** @internal Used by {@link TaskContext.safePoint} and the worker loop. */
159
168
  drainPending(taskId: string): PendingInputBatch;
160
169
  private setSessionState;
170
+ private inputAction;
161
171
  private setIdle;
162
172
  }