@sema-agent/core 7.9.1 → 7.10.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 (61) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/agents/child-model-seat.d.ts +81 -0
  3. package/dist/agents/child-model-seat.js +46 -0
  4. package/dist/agents/subagent.d.ts +5 -3
  5. package/dist/agents/subagent.js +20 -14
  6. package/dist/core/ask-unresolvable-notice.d.ts +52 -0
  7. package/dist/core/ask-unresolvable-notice.js +25 -0
  8. package/dist/core/auto-mode.d.ts +62 -3
  9. package/dist/core/auto-mode.js +31 -0
  10. package/dist/core/checkpoint-store.d.ts +14 -0
  11. package/dist/core/checkpoint-store.js +2 -1
  12. package/dist/core/engine-notice.d.ts +28 -7
  13. package/dist/core/gate-lanes.js +15 -0
  14. package/dist/core/governance-codes.d.ts +1 -1
  15. package/dist/core/governance-codes.js +4 -0
  16. package/dist/core/hooks.d.ts +24 -1
  17. package/dist/core/hooks.js +2 -0
  18. package/dist/core/permission-rule-model.d.ts +51 -16
  19. package/dist/core/permission-rule-model.js +55 -21
  20. package/dist/core/permission-rules.d.ts +6 -4
  21. package/dist/core/permission-rules.js +14 -14
  22. package/dist/core/roles.d.ts +8 -0
  23. package/dist/core/runner/contracts.d.ts +29 -4
  24. package/dist/core/runner/denial-limit-arms.d.ts +14 -3
  25. package/dist/core/runner/denial-limit-arms.js +15 -5
  26. package/dist/core/runner/permission-rule-lanes.d.ts +7 -1
  27. package/dist/core/runner/permission-rule-lanes.js +9 -3
  28. package/dist/core/runner/prepare-caps-and-workflow.d.ts +1 -1
  29. package/dist/core/runner/prepare-caps-and-workflow.js +14 -4
  30. package/dist/core/runner/prepare-gate-stations.d.ts +3 -2
  31. package/dist/core/runner/prepare-gate-stations.js +3 -0
  32. package/dist/core/runner/prepare-policy-chain.js +7 -6
  33. package/dist/core/runner/prepare-wiring-manifest.d.ts +1 -1
  34. package/dist/core/runner/prepare-wiring-manifest.js +8 -1
  35. package/dist/core/runner/runtask.d.ts +34 -32
  36. package/dist/core/runner/runtask.js +64 -34
  37. package/dist/core/runner-deps.d.ts +9 -2
  38. package/dist/core/swappable-deps.d.ts +90 -0
  39. package/dist/core/swappable-deps.js +55 -0
  40. package/dist/core/tool-policy.d.ts +26 -0
  41. package/dist/core/tool-policy.js +5 -1
  42. package/dist/core/wiring-manifest.d.ts +15 -1
  43. package/dist/core/wiring-manifest.js +10 -2
  44. package/dist/core/workflow-journal-store.d.ts +21 -2
  45. package/dist/core/workflow-journal-store.js +1 -1
  46. package/dist/engine/execution-env/node-execution-env.d.ts +2 -0
  47. package/dist/engine/execution-env/node-execution-env.js +2 -1
  48. package/dist/engine/harness/types.d.ts +11 -0
  49. package/dist/index.d.ts +5 -3
  50. package/dist/index.js +5 -3
  51. package/dist/orchestration/run-workflow-tool.d.ts +17 -0
  52. package/dist/orchestration/run-workflow-tool.js +12 -0
  53. package/dist/orchestration/workflow-observe.d.ts +1 -1
  54. package/dist/orchestration/workflow-observe.js +2 -0
  55. package/dist/orchestration/workflow-types.d.ts +37 -2
  56. package/dist/orchestration/workflow-types.js +16 -0
  57. package/dist/orchestration/workflow.d.ts +41 -2
  58. package/dist/orchestration/workflow.js +316 -48
  59. package/dist/stores/file/workflow-journal-store.js +10 -3
  60. package/package.json +1 -1
  61. package/test/export-surface.snapshot.json +51 -5
@@ -1,7 +1,9 @@
1
1
  import type { TaskResult, TaskStatus, ToolActivity } from "../core/types.js";
2
2
  export type WorkflowRunStatus = "running" | "completed" | "failed";
