@otto-code/protocol 0.5.2 → 0.5.4

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/messages.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { TerminalActivitySchema } from "./terminal-activity.js";
3
+ import { RunSchema } from "./orchestration.js";
3
4
  import { ArtifactMetadataSchema } from "./artifacts/types.js";
4
5
  import { ArtifactListRequestSchema, ArtifactCreateRequestSchema, ArtifactUpdateRequestSchema, ArtifactRegenerateRequestSchema, ArtifactCancelRequestSchema, ArtifactDeleteRequestSchema, ArtifactStarRequestSchema, ArtifactGetContentRequestSchema, ArtifactListResponseSchema, ArtifactCreateResponseSchema, ArtifactUpdateResponseSchema, ArtifactRegenerateResponseSchema, ArtifactCancelResponseSchema, ArtifactDeleteResponseSchema, ArtifactStarResponseSchema, ArtifactGetContentResponseSchema, ArtifactCreatedNotificationSchema, ArtifactUpdatedNotificationSchema, ArtifactDeletedNotificationSchema, } from "./artifacts/rpc-schemas.js";
5
6
  import { CLIENT_CAPS } from "./client-capabilities.js";
@@ -139,13 +140,20 @@ export const MutableGitHostingConfigSchema = z
139
140
  // agent-personalities.ts) so personalities persisted before the split keep their
140
141
  // role rather than silently losing it.
141
142
  export const PERSONALITY_ROLES = [
143
+ // Surfaces — the interactive / host-facing entry points.
142
144
  "chatter",
143
145
  "artificer",
144
146
  "scheduler",
145
- "writer",
146
- "coder",
147
+ // Thinking workers — read-only, return structured findings, never edit.
148
+ "researcher",
149
+ "planner",
147
150
  "judger",
148
151
  "advisor",
152
+ // Making workers — produce code, design, or short text.
153
+ "coder",
154
+ "designer",
155
+ "writer",
156
+ // Conductor — the sole role whose whole job is planning and driving a team.
149
157
  "orchestrator",
150
158
  ];
151
159
  // Two glow colors for the personality's thinking spinner (BlobLoader glowA/glowB).
@@ -1321,6 +1329,38 @@ export const ProviderUsageListRequestMessageSchema = z.object({
1321
1329
  type: z.literal("provider.usage.list.request"),
1322
1330
  requestId: z.string(),
1323
1331
  });
