@oai404iao/pi-subagent 0.3.0 → 0.4.0-alpha.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/README.md +250 -75
- package/agents/worker.md +1 -1
- package/config.example.json +3 -1
- package/config.schema.json +24 -4
- package/package.json +7 -7
- package/src/agent-state.ts +125 -0
- package/src/agent-sync.ts +64 -53
- package/src/agents.ts +3 -22
- package/src/catalog.ts +49 -0
- package/src/completion-mailbox.ts +656 -0
- package/src/config.ts +51 -6
- package/src/coordinator.ts +2385 -231
- package/src/descriptor.ts +104 -11
- package/src/index.ts +175 -26
- package/src/mailbox.ts +451 -0
- package/src/providers.ts +221 -28
- package/src/render.ts +25 -8
- package/src/scheduler.ts +173 -0
- package/src/schemas.ts +111 -11
- package/src/task-path.ts +188 -0
- package/src/types.ts +56 -7
package/src/schemas.ts
CHANGED
|
@@ -17,6 +17,15 @@ function agentNameParameter(agentNames?: readonly string[]) {
|
|
|
17
17
|
function delegationFields(agentNames?: readonly string[]) {
|
|
18
18
|
return {
|
|
19
19
|
agent: agentNameParameter(agentNames),
|
|
20
|
+
task_name: Type.Optional(
|
|
21
|
+
Type.String({
|
|
22
|
+
description:
|
|
23
|
+
"Stable readable child path segment; lowercase letters, digits, hyphens, and underscores",
|
|
24
|
+
pattern: "^[a-z0-9][a-z0-9_-]{0,63}$",
|
|
25
|
+
minLength: 1,
|
|
26
|
+
maxLength: 64,
|
|
27
|
+
}),
|
|
28
|
+
),
|
|
20
29
|
description: Type.String({
|
|
21
30
|
description: "Short 3-5 word display label for the delegated task",
|
|
22
31
|
minLength: 1,
|
|
@@ -29,6 +38,27 @@ function delegationFields(agentNames?: readonly string[]) {
|
|
|
29
38
|
};
|
|
30
39
|
}
|
|
31
40
|
|
|
41
|
+
const ContextParameters = Type.Object(
|
|
42
|
+
{
|
|
43
|
+
mode: StringEnum(
|
|
44
|
+
["fresh", "all_completed", "last_n_completed"] as const,
|
|
45
|
+
{
|
|
46
|
+
description:
|
|
47
|
+
"Parent context inherited once when the child is created",
|
|
48
|
+
},
|
|
49
|
+
),
|
|
50
|
+
completed_turns: Type.Optional(
|
|
51
|
+
Type.Integer({
|
|
52
|
+
description:
|
|
53
|
+
"Number of completed parent turns for last_n_completed",
|
|
54
|
+
minimum: 1,
|
|
55
|
+
maximum: 100,
|
|
56
|
+
}),
|
|
57
|
+
),
|
|
58
|
+
},
|
|
59
|
+
{ additionalProperties: false },
|
|
60
|
+
);
|
|
61
|
+
|
|
32
62
|
function forkDelegationFields(agentNames?: readonly string[]) {
|
|
33
63
|
return {
|
|
34
64
|
...delegationFields(agentNames),
|
|
@@ -45,10 +75,14 @@ function createDelegationParameters(
|
|
|
45
75
|
agentNames?: readonly string[],
|
|
46
76
|
) {
|
|
47
77
|
const fields = delegationFields(agentNames);
|
|
78
|
+
const contextualFields = {
|
|
79
|
+
...fields,
|
|
80
|
+
context: Type.Optional(ContextParameters),
|
|
81
|
+
};
|
|
48
82
|
return Type.Object(
|
|
49
83
|
enableRunInBackground
|
|
50
84
|
? {
|
|
51
|
-
...
|
|
85
|
+
...contextualFields,
|
|
52
86
|
run_in_background: Type.Optional(
|
|
53
87
|
Type.Boolean({
|
|
54
88
|
description:
|
|
@@ -56,7 +90,7 @@ function createDelegationParameters(
|
|
|
56
90
|
}),
|
|
57
91
|
),
|
|
58
92
|
}
|
|
59
|
-
:
|
|
93
|
+
: contextualFields,
|
|
60
94
|
{ additionalProperties: false },
|
|
61
95
|
);
|
|
62
96
|
}
|
|
@@ -75,21 +109,55 @@ export function delegationParameters(
|
|
|
75
109
|
return createDelegationParameters(enableRunInBackground, agentNames);
|
|
76
110
|
}
|
|
77
111
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
)
|
|
112
|
+
function createForkDelegationParameters(
|
|
113
|
+
enableRunInBackground: boolean,
|
|
114
|
+
agentNames?: readonly string[],
|
|
115
|
+
) {
|
|
116
|
+
const fields = forkDelegationFields(agentNames);
|
|
117
|
+
return Type.Object(
|
|
118
|
+
enableRunInBackground
|
|
119
|
+
? {
|
|
120
|
+
...fields,
|
|
121
|
+
run_in_background: Type.Optional(
|
|
122
|
+
Type.Boolean({
|
|
123
|
+
description:
|
|
124
|
+
"Run as a continuable inherited-context background child. Fork remains foreground by default.",
|
|
125
|
+
}),
|
|
126
|
+
),
|
|
127
|
+
}
|
|
128
|
+
: fields,
|
|
129
|
+
{ additionalProperties: false },
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export const ForegroundForkDelegationParameters =
|
|
134
|
+
createForkDelegationParameters(false);
|
|
82
135
|
|
|
83
|
-
export
|
|
84
|
-
|
|
85
|
-
|
|
136
|
+
export const ForkDelegationParameters =
|
|
137
|
+
createForkDelegationParameters(true);
|
|
138
|
+
|
|
139
|
+
export function forkDelegationParameters(
|
|
140
|
+
agentNames?: readonly string[],
|
|
141
|
+
enableRunInBackground = true,
|
|
142
|
+
) {
|
|
143
|
+
if (agentNames === undefined) {
|
|
144
|
+
return enableRunInBackground
|
|
145
|
+
? ForkDelegationParameters
|
|
146
|
+
: ForegroundForkDelegationParameters;
|
|
147
|
+
}
|
|
148
|
+
return createForkDelegationParameters(
|
|
149
|
+
enableRunInBackground,
|
|
150
|
+
agentNames,
|
|
151
|
+
);
|
|
86
152
|
}
|
|
87
153
|
|
|
88
154
|
export const SendMessageParameters = Type.Object(
|
|
89
155
|
{
|
|
90
156
|
subagent_id: Type.String({
|
|
91
|
-
description:
|
|
157
|
+
description:
|
|
158
|
+
"Readable absolute/relative task path or durable id of a direct continuable child",
|
|
92
159
|
minLength: 1,
|
|
160
|
+
maxLength: 4096,
|
|
93
161
|
}),
|
|
94
162
|
message: Type.String({
|
|
95
163
|
description: "Message to enqueue as the child's next FIFO turn",
|
|
@@ -99,11 +167,43 @@ export const SendMessageParameters = Type.Object(
|
|
|
99
167
|
{ additionalProperties: false },
|
|
100
168
|
);
|
|
101
169
|
|
|
170
|
+
export const FollowupTaskParameters = Type.Object(
|
|
171
|
+
{
|
|
172
|
+
subagent_id: Type.String({
|
|
173
|
+
description:
|
|
174
|
+
"Readable absolute/relative task path or durable id of a direct mailbox-v2 continuable child",
|
|
175
|
+
minLength: 1,
|
|
176
|
+
maxLength: 4096,
|
|
177
|
+
}),
|
|
178
|
+
},
|
|
179
|
+
{ additionalProperties: false },
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
export const DEFAULT_WAIT_AGENT_TIMEOUT_MS = 30_000;
|
|
183
|
+
export const MAX_WAIT_AGENT_TIMEOUT_MS = 120_000;
|
|
184
|
+
|
|
185
|
+
export const WaitAgentParameters = Type.Object(
|
|
186
|
+
{
|
|
187
|
+
timeout_ms: Type.Optional(
|
|
188
|
+
Type.Integer({
|
|
189
|
+
description:
|
|
190
|
+
"Maximum event-driven wait in milliseconds before returning a timeout",
|
|
191
|
+
minimum: 0,
|
|
192
|
+
maximum: MAX_WAIT_AGENT_TIMEOUT_MS,
|
|
193
|
+
default: DEFAULT_WAIT_AGENT_TIMEOUT_MS,
|
|
194
|
+
}),
|
|
195
|
+
),
|
|
196
|
+
},
|
|
197
|
+
{ additionalProperties: false },
|
|
198
|
+
);
|
|
199
|
+
|
|
102
200
|
export const InterruptParameters = Type.Object(
|
|
103
201
|
{
|
|
104
202
|
agent_id: Type.String({
|
|
105
|
-
description:
|
|
203
|
+
description:
|
|
204
|
+
"Readable absolute/relative task path or durable id of a live descendant whose current turn should stop",
|
|
106
205
|
minLength: 1,
|
|
206
|
+
maxLength: 4096,
|
|
107
207
|
}),
|
|
108
208
|
},
|
|
109
209
|
{ additionalProperties: false },
|
package/src/task-path.ts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SubagentDescriptor,
|
|
3
|
+
SubagentTask,
|
|
4
|
+
} from "./types.ts";
|
|
5
|
+
|
|
6
|
+
export const ROOT_TASK_PATH = "/root";
|
|
7
|
+
export const LEGACY_TASK_NAMESPACE = ".legacy";
|
|
8
|
+
export const MAX_TASK_NAME_LENGTH = 64;
|
|
9
|
+
export const MAX_TASK_PATH_LENGTH = 4096;
|
|
10
|
+
|
|
11
|
+
const TASK_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
12
|
+
const AGENT_ID_PATTERN =
|
|
13
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
14
|
+
|
|
15
|
+
function pathSegments(path: string): string[] {
|
|
16
|
+
if (path.length > MAX_TASK_PATH_LENGTH) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`task path exceeds ${MAX_TASK_PATH_LENGTH} characters`,
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
if (!path.startsWith("/") || path.endsWith("/") || path.includes("//")) {
|
|
22
|
+
throw new Error(`task path must be a canonical absolute path under ${ROOT_TASK_PATH}`);
|
|
23
|
+
}
|
|
24
|
+
const segments = path.slice(1).split("/");
|
|
25
|
+
if (segments[0] !== "root") {
|
|
26
|
+
throw new Error(`task path must be rooted at ${ROOT_TASK_PATH}`);
|
|
27
|
+
}
|
|
28
|
+
return segments;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function validateTaskName(value: string): string {
|
|
32
|
+
if (!TASK_NAME_PATTERN.test(value)) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
"task_name must contain 1-64 lowercase ASCII letters, digits, hyphens, or underscores and start with a letter or digit",
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
if (value === "root" || value === LEGACY_TASK_NAMESPACE) {
|
|
38
|
+
throw new Error(`task_name "${value}" is reserved`);
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function validateTaskPath(path: string): string {
|
|
44
|
+
if (path === ROOT_TASK_PATH) return path;
|
|
45
|
+
const segments = pathSegments(path);
|
|
46
|
+
for (let index = 1; index < segments.length; index++) {
|
|
47
|
+
const segment = segments[index]!;
|
|
48
|
+
if (
|
|
49
|
+
index === 1
|
|
50
|
+
&& segment === LEGACY_TASK_NAMESPACE
|
|
51
|
+
) {
|
|
52
|
+
const legacyId = segments[index + 1];
|
|
53
|
+
if (!legacyId || !AGENT_ID_PATTERN.test(legacyId)) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`legacy task paths must use ${ROOT_TASK_PATH}/${LEGACY_TASK_NAMESPACE}/<agent-id>`,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
index++;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
validateTaskName(segment);
|
|
62
|
+
}
|
|
63
|
+
return path;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function taskPath(parentPath: string, name: string): string {
|
|
67
|
+
validateTaskPath(parentPath);
|
|
68
|
+
validateTaskName(name);
|
|
69
|
+
const path = `${parentPath}/${name}`;
|
|
70
|
+
return validateTaskPath(path);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function legacyTaskPath(agentId: string): string {
|
|
74
|
+
if (!AGENT_ID_PATTERN.test(agentId)) {
|
|
75
|
+
throw new Error("legacy task path requires a UUIDv7 agent id");
|
|
76
|
+
}
|
|
77
|
+
return `${ROOT_TASK_PATH}/${LEGACY_TASK_NAMESPACE}/${agentId}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function descriptorTaskPath(
|
|
81
|
+
descriptor: SubagentDescriptor,
|
|
82
|
+
): string {
|
|
83
|
+
return descriptor.version === 3
|
|
84
|
+
? descriptor.task.path
|
|
85
|
+
: legacyTaskPath(descriptor.agentId);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function descriptorTask(
|
|
89
|
+
descriptor: SubagentDescriptor,
|
|
90
|
+
): SubagentTask {
|
|
91
|
+
if (descriptor.version === 3) return { ...descriptor.task };
|
|
92
|
+
return {
|
|
93
|
+
name: descriptor.agentId,
|
|
94
|
+
path: legacyTaskPath(descriptor.agentId),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function validateDescriptorTask(task: SubagentTask): SubagentTask {
|
|
99
|
+
const name = validateTaskName(task.name);
|
|
100
|
+
const path = validateTaskPath(task.path);
|
|
101
|
+
if (path === ROOT_TASK_PATH || path.split("/").at(-1) !== name) {
|
|
102
|
+
throw new Error("task.path must end with task.name");
|
|
103
|
+
}
|
|
104
|
+
return { name, path };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function slugTaskName(value: string): string {
|
|
108
|
+
const normalized = value
|
|
109
|
+
.normalize("NFKD")
|
|
110
|
+
.replace(/\p{Mark}/gu, "")
|
|
111
|
+
.toLowerCase()
|
|
112
|
+
.replace(/[^a-z0-9_-]+/g, "-")
|
|
113
|
+
.replace(/[-_]{2,}/g, "-")
|
|
114
|
+
.replace(/^[-_]+|[-_]+$/g, "")
|
|
115
|
+
.slice(0, MAX_TASK_NAME_LENGTH)
|
|
116
|
+
.replace(/[-_]+$/g, "");
|
|
117
|
+
const candidate =
|
|
118
|
+
!normalized || normalized === "root" || normalized === LEGACY_TASK_NAMESPACE
|
|
119
|
+
? "task"
|
|
120
|
+
: normalized;
|
|
121
|
+
return validateTaskName(candidate);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function numberedTaskName(base: string, ordinal: number): string {
|
|
125
|
+
validateTaskName(base);
|
|
126
|
+
if (!Number.isSafeInteger(ordinal) || ordinal < 2) {
|
|
127
|
+
throw new Error("task name ordinal must be an integer of at least 2");
|
|
128
|
+
}
|
|
129
|
+
const suffix = `-${ordinal}`;
|
|
130
|
+
const prefix = base
|
|
131
|
+
.slice(0, MAX_TASK_NAME_LENGTH - suffix.length)
|
|
132
|
+
.replace(/[-_]+$/g, "");
|
|
133
|
+
return validateTaskName(`${prefix || "task"}${suffix}`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function resolveTaskPath(
|
|
137
|
+
basePath: string,
|
|
138
|
+
reference: string,
|
|
139
|
+
): string {
|
|
140
|
+
validateTaskPath(basePath);
|
|
141
|
+
if (!reference.trim() || reference !== reference.trim()) {
|
|
142
|
+
throw new Error("task path reference must be a non-empty trimmed string");
|
|
143
|
+
}
|
|
144
|
+
if (reference.length > MAX_TASK_PATH_LENGTH) {
|
|
145
|
+
throw new Error(
|
|
146
|
+
`task path reference exceeds ${MAX_TASK_PATH_LENGTH} characters`,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
if (reference.includes("//") || (reference.length > 1 && reference.endsWith("/"))) {
|
|
150
|
+
throw new Error("task path reference contains an empty segment");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const absolute = reference.startsWith("/");
|
|
154
|
+
const segments = absolute ? ["root"] : pathSegments(basePath);
|
|
155
|
+
const input = absolute ? reference.slice(1).split("/") : reference.split("/");
|
|
156
|
+
if (absolute && input.shift() !== "root") {
|
|
157
|
+
throw new Error(`absolute task paths must be rooted at ${ROOT_TASK_PATH}`);
|
|
158
|
+
}
|
|
159
|
+
for (const segment of input) {
|
|
160
|
+
if (!segment || segment === ".") continue;
|
|
161
|
+
if (segment === "..") {
|
|
162
|
+
if (segments.length === 1) {
|
|
163
|
+
throw new Error(`task path reference cannot escape ${ROOT_TASK_PATH}`);
|
|
164
|
+
}
|
|
165
|
+
segments.pop();
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (segment === LEGACY_TASK_NAMESPACE) {
|
|
169
|
+
segments.push(segment);
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (
|
|
173
|
+
segments.at(-1) === LEGACY_TASK_NAMESPACE
|
|
174
|
+
&& AGENT_ID_PATTERN.test(segment)
|
|
175
|
+
) {
|
|
176
|
+
segments.push(segment);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
validateTaskName(segment);
|
|
180
|
+
segments.push(segment);
|
|
181
|
+
}
|
|
182
|
+
const resolved = `/${segments.join("/")}`;
|
|
183
|
+
return validateTaskPath(resolved);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function isAgentId(value: string): boolean {
|
|
187
|
+
return AGENT_ID_PATTERN.test(value);
|
|
188
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -2,18 +2,33 @@ import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
|
|
|
2
2
|
import type { Usage } from "@earendil-works/pi-ai";
|
|
3
3
|
|
|
4
4
|
export type AgentScope = "user" | "project" | "both";
|
|
5
|
-
|
|
5
|
+
/** Sources that runtime discovery is allowed to activate. */
|
|
6
|
+
export type AgentSource = "user" | "project";
|
|
7
|
+
/** `bundled` is retained only for reading descriptors written by older releases. */
|
|
8
|
+
export type AgentSnapshotSource = AgentSource | "bundled";
|
|
6
9
|
export type ReportDelivery = "wakeup" | "quiet";
|
|
10
|
+
export type BackgroundProtocol = "legacy" | "mailbox-v2";
|
|
7
11
|
export type SubagentMode = "one-shot" | "continuable";
|
|
8
12
|
export type SubagentProviderName = "spawn" | "fork";
|
|
9
13
|
export type SubagentStopReason = "completed" | "aborted" | "error" | "max-tokens";
|
|
14
|
+
export type ContextInheritance =
|
|
15
|
+
| { mode: "fresh" }
|
|
16
|
+
| { mode: "all_completed" }
|
|
17
|
+
| { mode: "last_n_completed"; completedTurns: number };
|
|
18
|
+
|
|
19
|
+
export interface SubagentTask {
|
|
20
|
+
name: string;
|
|
21
|
+
path: string;
|
|
22
|
+
}
|
|
10
23
|
|
|
11
24
|
export interface SubagentSettings {
|
|
12
25
|
agentScope: AgentScope;
|
|
13
|
-
syncBundledAgents: boolean;
|
|
14
26
|
maxDepth: number;
|
|
15
27
|
enableRunInBackground: boolean;
|
|
16
28
|
defaultBackground: boolean;
|
|
29
|
+
maxConcurrentBackgroundRuns: number;
|
|
30
|
+
maxIdleRuntimes: number;
|
|
31
|
+
backgroundProtocol?: BackgroundProtocol;
|
|
17
32
|
reportDelivery: ReportDelivery;
|
|
18
33
|
inheritExtensions: boolean;
|
|
19
34
|
openAIIdentity: boolean;
|
|
@@ -38,7 +53,7 @@ export interface AgentSnapshot {
|
|
|
38
53
|
model?: string;
|
|
39
54
|
thinking?: ThinkingLevel;
|
|
40
55
|
systemPrompt: string;
|
|
41
|
-
source:
|
|
56
|
+
source: AgentSnapshotSource;
|
|
42
57
|
}
|
|
43
58
|
|
|
44
59
|
export interface ResolvedModel {
|
|
@@ -48,18 +63,19 @@ export interface ResolvedModel {
|
|
|
48
63
|
|
|
49
64
|
export interface SubagentRuntimeSnapshot {
|
|
50
65
|
agentScope: AgentScope;
|
|
51
|
-
syncBundledAgents: boolean;
|
|
52
66
|
maxDepth: number;
|
|
53
67
|
enableRunInBackground: boolean;
|
|
54
68
|
defaultBackground: boolean;
|
|
69
|
+
maxConcurrentBackgroundRuns: number;
|
|
70
|
+
maxIdleRuntimes: number;
|
|
71
|
+
backgroundProtocol: BackgroundProtocol;
|
|
55
72
|
reportDelivery: ReportDelivery;
|
|
56
73
|
inheritExtensions: boolean;
|
|
57
74
|
openAIIdentity: boolean;
|
|
58
75
|
maxOutputBytes: number;
|
|
59
76
|
}
|
|
60
77
|
|
|
61
|
-
|
|
62
|
-
version: 2;
|
|
78
|
+
interface SubagentDescriptorBase {
|
|
63
79
|
mode: SubagentMode;
|
|
64
80
|
provider: SubagentProviderName;
|
|
65
81
|
label: string;
|
|
@@ -80,15 +96,32 @@ export interface SubagentDescriptor {
|
|
|
80
96
|
runtime: SubagentRuntimeSnapshot;
|
|
81
97
|
}
|
|
82
98
|
|
|
99
|
+
export interface SubagentDescriptorV2 extends SubagentDescriptorBase {
|
|
100
|
+
version: 2;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface SubagentDescriptorV3 extends SubagentDescriptorBase {
|
|
104
|
+
version: 3;
|
|
105
|
+
task: SubagentTask;
|
|
106
|
+
context: ContextInheritance;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export type SubagentDescriptor =
|
|
110
|
+
| SubagentDescriptorV2
|
|
111
|
+
| SubagentDescriptorV3;
|
|
112
|
+
|
|
83
113
|
export interface SubagentUsage extends Usage {
|
|
84
114
|
turns: number;
|
|
85
115
|
}
|
|
86
116
|
|
|
87
117
|
export interface SubagentRunResult {
|
|
88
118
|
agentId: string;
|
|
119
|
+
turnId: string;
|
|
89
120
|
piSessionId?: string;
|
|
90
121
|
sessionFile?: string;
|
|
91
122
|
output: string;
|
|
123
|
+
outputTruncated?: boolean;
|
|
124
|
+
omittedBytes?: number;
|
|
92
125
|
stopReason: SubagentStopReason;
|
|
93
126
|
usage: SubagentUsage;
|
|
94
127
|
}
|
|
@@ -102,9 +135,12 @@ export interface TraceItem {
|
|
|
102
135
|
export interface DelegationDetails {
|
|
103
136
|
kind: "delegation";
|
|
104
137
|
agentId: string;
|
|
138
|
+
taskPath: string;
|
|
139
|
+
turnId?: string;
|
|
105
140
|
piSessionId?: string;
|
|
106
141
|
provider: SubagentProviderName;
|
|
107
142
|
mode: SubagentMode;
|
|
143
|
+
context: ContextInheritance;
|
|
108
144
|
agent: string;
|
|
109
145
|
label: string;
|
|
110
146
|
depth: number;
|
|
@@ -118,18 +154,30 @@ export interface DelegationDetails {
|
|
|
118
154
|
|
|
119
155
|
export interface ControlDetails {
|
|
120
156
|
kind: "control";
|
|
121
|
-
action: "send" | "interrupt" | "list" | "report";
|
|
157
|
+
action: "send" | "followup" | "wait" | "interrupt" | "list" | "report";
|
|
122
158
|
agentId?: string;
|
|
159
|
+
taskPath?: string;
|
|
160
|
+
messageId?: string;
|
|
161
|
+
turnId?: string;
|
|
162
|
+
pendingMessages?: number;
|
|
163
|
+
claimedMessages?: number;
|
|
164
|
+
completionIds?: string[];
|
|
165
|
+
timedOut?: boolean;
|
|
166
|
+
unreadUpdates?: number;
|
|
123
167
|
}
|
|
124
168
|
|
|
125
169
|
export interface CatalogChild {
|
|
126
170
|
kind: "child";
|
|
127
171
|
agentId: string;
|
|
128
172
|
parentAgentId: string;
|
|
173
|
+
taskPath: string;
|
|
174
|
+
parentTaskPath: string;
|
|
129
175
|
depth: number;
|
|
130
176
|
descriptor: SubagentDescriptor;
|
|
131
177
|
sessionFile?: string;
|
|
132
178
|
status: "running" | "idle" | "ready";
|
|
179
|
+
pendingMessages: number;
|
|
180
|
+
unreadUpdates: number;
|
|
133
181
|
}
|
|
134
182
|
|
|
135
183
|
export interface CatalogDiagnostic {
|
|
@@ -146,6 +194,7 @@ export type CatalogEntry = CatalogChild | CatalogDiagnostic;
|
|
|
146
194
|
export interface ParentMessageDetails {
|
|
147
195
|
kind: "report" | "settled";
|
|
148
196
|
childAgentId: string;
|
|
197
|
+
taskPath?: string;
|
|
149
198
|
label: string;
|
|
150
199
|
stopReason?: SubagentStopReason;
|
|
151
200
|
truncated?: boolean;
|