3
- /** Status of one phase / agent-run within a workflow. */
4
- export type WorkflowItemStatus = "running" | "completed" | "failed";
3
+ /** Status of one phase / agent-run within a workflow. `"parked"` (#642) is an AGENT row's word only — the
4
+ * agent durably paused at an approval gate and the run suspended on it (the row carries the token, see
5
+ * {@link WorkflowAgentRun.parkedCheckpointToken}); a phase or group never parks (a parked agent ends the run). */
6
+ export type WorkflowItemStatus = "running" | "completed" | "failed" | "parked";
5
7
  export interface WorkflowPhase {
6
8
  title: string;
7
9
  /** F7/B7 (CC pretty.js:446478): a phase PRE-REGISTERED from `meta.phases` starts as `"pending"` — the plan
@@ -119,6 +121,16 @@ export interface WorkflowAgentRun {
119
121
  * (`fork(sessionId)→runTask`, or `runTask({sessionId})`) instead of a fresh re-run. An opaque id (not
120
122
  * content) → scope-gated via `getWorkflowRun`, no redaction needed. Absent for a stub run that minted none. */
121
123
  sessionId?: string;
124
+ /**
125
+ * #642 — the durable-approval checkpoint token this agent is PARKED on (`status: "parked"` only): the child
126
+ * durably paused at an approval gate under the host's forwarded `durableApproval`, the run recorded the
127
+ * park here and suspended. The mirror of the background agent row's `parkedCheckpointToken`, and the
128
+ * workflow-origin JOIN a host routes a parked approval by: a checkpoint whose `sourceTaskId` equals this
129
+ * row's {@link sessionId} is a workflow child's park, and this token is the same row's redemption key —
130
+ * the checkpoint row itself carries no workflow key. It is the resume CAPABILITY (never log it or put it
131
+ * in a URL); a durable row is its home exactly as on the background lane. Absent on every other status.
132
+ */
133
+ parkedCheckpointToken?: string;
122
134
  /**
123
135
  * #499 — the ENGINE-minted identity of the task run behind this record (= its `TaskResult.runId`).
124
136
  *
@@ -515,6 +527,29 @@ export declare class WorkflowAgentBlockedError extends Error {
515
527
  /** Human-readable cause, already bounded + redacted by the engine (classifier text is model output). */
516
528
  reason: string);
517
529
  }
530
+ /** #642 — the machine code of a run that SUSPENDED on a parked agent (the thrown error's `code`, the run's
531
+ * failed terminal). Not a script fault and not a host fault: an approval a person still has to decide. */
532
+ export declare const WORKFLOW_AGENT_PARKED_ERROR_CODE = "workflow.agent_parked";
533
+ /**
534
+ * #642 — thrown by `ctx.agent` / `ctx.agentStream().result()` when the child durably PAUSED at an approval gate
535
+ * under the host's forwarded `durableApproval` (the workflow lane's park family, the background delegation's
536
+ * twin): the wa* row records `status:"parked"` + `parkedCheckpointToken`, the journal records the parked leg at
537
+ * its ordinal, and the RUN SUSPENDS — every later spawn is refused with this same error and the run's terminal
538
+ * is this park whatever the script body returns (the team-discussion `teamPause` shape). Nothing after the
539
+ * parked call runs; the script must not retry it (an identical call parks again). A resume of the run
540
+ * (`resumeFromRunId`) with the host's decision for the token drives the parked child on and the script
541
+ * continues from here; without a decision the ordinal re-parks.
542
+ *
543
+ * Carries the non-secret `checkpointId` (display/correlation) and the gate kind — never the token (the resume
544
+ * capability lives on the wa* row, a durable row, exactly as on the background lane).
545
+ */
546
+ export declare class WorkflowAgentParkedError extends Error {
547
+ readonly label: string;
548
+ readonly gateKind: string;
549
+ readonly checkpointId?: string | undefined;
550
+ readonly code = "workflow.agent_parked";
551
+ constructor(label: string, gateKind: string, checkpointId?: string | undefined);
552
+ }
518
553
  /** design/98 §D.6 hard cap: thrown by `ctx.agent` once the workflow has spawned `max` agents (a runaway
519
554
  * LLM-authored script is bounded, not trusted — this counts cumulative spawns, so it binds even when the
520
555
  * token budget has room left, or when no budget was set at all). */
@@ -55,6 +55,22 @@ export class WorkflowAgentBlockedError extends Error {
55
55
  this.name = "WorkflowAgentBlockedError";
56
56
  }
57
57
  }