1332
+ // Daemon-wide "fun stats" counters — see docs/data-model.md ActivityStatsStore.
1333
+ // Every field defaults to 0 so old and new daemons/clients stay compatible as
1334
+ // counters are added later.
1335
+ export const ActivityCountersSchema = z.object({
1336
+ messagesSent: z.number().default(0),
1337
+ messagesReceived: z.number().default(0),
1338
+ tokensSent: z.number().default(0),
1339
+ tokensReceived: z.number().default(0),
1340
+ agentsCreated: z.number().default(0),
1341
+ runsOrchestrated: z.number().default(0),
1342
+ subagentsInvoked: z.number().default(0),
1343
+ backgroundTasksInvoked: z.number().default(0),
1344
+ thoughts: z.number().default(0),
1345
+ toolsCalled: z.number().default(0),
1346
+ artifactsCreated: z.number().default(0),
1347
+ schedulesExecuted: z.number().default(0),
1348
+ });
1349
+ export const StatsActivityGetRequestMessageSchema = z.object({
1350
+ type: z.literal("stats.activity.get.request"),
1351
+ requestId: z.string(),
1352
+ });
1353
+ export const StatsActivityGetResponseMessageSchema = z.object({
1354
+ type: z.literal("stats.activity.get.response"),
1355
+ payload: z.object({
1356
+ requestId: z.string(),
1357
+ today: ActivityCountersSchema,
1358
+ yesterday: ActivityCountersSchema,
1359
+ last7Days: ActivityCountersSchema,
1360
+ last30Days: ActivityCountersSchema,
1361
+ allTime: ActivityCountersSchema,
1362
+ }),
1363
+ });
1324
1364
  export const AgentContextGetUsageRequestMessageSchema = z.object({
1325
1365
  type: z.literal("agent.context.get_usage.request"),
1326
1366
  agentId: z.string(),
@@ -1456,6 +1496,56 @@ export const AgentSubagentStopResponseMessageSchema = z.object({
1456
1496
  type: z.literal("agent.subagent.stop.response"),
1457
1497
  payload: AgentActionResponsePayloadSchema,
1458
1498
  });
1499
+ // A background shell task launched by a provider's own Bash tool (Claude:
1500
+ // run_in_background). Not an agent, not a subagent — a plain shell process
1501
+ // the daemon tracks for the parent agent's Background Tasks track.
1502
+ // COMPAT(backgroundShellTasks): added in v0.5.3, drop the gate when daemon floor >= v0.5.3.
1503
+ export const BackgroundShellTaskInfoSchema = z.object({
1504
+ id: z.string(),
1505
+ parentAgentId: z.string(),
1506
+ provider: z.string(),
1507
+ command: z.string().optional(),
1508
+ description: z.string().optional(),
1509
+ status: z.enum(["running", "idle", "error", "closed"]),
1510
+ requiresAttention: z.boolean().optional(),
1511
+ createdAt: z.string(),
1512
+ updatedAt: z.string(),
1513
+ archivedAt: z.string().optional(),
1514
+ });
1515
+ // Pushed with the full current set of background shell tasks for a parent
1516
+ // agent whenever any of them changes (start/progress/settle/clear) — same
1517
+ // full-list reconciliation shape as TerminalsChangedSchema.
1518
+ export const BackgroundShellTasksChangedSchema = z.object({
1519
+ type: z.literal("background_shell_tasks_changed"),
1520
+ payload: z.object({
1521
+ parentAgentId: z.string(),
1522
+ tasks: z.array(BackgroundShellTaskInfoSchema),
1523
+ }),
1524
+ });
1525
+ // Stop a running background shell task. The daemon resolves it to the owning
1526
+ // provider session's task and calls stopTask, same as agent.subagent.stop.
1527
+ export const AgentBackgroundTaskStopRequestMessageSchema = z.object({
1528
+ type: z.literal("agent.background_task.stop.request"),
1529
+ parentAgentId: z.string(),
1530
+ taskId: z.string(),
1531
+ requestId: z.string(),
1532
+ });
1533
+ export const AgentBackgroundTaskStopResponseMessageSchema = z.object({
1534
+ type: z.literal("agent.background_task.stop.response"),
1535
+ payload: AgentActionResponsePayloadSchema,
1536
+ });
1537
+ // Clear one or more terminal background shell tasks from the track. Still-live
1538
+ // tasks are stopped best-effort first.
1539
+ export const AgentBackgroundTaskClearRequestMessageSchema = z.object({
1540
+ type: z.literal("agent.background_task.clear.request"),
1541
+ parentAgentId: z.string(),
1542
+ taskIds: z.array(z.string()),
1543
+ requestId: z.string(),
1544
+ });
1545
+ export const AgentBackgroundTaskClearResponseMessageSchema = z.object({
1546
+ type: z.literal("agent.background_task.clear.response"),
1547
+ payload: AgentActionResponsePayloadSchema,
1548
+ });
1459
1549
  // Switch a running agent to an Agent Personality (or clear with null). The
1460
1550
  // daemon re-resolves the id against the roster + the agent's cwd provider
1461
1551
  // snapshot and applies the full personality live — system prompt, identity
@@ -1622,6 +1712,80 @@ export const CheckoutGitLogAppendedNotificationSchema = z.object({
1622
1712
  entries: z.array(GitOperationLogEntrySchema),
1623
1713
  }),
1624
1714
  });
