@sublang/playbook 17.2.0 → 17.4.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 +5 -2
- package/docs/cli.md +6 -5
- package/docs/configuration.md +72 -18
- package/docs/embedding.md +94 -0
- package/package.json +34 -5
- package/reference/sdlc/captain.md +6 -4
- package/reference/sdlc/captain.playbook/captain.fsm.d.ts +5 -0
- package/reference/sdlc/captain.playbook/captain.fsm.js +4 -3
- package/reference/sdlc/captain.playbook/captain.fsm.ts +9 -4
- package/reference/sdlc/captain.playbook/captain.gears.md +6 -3
- package/reference/sdlc/captain.playbook/captain.playbook.d.ts +2 -0
- package/reference/sdlc/captain.playbook/captain.playbook.js +7 -3
- package/reference/sdlc/captain.playbook/captain.playbook.ts +8 -4
- package/reference/sdlc/code.playbook/asset-types.d.ts +32 -0
- package/reference/sdlc/code.playbook/bin/launch-config.js +84 -31
- package/reference/sdlc/code.playbook/bin/playbook.js +5 -3
- package/reference/sdlc/code.playbook/bin/portable-codec.js +12 -5
- package/reference/sdlc/code.playbook/bin/run.js +74 -7
- package/reference/sdlc/code.playbook/bin/session-host.js +16 -4
- package/reference/sdlc/code.playbook/bin/session-media.js +46 -0
- package/reference/sdlc/code.playbook/bin/session-store.js +164 -25
- package/reference/sdlc/code.playbook/playbook-captain.d.ts +23 -4
- package/reference/sdlc/code.playbook/playbook-captain.js +188 -23
- package/reference/sdlc/code.playbook/playbook-captain.ts +223 -31
- package/reference/sdlc/code.playbook/playbook.config.template.yaml +22 -5
- package/reference/sdlc/code.playbook/session-assets.d.ts +53 -0
- package/reference/sdlc/code.playbook/session-assets.js +302 -0
- package/reference/sdlc/code.playbook/session-host.d.ts +9 -1
- package/reference/sdlc/code.playbook/session-store.d.ts +26 -2
- package/reference/sdlc/code.playbook/worker-evidence.d.ts +8 -0
- package/reference/sdlc/code.playbook/worker-evidence.js +51 -0
- package/reference/sdlc/inspect.md +40 -0
- package/reference/sdlc/inspect.playbook/inspect.fsm.d.ts +168 -0
- package/reference/sdlc/inspect.playbook/inspect.fsm.js +354 -0
- package/reference/sdlc/inspect.playbook/inspect.fsm.ts +455 -0
- package/reference/sdlc/inspect.playbook/inspect.gears.md +36 -0
- package/reference/sdlc/inspect.playbook/inspect.playbook.d.ts +17 -0
- package/reference/sdlc/inspect.playbook/inspect.playbook.js +142 -0
- package/reference/sdlc/inspect.playbook/inspect.playbook.ts +184 -0
- package/reference/sdlc/inspect.playbook/inspect.registry.d.ts +41 -0
- package/reference/sdlc/inspect.playbook/inspect.registry.js +51 -0
- package/reference/sdlc/inspect.playbook/inspect.registry.ts +110 -0
- package/slc/workflow-contracts.json +43 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Machine construction input. The caller-supplied inspection request and any
|
|
3
|
+
* relevant discussion context are delivered through the Boss entry event; an
|
|
4
|
+
* optional seed may ride along at construction. No agent call runs before the
|
|
5
|
+
* first Boss-originated event.
|
|
6
|
+
*/
|
|
7
|
+
export interface InspectInput {
|
|
8
|
+
inspectionRequest?: string;
|
|
9
|
+
discussionContext?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Terminal workflow output returned to the caller. Source declares two terminal
|
|
13
|
+
* returns: `{ status: 'complete', report }` and `{ status: 'unavailable', report }`.
|
|
14
|
+
*/
|
|
15
|
+
export type MachineOutput = {
|
|
16
|
+
status: 'complete';
|
|
17
|
+
report: string;
|
|
18
|
+
} | {
|
|
19
|
+
status: 'unavailable';
|
|
20
|
+
report: string;
|
|
21
|
+
};
|
|
22
|
+
/** Standard suspended-question record carried while awaiting a Boss reply. */
|
|
23
|
+
export interface PendingBossQuestion {
|
|
24
|
+
questionId: string;
|
|
25
|
+
resumeStateId: string;
|
|
26
|
+
sourceItem: string;
|
|
27
|
+
asker: {
|
|
28
|
+
kind: 'captain';
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'role';
|
|
31
|
+
roleId: string;
|
|
32
|
+
};
|
|
33
|
+
question: string;
|
|
34
|
+
}
|
|
35
|
+
/** Typed input for the delegated `player` (Inspector) actor. */
|
|
36
|
+
export interface PlayerInput {
|
|
37
|
+
stateId: string;
|
|
38
|
+
role: 'inspector';
|
|
39
|
+
sourceItem: string;
|
|
40
|
+
prompt: string;
|
|
41
|
+
inspectionRequest: string;
|
|
42
|
+
discussionContext: string;
|
|
43
|
+
pendingBossQuestion?: PendingBossQuestion;
|
|
44
|
+
bossReply?: string;
|
|
45
|
+
result: Record<'completed' | 'unavailable' | 'needsBossReply', string>;
|
|
46
|
+
}
|
|
47
|
+
/** Discriminated result contract the Inspector actor returns. */
|
|
48
|
+
export type PlayerOutput = {
|
|
49
|
+
guard: 'completed';
|
|
50
|
+
status: string;
|
|
51
|
+
report: string;
|
|
52
|
+
} | {
|
|
53
|
+
guard: 'unavailable';
|
|
54
|
+
status: string;
|
|
55
|
+
report: string;
|
|
56
|
+
} | {
|
|
57
|
+
guard: 'needsBossReply';
|
|
58
|
+
question: string;
|
|
59
|
+
};
|
|
60
|
+
interface LastError {
|
|
61
|
+
name: string;
|
|
62
|
+
message: string;
|
|
63
|
+
stack?: string;
|
|
64
|
+
}
|
|
65
|
+
interface InspectContext {
|
|
66
|
+
inspectionRequest: string;
|
|
67
|
+
discussionContext: string;
|
|
68
|
+
report: string;
|
|
69
|
+
status: 'complete' | 'unavailable' | null;
|
|
70
|
+
lastError: LastError | null;
|
|
71
|
+
pendingBossQuestion: PendingBossQuestion | null;
|
|
72
|
+
bossReply: string | null;
|
|
73
|
+
}
|
|
74
|
+
interface AcceptedOutcomeParams {
|
|
75
|
+
source: string;
|
|
76
|
+
target: string;
|
|
77
|
+
acceptedOutcome: string;
|
|
78
|
+
}
|
|
79
|
+
export declare const concurrentRoleSets: readonly [];
|
|
80
|
+
export declare const inspectMachine: import("xstate").StateMachine<InspectContext, {
|
|
81
|
+
type: "START";
|
|
82
|
+
inspectionRequest: string;
|
|
83
|
+
discussionContext?: string;
|
|
84
|
+
} | {
|
|
85
|
+
type: "BOSS_REPLY";
|
|
86
|
+
answer: string;
|
|
87
|
+
questionId?: string;
|
|
88
|
+
}, {
|
|
89
|
+
[x: string]: import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<PlayerOutput, PlayerInput, import("xstate").EventObject>> | undefined;
|
|
90
|
+
}, {
|
|
91
|
+
src: "player";
|
|
92
|
+
logic: import("xstate").PromiseActorLogic<PlayerOutput, PlayerInput, import("xstate").EventObject>;
|
|
93
|
+
id: string | undefined;
|
|
94
|
+
}, {
|
|
95
|
+
type: "playbook.acceptedOutcome";
|
|
96
|
+
params: AcceptedOutcomeParams;
|
|
97
|
+
} | {
|
|
98
|
+
type: "clearBossReplyContext";
|
|
99
|
+
params: unknown;
|
|
100
|
+
} | {
|
|
101
|
+
type: "setPendingBossQuestion";
|
|
102
|
+
params: unknown;
|
|
103
|
+
} | {
|
|
104
|
+
type: "applyEntry";
|
|
105
|
+
params: unknown;
|
|
106
|
+
} | {
|
|
107
|
+
type: "recordCompleted";
|
|
108
|
+
params: unknown;
|
|
109
|
+
} | {
|
|
110
|
+
type: "recordUnavailable";
|
|
111
|
+
params: unknown;
|
|
112
|
+
} | {
|
|
113
|
+
type: "storeBossReply";
|
|
114
|
+
params: unknown;
|
|
115
|
+
} | {
|
|
116
|
+
type: "rememberError";
|
|
117
|
+
params: unknown;
|
|
118
|
+
} | {
|
|
119
|
+
type: "rememberMalformedOutput";
|
|
120
|
+
params: unknown;
|
|
121
|
+
} | {
|
|
122
|
+
type: "rememberEmptyReply";
|
|
123
|
+
params: unknown;
|
|
124
|
+
}, {
|
|
125
|
+
type: "hasInspectionRequest";
|
|
126
|
+
params: unknown;
|
|
127
|
+
} | {
|
|
128
|
+
type: "hasBossReply";
|
|
129
|
+
params: unknown;
|
|
130
|
+
} | {
|
|
131
|
+
type: "playerCompleted";
|
|
132
|
+
params: unknown;
|
|
133
|
+
} | {
|
|
134
|
+
type: "playerUnavailable";
|
|
135
|
+
params: unknown;
|
|
136
|
+
} | {
|
|
137
|
+
type: "playerNeedsBossReply";
|
|
138
|
+
params: unknown;
|
|
139
|
+
}, never, "failed" | "ready" | "complete" | "awaitBossReply" | "unavailable" | "inspecting", string, InspectInput, {
|
|
140
|
+
status: "complete";
|
|
141
|
+
report: string;
|
|
142
|
+
} | {
|
|
143
|
+
status: "unavailable";
|
|
144
|
+
report: string;
|
|
145
|
+
}, import("xstate").EventObject, import("xstate").MetaObject, {
|
|
146
|
+
id: "inspect";
|
|
147
|
+
states: {
|
|
148
|
+
readonly ready: {
|
|
149
|
+
id: "ready";
|
|
150
|
+
};
|
|
151
|
+
readonly inspecting: {
|
|
152
|
+
id: "inspecting";
|
|
153
|
+
};
|
|
154
|
+
readonly awaitBossReply: {
|
|
155
|
+
id: "awaitBossReply";
|
|
156
|
+
};
|
|
157
|
+
readonly complete: {
|
|
158
|
+
id: "complete";
|
|
159
|
+
};
|
|
160
|
+
readonly unavailable: {
|
|
161
|
+
id: "unavailable";
|
|
162
|
+
};
|
|
163
|
+
readonly failed: {
|
|
164
|
+
id: "failed";
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
}>;
|
|
168
|
+
export {};
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
|
|
3
|
+
import { setup, fromPromise, assign } from 'xstate';
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Source-derived constants.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// INSPECT-1 full final prompt, verbatim from the GEARS blockquote. The literal
|
|
8
|
+
// leading `>` on the quoted-context lines is prompt content and is preserved.
|
|
9
|
+
const INSPECT_1_PROMPT = [
|
|
10
|
+
'Inspect the requested material and give an evidence-based explanation.',
|
|
11
|
+
'Use the attachments actually supplied to this call. Attachment names and metadata alone do not prove what their bytes show.',
|
|
12
|
+
'For a request about a running interface, use the available browser tools to open the requested location, inspect it, and capture a screenshot when needed to support the explanation. Request screenshots as native image content by omitting an explicit filename when the tool supports that form.',
|
|
13
|
+
'Reason from the images or tool results you actually receive, and explain the concrete observations that support your conclusions. Distinguish observed behavior from inference. Never claim to have opened, captured, or viewed something that the available evidence does not establish.',
|
|
14
|
+
'Do not edit repository files, create commits, implement changes, or make unrelated changes to the inspected application. Browser interaction remains within the inspection Boss requested.',
|
|
15
|
+
'If a missing choice or target prevents a useful inspection, ask Boss one concise question carrying every detail needed to answer. Do not invent the missing target.',
|
|
16
|
+
'If required evidence or tools are unavailable, explain exactly what is unavailable and what that prevents you from concluding. Do not substitute a promise to inspect later for a result.',
|
|
17
|
+
"Otherwise, complete the requested inspection and explain the findings, answering Boss's request directly. Make clear which captured figures support the findings without inventing a file path or asset identifier.",
|
|
18
|
+
'',
|
|
19
|
+
'> Inspection request: <inspection-request>',
|
|
20
|
+
'> Discussion context: <discussion-context>',
|
|
21
|
+
].join('\n');
|
|
22
|
+
// INSPECT-1 local result contract, guard names and descriptions preserved
|
|
23
|
+
// verbatim in declared order, with the universal needsBossReply appended.
|
|
24
|
+
const INSPECT_1_RESULT = {
|
|
25
|
+
completed: "Inspector's response affirmatively supports a completed inspection, not depending on any fixed presentation format. `inspect` terminates successfully and returns `{ status: 'complete', report }` to the caller, and its terminal description states that the inspection is complete without a repository change. Output shall include `status` (the string complete) and `report: <verbatim final text>`, where report is Inspector's complete explanation.",
|
|
26
|
+
unavailable: "Inspector's response affirmatively supports that required evidence or tools are unavailable, not depending on any fixed presentation format. `inspect` terminates as an authored failure and returns `{ status: 'unavailable', report }` to the caller, and its terminal description states that the requested inspection could not be completed. Output shall include `status` (the string unavailable) and `report: <verbatim final text>`, where report is Inspector's complete explanation of the missing evidence or tools.",
|
|
27
|
+
needsBossReply: "The acting agent's prose surfaces a clarifying question for Boss that the agent cannot answer alone. Output shall include `question: <verbatim question text from the acting agent's prose>`.",
|
|
28
|
+
};
|
|
29
|
+
// Role-id arrays per parallel group; this machine has no parallel group.
|
|
30
|
+
export const concurrentRoleSets = [];
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Structural narrowing helpers (accept unknown event output and narrow to the
|
|
33
|
+
// declared contract before reading fields).
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
function playerOutputOf(event) {
|
|
36
|
+
if (typeof event !== 'object' || event === null)
|
|
37
|
+
return null;
|
|
38
|
+
const output = event.output;
|
|
39
|
+
if (typeof output !== 'object' || output === null)
|
|
40
|
+
return null;
|
|
41
|
+
const guard = output.guard;
|
|
42
|
+
if (guard === 'completed' || guard === 'unavailable') {
|
|
43
|
+
const status = output.status;
|
|
44
|
+
const report = output.report;
|
|
45
|
+
if (typeof status === 'string' && typeof report === 'string' && report.trim().length > 0) {
|
|
46
|
+
return guard === 'completed'
|
|
47
|
+
? { guard: 'completed', status, report }
|
|
48
|
+
: { guard: 'unavailable', status, report };
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
if (guard === 'needsBossReply') {
|
|
53
|
+
const question = output.question;
|
|
54
|
+
if (typeof question === 'string')
|
|
55
|
+
return { guard: 'needsBossReply', question };
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
function reportOf(event) {
|
|
61
|
+
const output = playerOutputOf(event);
|
|
62
|
+
return output && (output.guard === 'completed' || output.guard === 'unavailable')
|
|
63
|
+
? output.report
|
|
64
|
+
: '';
|
|
65
|
+
}
|
|
66
|
+
function normalizeError(error) {
|
|
67
|
+
if (error instanceof Error) {
|
|
68
|
+
return error.stack !== undefined
|
|
69
|
+
? { name: error.name, message: error.message, stack: error.stack }
|
|
70
|
+
: { name: error.name, message: error.message };
|
|
71
|
+
}
|
|
72
|
+
return { name: 'Error', message: typeof error === 'string' ? error : 'Unknown error' };
|
|
73
|
+
}
|
|
74
|
+
function nonEmptyString(value) {
|
|
75
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
76
|
+
}
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Machine.
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
export const inspectMachine = setup({
|
|
81
|
+
types: {
|
|
82
|
+
context: {},
|
|
83
|
+
events: {},
|
|
84
|
+
input: {},
|
|
85
|
+
output: {},
|
|
86
|
+
},
|
|
87
|
+
actors: {
|
|
88
|
+
// Delegated Inspector work; the runner supplies the implementation.
|
|
89
|
+
player: fromPromise(async () => {
|
|
90
|
+
throw new Error('player actor must be provided by the runner');
|
|
91
|
+
}),
|
|
92
|
+
},
|
|
93
|
+
actions: {
|
|
94
|
+
// No-op accepted-outcome marker; the linked runtime consumes these
|
|
95
|
+
// three string params to publish the accepted-outcome trace.
|
|
96
|
+
'playbook.acceptedOutcome': (_args, _params) => { },
|
|
97
|
+
applyEntry: assign({
|
|
98
|
+
inspectionRequest: ({ event }) => {
|
|
99
|
+
const value = event.inspectionRequest;
|
|
100
|
+
return typeof value === 'string' ? value : '';
|
|
101
|
+
},
|
|
102
|
+
discussionContext: ({ context, event }) => {
|
|
103
|
+
const value = event.discussionContext;
|
|
104
|
+
return typeof value === 'string' ? value : context.discussionContext;
|
|
105
|
+
},
|
|
106
|
+
report: () => '',
|
|
107
|
+
status: () => null,
|
|
108
|
+
lastError: () => null,
|
|
109
|
+
pendingBossQuestion: () => null,
|
|
110
|
+
bossReply: () => null,
|
|
111
|
+
}),
|
|
112
|
+
recordCompleted: assign({
|
|
113
|
+
report: ({ event }) => reportOf(event),
|
|
114
|
+
status: () => 'complete',
|
|
115
|
+
}),
|
|
116
|
+
recordUnavailable: assign({
|
|
117
|
+
report: ({ event }) => reportOf(event),
|
|
118
|
+
status: () => 'unavailable',
|
|
119
|
+
}),
|
|
120
|
+
setPendingBossQuestion: assign({
|
|
121
|
+
pendingBossQuestion: ({ event }) => {
|
|
122
|
+
const output = playerOutputOf(event);
|
|
123
|
+
const question = output && output.guard === 'needsBossReply' ? output.question : '';
|
|
124
|
+
return {
|
|
125
|
+
questionId: 'inspecting',
|
|
126
|
+
resumeStateId: 'inspecting',
|
|
127
|
+
sourceItem: 'INSPECT-1',
|
|
128
|
+
asker: { kind: 'role', roleId: 'inspector' },
|
|
129
|
+
question,
|
|
130
|
+
};
|
|
131
|
+
},
|
|
132
|
+
}),
|
|
133
|
+
storeBossReply: assign({
|
|
134
|
+
bossReply: ({ event }) => {
|
|
135
|
+
const answer = event.answer;
|
|
136
|
+
return typeof answer === 'string' ? answer : '';
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
clearBossReplyContext: assign({
|
|
140
|
+
pendingBossQuestion: () => null,
|
|
141
|
+
bossReply: () => null,
|
|
142
|
+
}),
|
|
143
|
+
rememberError: assign({
|
|
144
|
+
lastError: ({ event }) => normalizeError(event.error),
|
|
145
|
+
}),
|
|
146
|
+
rememberMalformedOutput: assign({
|
|
147
|
+
lastError: () => ({
|
|
148
|
+
name: 'MalformedActorOutput',
|
|
149
|
+
message: 'Inspector returned an unrecognized result.',
|
|
150
|
+
}),
|
|
151
|
+
}),
|
|
152
|
+
rememberEmptyReply: assign({
|
|
153
|
+
lastError: () => ({
|
|
154
|
+
name: 'InvalidBossReply',
|
|
155
|
+
message: 'BOSS_REPLY carried an empty or whitespace-only answer.',
|
|
156
|
+
}),
|
|
157
|
+
}),
|
|
158
|
+
},
|
|
159
|
+
guards: {
|
|
160
|
+
hasInspectionRequest: ({ event }) => nonEmptyString(event.inspectionRequest),
|
|
161
|
+
hasBossReply: ({ event }) => nonEmptyString(event.answer),
|
|
162
|
+
playerCompleted: ({ event }) => playerOutputOf(event)?.guard === 'completed',
|
|
163
|
+
playerUnavailable: ({ event }) => playerOutputOf(event)?.guard === 'unavailable',
|
|
164
|
+
playerNeedsBossReply: ({ event }) => playerOutputOf(event)?.guard === 'needsBossReply',
|
|
165
|
+
},
|
|
166
|
+
}).createMachine({
|
|
167
|
+
id: 'inspect',
|
|
168
|
+
description: 'Investigate and explain existing material or a running interface without changing the repository.',
|
|
169
|
+
initial: 'ready',
|
|
170
|
+
context: ({ input }) => ({
|
|
171
|
+
inspectionRequest: input.inspectionRequest ?? '',
|
|
172
|
+
discussionContext: input.discussionContext ?? '',
|
|
173
|
+
report: '',
|
|
174
|
+
status: null,
|
|
175
|
+
lastError: null,
|
|
176
|
+
pendingBossQuestion: null,
|
|
177
|
+
bossReply: null,
|
|
178
|
+
}),
|
|
179
|
+
output: ({ context }) => context.status === 'complete'
|
|
180
|
+
? { status: 'complete', report: context.report }
|
|
181
|
+
: { status: 'unavailable', report: context.report },
|
|
182
|
+
states: {
|
|
183
|
+
ready: {
|
|
184
|
+
id: 'ready',
|
|
185
|
+
description: 'Idle hub awaiting a Boss inspection request.',
|
|
186
|
+
tags: ['playbook.parked'],
|
|
187
|
+
meta: {
|
|
188
|
+
playbook: {
|
|
189
|
+
stateId: 'ready',
|
|
190
|
+
description: 'Idle hub awaiting a Boss inspection request.',
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
on: {
|
|
194
|
+
START: {
|
|
195
|
+
guard: 'hasInspectionRequest',
|
|
196
|
+
target: 'inspecting',
|
|
197
|
+
actions: 'applyEntry',
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
inspecting: {
|
|
202
|
+
id: 'inspecting',
|
|
203
|
+
description: 'Inspector investigates the requested material and gives an evidence-based explanation.',
|
|
204
|
+
tags: ['playbook.busy'],
|
|
205
|
+
meta: {
|
|
206
|
+
playbook: {
|
|
207
|
+
stateId: 'inspecting',
|
|
208
|
+
description: 'Inspector investigates the requested material and gives an evidence-based explanation.',
|
|
209
|
+
role: 'inspector',
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
invoke: {
|
|
213
|
+
src: 'player',
|
|
214
|
+
input: ({ context }) => ({
|
|
215
|
+
stateId: 'inspecting',
|
|
216
|
+
role: 'inspector',
|
|
217
|
+
sourceItem: 'INSPECT-1',
|
|
218
|
+
prompt: INSPECT_1_PROMPT,
|
|
219
|
+
inspectionRequest: context.inspectionRequest,
|
|
220
|
+
discussionContext: context.discussionContext,
|
|
221
|
+
...(context.pendingBossQuestion
|
|
222
|
+
? { pendingBossQuestion: context.pendingBossQuestion }
|
|
223
|
+
: {}),
|
|
224
|
+
...(context.bossReply ? { bossReply: context.bossReply } : {}),
|
|
225
|
+
result: INSPECT_1_RESULT,
|
|
226
|
+
}),
|
|
227
|
+
onDone: [
|
|
228
|
+
{
|
|
229
|
+
guard: 'playerCompleted',
|
|
230
|
+
target: 'complete',
|
|
231
|
+
actions: [
|
|
232
|
+
{
|
|
233
|
+
type: 'playbook.acceptedOutcome',
|
|
234
|
+
params: {
|
|
235
|
+
source: 'inspecting',
|
|
236
|
+
target: 'complete',
|
|
237
|
+
acceptedOutcome: 'completed',
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
'recordCompleted',
|
|
241
|
+
'clearBossReplyContext',
|
|
242
|
+
],
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
guard: 'playerUnavailable',
|
|
246
|
+
target: 'unavailable',
|
|
247
|
+
actions: [
|
|
248
|
+
{
|
|
249
|
+
type: 'playbook.acceptedOutcome',
|
|
250
|
+
params: {
|
|
251
|
+
source: 'inspecting',
|
|
252
|
+
target: 'unavailable',
|
|
253
|
+
acceptedOutcome: 'unavailable',
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
'recordUnavailable',
|
|
257
|
+
'clearBossReplyContext',
|
|
258
|
+
],
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
guard: 'playerNeedsBossReply',
|
|
262
|
+
target: 'awaitBossReply',
|
|
263
|
+
actions: [
|
|
264
|
+
{
|
|
265
|
+
type: 'playbook.acceptedOutcome',
|
|
266
|
+
params: {
|
|
267
|
+
source: 'inspecting',
|
|
268
|
+
target: 'awaitBossReply',
|
|
269
|
+
acceptedOutcome: 'needsBossReply',
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
'setPendingBossQuestion',
|
|
273
|
+
],
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
target: 'failed',
|
|
277
|
+
actions: ['rememberMalformedOutput', 'clearBossReplyContext'],
|
|
278
|
+
},
|
|
279
|
+
],
|
|
280
|
+
onError: {
|
|
281
|
+
target: 'failed',
|
|
282
|
+
actions: ['rememberError', 'clearBossReplyContext'],
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
awaitBossReply: {
|
|
287
|
+
id: 'awaitBossReply',
|
|
288
|
+
description: "Waiting for Boss to answer the acting agent's question.",
|
|
289
|
+
tags: ['playbook.parked'],
|
|
290
|
+
meta: {
|
|
291
|
+
playbook: {
|
|
292
|
+
stateId: 'awaitBossReply',
|
|
293
|
+
description: "Waiting for Boss to answer the acting agent's question.",
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
on: {
|
|
297
|
+
BOSS_REPLY: [
|
|
298
|
+
{
|
|
299
|
+
guard: 'hasBossReply',
|
|
300
|
+
target: '#inspecting',
|
|
301
|
+
reenter: true,
|
|
302
|
+
actions: 'storeBossReply',
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
target: '#failed',
|
|
306
|
+
actions: ['rememberEmptyReply', 'clearBossReplyContext'],
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
complete: {
|
|
312
|
+
id: 'complete',
|
|
313
|
+
type: 'final',
|
|
314
|
+
description: 'The inspection is complete without a repository change.',
|
|
315
|
+
meta: {
|
|
316
|
+
playbook: {
|
|
317
|
+
stateId: 'complete',
|
|
318
|
+
description: 'The inspection is complete without a repository change.',
|
|
319
|
+
terminal: 'success',
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
unavailable: {
|
|
324
|
+
id: 'unavailable',
|
|
325
|
+
type: 'final',
|
|
326
|
+
description: 'The requested inspection could not be completed.',
|
|
327
|
+
meta: {
|
|
328
|
+
playbook: {
|
|
329
|
+
stateId: 'unavailable',
|
|
330
|
+
description: 'The requested inspection could not be completed.',
|
|
331
|
+
terminal: 'failure',
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
failed: {
|
|
336
|
+
id: 'failed',
|
|
337
|
+
description: 'A control error or malformed result interrupted the inspection; awaiting Boss recovery.',
|
|
338
|
+
tags: ['playbook.parked'],
|
|
339
|
+
meta: {
|
|
340
|
+
playbook: {
|
|
341
|
+
stateId: 'failed',
|
|
342
|
+
description: 'A control error or malformed result interrupted the inspection; awaiting Boss recovery.',
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
on: {
|
|
346
|
+
START: {
|
|
347
|
+
guard: 'hasInspectionRequest',
|
|
348
|
+
target: 'inspecting',
|
|
349
|
+
actions: 'applyEntry',
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
});
|