@narumitw/pi-subagents 0.54.0 → 1.0.1
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 +22 -13
- package/package.json +1 -1
- package/src/automation-registration.ts +137 -0
- package/src/automation-tool.ts +40 -0
- package/src/automation.ts +6 -156
- package/src/cached-module-loader.ts +18 -0
- package/src/completion-delivery.ts +80 -8
- package/src/config-registration.ts +89 -0
- package/src/config-ui.ts +2 -2
- package/src/consult-registration.ts +132 -0
- package/src/consult-tool.ts +95 -0
- package/src/consult.ts +37 -204
- package/src/create-stateful-transport.ts +106 -18
- package/src/inspect-registration.ts +64 -0
- package/src/inspect-tool.ts +43 -0
- package/src/inspect.ts +11 -69
- package/src/params.ts +1 -1
- package/src/persistence.ts +105 -6
- package/src/pi-args.ts +41 -0
- package/src/registry-types.ts +21 -4
- package/src/registry.ts +204 -36
- package/src/render.ts +2 -6
- package/src/runner-outcome.ts +31 -0
- package/src/runner.ts +18 -79
- package/src/stateful-guidance.ts +1 -1
- package/src/stateful-render.ts +0 -1
- package/src/stateful-tool-params.ts +13 -20
- package/src/stateful.ts +24 -20
- package/src/subagents.ts +81 -28
- package/src/verified-execution-contract.ts +3 -31
- package/src/verified-execution-schema.ts +32 -0
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
import { StringEnum } from "@earendil-works/pi-ai";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
3
|
|
|
4
|
-
const MANAGE_ACTIONS = ["
|
|
4
|
+
const MANAGE_ACTIONS = ["interrupt", "close"] as const;
|
|
5
5
|
const MAILBOX_ACTIONS = ["send", "read"] as const;
|
|
6
6
|
const MAX_MAILBOX_MESSAGE_LENGTH = 16 * 1024;
|
|
7
7
|
|
|
8
8
|
export const ManageParamsSchema = Type.Object(
|
|
9
9
|
{
|
|
10
10
|
action: StringEnum(MANAGE_ACTIONS, {
|
|
11
|
-
description:
|
|
12
|
-
"Use list to inspect agents, interrupt to stop active work, or close to release agents.",
|
|
11
|
+
description: "Interrupt active work or close an agent and release its resources.",
|
|
13
12
|
}),
|
|
14
13
|
agentId: Type.Optional(
|
|
15
14
|
Type.String({ minLength: 1, description: "Required for interrupt and close." }),
|
|
16
15
|
),
|
|
17
|
-
includeClosed: Type.Optional(
|
|
18
|
-
Type.Boolean({
|
|
19
|
-
default: false,
|
|
20
|
-
description: "List closed records as well as retained agents.",
|
|
21
|
-
}),
|
|
22
|
-
),
|
|
23
16
|
subtree: Type.Optional(
|
|
24
17
|
Type.Boolean({
|
|
25
18
|
default: false,
|
|
@@ -57,9 +50,11 @@ export const MailboxParamsSchema = Type.Object(
|
|
|
57
50
|
{ additionalProperties: false },
|
|
58
51
|
);
|
|
59
52
|
|
|
60
|
-
export type ValidatedManageParams =
|
|
61
|
-
|
|
62
|
-
|
|
53
|
+
export type ValidatedManageParams = {
|
|
54
|
+
action: "interrupt" | "close";
|
|
55
|
+
agentId: string;
|
|
56
|
+
subtree?: boolean;
|
|
57
|
+
};
|
|
63
58
|
|
|
64
59
|
export type ValidatedMailboxParams =
|
|
65
60
|
| {
|
|
@@ -73,21 +68,19 @@ export type ValidatedMailboxParams =
|
|
|
73
68
|
|
|
74
69
|
export function validateManageParams(params: unknown): ValidatedManageParams {
|
|
75
70
|
const values = parameterRecord(params, "subagent_manage");
|
|
76
|
-
assertKnownKeys("subagent_manage", values, ["action", "agentId", "
|
|
71
|
+
assertKnownKeys("subagent_manage", values, ["action", "agentId", "subtree"]);
|
|
77
72
|
const action = values.action;
|
|
73
|
+
if (action === "list") {
|
|
74
|
+
throw new Error(
|
|
75
|
+
'subagent_manage no longer supports "list"; use subagent_inspect action "list_runs"',
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
78
|
if (
|
|
79
79
|
typeof action !== "string" ||
|
|
80
80
|
!MANAGE_ACTIONS.includes(action as (typeof MANAGE_ACTIONS)[number])
|
|
81
81
|
) {
|
|
82
82
|
throw new Error(`subagent_manage action must be one of: ${MANAGE_ACTIONS.join(", ")}`);
|
|
83
83
|
}
|
|
84
|
-
if (action === "list") {
|
|
85
|
-
assertOptionalBoolean("subagent_manage", action, values, "includeClosed");
|
|
86
|
-
return {
|
|
87
|
-
action,
|
|
88
|
-
...(values.includeClosed === undefined ? {} : { includeClosed: values.includeClosed }),
|
|
89
|
-
} as ValidatedManageParams;
|
|
90
|
-
}
|
|
91
84
|
assertRequiredString("subagent_manage", action, values, "agentId");
|
|
92
85
|
assertOptionalBoolean("subagent_manage", action, values, "subtree");
|
|
93
86
|
return {
|
package/src/stateful.ts
CHANGED
|
@@ -20,7 +20,10 @@ import {
|
|
|
20
20
|
import { issueCapabilityGrant } from "./capability-grant.js";
|
|
21
21
|
import { CompletionDeliveryBroker } from "./completion-delivery.js";
|
|
22
22
|
import { buildContextSnapshot, type ContextMode, redactPrivateText } from "./context.js";
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
type CreateStatefulTransportOptions,
|
|
25
|
+
createStatefulTransport,
|
|
26
|
+
} from "./create-stateful-transport.js";
|
|
24
27
|
import {
|
|
25
28
|
assertDelegationTargetAllowed,
|
|
26
29
|
resolveSubagentTarget,
|
|
@@ -52,7 +55,7 @@ import {
|
|
|
52
55
|
hashSpawnRequest,
|
|
53
56
|
MAX_SPAWN_IDEMPOTENCY_KEY_LENGTH,
|
|
54
57
|
} from "./spawn-idempotency.js";
|
|
55
|
-
import {
|
|
58
|
+
import { summarizeStatefulAgent } from "./stateful-agent-view.js";
|
|
56
59
|
import { resolveCompletionDelivery, resolveStatefulTransportKind } from "./stateful-config.js";
|
|
57
60
|
import { createSpawnPromptGuidelines } from "./stateful-guidance.js";
|
|
58
61
|
import {
|
|
@@ -133,6 +136,7 @@ export interface StatefulSubagentDependencies {
|
|
|
133
136
|
workspaceManager?: WorkspaceManager;
|
|
134
137
|
settings?: SubagentRuntimeSettings;
|
|
135
138
|
getSettings?: () => SubagentSettings | undefined;
|
|
139
|
+
loadTransport?: CreateStatefulTransportOptions["loadTransport"];
|
|
136
140
|
}
|
|
137
141
|
|
|
138
142
|
export interface StatefulSubagentRuntimeStatus {
|
|
@@ -300,10 +304,16 @@ export function registerStatefulSubagents(
|
|
|
300
304
|
const reason = error instanceof Error ? error.message : String(error);
|
|
301
305
|
ctx.ui.notify(`Subagent completion delivery failed: ${reason}`, "warning");
|
|
302
306
|
},
|
|
303
|
-
|
|
307
|
+
onAcknowledged: (completions, deliveredAt) => {
|
|
304
308
|
if (generation !== runtimeGeneration) return;
|
|
305
309
|
for (const completion of completions) {
|
|
306
|
-
nextRegistry
|
|
310
|
+
void nextRegistry
|
|
311
|
+
.markCompletionDelivered(completion.completionId, deliveredAt)
|
|
312
|
+
.catch((error: unknown) => {
|
|
313
|
+
if (!ctx.hasUI || generation !== runtimeGeneration) return;
|
|
314
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
315
|
+
ctx.ui.notify(`Subagent completion acknowledgement failed: ${reason}`, "warning");
|
|
316
|
+
});
|
|
307
317
|
}
|
|
308
318
|
},
|
|
309
319
|
});
|
|
@@ -313,6 +323,7 @@ export function registerStatefulSubagents(
|
|
|
313
323
|
getParentRuntime: () => ({ ...parentRuntime }),
|
|
314
324
|
getSettings: getCurrentSettings,
|
|
315
325
|
createInProcessSession: dependencies.createInProcessSession,
|
|
326
|
+
loadTransport: dependencies.loadTransport,
|
|
316
327
|
});
|
|
317
328
|
nextRegistry = new AgentRegistry(transport, {
|
|
318
329
|
maxAgents: nextLimits.maxAgents,
|
|
@@ -378,6 +389,9 @@ export function registerStatefulSubagents(
|
|
|
378
389
|
registry = nextRegistry;
|
|
379
390
|
persistence = sessionPersistence;
|
|
380
391
|
completionBroker = sessionBroker;
|
|
392
|
+
for (const completion of nextRegistry.listPendingCompletions()) {
|
|
393
|
+
sessionBroker.enqueue(completion);
|
|
394
|
+
}
|
|
381
395
|
runtimeLimits = nextLimits;
|
|
382
396
|
refreshSpawnToolRegistration?.();
|
|
383
397
|
const sweepEveryMs = Math.max(
|
|
@@ -402,6 +416,10 @@ export function registerStatefulSubagents(
|
|
|
402
416
|
completionBroker?.onParentTurnStart();
|
|
403
417
|
});
|
|
404
418
|
|
|
419
|
+
pi.on("context", (event) => {
|
|
420
|
+
completionBroker?.onParentContext(event.messages);
|
|
421
|
+
});
|
|
422
|
+
|
|
405
423
|
pi.on("agent_settled", () => {
|
|
406
424
|
completionBroker?.onParentSettled();
|
|
407
425
|
});
|
|
@@ -835,8 +853,8 @@ export function registerStatefulSubagents(
|
|
|
835
853
|
name: "subagent_manage",
|
|
836
854
|
label: "Manage Subagents",
|
|
837
855
|
description:
|
|
838
|
-
"
|
|
839
|
-
promptSnippet: "
|
|
856
|
+
"Interrupt active work while keeping an agent reusable, or close agents and release their resources. Use subagent_inspect for every read-only list, detail, status, and diagnostic operation.",
|
|
857
|
+
promptSnippet: "Interrupt or close retained detached subagents",
|
|
840
858
|
parameters: ManageParamsSchema,
|
|
841
859
|
...createStatefulToolRenderer("manage"),
|
|
842
860
|
async execute(_id, params, signal): Promise<StatefulActionToolResult> {
|
|
@@ -848,20 +866,6 @@ export function registerStatefulSubagents(
|
|
|
848
866
|
return value;
|
|
849
867
|
};
|
|
850
868
|
const operation = validateManageParams(params);
|
|
851
|
-
if (operation.action === "list") {
|
|
852
|
-
const agents = ownedRegistry.list(operation.includeClosed);
|
|
853
|
-
return {
|
|
854
|
-
content: [
|
|
855
|
-
{
|
|
856
|
-
type: "text",
|
|
857
|
-
text: agents.length
|
|
858
|
-
? agents.map(formatStatefulAgentLine).join("\n")
|
|
859
|
-
: "No stateful subagents.",
|
|
860
|
-
},
|
|
861
|
-
],
|
|
862
|
-
details: { agents: agents.map(summarizeStatefulAgent) },
|
|
863
|
-
};
|
|
864
|
-
}
|
|
865
869
|
const agentId = operation.agentId;
|
|
866
870
|
if (operation.action === "interrupt") {
|
|
867
871
|
if (operation.subtree) {
|
package/src/subagents.ts
CHANGED
|
@@ -21,11 +21,24 @@ import type {
|
|
|
21
21
|
DelegationCwdPolicy,
|
|
22
22
|
SubagentSettings,
|
|
23
23
|
} from "./agents/types.js";
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
type AutomationRegistrationDependencies,
|
|
26
|
+
registerSubagentAutomation,
|
|
27
|
+
} from "./automation-registration.js";
|
|
28
|
+
import { cachedModuleLoader, throwIfAborted } from "./cached-module-loader.js";
|
|
29
|
+
import {
|
|
30
|
+
type ConfigRegistrationDependencies,
|
|
31
|
+
registerSubagentConfigCommand,
|
|
32
|
+
registerSubagentConfigLifecycle,
|
|
33
|
+
} from "./config-registration.js";
|
|
34
|
+
import {
|
|
35
|
+
type ConsultRegistrationDependencies,
|
|
36
|
+
registerSubagentConsult,
|
|
37
|
+
} from "./consult-registration.js";
|
|
38
|
+
import {
|
|
39
|
+
type InspectRegistrationDependencies,
|
|
40
|
+
registerSubagentInspect,
|
|
41
|
+
} from "./inspect-registration.js";
|
|
29
42
|
import { MAX_BLOCKING_PARALLEL_CONCURRENCY } from "./limits.js";
|
|
30
43
|
import { SubagentParams } from "./params.js";
|
|
31
44
|
import { renderSubagentCall, renderSubagentResult } from "./render.js";
|
|
@@ -40,17 +53,34 @@ import {
|
|
|
40
53
|
resolveBlockingMaxParallelTasks,
|
|
41
54
|
} from "./settings.js";
|
|
42
55
|
import { registerStatefulSubagents } from "./stateful.js";
|
|
56
|
+
import type { SubagentTransport } from "./transport.js";
|
|
57
|
+
|
|
58
|
+
type BlockingExecutionModule = Pick<typeof import("./execution.js"), "executeSubagent">;
|
|
59
|
+
|
|
60
|
+
export interface SubagentsDependencies {
|
|
61
|
+
loadBlockingExecution?: () => Promise<BlockingExecutionModule>;
|
|
62
|
+
loadStatefulTransport?: () => Promise<SubagentTransport>;
|
|
63
|
+
automation?: AutomationRegistrationDependencies;
|
|
64
|
+
config?: ConfigRegistrationDependencies;
|
|
65
|
+
consult?: ConsultRegistrationDependencies;
|
|
66
|
+
inspect?: InspectRegistrationDependencies;
|
|
67
|
+
}
|
|
43
68
|
|
|
44
|
-
export default function (pi: ExtensionAPI) {
|
|
69
|
+
export default function (pi: ExtensionAPI, dependencies: SubagentsDependencies = {}) {
|
|
70
|
+
const loadBlockingExecution = cachedModuleLoader(
|
|
71
|
+
dependencies.loadBlockingExecution ?? (() => import("./execution.js")),
|
|
72
|
+
);
|
|
45
73
|
const configOwner = registerSubagentConfigLifecycle(pi);
|
|
46
74
|
const settings = readSubagentSettings();
|
|
47
75
|
let currentSettings: SubagentSettings | undefined = settings;
|
|
48
76
|
let currentCatalog = "";
|
|
49
77
|
const blockingEnabled = settings?.blocking?.enabled !== false;
|
|
50
78
|
const refreshBlockingCatalog = blockingEnabled
|
|
51
|
-
? registerBlockingSubagent(pi, () => currentSettings)
|
|
79
|
+
? registerBlockingSubagent(pi, () => currentSettings, loadBlockingExecution)
|
|
52
80
|
: () => undefined;
|
|
53
|
-
if (blockingEnabled)
|
|
81
|
+
if (blockingEnabled) {
|
|
82
|
+
registerSubagentAutomation(pi, { getSettings: () => currentSettings }, dependencies.automation);
|
|
83
|
+
}
|
|
54
84
|
let refreshStatefulCatalog: (catalog: string) => void = () => undefined;
|
|
55
85
|
let refreshConsultCatalog: (catalog: string) => void = () => undefined;
|
|
56
86
|
|
|
@@ -78,6 +108,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
78
108
|
blockingEnabled,
|
|
79
109
|
settings: settings?.stateful,
|
|
80
110
|
getSettings: () => currentSettings,
|
|
111
|
+
loadTransport: dependencies.loadStatefulTransport,
|
|
81
112
|
});
|
|
82
113
|
refreshStatefulCatalog = statefulRuntime.setAgentCatalog;
|
|
83
114
|
const getBlockingEnabled = () => blockingEnabled;
|
|
@@ -88,18 +119,24 @@ export default function (pi: ExtensionAPI) {
|
|
|
88
119
|
currentSettings?.cwdPolicy?.consultation ?? DEFAULT_CONSULTATION_CWD_POLICY;
|
|
89
120
|
const getDelegationCwdPolicy = () =>
|
|
90
121
|
currentSettings?.cwdPolicy?.delegation ?? DEFAULT_DELEGATION_CWD_POLICY;
|
|
91
|
-
registerSubagentInspect(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
122
|
+
registerSubagentInspect(
|
|
123
|
+
pi,
|
|
124
|
+
{
|
|
125
|
+
...statefulRuntime,
|
|
126
|
+
getBlockingEnabled,
|
|
127
|
+
getMaxParallelTasks,
|
|
128
|
+
getConsultResourcePolicy,
|
|
129
|
+
getConsultationCwdPolicy,
|
|
130
|
+
getDelegationCwdPolicy,
|
|
131
|
+
},
|
|
132
|
+
dependencies.inspect,
|
|
133
|
+
);
|
|
99
134
|
if (blockingEnabled) {
|
|
100
|
-
refreshConsultCatalog = registerSubagentConsult(
|
|
101
|
-
|
|
102
|
-
|
|
135
|
+
refreshConsultCatalog = registerSubagentConsult(
|
|
136
|
+
pi,
|
|
137
|
+
{ getSettings: () => currentSettings },
|
|
138
|
+
dependencies.consult,
|
|
139
|
+
);
|
|
103
140
|
}
|
|
104
141
|
registerSubagentConfigCommand(
|
|
105
142
|
pi,
|
|
@@ -155,12 +192,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
155
192
|
},
|
|
156
193
|
},
|
|
157
194
|
configOwner,
|
|
195
|
+
dependencies.config,
|
|
158
196
|
);
|
|
159
197
|
}
|
|
160
198
|
|
|
161
199
|
function registerBlockingSubagent(
|
|
162
200
|
pi: ExtensionAPI,
|
|
163
201
|
getSettings: () => SubagentSettings | undefined,
|
|
202
|
+
loadExecution: () => Promise<BlockingExecutionModule>,
|
|
164
203
|
): (catalog: string) => void {
|
|
165
204
|
let catalog = "";
|
|
166
205
|
const activeControllers = new Set<AbortController>();
|
|
@@ -212,14 +251,28 @@ function registerBlockingSubagent(
|
|
|
212
251
|
const effectiveSignal = signal
|
|
213
252
|
? AbortSignal.any([signal, lifecycleController.signal])
|
|
214
253
|
: lifecycleController.signal;
|
|
215
|
-
const work =
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
254
|
+
const work = (async () => {
|
|
255
|
+
throwIfAborted(effectiveSignal, "Blocking subagent execution was cancelled");
|
|
256
|
+
let executionModule: BlockingExecutionModule;
|
|
257
|
+
try {
|
|
258
|
+
executionModule = await loadExecution();
|
|
259
|
+
} catch (error) {
|
|
260
|
+
throwIfAborted(
|
|
261
|
+
effectiveSignal,
|
|
262
|
+
"Blocking subagent execution was cancelled while loading",
|
|
263
|
+
);
|
|
264
|
+
throw error;
|
|
265
|
+
}
|
|
266
|
+
throwIfAborted(effectiveSignal, "Blocking subagent execution was cancelled while loading");
|
|
267
|
+
return executionModule.executeSubagent(
|
|
268
|
+
toolCallId,
|
|
269
|
+
params,
|
|
270
|
+
effectiveSignal,
|
|
271
|
+
onUpdate,
|
|
272
|
+
ctx,
|
|
273
|
+
getSettings(),
|
|
274
|
+
);
|
|
275
|
+
})();
|
|
223
276
|
activeWork.add(work);
|
|
224
277
|
try {
|
|
225
278
|
return await work;
|
|
@@ -256,8 +309,8 @@ function appendAgentCatalog(baseDescription: string, catalog: string): string {
|
|
|
256
309
|
}
|
|
257
310
|
|
|
258
311
|
export { parsePositiveInteger } from "./execution/runtime-policy.js";
|
|
312
|
+
export { buildPiArgs } from "./pi-args.js";
|
|
259
313
|
export { formatTokens, formatUsageStats } from "./render.js";
|
|
260
|
-
export { buildPiArgs } from "./runner.js";
|
|
261
314
|
export {
|
|
262
315
|
DEFAULT_CONSULT_RESOURCE_POLICY,
|
|
263
316
|
DEFAULT_CONSULTATION_CWD_POLICY,
|
|
@@ -1,41 +1,13 @@
|
|
|
1
|
-
import { StringEnum } from "@earendil-works/pi-ai";
|
|
2
|
-
import { type Static, Type } from "typebox";
|
|
3
1
|
import { normalizeDelegationContract } from "./delegation-contract.js";
|
|
4
2
|
import {
|
|
5
3
|
type VerificationCheckRequest,
|
|
6
4
|
validateVerificationChecks,
|
|
7
5
|
} from "./verification-harness.js";
|
|
6
|
+
import type { VerifiedExecutionContract } from "./verified-execution-schema.js";
|
|
8
7
|
import type { ResolvedWorkflowTask } from "./workflow-planning.js";
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
id: Type.String({
|
|
13
|
-
minLength: 1,
|
|
14
|
-
maxLength: 256,
|
|
15
|
-
pattern: "^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$",
|
|
16
|
-
}),
|
|
17
|
-
command: StringEnum(["git", "node", "npm", "npx"] as const),
|
|
18
|
-
args: Type.Optional(Type.Array(Type.String({ maxLength: 4096 }), { maxItems: 64 })),
|
|
19
|
-
cwd: Type.Optional(Type.String({ minLength: 1, maxLength: 4096 })),
|
|
20
|
-
timeoutMs: Type.Optional(Type.Integer({ minimum: 1, maximum: 600_000 })),
|
|
21
|
-
},
|
|
22
|
-
{ additionalProperties: false },
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
export const VerifiedExecutionContractSchema = Type.Object(
|
|
26
|
-
{
|
|
27
|
-
verifierAgent: Type.String({ minLength: 1, maxLength: 256 }),
|
|
28
|
-
maxReworkCycles: Type.Optional(Type.Integer({ minimum: 0, maximum: 1, default: 1 })),
|
|
29
|
-
checks: Type.Optional(Type.Array(VerificationCheckSchema, { maxItems: 32 })),
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
additionalProperties: false,
|
|
33
|
-
description:
|
|
34
|
-
"Explicitly gate mutating workflow success on executor-owned deterministic checks, one least-authority independent verifier, exact submitted-state identity, and managed integration acceptance.",
|
|
35
|
-
},
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
export type VerifiedExecutionContract = Static<typeof VerifiedExecutionContractSchema>;
|
|
9
|
+
export type { VerifiedExecutionContract } from "./verified-execution-schema.js";
|
|
10
|
+
export { VerifiedExecutionContractSchema } from "./verified-execution-schema.js";
|
|
39
11
|
|
|
40
12
|
export interface PreparedVerifiedWorkflow {
|
|
41
13
|
tasks: ResolvedWorkflowTask[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { StringEnum } from "@earendil-works/pi-ai";
|
|
2
|
+
import { type Static, Type } from "typebox";
|
|
3
|
+
|
|
4
|
+
const VerificationCheckSchema = Type.Object(
|
|
5
|
+
{
|
|
6
|
+
id: Type.String({
|
|
7
|
+
minLength: 1,
|
|
8
|
+
maxLength: 256,
|
|
9
|
+
pattern: "^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$",
|
|
10
|
+
}),
|
|
11
|
+
command: StringEnum(["git", "node", "npm", "npx"] as const),
|
|
12
|
+
args: Type.Optional(Type.Array(Type.String({ maxLength: 4096 }), { maxItems: 64 })),
|
|
13
|
+
cwd: Type.Optional(Type.String({ minLength: 1, maxLength: 4096 })),
|
|
14
|
+
timeoutMs: Type.Optional(Type.Integer({ minimum: 1, maximum: 600_000 })),
|
|
15
|
+
},
|
|
16
|
+
{ additionalProperties: false },
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
export const VerifiedExecutionContractSchema = Type.Object(
|
|
20
|
+
{
|
|
21
|
+
verifierAgent: Type.String({ minLength: 1, maxLength: 256 }),
|
|
22
|
+
maxReworkCycles: Type.Optional(Type.Integer({ minimum: 0, maximum: 1, default: 1 })),
|
|
23
|
+
checks: Type.Optional(Type.Array(VerificationCheckSchema, { maxItems: 32 })),
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
additionalProperties: false,
|
|
27
|
+
description:
|
|
28
|
+
"Explicitly gate mutating workflow success on executor-owned deterministic checks, one least-authority independent verifier, exact submitted-state identity, and managed integration acceptance.",
|
|
29
|
+
},
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export type VerifiedExecutionContract = Static<typeof VerifiedExecutionContractSchema>;
|