1715
+ // ── Orchestration runs (agent-orchestration) ────────────────────────────────
1716
+ // Daemon-owned multi-agent Run projection + control. Gated by
1717
+ // server_info.features.agentOrchestration. See projects/agent-orchestration.
1718
+ export const RunsGetSnapshotRequestSchema = z.object({
1719
+ type: z.literal("runs.get_snapshot.request"),
1720
+ requestId: z.string(),
1721
+ });
1722
+ export const RunsGetSnapshotResponseSchema = z.object({
1723
+ type: z.literal("runs.get_snapshot.response"),
1724
+ payload: z.object({
1725
+ runs: z.array(RunSchema),
1726
+ requestId: z.string(),
1727
+ }),
1728
+ });
1729
+ // Single-run push, broadcast on every phase/status change. Clients merge by id.
1730
+ export const RunsUpdatedNotificationSchema = z.object({
1731
+ type: z.literal("runs.updated.notification"),
1732
+ payload: z.object({
1733
+ run: RunSchema,
1734
+ }),
1735
+ });
1736
+ // Answer an attended run's `gate` phase (approve or reject, with an optional
1737
+ // note). `accepted` is false when the run wasn't awaiting a gate.
1738
+ export const RunsGateRespondRequestSchema = z.object({
1739
+ type: z.literal("runs.gate_respond.request"),
1740
+ runId: z.string(),
1741
+ phaseId: z.string(),
1742
+ approved: z.boolean(),
1743
+ note: z.string().optional(),
1744
+ requestId: z.string(),
1745
+ });
1746
+ export const RunsGateRespondResponseSchema = z.object({
1747
+ type: z.literal("runs.gate_respond.response"),
1748
+ payload: z.object({
1749
+ runId: z.string(),
1750
+ accepted: z.boolean(),
1751
+ requestId: z.string(),
1752
+ }),
1753
+ });
1754
+ export const RunsCancelRequestSchema = z.object({
1755
+ type: z.literal("runs.cancel.request"),
1756
+ runId: z.string(),
1757
+ requestId: z.string(),
1758
+ });
1759
+ export const RunsCancelResponseSchema = z.object({
1760
+ type: z.literal("runs.cancel.response"),
1761
+ payload: z.object({
1762
+ runId: z.string(),
1763
+ canceled: z.boolean(),
1764
+ requestId: z.string(),
1765
+ }),
1766
+ });
1767
+ // Delete every finished (done/failed/canceled) run from disk and memory.
1768
+ // Active/paused runs are left untouched. Gated by
1769
+ // server_info.features.runsClear.
1770
+ export const RunsClearRequestSchema = z.object({
1771
+ type: z.literal("runs.clear.request"),
1772
+ requestId: z.string(),
1773
+ });
1774
+ export const RunsClearResponseSchema = z.object({
1775
+ type: z.literal("runs.clear.response"),
1776
+ payload: z.object({
1777
+ runIds: z.array(z.string()),
1778
+ requestId: z.string(),
1779
+ }),
1780
+ });
1781
+ // Broadcast to every connected client (including the requester) so all
1782
+ // caches drop the same runs, mirroring runs.updated.notification's upsert.
1783
+ export const RunsClearedNotificationSchema = z.object({
1784
+ type: z.literal("runs.cleared.notification"),
1785
+ payload: z.object({
1786
+ runIds: z.array(z.string()),
1787
+ }),
1788
+ });
1625
1789
  // Namespaced successor to checkout_commit_request: per-file selection and
1626
1790
  // structured errors. Gated by server_info.features.checkoutGitCommit; the flat
1627
1791
  // RPC stays accepted for old clients.
@@ -2320,6 +2484,7 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
2320
2484
  RefreshProvidersSnapshotRequestMessageSchema,
2321
2485
  ProviderDiagnosticRequestMessageSchema,
2322
2486
  ProviderUsageListRequestMessageSchema,
2487
+ StatsActivityGetRequestMessageSchema,
2323
2488
  AgentContextGetUsageRequestMessageSchema,
2324
2489
  ResumeAgentRequestMessageSchema,
2325
2490
  ImportAgentRequestMessageSchema,
@@ -2336,6 +2501,8 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
2336
2501
  SetAgentFeatureRequestMessageSchema,
2337
2502
  AgentDetachRequestMessageSchema,
2338
2503
  AgentSubagentStopRequestMessageSchema,
2504
+ AgentBackgroundTaskStopRequestMessageSchema,
2505
+ AgentBackgroundTaskClearRequestMessageSchema,
2339
2506
  AgentPersonalitySetRequestMessageSchema,
2340
2507
  AgentRewindRequestMessageSchema,
2341
2508
  AgentPermissionResponseMessageSchema,
@@ -2347,6 +2514,10 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
2347
2514
  CheckoutGitCommitAgentRequestSchema,
2348
2515
  CheckoutGitRollbackRequestSchema,
2349
2516
  CheckoutGitGetOperationLogRequestSchema,
2517
+ RunsGetSnapshotRequestSchema,
2518
+ RunsGateRespondRequestSchema,
2519
+ RunsCancelRequestSchema,
2520
+ RunsClearRequestSchema,
2350
2521
  CheckoutMergeRequestSchema,
2351
2522
  CheckoutMergeFromBaseRequestSchema,
2352
2523
  CheckoutPullRequestSchema,
@@ -2623,6 +2794,8 @@ export const ServerInfoStatusPayloadSchema = z
2623
2794
  artifacts: z.boolean().optional(),
2624
2795
  // COMPAT(observedSubagents): added in v0.4.3, drop the gate when daemon floor >= v0.4.3.
2625
2796
  observedSubagents: z.boolean().optional(),
2797
+ // COMPAT(backgroundShellTasks): added in v0.5.3, drop the gate when daemon floor >= v0.5.3.
2798
+ backgroundShellTasks: z.boolean().optional(),
2626
2799
  // COMPAT(textEditor): added in v0.4.4, drop the gate when daemon floor >= v0.4.4.
2627
2800
  textEditor: z.boolean().optional(),
2628
2801
  // COMPAT(projectSearch): added in v0.4.4, drop the gate when daemon floor >= v0.4.4.
@@ -2653,6 +2826,12 @@ export const ServerInfoStatusPayloadSchema = z
2653
2826
  agentTeams: z.boolean().optional(),
2654
2827
  // COMPAT(modelTierOverrides): added in v0.5.2, drop the gate when daemon floor >= v0.5.2.
