@multiclawcli/core 0.13.0 → 0.14.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/dist/index.d.ts +3 -0
- package/dist/index.js +922 -235
- package/dist/orchestrator/AgentRunner.d.ts +4 -1
- package/dist/orchestrator/AgentSessionManager.d.ts +18 -10
- package/dist/orchestrator/Orchestrator.d.ts +22 -2
- package/dist/types/agent.d.ts +4 -3
- package/dist/types/config.d.ts +38 -14
- package/dist/types/event.d.ts +21 -0
- package/dist/types/leader.d.ts +7 -2
- package/dist/types/runtime.d.ts +4 -0
- package/dist/types/session.d.ts +36 -0
- package/dist/utils/handoff.d.ts +7 -0
- package/dist/utils/resumePlan.d.ts +3 -3
- package/dist/utils/session.d.ts +7 -0
- package/dist/utils/work.d.ts +3 -0
- package/package.json +1 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { EventBus } from "../event/EventBus";
|
|
2
2
|
import type { AgentDefinition, AgentResult } from "../types/agent";
|
|
3
3
|
import type { MultiClawConfig } from "../types/config";
|
|
4
|
-
import type {
|
|
4
|
+
import type { SessionIntent } from "../types/session";
|
|
5
|
+
import { AgentSessionManager } from "./AgentSessionManager";
|
|
5
6
|
import type { ContextManager } from "./ContextManager";
|
|
6
7
|
export declare class AgentRunner {
|
|
7
8
|
private eventBus;
|
|
@@ -10,6 +11,8 @@ export declare class AgentRunner {
|
|
|
10
11
|
private config;
|
|
11
12
|
private sessionManager?;
|
|
12
13
|
constructor(eventBus: EventBus, contextManager: ContextManager, globalWorkDir: string, config: MultiClawConfig, sessionManager?: AgentSessionManager | undefined);
|
|
14
|
+
private sessionTask;
|
|
15
|
+
previewSession(agent: AgentDefinition): SessionIntent;
|
|
13
16
|
run(agent: AgentDefinition, signal?: AbortSignal, instruction?: string): Promise<AgentResult>;
|
|
14
17
|
/**
|
|
15
18
|
* Publish one chunk of agent output.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentOutput, AgentRuntime, AgentTask } from "../types/runtime";
|
|
2
|
+
import type { SessionEvent, SessionIntent, SessionRecord } from "../types/session";
|
|
2
3
|
/** What one agent did with a mid-turn message. */
|
|
3
4
|
export interface SupplementReport {
|
|
4
5
|
agentId: string;
|
|
@@ -11,20 +12,24 @@ export interface SupplementReport {
|
|
|
11
12
|
}
|
|
12
13
|
/** Owns reusable agent sessions across independent orchestration turns. */
|
|
13
14
|
export declare class AgentSessionManager {
|
|
15
|
+
private listeners;
|
|
16
|
+
subscribe(listener: (event: SessionEvent) => void): () => void;
|
|
17
|
+
private publish;
|
|
14
18
|
private entries;
|
|
15
19
|
private resetting?;
|
|
16
20
|
private closing?;
|
|
17
21
|
private closed;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
private compatible;
|
|
23
|
+
inspect(runtime: AgentRuntime, task: AgentTask, context?: {
|
|
24
|
+
session?: SessionRecord;
|
|
25
|
+
strict?: boolean;
|
|
26
|
+
}): SessionIntent;
|
|
27
|
+
execute(runtime: AgentRuntime, task: AgentTask, context?: {
|
|
28
|
+
session?: SessionRecord;
|
|
29
|
+
strict?: boolean;
|
|
30
|
+
executionId?: string;
|
|
31
|
+
attempt?: number;
|
|
32
|
+
}): Promise<AgentOutput>;
|
|
28
33
|
/**
|
|
29
34
|
* Deliver a message into every session that is running a turn right now.
|
|
30
35
|
*
|
|
@@ -40,10 +45,13 @@ export declare class AgentSessionManager {
|
|
|
40
45
|
* "steering failed".
|
|
41
46
|
*/
|
|
42
47
|
supplement(text: string): Promise<SupplementReport[]>;
|
|
48
|
+
/** Close selected idle conversations without resetting the leader. */
|
|
49
|
+
resetAgents(agentIds: string[]): Promise<void>;
|
|
43
50
|
/** Closes all sessions and permits a fresh conversation after cleanup completes. */
|
|
44
51
|
reset(): Promise<void>;
|
|
45
52
|
/** Terminal, idempotent cleanup barrier. No new executions may start. */
|
|
46
53
|
close(): Promise<void>;
|
|
47
54
|
private drain;
|
|
48
55
|
private closeEntry;
|
|
56
|
+
private closeSession;
|
|
49
57
|
}
|
|
@@ -1,21 +1,39 @@
|
|
|
1
1
|
import { EventBus } from "../event/EventBus";
|
|
2
2
|
import type { MultiClawConfig, OrchestrationPreview, OrchestratorResult } from "../types/config";
|
|
3
|
-
import
|
|
3
|
+
import { AgentSessionManager } from "./AgentSessionManager";
|
|
4
4
|
export declare class Orchestrator {
|
|
5
5
|
private config;
|
|
6
|
+
private sessions?;
|
|
6
7
|
readonly eventBus: EventBus;
|
|
7
8
|
private contextManager;
|
|
8
9
|
private runner;
|
|
9
10
|
private workDir;
|
|
10
11
|
/** Which configured checkpoints have already been triggered this run. */
|
|
11
12
|
private checkpointTriggered;
|
|
12
|
-
|
|
13
|
+
private originalRequirement;
|
|
14
|
+
private work?;
|
|
15
|
+
private routing?;
|
|
16
|
+
private assignments;
|
|
17
|
+
private excluded;
|
|
18
|
+
private rerouting;
|
|
19
|
+
private repairSpent;
|
|
20
|
+
private leaderCosts;
|
|
21
|
+
private ownsSessions;
|
|
22
|
+
private cleanupAttempted;
|
|
23
|
+
private offSessions;
|
|
24
|
+
private sessionRecords;
|
|
25
|
+
private recovery;
|
|
26
|
+
private routeError?;
|
|
27
|
+
constructor(config: MultiClawConfig, sessions?: AgentSessionManager | undefined);
|
|
13
28
|
preview(options?: {
|
|
14
29
|
signal?: AbortSignal;
|
|
15
30
|
}): Promise<OrchestrationPreview>;
|
|
31
|
+
private previewManaged;
|
|
16
32
|
run(options?: {
|
|
17
33
|
signal?: AbortSignal;
|
|
18
34
|
}): Promise<OrchestratorResult>;
|
|
35
|
+
private runManaged;
|
|
36
|
+
private runPass;
|
|
19
37
|
private reviewPolicyError;
|
|
20
38
|
private reviewDelivery;
|
|
21
39
|
private handleCheckpoint;
|
|
@@ -53,6 +71,8 @@ export declare class Orchestrator {
|
|
|
53
71
|
* job, and that is what `message` records.
|
|
54
72
|
*/
|
|
55
73
|
private resolveTurn;
|
|
74
|
+
private beginWork;
|
|
75
|
+
private captureWork;
|
|
56
76
|
/**
|
|
57
77
|
* The configured team, as copies.
|
|
58
78
|
*
|
package/dist/types/agent.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ export interface AgentDefinition {
|
|
|
64
64
|
retries?: number;
|
|
65
65
|
workDir?: string;
|
|
66
66
|
}
|
|
67
|
-
export type AgentStatus = "pending" | "running" | "retrying" | "success" | "failed"
|
|
67
|
+
export type AgentStatus = "pending" | "running" | "retrying" | "handed_back" | "success" | "failed"
|
|
68
68
|
/**
|
|
69
69
|
* The run was stopped by its AbortSignal rather than finishing or erroring.
|
|
70
70
|
* Distinct from `failed` so a Ctrl-C does not read as a crash, and so the
|
|
@@ -72,6 +72,7 @@ export type AgentStatus = "pending" | "running" | "retrying" | "success" | "fail
|
|
|
72
72
|
*/
|
|
73
73
|
| "cancelled" | "skipped";
|
|
74
74
|
export interface AgentResult {
|
|
75
|
+
handoffReason?: string;
|
|
75
76
|
agentId: string;
|
|
76
77
|
agentName: string;
|
|
77
78
|
status: AgentStatus;
|
|
@@ -87,8 +88,8 @@ export interface AgentResult {
|
|
|
87
88
|
usage?: AgentOutput["usage"];
|
|
88
89
|
/** USD cost the runtime reported; absent when the provider does not price in USD. */
|
|
89
90
|
costUsd?: number;
|
|
90
|
-
/** Session
|
|
91
|
-
|
|
91
|
+
/** Reliable Session facts, including on failed and cancelled executions. */
|
|
92
|
+
session?: import("./session").SessionRecord;
|
|
92
93
|
}
|
|
93
94
|
export interface SubTask {
|
|
94
95
|
id: string;
|
package/dist/types/config.d.ts
CHANGED
|
@@ -1,21 +1,36 @@
|
|
|
1
1
|
import type { AgentDefinition, PermissionMode } from "./agent";
|
|
2
2
|
import type { LeaderMessage } from "./leader";
|
|
3
3
|
import type { RuntimePermissionHandler, RuntimeQuestionHandler } from "./runtime";
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
/** Caller-owned facts for the latest work in this console session. */
|
|
5
|
+
export interface WorkContext {
|
|
6
|
+
id: string;
|
|
7
|
+
originalRequirement: string;
|
|
8
|
+
requirement: string;
|
|
9
|
+
agents: Array<{
|
|
10
|
+
agentId: string;
|
|
11
|
+
scope?: string;
|
|
12
|
+
plan?: string;
|
|
13
|
+
session?: import("./session").SessionRecord;
|
|
14
|
+
dependsOn?: string[];
|
|
15
|
+
taskTitle?: string;
|
|
16
|
+
}>;
|
|
17
|
+
outcome?: TurnOutcome;
|
|
18
|
+
}
|
|
19
|
+
export interface RoutingInfo {
|
|
20
|
+
mode: "run" | "continue";
|
|
21
|
+
workId?: string;
|
|
22
|
+
reroutes: number;
|
|
23
|
+
error?: string;
|
|
24
|
+
}
|
|
25
|
+
/** One session turn, paired with its reply and observed execution facts. */
|
|
12
26
|
export interface TurnRecord {
|
|
13
27
|
/** What the user asked for. */
|
|
14
28
|
requirement: string;
|
|
15
29
|
/** How the turn ended in words, when it ended that way. */
|
|
16
30
|
reply?: LeaderMessage;
|
|
17
|
-
/** Observed execution and acceptance facts
|
|
31
|
+
/** Observed execution and acceptance facts when agents ran. */
|
|
18
32
|
outcome?: TurnOutcome;
|
|
33
|
+
work?: WorkContext;
|
|
19
34
|
}
|
|
20
35
|
/** Compact facts for the next leader turn, not a model-generated summary or retry instruction. */
|
|
21
36
|
export interface TurnOutcome {
|
|
@@ -95,6 +110,8 @@ export interface MultiClawConfig {
|
|
|
95
110
|
* unset and sees no conversation at all.
|
|
96
111
|
*/
|
|
97
112
|
history?: TurnRecord[];
|
|
113
|
+
/** Latest work only; dialogue turns do not replace it. */
|
|
114
|
+
latestWork?: WorkContext;
|
|
98
115
|
/**
|
|
99
116
|
* Continue known agent sessions, and optionally re-run a fixed set of agents
|
|
100
117
|
* instead of letting the leader route.
|
|
@@ -109,15 +126,14 @@ export interface MultiClawConfig {
|
|
|
109
126
|
* whichever agents the route happens to pick. This is what makes a new
|
|
110
127
|
* instruction land in a conversation the agents already remember.
|
|
111
128
|
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* exactly as before.
|
|
129
|
+
* Session records are candidates, checked by core against work identity and
|
|
130
|
+
* immutable creation settings. Loading is confirmed only by runtime success.
|
|
115
131
|
*/
|
|
116
132
|
resume?: {
|
|
117
133
|
/** Agent ids to run, in the order they were originally selected. */
|
|
118
134
|
agents?: string[];
|
|
119
|
-
/** agentId →
|
|
120
|
-
sessions?: Record<string,
|
|
135
|
+
/** agentId → observed Session facts used to check continuation or loading. */
|
|
136
|
+
sessions?: Record<string, import("./session").SessionRecord>;
|
|
121
137
|
};
|
|
122
138
|
logDir?: string;
|
|
123
139
|
continueOnError?: boolean;
|
|
@@ -152,6 +168,9 @@ export interface MultiClawConfig {
|
|
|
152
168
|
};
|
|
153
169
|
}
|
|
154
170
|
export interface OrchestrationPreview {
|
|
171
|
+
sessions?: import("./session").SessionIntent[];
|
|
172
|
+
originalRequirement?: string;
|
|
173
|
+
routing?: RoutingInfo;
|
|
155
174
|
name: string;
|
|
156
175
|
requirement?: string;
|
|
157
176
|
totalAgents: number;
|
|
@@ -169,6 +188,11 @@ export interface DeliverableSummary {
|
|
|
169
188
|
modifiedAt: string;
|
|
170
189
|
}
|
|
171
190
|
export interface OrchestratorResult {
|
|
191
|
+
originalRequirement?: string;
|
|
192
|
+
routing?: RoutingInfo;
|
|
193
|
+
work?: WorkContext;
|
|
194
|
+
/** Current route results; agentResults remains the full execution audit. */
|
|
195
|
+
effectiveAgentResults?: import("./agent").AgentResult[];
|
|
172
196
|
name: string;
|
|
173
197
|
/** With review enabled, true only when execution and delivery acceptance both succeed. */
|
|
174
198
|
success: boolean;
|
package/dist/types/event.d.ts
CHANGED
|
@@ -11,6 +11,27 @@ export interface StageInfo {
|
|
|
11
11
|
}>;
|
|
12
12
|
}
|
|
13
13
|
export type MultiClawEvent = {
|
|
14
|
+
type: "agent:session";
|
|
15
|
+
timestamp: string;
|
|
16
|
+
payload: import("./session").SessionEvent;
|
|
17
|
+
} | {
|
|
18
|
+
type: "orchestration:route";
|
|
19
|
+
timestamp: string;
|
|
20
|
+
payload: {
|
|
21
|
+
routing: import("./config").RoutingInfo;
|
|
22
|
+
work?: import("./config").WorkContext;
|
|
23
|
+
};
|
|
24
|
+
} | {
|
|
25
|
+
type: "orchestration:routing-error";
|
|
26
|
+
timestamp: string;
|
|
27
|
+
payload: {
|
|
28
|
+
message: string;
|
|
29
|
+
};
|
|
30
|
+
} | {
|
|
31
|
+
type: "agent:handed-back";
|
|
32
|
+
timestamp: string;
|
|
33
|
+
payload: AgentResult;
|
|
34
|
+
} | {
|
|
14
35
|
type: "orchestration:start";
|
|
15
36
|
timestamp: string;
|
|
16
37
|
payload: {
|
package/dist/types/leader.d.ts
CHANGED
|
@@ -6,9 +6,14 @@
|
|
|
6
6
|
* is the familiar case; the other two exist so that a greeting or a question is
|
|
7
7
|
* answered instead of spinning up every agent in the config.
|
|
8
8
|
*/
|
|
9
|
-
export type LeaderMode = "run" | "reply" | "ask";
|
|
9
|
+
export type LeaderMode = "run" | "continue" | "reply" | "ask";
|
|
10
10
|
export type LeaderDecision = {
|
|
11
|
-
mode: "run";
|
|
11
|
+
mode: "run" | "continue";
|
|
12
|
+
workId?: string;
|
|
13
|
+
tasks?: Array<{
|
|
14
|
+
agentId: string;
|
|
15
|
+
scope: string;
|
|
16
|
+
}>;
|
|
12
17
|
run: string[];
|
|
13
18
|
/** Complete task combining the original goal with clarification constraints. */
|
|
14
19
|
requirement?: string;
|
package/dist/types/runtime.d.ts
CHANGED
|
@@ -133,7 +133,10 @@ export type RuntimeQuestionResponse = {
|
|
|
133
133
|
/** Structured form input only; the signal aborts when the requesting turn ends. */
|
|
134
134
|
export type RuntimeQuestionHandler = (request: RuntimeQuestionRequest, signal: AbortSignal) => Promise<RuntimeQuestionResponse>;
|
|
135
135
|
export interface AgentTask {
|
|
136
|
+
/** Host work identity, independent of provider session identity. */
|
|
137
|
+
workId?: string;
|
|
136
138
|
agentId: string;
|
|
139
|
+
provider?: string;
|
|
137
140
|
systemPrompt: string;
|
|
138
141
|
prompt: string;
|
|
139
142
|
workDir: string;
|
|
@@ -228,6 +231,7 @@ export interface RuntimeSession {
|
|
|
228
231
|
*/
|
|
229
232
|
readonly capabilities: {
|
|
230
233
|
continuation: boolean;
|
|
234
|
+
load: boolean;
|
|
231
235
|
supplement: boolean;
|
|
232
236
|
};
|
|
233
237
|
/** Rejects overlapping turns; it does not implicitly queue or inject input. */
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Observed provider conversation facts, independent of an execution's outcome. */
|
|
2
|
+
export interface SessionRecord {
|
|
3
|
+
bindingId: string;
|
|
4
|
+
agentId: string;
|
|
5
|
+
workId?: string;
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
runtime: string;
|
|
8
|
+
compatibilityKey: string;
|
|
9
|
+
state: "opening" | "idle" | "running" | "cancelling" | "closing" | "closed" | "unknown";
|
|
10
|
+
capabilities: {
|
|
11
|
+
continuation: boolean;
|
|
12
|
+
load: boolean;
|
|
13
|
+
supplement: boolean;
|
|
14
|
+
};
|
|
15
|
+
action: "created" | "loaded" | "reused";
|
|
16
|
+
observedAt: string;
|
|
17
|
+
reason?: string;
|
|
18
|
+
failure?: {
|
|
19
|
+
code: "incompatible" | "unsupported" | "opening_failed" | "load_failed" | "turn_failed" | "cleanup_failed";
|
|
20
|
+
message: string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface SessionEvent {
|
|
24
|
+
action: "opening" | "created" | "load_requested" | "loaded" | "reused" | "state_changed" | "opening_failed" | "load_failed" | "closing" | "closed" | "cleanup_failed";
|
|
25
|
+
executionId: string;
|
|
26
|
+
attempt: number;
|
|
27
|
+
record: SessionRecord;
|
|
28
|
+
requestedSessionId?: string;
|
|
29
|
+
reason?: string;
|
|
30
|
+
}
|
|
31
|
+
/** Read-only intent; loading and cleanup have not happened. */
|
|
32
|
+
export interface SessionIntent {
|
|
33
|
+
agentId: string;
|
|
34
|
+
action: "create" | "reuse" | "load" | "unavailable";
|
|
35
|
+
reason: string;
|
|
36
|
+
}
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
export interface ResumePlan {
|
|
18
18
|
/** Ids that will run, in the order the caller named them. */
|
|
19
19
|
agents: readonly string[];
|
|
20
|
-
/** Agent
|
|
21
|
-
sessions?: Readonly<Record<string,
|
|
20
|
+
/** Agent ID → observed Session metadata to check before resuming. */
|
|
21
|
+
sessions?: Readonly<Record<string, import("../types/session").SessionRecord>>;
|
|
22
22
|
/** The team the ids were chosen from; supplies each agent's dependencies. */
|
|
23
23
|
team: readonly {
|
|
24
24
|
id: string;
|
|
@@ -26,7 +26,7 @@ export interface ResumePlan {
|
|
|
26
26
|
}[];
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
|
-
* One clause per agent — `dev starts fresh`, `reviewer
|
|
29
|
+
* One clause per agent — `dev starts fresh`, `reviewer will attempt to resume its session` —
|
|
30
30
|
* followed by one clause per agent whose dependencies were pruned.
|
|
31
31
|
*
|
|
32
32
|
* Deliberately a description, not a plan: what actually runs stays core's
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentRuntime, AgentTask } from "../types/runtime";
|
|
2
|
+
import type { SessionEvent, SessionRecord } from "../types/session";
|
|
3
|
+
/** Only immutable creation options participate; target IDs and work identity are checked separately. */
|
|
4
|
+
export declare function sessionCompatibilityKey(runtime: Pick<AgentRuntime, "name">, task: AgentTask): string;
|
|
5
|
+
export declare function isSessionRecord(value: unknown): value is SessionRecord;
|
|
6
|
+
export declare function isSessionEvent(value: unknown): value is SessionEvent;
|
|
7
|
+
export declare function describeSession(record: SessionRecord): string;
|