58
+ export const WORKFLOW_AGENT_PARKED_ERROR_CODE = "workflow.agent_parked";
59
+ export class WorkflowAgentParkedError extends Error {
60
+ label;
61
+ gateKind;
62
+ checkpointId;
63
+ code = WORKFLOW_AGENT_PARKED_ERROR_CODE;
64
+ constructor(label, gateKind, checkpointId) {
65
+ super(`workflow agent "${label}" is parked at an approval gate (${gateKind}${checkpointId !== undefined ? `, checkpoint ${checkpointId}` : ""}) — ` +
66
+ "the workflow is suspended until the approval is decided; nothing after this call runs. Do not re-issue the call: " +
67
+ "a resume of this run carrying the decision continues from here.");
68
+ this.label = label;
69
+ this.gateKind = gateKind;
70
+ this.checkpointId = checkpointId;
71
+ this.name = "WorkflowAgentParkedError";
72
+ }
73
+ }
58
74
  export class WorkflowMaxAgentsError extends Error {
59
75
  max;
60
76
  budgetTotal;
@@ -1,5 +1,6 @@
1
1
  import type { TSchema } from "typebox";
2
- import type { RunnerSelfSeat } from "../core/runner/contracts.js";
2
+ import type { InheritedGate, RunnerSelfSeat } from "../core/runner/contracts.js";
3
+ import type { CheckpointToken, ResumeOutcome } from "../core/checkpoint-store.js";
3
4
  import type { AgentDefinition, TaskEvent, TaskResult, TaskSpec } from "../core/types.js";
4
5
  import type { WorkflowRunStore } from "../core/workflow-run-store.js";
5
6
  import type { WorkflowJournalStore, ResumeClaimArgs } from "../core/workflow-journal-store.js";
@@ -120,7 +121,9 @@ export declare class WorkflowJournalIncompatibleError extends Error {
120
121
  readonly fromRunId: string;
121
122
  readonly ordinal: number;
122
123
  readonly code = "workflow.journal_incompatible";
123
- constructor(fromRunId: string, ordinal: number);
124
+ constructor(fromRunId: string, ordinal: number,
125
+ /** #642: an alternative reason clause (the parked-row cross-check); absent ⇒ the no-terminal-cause wording. */
126
+ reason?: string);
124
127
  }
125
128
  /**
126
129
  * A TRUSTED, run-scoped internal channel carrying the workflow **nesting depth** across a process boundary
@@ -282,6 +285,18 @@ export interface WorkflowRunContext {
282
285
  /** Emit a narrator log line (observability only — not stored on the run). */
283
286
  log(message: string): void;
284
287
  }
288
+ /**
289
+ * #642 — one decision a resume carries for a PARKED ordinal of the prior run ({@link RunWorkflowOptions.parkedResume}):
290
+ * the checkpoint token the wa* row is parked on (the row's `parkedCheckpointToken`, the redemption key), the
291
+ * caller's decision for it (the same {@link ResumeOutcome} a top-level `runner.resume` takes), and the optional
292
+ * cross-process re-supply of the checkpoint's opaque parent constraints. The token is matched by string equality
293
+ * against the journaled parked entry — an entry whose token no decision names re-parks.
294
+ */
295
+ export interface WorkflowParkedResume {
296
+ token: CheckpointToken;
297
+ outcome: ResumeOutcome;
298
+ inheritedGate?: InheritedGate;
299
+ }
285
300
  export interface RunWorkflowOptions {
286
301
  /** Trusted caller-supplied run id. Used by the unified task registry so tool-launched workflows expose
287
302
  * `task_id === runId` (`w*`) without making the model choose an id. Omit for the legacy UUID mint path. */
@@ -435,6 +450,30 @@ export interface RunWorkflowOptions {
435
450
  * credential half of model inheritance; scripts can never set it — governance strips it — so
436
451
  * this is always the host's). NOT call identity (auth, not behavior; a function, not data). */
437
452
  defaultGetApiKeyAndHeaders?: TaskSpec["getApiKeyAndHeaders"];
453
+ /**
454
+ * #642 — the HOST run's `durableApproval` opt-in (value copy), inherited into every spawned agent whose
455
+ * fold left the seat unpinned (a deployment baseline that pins `durableApproval` wins; scripts can never set
456
+ * it — governance strips it). With it a workflow child's plain policy `ask` — an ask the host's approver
457
+ * answers `unavailable` for, or a durable mandate — PARKS durably instead of denying fail-closed, exactly as
458
+ * a background delegation child's does under the §7.3 park family: the wa* row records `status:"parked"` +
459
+ * the token, the run SUSPENDS (the script cannot continue past a parked call), and a resume drives the
460
+ * parked child on with the caller's decision ({@link parkedResume}). Tighten-only: a park capability,
461
+ * never a widening — the decision stays with a person. REQUIRES {@link store} (the wa* row's durable home;
462
+ * refused loudly at entry without it). Threaded by the Workflow tool from the host's trusted seat; a
463
+ * directly-started workflow passes its own. NOT call identity.
464
+ */
465
+ defaultDurableApproval?: TaskSpec["durableApproval"];
466
+ /**
467
+ * #642 — the decisions a resume ({@link resumeFromRunId}) carries for PARKED ordinals of the prior run: at
468
+ * an ordinal whose journal entry is `parked` (a matching call key), the run drives the parked child's own
469
+ * resume — `runner.resumeStream(token, outcome, …)` on the pinned session, the child's spec rebuilt from
470
+ * the script call exactly as at spawn — and settles its result at that ordinal, so the script continues past
471
+ * the call it parked on. A parked ordinal with NO decision here re-parks (the row and the journal say the
472
+ * same thing again, the run suspends again); it is never run live. `inheritedGate` is the cross-process
473
+ * re-supply of the checkpoint's opaque parent constraints (the same seat the background lane's drive
474
+ * takes). TRUSTED: a host-supplied decision, never a script/model argument; requires `resumeFromRunId`.
475
+ */
476
+ parkedResume?: ReadonlyArray<WorkflowParkedResume>;
438
477
  /** design/148 S1 — the HOST run's adopted center artifact (trusted, threaded by the Workflow tool
439
478
  * from ctx): every spawned agent composes the same closure. */
440
479
  parentCenterArtifactDigest?: string;