2655
2828
  modelTierOverrides: z.boolean().optional(),
2829
+ // COMPAT(agentOrchestration): added in v0.5.3, drop the gate when daemon floor >= v0.5.3.
2830
+ agentOrchestration: z.boolean().optional(),
2831
+ // COMPAT(activityStats): added in v0.5.3, drop the gate when daemon floor >= v0.5.3.
2832
+ activityStats: z.boolean().optional(),
2833
+ // COMPAT(runsClear): added in v0.5.3, drop the gate when daemon floor >= v0.5.3.
2834
+ runsClear: z.boolean().optional(),
2656
2835
  })
2657
2836
  .optional(),
2658
2837
  })
@@ -4807,6 +4986,9 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
4807
4986
  SetAgentFeatureResponseMessageSchema,
4808
4987
  AgentDetachResponseMessageSchema,
4809
4988
  AgentSubagentStopResponseMessageSchema,
4989
+ AgentBackgroundTaskStopResponseMessageSchema,
4990
+ AgentBackgroundTaskClearResponseMessageSchema,
4991
+ BackgroundShellTasksChangedSchema,
4810
4992
  AgentPersonalitySetResponseMessageSchema,
4811
4993
  AgentRewindResponseMessageSchema,
4812
4994
  UpdateAgentResponseMessageSchema,
@@ -4829,6 +5011,12 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
4829
5011
  CheckoutGitRollbackResponseSchema,
4830
5012
  CheckoutGitGetOperationLogResponseSchema,
4831
5013
  CheckoutGitLogAppendedNotificationSchema,
5014
+ RunsGetSnapshotResponseSchema,
5015
+ RunsUpdatedNotificationSchema,
5016
+ RunsGateRespondResponseSchema,
5017
+ RunsCancelResponseSchema,
5018
+ RunsClearResponseSchema,
5019
+ RunsClearedNotificationSchema,
4832
5020
  CheckoutMergeResponseSchema,
4833
5021
  CheckoutMergeFromBaseResponseSchema,
4834
5022
  CheckoutPullResponseSchema,
@@ -4881,6 +5069,7 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
4881
5069
  RefreshProvidersSnapshotResponseMessageSchema,
4882
5070
  ProviderDiagnosticResponseMessageSchema,
4883
5071
  ProviderUsageListResponseMessageSchema,
5072
+ StatsActivityGetResponseMessageSchema,
4884
5073
  AgentContextGetUsageResponseMessageSchema,
4885
5074
  ListCommandsResponseSchema,
4886
5075
  ListTerminalsResponseSchema,
