@sublang/playbook 4.0.0 → 5.0.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.
@@ -48,7 +48,20 @@ export type JudgePurpose = 'boss-input-classification' | 'player-output-adjudica
48
48
  export interface RuntimeBoundaryCalls {
49
49
  callPlayer(input: PlaybookPlayerInput, playerId: string, prompt: string, signal: AbortSignal): Promise<PlayerResult>;
50
50
  callJudge(purpose: JudgePurpose, stateId: string | undefined, prompt: string, signal: AbortSignal): Promise<string>;
51
- callCaptain?(input: PlaybookCaptainInput, prompt: string, signal: AbortSignal): Promise<CaptainResult>;
51
+ callCaptain?(input: PlaybookCaptainInput, prompt: string, signal: AbortSignal, callOptions?: XStateCaptainCallOptions): Promise<CaptainResult>;
52
+ }
53
+ /**
54
+ * Presentation selection for one traced direct-Captain call
55
+ * (slc/link.md §Captain adjudication). `'visible'` (the default) is the
56
+ * workflow form: the port receives `{ visibility: 'visible', resume: false }`
57
+ * and the trace pair carries both members. `'hidden'` is the controller form
58
+ * (DR-029): the port receives `{ visibility: 'hidden', resume: false }`
59
+ * while the host's session-Captain wrapper owns the actual durable-conversation
60
+ * resume selection, so the trace pair carries `visibility: 'hidden'` and no
61
+ * `resume` member — the pinned token never enters runtime telemetry.
62
+ */
63
+ export interface XStateCaptainCallOptions {
64
+ visibility?: 'visible' | 'hidden';
52
65
  }
53
66
  export interface ScheduledStatus {
54
67
  message: string;
@@ -81,6 +94,46 @@ export interface XStatePlaybookRuntimeCompat {
81
94
  /** The engine ABI the artifact was linked against. */
82
95
  runtimeAbi: number;
83
96
  }
97
+ /**
98
+ * One direct-Captain actor invocation handed to a spec's `captainStrategy`
99
+ * (slc/link.md §Captain adjudication, controller form). The engine owns
100
+ * signal combination, emission draining, trace pairing, the shared
101
+ * Captain/judge lane, and control-plane latching; the strategy owns the
102
+ * playbook-specific call pipeline — e.g. the controller's hidden decision
103
+ * call, `{ action, … }` control-JSON validation with its single corrective
104
+ * re-ask, and controller-port submission.
105
+ */
106
+ export interface XStateCaptainStrategyRun<TOptions> {
107
+ input: PlaybookCaptainInput;
108
+ /** The prompt composed by the spec's Captain composer for `input`. */
109
+ prompt: string;
110
+ /** Combined invocation-lifetime + active-boundary abort signal. */
111
+ signal: AbortSignal;
112
+ /** The immutable validated runtime options. */
113
+ options: TOptions;
114
+ /** The bound immutable playbook session identity. */
115
+ session: PlaybookSession;
116
+ /**
117
+ * One traced Captain call through the shared serialized lane; every call —
118
+ * initial or corrective — emits its own paired `captain.call.started` /
119
+ * `captain.call.finished` boundary. Throws the boundary's authoritative
120
+ * failure for non-`ok` and empty-`ok` results exactly as the default
121
+ * pipeline does.
122
+ */
123
+ callCaptain(prompt: string, callOptions?: XStateCaptainCallOptions): Promise<CaptainResult>;
124
+ /**
125
+ * DR-028: true when `error` is the boundary's re-askable empty-`ok`
126
+ * marker; the strategy may re-issue the same composed call exactly once.
127
+ */
128
+ isEmptyOkRetry(error: unknown): boolean;
129
+ /**
130
+ * Mark `error` as a recoverable FSM-result failure: it travels the invoked
131
+ * actor's XState `onError` path without being latched as a control-plane
132
+ * error, so the machine's authored recovery arms can route it.
133
+ */
134
+ recoverableFailure<E extends Error>(error: E): E;
135
+ }
136
+ export type XStateCaptainStrategy<TOptions> = (run: XStateCaptainStrategyRun<TOptions>) => Promise<PlaybookActorOutput>;
84
137
  export interface XStatePlaybookRuntimeSpec<TOptions> {
85
138
  /** Diagnostic label used in internal invariant errors. Default 'playbook'. */
86
139
  label?: string;
@@ -112,8 +165,18 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
112
165
  * the XState machine alone.
113
166
  */
114
167
  bossEvents?: readonly XStateBossEventSpec[];
115
- /** Boss-input classifier override; default: generic parked-state classifier. */
116
- classifyBossText?: (text: string, ports: PlaybookPorts, signal: AbortSignal, snapshotOrState: unknown, boundary?: RuntimeBoundaryCalls) => Promise<EventObject | undefined>;
168
+ /** Boss-input classifier override; default: generic parked-state classifier. Receives the bound validated options last so a fully deterministic controller mapping can consult host-supplied option members (slc/link.md §Boss-event mapping). */
169
+ classifyBossText?: (text: string, ports: PlaybookPorts, signal: AbortSignal, snapshotOrState: unknown, boundary?: RuntimeBoundaryCalls, options?: TOptions) => Promise<EventObject | undefined>;
170
+ /**
171
+ * Direct-Captain actor strategy override (slc/link.md §Captain
172
+ * adjudication, controller form): replaces the default visible-call +
173
+ * hidden-judge pipeline for every `captain` state of this machine. The
174
+ * engine still composes the prompt, combines signals, traces each call as
175
+ * its own pair, and latches control-plane errors; failures the strategy
176
+ * marks with `recoverableFailure` travel the actor's `onError` path as
177
+ * recoverable FSM-result failures instead.
178
+ */
179
+ captainStrategy?: XStateCaptainStrategy<TOptions>;
117
180
  /** Status line emitted after classification names an event. Default: none. */
118
181
  classificationStatus?: (event: EventObject) => string | undefined;
119
182
  /** Map a player-invoking state's input to the host player id. Default: lowercased player name. */
@@ -130,6 +193,18 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
130
193
  extractRequiredFields?: (description: string) => string[];
131
194
  /** Required fields carried verbatim from the player's finalText instead of judge JSON. Default: none. */
132
195
  verbatimPayloadFields?: ReadonlySet<string>;
196
+ /**
197
+ * DR-029 / PBRT-52: the runtime-authored ControlView context
198
+ * projection — the exact FSM context members `describe()` may expose,
199
+ * in the order the view lists them. Only this artifact knows which of
200
+ * its context members are safe and relevant for a controller prompt, so
201
+ * the engine exports what is named here and nothing else: a member the
202
+ * artifact has not named stays private, and a member added to the FSM
203
+ * later stays private until someone names it. Absent or empty: the view
204
+ * carries no context at all. `pendingBossQuestion` and `lastError` are
205
+ * surfaced first-class by the view and shall not be named here.
206
+ */
207
+ controlContextFields?: readonly string[];
133
208
  /** States that may suspend for a Boss reply. Default: targets of the FSM's `awaitBossReply` BOSS_REPLY transitions. */
134
209
  resumableStateIds?: ReadonlySet<string>;
135
210
  /** Human status lines for a root transition. Default: entry lines with question/failure surfacing. */
@@ -215,6 +290,12 @@ export declare function defaultBuildCaptainJudgePrompt(input: {
215
290
  }, finalText: string): string;
216
291
  /** Targets of the FSM's `awaitBossReply` BOSS_REPLY transitions. */
217
292
  export declare function resumableStateIdsFromMachine(machine: AnyStateMachine): ReadonlySet<string>;
293
+ /**
294
+ * Source state descriptions by state key, node id, and `meta.playbook`
295
+ * state id, read from `machine.config`. Control actions are labeled from
296
+ * these descriptions (DR-029); a state without one has no entry.
297
+ */
298
+ export declare function stateDescriptionsFromMachine(machine: AnyStateMachine): ReadonlyMap<string, string>;
218
299
  /**
219
300
  * Build a `PlaybookRuntimeFactory` that interprets the given FSM artifact
220
301
  * under the slc/link.md contract. The factory provides every actor kind the
@@ -222,7 +303,8 @@ export declare function resumableStateIdsFromMachine(machine: AnyStateMachine):
222
303
  * (literal and dynamic) — and implements the full runtime lifecycle including
223
304
  * the optional parked-session snapshot capability (DR-014).
224
305
  *
225
- * Scope: single-region root machines (each snapshot exposes exactly one
226
- * playbook state id). Parallel-region FSMs keep their own linked runtimes.
306
+ * Scope: machines that declare no parallel state (each snapshot exposes
307
+ * exactly one playbook state id). Parallel-region FSMs keep their own linked
308
+ * runtimes.
227
309
  */
228
310
  export declare function createXStatePlaybookRuntime<TOptions>(machine: AnyStateMachine, spec: XStatePlaybookRuntimeSpec<TOptions>): PlaybookRuntimeFactory<TOptions>;