@@ -0,0 +1,152 @@
1
+ import { z } from "zod";
2
+ export declare const RUN_PHASE_TYPES: readonly ["research", "plan", "refactor", "implement", "design", "verify", "gate", "deliver"];
3
+ export type RunPhaseType = (typeof RUN_PHASE_TYPES)[number];
4
+ export declare function isRunPhaseType(value: string): value is RunPhaseType;
5
+ /** The role a phase type dispatches to by default (null for human `gate`). */
6
+ export declare function defaultRoleForPhaseType(type: RunPhaseType): string | null;
7
+ export declare const RUN_PHASE_STATUSES: readonly ["pending", "running", "blocked", "done", "failed", "skipped"];
8
+ export type RunPhaseStatus = (typeof RUN_PHASE_STATUSES)[number];
9
+ export declare const RUN_STATUSES: readonly ["pending", "running", "paused", "done", "failed", "canceled"];
10
+ export type RunStatus = (typeof RUN_STATUSES)[number];
11
+ export declare function isRunPhaseStatus(value: string): value is RunPhaseStatus;
12
+ export declare function isRunStatus(value: string): value is RunStatus;
13
+ /** Terminal run statuses — no further phases will run. */
14
+ export declare function isTerminalRunStatus(value: string): boolean;
15
+ /** Terminal phase statuses — the phase will not change again on its own. */
16
+ export declare function isTerminalPhaseStatus(value: string): boolean;
17
+ export declare const RunPhaseJudgeSpecSchema: z.ZodObject<{
18
+ role: z.ZodOptional<z.ZodString>;
19
+ criteria: z.ZodOptional<z.ZodArray<z.ZodString>>;
20
+ }, z.core.$loose>;
21
+ export declare const RunPhaseDeclarationSchema: z.ZodObject<{
22
+ id: z.ZodString;
23
+ type: z.ZodString;
24
+ title: z.ZodString;
25
+ task: z.ZodString;
26
+ role: z.ZodOptional<z.ZodString>;
27
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
28
+ fanOut: z.ZodOptional<z.ZodNumber>;
29
+ keepBest: z.ZodOptional<z.ZodNumber>;
30
+ judge: z.ZodOptional<z.ZodObject<{
31
+ role: z.ZodOptional<z.ZodString>;
32
+ criteria: z.ZodOptional<z.ZodArray<z.ZodString>>;
33
+ }, z.core.$loose>>;
34
+ }, z.core.$loose>;
35
+ export type RunPhaseDeclaration = z.infer<typeof RunPhaseDeclarationSchema>;
36
+ export declare const RunPlanSchema: z.ZodObject<{
37
+ title: z.ZodString;
38
+ requirements: z.ZodOptional<z.ZodArray<z.ZodString>>;
39
+ autopilot: z.ZodOptional<z.ZodBoolean>;
40
+ phases: z.ZodArray<z.ZodObject<{
41
+ id: z.ZodString;
42
+ type: z.ZodString;
43
+ title: z.ZodString;
44
+ task: z.ZodString;
45
+ role: z.ZodOptional<z.ZodString>;
46
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
47
+ fanOut: z.ZodOptional<z.ZodNumber>;
48
+ keepBest: z.ZodOptional<z.ZodNumber>;
49
+ judge: z.ZodOptional<z.ZodObject<{
50
+ role: z.ZodOptional<z.ZodString>;
51
+ criteria: z.ZodOptional<z.ZodArray<z.ZodString>>;
52
+ }, z.core.$loose>>;
53
+ }, z.core.$loose>>;
54
+ }, z.core.$loose>;
55
+ export type RunPlan = z.infer<typeof RunPlanSchema>;
56
+ export declare const RunPhaseCandidateSchema: z.ZodObject<{
57
+ agentId: z.ZodString;
58
+ personalityId: z.ZodOptional<z.ZodString>;
59
+ verdict: z.ZodOptional<z.ZodObject<{
60
+ verdict: z.ZodString;
61
+ score: z.ZodOptional<z.ZodNumber>;
62
+ criteria: z.ZodOptional<z.ZodArray<z.ZodObject<{
63
+ name: z.ZodString;
64
+ met: z.ZodBoolean;
65
+ evidence: z.ZodOptional<z.ZodString>;
66
+ }, z.core.$loose>>>;
67
+ summary: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$loose>>;
69
+ summary: z.ZodOptional<z.ZodString>;
70
+ }, z.core.$loose>;
71
+ export type RunPhaseCandidate = z.infer<typeof RunPhaseCandidateSchema>;
72
+ export declare const RunPhaseSchema: z.ZodObject<{
73
+ id: z.ZodString;
74
+ type: z.ZodString;
75
+ title: z.ZodString;
76
+ task: z.ZodString;
77
+ status: z.ZodString;
78
+ assigneeRole: z.ZodOptional<z.ZodString>;
79
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
80
+ fanOut: z.ZodOptional<z.ZodNumber>;
81
+ keepBest: z.ZodOptional<z.ZodNumber>;
82
+ candidates: z.ZodOptional<z.ZodArray<z.ZodObject<{
83
+ agentId: z.ZodString;
84
+ personalityId: z.ZodOptional<z.ZodString>;
85
+ verdict: z.ZodOptional<z.ZodObject<{
86
+ verdict: z.ZodString;
87
+ score: z.ZodOptional<z.ZodNumber>;
88
+ criteria: z.ZodOptional<z.ZodArray<z.ZodObject<{
89
+ name: z.ZodString;
90
+ met: z.ZodBoolean;
91
+ evidence: z.ZodOptional<z.ZodString>;
92
+ }, z.core.$loose>>>;
93
+ summary: z.ZodOptional<z.ZodString>;
94
+ }, z.core.$loose>>;
95
+ summary: z.ZodOptional<z.ZodString>;
96
+ }, z.core.$loose>>>;
97
+ notes: z.ZodOptional<z.ZodString>;
98
+ startedAt: z.ZodOptional<z.ZodString>;
99
+ completedAt: z.ZodOptional<z.ZodString>;
100
+ }, z.core.$loose>;
101
+ export type RunPhase = z.infer<typeof RunPhaseSchema>;
102
+ export declare const RunSchema: z.ZodObject<{
103
+ id: z.ZodString;
104
+ title: z.ZodString;
105
+ status: z.ZodString;
106
+ requirements: z.ZodOptional<z.ZodArray<z.ZodString>>;
107
+ autopilot: z.ZodOptional<z.ZodBoolean>;
108
+ phases: z.ZodDefault<z.ZodArray<z.ZodObject<{
109
+ id: z.ZodString;
110
+ type: z.ZodString;
111
+ title: z.ZodString;
112
+ task: z.ZodString;
113
+ status: z.ZodString;
114
+ assigneeRole: z.ZodOptional<z.ZodString>;
115
+ dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
116
+ fanOut: z.ZodOptional<z.ZodNumber>;
117
+ keepBest: z.ZodOptional<z.ZodNumber>;
118
+ candidates: z.ZodOptional<z.ZodArray<z.ZodObject<{
119
+ agentId: z.ZodString;
120
+ personalityId: z.ZodOptional<z.ZodString>;
121
+ verdict: z.ZodOptional<z.ZodObject<{
122
+ verdict: z.ZodString;
123
+ score: z.ZodOptional<z.ZodNumber>;
124
+ criteria: z.ZodOptional<z.ZodArray<z.ZodObject<{
125
+ name: z.ZodString;
126
+ met: z.ZodBoolean;
127
+ evidence: z.ZodOptional<z.ZodString>;
128
+ }, z.core.$loose>>>;
129
+ summary: z.ZodOptional<z.ZodString>;
130
+ }, z.core.$loose>>;
131
+ summary: z.ZodOptional<z.ZodString>;
132
+ }, z.core.$loose>>>;
133
+ notes: z.ZodOptional<z.ZodString>;
134
+ startedAt: z.ZodOptional<z.ZodString>;
135
+ completedAt: z.ZodOptional<z.ZodString>;
136
+ }, z.core.$loose>>>;
137
+ conductorAgentId: z.ZodOptional<z.ZodString>;
138
+ cwd: z.ZodOptional<z.ZodString>;
139
+ workspaceId: z.ZodOptional<z.ZodString>;
140
+ teamId: z.ZodOptional<z.ZodString>;
141
+ teamName: z.ZodOptional<z.ZodString>;
142
+ error: z.ZodOptional<z.ZodString>;
143
+ summary: z.ZodOptional<z.ZodString>;
144
+ summaryStatus: z.ZodOptional<z.ZodString>;
145
+ agentCount: z.ZodOptional<z.ZodNumber>;
146
+ createdAt: z.ZodOptional<z.ZodString>;
147
+ updatedAt: z.ZodOptional<z.ZodString>;
148
+ }, z.core.$loose>;
149
+ export type Run = z.infer<typeof RunSchema>;
150
+ export declare const RUN_SUMMARY_STATUSES: readonly ["pending", "ready", "failed"];
151
+ export type RunSummaryStatus = (typeof RUN_SUMMARY_STATUSES)[number];
152
+ //# sourceMappingURL=orchestration.d.ts.map
@@ -0,0 +1,199 @@
1
+ import { z } from "zod";
2
+ import { JudgeVerdictSchema } from "./judge-verdict.js";
3
+ // The orchestration data model — a daemon-owned "Run": one execution of a
4
+ // declared multi-agent plan, and its observable/resumable projection to clients.
5
+ // See projects/agent-orchestration/agent-orchestration.md. This is Otto's
6
+ // provider-agnostic answer to a harness "Workflow": the conductor (an
7
+ // orchestrator-role agent) DECLARES the shape (typed phases, assignments, the
8
+ // loop target) via `start_run`, and the daemon runtime drives control flow —
9
+ // fan-out, gather-barrier, gate, loop — in code, so orchestrating is cheaper
10
+ // than hand-tracking N agent ids across async notifications.
11
+ //
12
+ // Wire-forward-compat, per the protocol contract: every open vocabulary (phase
13
+ // type, phase/run status) rides as a plain string leaf validated by a
14
+ // normalizer, never a z.enum, so the daemon can grow the vocabulary without
15
+ // breaking an older client's parse. Objects `.passthrough()`; no transforms.
16
+ // ── The deterministic plan vocabulary ──────────────────────────────────────
17
+ // Fixed phase types used by the runtime (NOT roles). The dispatcher maps a phase
18
+ // type to the role that fills it: research→researcher, plan→planner,
19
+ // refactor/implement→coder, design→designer, verify→judger, gate→human (no
20
+ // agent), deliver→coder/writer.
21
+ export const RUN_PHASE_TYPES = [
22
+ "research",
23
+ "plan",
24
+ "refactor",
25
+ "implement",
26
+ "design",
27
+ "verify",
28
+ "gate",
29
+ "deliver",
30
+ ];
31
+ const PHASE_TYPE_SET = new Set(RUN_PHASE_TYPES);
32
+ export function isRunPhaseType(value) {
33
+ return PHASE_TYPE_SET.has(value);
34
+ }
35
+ // The default role that fills each phase type. `gate` has no role — it's a human
36
+ // approval point. `deliver` defaults to coder (a writer may cover small text
37
+ // deliverables; the conductor can override per phase).
38
+ const PHASE_TYPE_DEFAULT_ROLE = {
39
+ research: "researcher",
40
+ plan: "planner",
41
+ refactor: "coder",
42
+ implement: "coder",
43
+ design: "designer",
44
+ verify: "judger",
45
+ gate: null,
46
+ deliver: "coder",
47
+ };
48
+ /** The role a phase type dispatches to by default (null for human `gate`). */
49
+ export function defaultRoleForPhaseType(type) {
50
+ return PHASE_TYPE_DEFAULT_ROLE[type];
51
+ }
52
+ // ── Phase + run status (open vocabularies, plain-string on the wire) ─────────
53
+ export const RUN_PHASE_STATUSES = [
54
+ "pending",
55
+ "running",
56
+ "blocked", // a gate phase awaiting human approval
57
+ "done",
58
+ "failed",
59
+ "skipped",
60
+ ];
61
+ export const RUN_STATUSES = [
62
+ "pending",
63
+ "running",
64
+ "paused", // stopped at an attended gate, awaiting the user
65
+ "done",
66
+ "failed",
67
+ "canceled",
68
+ ];
69
+ const PHASE_STATUS_SET = new Set(RUN_PHASE_STATUSES);
70
+ const RUN_STATUS_SET = new Set(RUN_STATUSES);
71
+ export function isRunPhaseStatus(value) {
72
+ return PHASE_STATUS_SET.has(value);
73
+ }
74
+ export function isRunStatus(value) {
75
+ return RUN_STATUS_SET.has(value);
76
+ }
77
+ /** Terminal run statuses — no further phases will run. */
78
+ export function isTerminalRunStatus(value) {
79
+ return value === "done" || value === "failed" || value === "canceled";
80
+ }
81
+ /** Terminal phase statuses — the phase will not change again on its own. */
82
+ export function isTerminalPhaseStatus(value) {
83
+ return value === "done" || value === "failed" || value === "skipped";
84
+ }
85
+ // ── Declaration schema (the `start_run` input) ──────────────────────────────
86
+ // What the conductor DECLARES. Kept minimal and schema-validated so a bad plan
87
+ // is rejected at the tool boundary. `role` overrides the phase-type default;
88
+ // `fanOut` spawns N parallel candidates; `judge` attaches a verify sub-step so a
89
+ // making/research phase's output is graded and (with `keepBest`) looped until
90
+ // enough candidates pass.
91
+ export const RunPhaseJudgeSpecSchema = z
92
+ .object({
93
+ role: z.string().min(1).optional(),
94
+ criteria: z.array(z.string().min(1)).optional(),
95
+ })
96
+ .passthrough();
97
+ export const RunPhaseDeclarationSchema = z
98
+ .object({
99
+ // Caller-assigned id, referenced by other phases' `dependsOn`.
100
+ id: z.string().min(1),
101
+ type: z.string().min(1),
102
+ title: z.string().min(1),
103
+ // The instruction handed to the assigned agent(s) as their prompt.
104
+ task: z.string().min(1),
105
+ // Override the phase-type's default role (e.g. deliver→writer).
106
+ role: z.string().min(1).optional(),
107
+ // Phase ids that must reach a terminal state before this phase starts.
108
+ // Absent/empty ⇒ runs after the previous declared phase (linear default).
109
+ dependsOn: z.array(z.string().min(1)).optional(),
110
+ // Spawn N parallel candidates from the same task (different angles). 1 ⇒ solo.
111
+ fanOut: z.number().int().min(1).max(16).optional(),
112
+ // With a judge: keep the best N passers; if fewer pass, the runtime
113
+ // re-dispatches replacements until the target is met or a cap trips.
114
+ keepBest: z.number().int().min(1).max(16).optional(),
115
+ // Attach a structured-judge sub-step to a non-verify phase.
116
+ judge: RunPhaseJudgeSpecSchema.optional(),
117
+ })
118
+ .passthrough();
119
+ export const RunPlanSchema = z
120
+ .object({
121
+ title: z.string().min(1),
122
+ // Immutable acceptance criteria — the run is "not done until every one is
123
+ // met." Carried onto the Run and shown at gates.
124
+ requirements: z.array(z.string().min(1)).optional(),
125
+ // Attended by default: the run pauses at `gate` phases for the user.
126
+ // Autopilot runs straight through (eligibility enforced daemon-side).
127
+ autopilot: z.boolean().optional(),
128
+ phases: z.array(RunPhaseDeclarationSchema).min(1).max(64),
129
+ })
130
+ .passthrough();
131
+ // ── Projection schema (the Run the daemon persists + pushes to clients) ─────
132
+ // One spawned candidate for a phase: the observable child agent plus, when the
133
+ // phase judged it, that candidate's verdict.
134
+ export const RunPhaseCandidateSchema = z
135
+ .object({
136
+ agentId: z.string().min(1),
137
+ // The personality that filled the role for this candidate, if resolved.
138
+ personalityId: z.string().min(1).optional(),
139
+ verdict: JudgeVerdictSchema.optional(),
140
+ // The candidate's final message (synthesis input); may be large — clients
141
+ // truncate for display.
142
+ summary: z.string().optional(),
143
+ })
144
+ .passthrough();
145
+ export const RunPhaseSchema = z
146
+ .object({
147
+ id: z.string().min(1),
148
+ type: z.string().min(1),
149
+ title: z.string().min(1),
150
+ task: z.string().min(1),
151
+ status: z.string().min(1),
152
+ // Resolved dispatch target. `assigneeRole` is what the type/override asked
153
+ // for; `candidates` are the spawned agents (>1 when fanned out).
154
+ assigneeRole: z.string().min(1).optional(),
155
+ dependsOn: z.array(z.string().min(1)).optional(),
156
+ fanOut: z.number().int().min(1).optional(),
157
+ keepBest: z.number().int().min(1).optional(),
158
+ candidates: z.array(RunPhaseCandidateSchema).optional(),
159
+ // Free-text runtime notes (why it blocked, which cap tripped, gap named).
160
+ notes: z.string().optional(),
161
+ startedAt: z.string().optional(),
162
+ completedAt: z.string().optional(),
163
+ })
164
+ .passthrough();
165
+ export const RunSchema = z
166
+ .object({
167
+ id: z.string().min(1),
168
+ title: z.string().min(1),
169
+ status: z.string().min(1),
170
+ // Immutable requirements block (see RunPlan.requirements).
171
+ requirements: z.array(z.string().min(1)).optional(),
172
+ autopilot: z.boolean().optional(),
173
+ phases: z.array(RunPhaseSchema).default([]),
174
+ // The conductor agent that owns this run, and the workspace it runs in.
175
+ conductorAgentId: z.string().min(1).optional(),
176
+ cwd: z.string().optional(),
177
+ workspaceId: z.string().optional(),
178
+ // The team that was active when this run started (id for a stable filter key,
179
+ // name for display). Absent on runs started without an active team.
180
+ teamId: z.string().min(1).optional(),
181
+ teamName: z.string().min(1).optional(),
182
+ // Set when the run ends in failure or a cap trips.
183
+ error: z.string().optional(),
184
+ // AI-generated, human-readable summary of the whole run (from a Writer
185
+ // personality). `summaryStatus` is a plain-string, forward-compat leaf:
186
+ // "pending" (being generated), "ready", or "failed". Both absent on daemons
187
+ // or runs without the run-summary feature.
188
+ summary: z.string().optional(),
189
+ summaryStatus: z.string().optional(),
190
+ // Total child agents this run spawned (makers + judgers) — a complexity
191
+ // signal surfaced in the Runs display. Grows as the run executes.
192
+ agentCount: z.number().int().min(0).optional(),
193
+ createdAt: z.string().optional(),
194
+ updatedAt: z.string().optional(),
195
+ })
196
+ .passthrough();
197
+ // Summary generation lifecycle (plain-string on the wire; see RunSchema.summaryStatus).
198
+ export const RUN_SUMMARY_STATUSES = ["pending", "ready", "failed"];
199
+ //# sourceMappingURL=orchestration.js.map
@@ -8,6 +8,7 @@ export interface AgentModeVisuals {
8
8
  }
9
9
  export type AgentProviderModeDefinition = Omit<AgentMode, "icon" | "colorTier"> & AgentModeVisuals & {
10
10
  isUnattended?: boolean;
11
+ userSelectable?: boolean;
11
12
  };
12
13
  export interface AgentProviderDefinition {
13
14
  id: string;
@@ -30,5 +31,14 @@ export declare const AGENT_PROVIDER_IDS: string[];
30
31
  export declare const AgentProviderSchema: z.ZodString;
31
32
  export declare function isValidAgentProvider(value: string, validIds?: Iterable<string>): boolean;
32
33
  export declare function getUnattendedModeId(provider: string, definitions?: AgentProviderDefinition[]): string | undefined;
34
+ /**
35
+ * Whether a user may pick this mode themselves. False only for modes explicitly
36
+ * flagged `userSelectable: false` in the static manifest (Claude "dontAsk") — a
37
+ * system-assigned mode that agents can run in but no one selects by hand. Unknown
38
+ * modes (dynamic/ACP, custom providers) default to selectable. The flag is a
39
+ * static property of the mode, so this always consults the built-in manifest
40
+ * rather than snapshot-derived definitions (which don't carry it).
41
+ */
42
+ export declare function isUserSelectableMode(provider: string, modeId: string): boolean;
33
43
  export declare function getModeVisuals(provider: string, modeId: string, definitions: AgentProviderDefinition[]): AgentModeVisuals | undefined;
34
44
  //# sourceMappingURL=provider-manifest.d.ts.map