@sublang/slc 0.2.0 → 0.3.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 +37 -14
- package/dist/app.d.ts +13 -2
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +60 -11
- package/dist/app.js.map +1 -1
- package/dist/cligent-agent.d.ts +19 -0
- package/dist/cligent-agent.d.ts.map +1 -1
- package/dist/cligent-agent.js +125 -30
- package/dist/cligent-agent.js.map +1 -1
- package/dist/compiled-executor.d.ts +6 -0
- package/dist/compiled-executor.d.ts.map +1 -1
- package/dist/compiled-executor.js +1 -0
- package/dist/compiled-executor.js.map +1 -1
- package/dist/config-file.d.ts +9 -0
- package/dist/config-file.d.ts.map +1 -1
- package/dist/config-file.js +28 -2
- package/dist/config-file.js.map +1 -1
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +9 -3
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/playbook-ports.d.ts +8 -0
- package/dist/playbook-ports.d.ts.map +1 -1
- package/dist/playbook-ports.js +14 -2
- package/dist/playbook-ports.js.map +1 -1
- package/dist/progress.d.ts +71 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +96 -0
- package/dist/progress.js.map +1 -0
- package/dist/runner.d.ts +6 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +46 -2
- package/dist/runner.js.map +1 -1
- package/dist/slc.config.template.yaml +5 -1
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -49,16 +49,27 @@ compile stage — without waiting on a compile.
|
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
npm install -g @sublang/slc @sublang/playbook
|
|
52
|
+
npm install -g @anthropic-ai/claude-agent-sdk @openai/codex-sdk
|
|
52
53
|
slc --version
|
|
53
54
|
```
|
|
54
55
|
|
|
56
|
+
The second line supplies the agent SDKs for the default Claude and Codex
|
|
57
|
+
lineup. Playbook 4 installs none itself — which versions work is
|
|
58
|
+
`@sublang/cligent`'s to enforce at load — so name the SDKs your own
|
|
59
|
+
configuration needs. If one is missing, the compile stops before any
|
|
60
|
+
agent call and names the package to install; if one is too old, it
|
|
61
|
+
names the installed and required versions along with the exact version
|
|
62
|
+
to install.
|
|
63
|
+
|
|
55
64
|
Compiled artifacts import the Playbook engine from their own directory;
|
|
56
65
|
when that import does not resolve, `playbook run` (3.1+) links its own
|
|
57
66
|
engine beside the artifact and says so (`--no-provision` opts out).
|
|
58
|
-
Working inside an npm project instead? Install
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
67
|
+
Working inside an npm project instead? Install the same set there — the
|
|
68
|
+
compiler, the engine, and the SDKs your lineup uses — and prefix the
|
|
69
|
+
commands with `npx`. A project's own install is always authoritative,
|
|
70
|
+
and a globally installed SDK is invisible to a project's nested
|
|
71
|
+
`@sublang/cligent`, so the SDKs belong in the same tree
|
|
72
|
+
([RELEASE-11](specs/dev/release.md#release-11) has the full rules).
|
|
62
73
|
|
|
63
74
|
Requirements:
|
|
64
75
|
|
|
@@ -87,10 +98,13 @@ slc playbook my-workflow.md
|
|
|
87
98
|
dependency, so it compiles in any directory — no clone, no project
|
|
88
99
|
setup. Compilation drives your configured coding agent — the first run
|
|
89
100
|
seeds `~/.config/slc/config.yaml` with `agent: claude-code`; set
|
|
90
|
-
`SLC_AGENT` (or edit that file) to use another agent CLI
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
101
|
+
`SLC_AGENT` (or edit that file) to use another agent CLI. Expect it to
|
|
102
|
+
take a while: duration is agent- and workload-dependent, and measured
|
|
103
|
+
compiles of a five-line workflow have run from tens of minutes to more
|
|
104
|
+
than two hours, with the first intermediate typically landing within
|
|
105
|
+
about five minutes. Plain-text input (`.txt`) works too; it is
|
|
106
|
+
normalized first. The pipeline's optimization pass, which rewrites
|
|
107
|
+
judgment-free steps into plain script, runs by default
|
|
94
108
|
(`--no-optimize` skips it).
|
|
95
109
|
|
|
96
110
|
Artifacts land in your working directory: `my-workflow.playbook/` holds
|
|
@@ -106,9 +120,16 @@ Intermediates are first-class: edit one and re-run a single phase
|
|
|
106
120
|
(`slc playbook.gears2fsm …`) and it lands in the same place.
|
|
107
121
|
`slc --help` shows all invocation forms.
|
|
108
122
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
and
|
|
123
|
+
While a compile runs, `slc` reports progress on stderr: each phase as it
|
|
124
|
+
starts, each artifact as it lands with the elapsed time, the compiled
|
|
125
|
+
runtime's own state transitions, and a heartbeat so the terminal is
|
|
126
|
+
never silent for more than 30 seconds. An agent call that goes quiet for
|
|
127
|
+
`stallTimeout` seconds (default 600, `0` disables) is aborted and
|
|
128
|
+
reported as a failed phase rather than hanging indefinitely.
|
|
129
|
+
|
|
130
|
+
Success prints the written artifact paths to stdout and exits 0; a
|
|
131
|
+
failure prints diagnostics to stderr — naming the failing phase when one
|
|
132
|
+
is at fault — and exits non-zero.
|
|
112
133
|
|
|
113
134
|
## Configuration
|
|
114
135
|
|
|
@@ -123,14 +144,16 @@ and `pipelinePath` to the working directory.
|
|
|
123
144
|
# slc.config.yaml
|
|
124
145
|
agent: claude-code # claude-code | codex | gemini | opencode
|
|
125
146
|
model: claude-opus-4-8 # optional; omit to use the agent CLI's default
|
|
147
|
+
stallTimeout: 600 # seconds of agent silence before a stalled call fails
|
|
126
148
|
pipelinePath: # search roots for <pipeline> references; defaults to the cwd
|
|
127
149
|
- ./pipelines
|
|
128
150
|
```
|
|
129
151
|
|
|
130
152
|
A `slc.config.yaml` in the working directory wins over the user config;
|
|
131
|
-
`SLC_AGENT`, `SLC_MODEL`, and `SLC_PIPELINE_PATH`
|
|
132
|
-
key. Discovery order, `--config`, and validation
|
|
133
|
-
[CLI spec](specs/user/cli.md); `slc --help` prints the
|
|
153
|
+
`SLC_AGENT`, `SLC_MODEL`, `SLC_STALL_TIMEOUT`, and `SLC_PIPELINE_PATH`
|
|
154
|
+
override either per key. Discovery order, `--config`, and validation
|
|
155
|
+
rules live in the [CLI spec](specs/user/cli.md); `slc --help` prints the
|
|
156
|
+
summary.
|
|
134
157
|
|
|
135
158
|
## How pipelines work
|
|
136
159
|
|
package/dist/app.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createConfiguredCompiledFactory, createConfiguredExecutor, type AgentSelection } from './config.js';
|
|
2
2
|
import { type FileConfig } from './config-file.js';
|
|
3
|
+
import { type ProgressSink } from './progress.js';
|
|
3
4
|
import { type SlcDeps } from './runner.js';
|
|
4
5
|
/** The program name. */
|
|
5
6
|
export declare const name = "slc";
|
|
@@ -14,6 +15,8 @@ export type DepsBuilder = (io: {
|
|
|
14
15
|
configPath?: string;
|
|
15
16
|
/** Sink for host notes such as first-run config seeding (DR-015, CLI-30). */
|
|
16
17
|
note?: (text: string) => void;
|
|
18
|
+
/** The run's progress sink, rendered to stderr by the bin (DR-019, CLI-35). */
|
|
19
|
+
progress?: ProgressSink;
|
|
17
20
|
}) => SlcDeps | Promise<SlcDeps>;
|
|
18
21
|
/** Injectable IO and configuration for {@link run}; all fields default to the process. */
|
|
19
22
|
export interface RunOptions {
|
|
@@ -46,19 +49,27 @@ export type CompiledFactoryBuilder = typeof createConfiguredCompiledFactory;
|
|
|
46
49
|
* @throws {import('./config.js').ConfigError} when neither source supplies an
|
|
47
50
|
* agent, or the resolved agent is unsupported (CLI-12).
|
|
48
51
|
*/
|
|
49
|
-
export declare function buildSlcDeps({ env, cwd, signal, configPath, note }: Parameters<DepsBuilder>[0], createExecutor?: ExecutorFactory, createCompiled?: CompiledFactoryBuilder): Promise<SlcDeps>;
|
|
52
|
+
export declare function buildSlcDeps({ env, cwd, signal, configPath, note, progress }: Parameters<DepsBuilder>[0], createExecutor?: ExecutorFactory, createCompiled?: CompiledFactoryBuilder): Promise<SlcDeps>;
|
|
50
53
|
/** The cligent-invocation selection after merging environment over file (DR-006). */
|
|
51
54
|
export interface RunConfig {
|
|
52
55
|
selection: AgentSelection;
|
|
53
56
|
/** Search-root source: an `SLC_PIPELINE_PATH` string, the file's sequence, or undefined. */
|
|
54
57
|
pipelinePath: string | string[] | undefined;
|
|
58
|
+
/** Agent-stall watchdog window in milliseconds; `0` disables (DR-019, CLI-34). */
|
|
59
|
+
stallTimeoutMs: number;
|
|
55
60
|
}
|
|
61
|
+
/** Default agent-stall watchdog window in seconds (DR-019, CLI-34). */
|
|
62
|
+
export declare const DEFAULT_STALL_TIMEOUT_SECONDS = 600;
|
|
56
63
|
/**
|
|
57
64
|
* Merges the environment over config-file values per key (DR-006, CLI-20): for
|
|
58
65
|
* each key a non-blank environment variable wins, otherwise the file value,
|
|
59
66
|
* otherwise the built-in default. The agent and model go through
|
|
60
67
|
* {@link resolveAgentSelection} so the supported-agent check stays single-sourced
|
|
61
|
-
* (CLI-7, CLI-12)
|
|
68
|
+
* (CLI-7, CLI-12); the stall timeout defaults to
|
|
69
|
+
* {@link DEFAULT_STALL_TIMEOUT_SECONDS} with `0` disabling the watchdog
|
|
70
|
+
* (DR-019, CLI-34).
|
|
71
|
+
*
|
|
72
|
+
* @throws {Error} when `SLC_STALL_TIMEOUT` is not a non-negative number.
|
|
62
73
|
*/
|
|
63
74
|
export declare function resolveRunConfig(env: Record<string, string | undefined>, file: FileConfig): RunConfig;
|
|
64
75
|
/** Usage text naming the documented invocation forms and configuration (CLI-2). */
|
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,+BAA+B,EAC/B,wBAAwB,EAExB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AACrB,OAAO,
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
package/dist/app.js
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { createRequire } from 'node:module';
|
|
17
17
|
import { createConfiguredCompiledFactory, createConfiguredExecutor, resolveAgentSelection, } from './config.js';
|
|
18
|
-
import { loadConfigFile } from './config-file.js';
|
|
18
|
+
import { loadConfigFile, MAX_STALL_TIMEOUT_SECONDS, } from './config-file.js';
|
|
19
|
+
import { createProgressReporter } from './progress.js';
|
|
19
20
|
import { createPipelineResolver, pipelineSearchRoots, withReservedPipelines, } from './resolver.js';
|
|
20
21
|
import { runSlc } from './runner.js';
|
|
21
22
|
const manifest = createRequire(import.meta.url)('../package.json');
|
|
@@ -45,7 +46,7 @@ export function version() {
|
|
|
45
46
|
* @throws {import('./config.js').ConfigError} when neither source supplies an
|
|
46
47
|
* agent, or the resolved agent is unsupported (CLI-12).
|
|
47
48
|
*/
|
|
48
|
-
export async function buildSlcDeps({ env, cwd, signal, configPath, note },
|
|
49
|
+
export async function buildSlcDeps({ env, cwd, signal, configPath, note, progress },
|
|
49
50
|
// Injectable so a test can capture the executor options — notably the
|
|
50
51
|
// non-interactive write permission below — without constructing a real
|
|
51
52
|
// adapter, the same seam pattern as `createConfiguredExecutor`'s
|
|
@@ -58,22 +59,40 @@ createExecutor = createConfiguredExecutor, createCompiled = createConfiguredComp
|
|
|
58
59
|
// First-run seeding (DR-015): name the created user config on stderr.
|
|
59
60
|
onSeed: (path) => note?.(`slc: seeded ${path} (agent: claude-code)\n`),
|
|
60
61
|
});
|
|
61
|
-
const { selection, pipelinePath } = resolveRunConfig(env, file.config);
|
|
62
|
+
const { selection, pipelinePath, stallTimeoutMs } = resolveRunConfig(env, file.config);
|
|
62
63
|
const resolver = withReservedPipelines(createPipelineResolver(pipelineSearchRoots(pipelinePath, cwd)));
|
|
63
64
|
// Auto-accept the agents' file operations so a non-interactive `slc` run can
|
|
64
65
|
// write its target artifact; the DR-003 generic checks still guard the
|
|
65
|
-
// protected inputs (DR-004).
|
|
66
|
-
|
|
66
|
+
// protected inputs (DR-004). The stall watchdog rides every constructed
|
|
67
|
+
// transport (DR-019, CLI-35).
|
|
68
|
+
const agentOpts = {
|
|
69
|
+
cwd,
|
|
70
|
+
permissions: { mode: 'auto' },
|
|
71
|
+
stallTimeoutMs,
|
|
72
|
+
};
|
|
67
73
|
const executor = createExecutor(selection, agentOpts);
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
// Compiled-runtime status streams to the same reporter as phase progress
|
|
75
|
+
// (PHEXEC-25, CLI-32).
|
|
76
|
+
const compiled = createCompiled(selection, {
|
|
77
|
+
...agentOpts,
|
|
78
|
+
onStatus: progress === undefined
|
|
79
|
+
? undefined
|
|
80
|
+
: (line) => progress({ kind: 'status', text: line }),
|
|
81
|
+
});
|
|
82
|
+
return { resolver, executor, compiled, cwd, signal, progress };
|
|
70
83
|
}
|
|
84
|
+
/** Default agent-stall watchdog window in seconds (DR-019, CLI-34). */
|
|
85
|
+
export const DEFAULT_STALL_TIMEOUT_SECONDS = 600;
|
|
71
86
|
/**
|
|
72
87
|
* Merges the environment over config-file values per key (DR-006, CLI-20): for
|
|
73
88
|
* each key a non-blank environment variable wins, otherwise the file value,
|
|
74
89
|
* otherwise the built-in default. The agent and model go through
|
|
75
90
|
* {@link resolveAgentSelection} so the supported-agent check stays single-sourced
|
|
76
|
-
* (CLI-7, CLI-12)
|
|
91
|
+
* (CLI-7, CLI-12); the stall timeout defaults to
|
|
92
|
+
* {@link DEFAULT_STALL_TIMEOUT_SECONDS} with `0` disabling the watchdog
|
|
93
|
+
* (DR-019, CLI-34).
|
|
94
|
+
*
|
|
95
|
+
* @throws {Error} when `SLC_STALL_TIMEOUT` is not a non-negative number.
|
|
77
96
|
*/
|
|
78
97
|
export function resolveRunConfig(env, file) {
|
|
79
98
|
const selection = resolveAgentSelection({
|
|
@@ -82,7 +101,24 @@ export function resolveRunConfig(env, file) {
|
|
|
82
101
|
SLC_EFFORT: nonBlank(env.SLC_EFFORT) ?? file.effort,
|
|
83
102
|
});
|
|
84
103
|
const pipelinePath = nonBlank(env.SLC_PIPELINE_PATH) ?? file.pipelinePath;
|
|
85
|
-
|
|
104
|
+
const stallSeconds = parseStallTimeout(nonBlank(env.SLC_STALL_TIMEOUT)) ??
|
|
105
|
+
file.stallTimeout ??
|
|
106
|
+
DEFAULT_STALL_TIMEOUT_SECONDS;
|
|
107
|
+
return { selection, pipelinePath, stallTimeoutMs: stallSeconds * 1000 };
|
|
108
|
+
}
|
|
109
|
+
function parseStallTimeout(value) {
|
|
110
|
+
if (value === undefined)
|
|
111
|
+
return undefined;
|
|
112
|
+
const seconds = Number(value);
|
|
113
|
+
if (!Number.isFinite(seconds) || seconds < 0) {
|
|
114
|
+
throw new Error(`SLC_STALL_TIMEOUT "${value}" must be a non-negative number of seconds (0 disables the stall watchdog)`);
|
|
115
|
+
}
|
|
116
|
+
// Beyond the timer range Node clamps the delay to 1 ms, which would abort
|
|
117
|
+
// every agent call at once — refuse rather than invert the watchdog.
|
|
118
|
+
if (seconds > MAX_STALL_TIMEOUT_SECONDS) {
|
|
119
|
+
throw new Error(`SLC_STALL_TIMEOUT "${value}" must be at most ${MAX_STALL_TIMEOUT_SECONDS} seconds (0 disables the stall watchdog)`);
|
|
120
|
+
}
|
|
121
|
+
return seconds;
|
|
86
122
|
}
|
|
87
123
|
/** Returns `value` when set and not all-whitespace, else `undefined` (DR-006). */
|
|
88
124
|
function nonBlank(value) {
|
|
@@ -117,12 +153,14 @@ export function usageText() {
|
|
|
117
153
|
' environment variable below:',
|
|
118
154
|
' ./slc.config.yaml',
|
|
119
155
|
' ${XDG_CONFIG_HOME:-~/.config}/slc/config.yaml',
|
|
120
|
-
' Keys: agent, model, effort, pipelinePath.',
|
|
156
|
+
' Keys: agent, model, effort, pipelinePath, stallTimeout.',
|
|
121
157
|
'',
|
|
122
158
|
' SLC_AGENT agent CLI: claude-code | codex | gemini | opencode',
|
|
123
159
|
' SLC_MODEL optional model for the agent CLI',
|
|
124
160
|
' SLC_EFFORT optional adapter-scoped reasoning effort (e.g. xhigh)',
|
|
125
161
|
' SLC_PIPELINE_PATH search roots for <pipeline> references (default: cwd)',
|
|
162
|
+
' SLC_STALL_TIMEOUT seconds of agent inactivity before a stalled call',
|
|
163
|
+
' fails the run (default: 600; 0 disables)',
|
|
126
164
|
'',
|
|
127
165
|
].join('\n');
|
|
128
166
|
}
|
|
@@ -170,6 +208,9 @@ export async function run(argv, options = {}) {
|
|
|
170
208
|
const env = options.env ?? process.env;
|
|
171
209
|
const cwd = options.cwd ?? process.cwd();
|
|
172
210
|
const signal = options.signal ?? new AbortController().signal;
|
|
211
|
+
// In-run progress renders on stderr as it happens, with the silence-bounded
|
|
212
|
+
// heartbeat (DR-019, CLI-32, CLI-33, CLI-35).
|
|
213
|
+
const reporter = createProgressReporter(stderr);
|
|
173
214
|
let deps;
|
|
174
215
|
let rest;
|
|
175
216
|
try {
|
|
@@ -183,15 +224,23 @@ export async function run(argv, options = {}) {
|
|
|
183
224
|
signal,
|
|
184
225
|
configPath: extracted.configPath,
|
|
185
226
|
note: stderr,
|
|
227
|
+
progress: reporter.sink,
|
|
186
228
|
});
|
|
187
229
|
}
|
|
188
230
|
catch (error) {
|
|
189
231
|
// Configuration refusals — a bad `--config`, an invalid config file
|
|
190
232
|
// (CLI-21), or an unset/unsupported agent (CLI-12) — fail the run.
|
|
233
|
+
reporter.dispose();
|
|
191
234
|
stderr(`${name}: ${messageOf(error)}\n`);
|
|
192
235
|
return 1;
|
|
193
236
|
}
|
|
194
|
-
|
|
237
|
+
let result;
|
|
238
|
+
try {
|
|
239
|
+
result = await runSlc(rest, deps);
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
reporter.dispose();
|
|
243
|
+
}
|
|
195
244
|
if (result.ok) {
|
|
196
245
|
if (result.outputs.length > 0)
|
|
197
246
|
stdout(`${result.outputs.join('\n')}\n`);
|
package/dist/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,0EAA0E;AAE1E;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EACL,+BAA+B,EAC/B,wBAAwB,EACxB,qBAAqB,GAEtB,MAAM,aAAa,CAAC;AACrB,OAAO,
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
package/dist/cligent-agent.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import type { AgentAdapter, PermissionPolicy } from '@sublang/cligent';
|
|
2
2
|
import type { AgentClient } from './interpreter.js';
|
|
3
|
+
/** Timer seams for the stall watchdog; injected in tests. */
|
|
4
|
+
export interface WatchdogTimers {
|
|
5
|
+
setTimeout(callback: () => void, ms: number): unknown;
|
|
6
|
+
clearTimeout(handle: unknown): void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The production watchdog timers. Exported so a test can assert the ref
|
|
10
|
+
* behavior the watchdog's correctness depends on, which an injected fake
|
|
11
|
+
* would bypass.
|
|
12
|
+
*/
|
|
13
|
+
export declare const defaultWatchdogTimers: WatchdogTimers;
|
|
3
14
|
/** Wraps a Cligent adapter as an {@link AgentClient} for the interpreter. */
|
|
4
15
|
export declare function createCligentAgent(opts: {
|
|
5
16
|
adapter: AgentAdapter;
|
|
@@ -7,5 +18,13 @@ export declare function createCligentAgent(opts: {
|
|
|
7
18
|
permissions?: PermissionPolicy;
|
|
8
19
|
/** Adapter-scoped reasoning effort, validated by the configuration layer. */
|
|
9
20
|
effort?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Milliseconds of adapter-event inactivity after which the in-flight call is
|
|
23
|
+
* aborted and reported as an error (DR-019, PHEXEC-36). Zero or absent
|
|
24
|
+
* disables the watchdog.
|
|
25
|
+
*/
|
|
26
|
+
stallTimeoutMs?: number;
|
|
27
|
+
/** Watchdog timer seams; defaults to real timers. Injected in tests. */
|
|
28
|
+
watchdogTimers?: WatchdogTimers;
|
|
10
29
|
}): AgentClient;
|
|
11
30
|
//# sourceMappingURL=cligent-agent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cligent-agent.d.ts","sourceRoot":"","sources":["../src/cligent-agent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cligent-agent.d.ts","sourceRoot":"","sources":["../src/cligent-agent.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,YAAY,EAGZ,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,kBAAkB,CAAC;AAGpE,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACtD,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACrC;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,cASnC,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,GAAG,WAAW,CAiFd"}
|
package/dist/cligent-agent.js
CHANGED
|
@@ -7,11 +7,36 @@
|
|
|
7
7
|
* draining its event stream into a normalized {@link AgentRunResult}. The host
|
|
8
8
|
* supplies the concrete `AgentAdapter` (e.g. Claude Code, Codex) and any write
|
|
9
9
|
* permissions, keeping agent selection a configuration concern (PHEXEC-13); the
|
|
10
|
-
* DR-003 write-scope sandbox would be configured here via `permissions`.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* DR-003 write-scope sandbox would be configured here via `permissions`.
|
|
11
|
+
*
|
|
12
|
+
* The transport also owns the agent-stall watchdog (DR-019, PHEXEC-36): with a
|
|
13
|
+
* positive `stallTimeoutMs`, an in-flight call that observes no adapter event
|
|
14
|
+
* for that window is aborted through a call-local controller — the caller's
|
|
15
|
+
* signal is composed in, never mutated — and reported as an error carrying the
|
|
16
|
+
* inactivity duration. Cligent's abort drain guarantees the event loop then
|
|
17
|
+
* terminates promptly with a terminal event, so a tripped watchdog cannot
|
|
18
|
+
* itself hang. No retry occurs at this seam (PHEXEC-12, PHEXEC-23).
|
|
19
|
+
*
|
|
20
|
+
* This transport is exercised by integration runs and by tests that fake the
|
|
21
|
+
* adapter's event stream. See specs/dev/phase-execution.md.
|
|
13
22
|
*/
|
|
14
23
|
import { Cligent } from '@sublang/cligent';
|
|
24
|
+
import { formatElapsed } from './progress.js';
|
|
25
|
+
/**
|
|
26
|
+
* The production watchdog timers. Exported so a test can assert the ref
|
|
27
|
+
* behavior the watchdog's correctness depends on, which an injected fake
|
|
28
|
+
* would bypass.
|
|
29
|
+
*/
|
|
30
|
+
export const defaultWatchdogTimers = {
|
|
31
|
+
// Deliberately referenced: the watchdog is the only thing guaranteed to end
|
|
32
|
+
// a stalled call, so it must hold the event loop open for its window. An
|
|
33
|
+
// unref'd timer lets Node exit the moment a dead agent transport stops
|
|
34
|
+
// holding I/O, killing the run before the stall is ever diagnosed. The
|
|
35
|
+
// timer is cleared on every event and in `dispose`, so it cannot outlive
|
|
36
|
+
// the call it guards.
|
|
37
|
+
setTimeout: (callback, ms) => setTimeout(callback, ms),
|
|
38
|
+
clearTimeout: (handle) => clearTimeout(handle),
|
|
39
|
+
};
|
|
15
40
|
/** Wraps a Cligent adapter as an {@link AgentClient} for the interpreter. */
|
|
16
41
|
export function createCligentAgent(opts) {
|
|
17
42
|
const cligent = new Cligent(opts.adapter, {
|
|
@@ -20,41 +45,66 @@ export function createCligentAgent(opts) {
|
|
|
20
45
|
// Validated adapter-scoped by the configuration layer (CLI-12).
|
|
21
46
|
...(opts.effort !== undefined ? { effort: opts.effort } : {}),
|
|
22
47
|
});
|
|
48
|
+
const stallMs = opts.stallTimeoutMs ?? 0;
|
|
49
|
+
const timers = opts.watchdogTimers ?? defaultWatchdogTimers;
|
|
23
50
|
return {
|
|
24
51
|
async run({ prompt, cwd, model, resume, allowedTools, signal, }) {
|
|
52
|
+
const watchdog = createWatchdog(signal, stallMs, timers);
|
|
25
53
|
const texts = [];
|
|
26
54
|
let resultText = '';
|
|
27
55
|
let status = 'incomplete';
|
|
28
56
|
let resumeToken;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
try {
|
|
58
|
+
for await (const raw of cligent.run(prompt, {
|
|
59
|
+
abortSignal: watchdog.signal,
|
|
60
|
+
cwd,
|
|
61
|
+
model,
|
|
62
|
+
...(resume !== undefined ? { resume } : {}),
|
|
63
|
+
...(allowedTools !== undefined
|
|
64
|
+
? { allowedTools: [...allowedTools] }
|
|
65
|
+
: {}),
|
|
66
|
+
})) {
|
|
67
|
+
// Any adapter event is activity, regardless of type: the reliable
|
|
68
|
+
// event subset differs per adapter, so the watchdog resets on every
|
|
69
|
+
// iteration (DR-019).
|
|
70
|
+
watchdog.touch();
|
|
71
|
+
const event = raw;
|
|
72
|
+
if (event.type === 'text') {
|
|
73
|
+
texts.push(event.payload.content);
|
|
74
|
+
}
|
|
75
|
+
else if (event.type === 'error') {
|
|
76
|
+
status = 'error';
|
|
77
|
+
texts.push(event.payload.message);
|
|
78
|
+
}
|
|
79
|
+
else if (event.type === 'done') {
|
|
80
|
+
status =
|
|
81
|
+
event.payload.status === 'success'
|
|
82
|
+
? 'success'
|
|
83
|
+
: event.payload.status === 'error'
|
|
84
|
+
? 'error'
|
|
85
|
+
: 'incomplete';
|
|
86
|
+
if (event.payload.result)
|
|
87
|
+
resultText = event.payload.result;
|
|
88
|
+
resumeToken = event.payload.resumeToken;
|
|
89
|
+
}
|
|
56
90
|
}
|
|
57
91
|
}
|
|
92
|
+
finally {
|
|
93
|
+
watchdog.dispose();
|
|
94
|
+
}
|
|
95
|
+
// A real success that lands inside Cligent's post-abort drain wins over
|
|
96
|
+
// the stall verdict: the call did complete, and reporting a hang would
|
|
97
|
+
// discard a finished phase — the expensive false negative this watchdog
|
|
98
|
+
// exists to avoid causing. A genuine stall drains to `interrupted`, so
|
|
99
|
+
// this never softens a real hang.
|
|
100
|
+
if (watchdog.tripped && status !== 'success') {
|
|
101
|
+
return {
|
|
102
|
+
status: 'error',
|
|
103
|
+
text: `agent call stalled: no agent activity for ${formatElapsed(stallMs)}; ` +
|
|
104
|
+
'aborted by the stall watchdog (SLC_STALL_TIMEOUT / stallTimeout)',
|
|
105
|
+
...(resumeToken !== undefined ? { resumeToken } : {}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
58
108
|
return {
|
|
59
109
|
status,
|
|
60
110
|
text: (resultText || texts.join('\n')).trim(),
|
|
@@ -63,4 +113,49 @@ export function createCligentAgent(opts) {
|
|
|
63
113
|
},
|
|
64
114
|
};
|
|
65
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Builds the watchdog for one call: a call-local controller composed with the
|
|
118
|
+
* caller's signal, plus a single reset-on-activity timeout (DR-019). With a
|
|
119
|
+
* non-positive window the caller's signal passes through untouched.
|
|
120
|
+
*/
|
|
121
|
+
function createWatchdog(signal, stallMs, timers) {
|
|
122
|
+
if (stallMs <= 0) {
|
|
123
|
+
return {
|
|
124
|
+
signal,
|
|
125
|
+
touch: () => { },
|
|
126
|
+
tripped: false,
|
|
127
|
+
dispose: () => { },
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const controller = new AbortController();
|
|
131
|
+
let tripped = false;
|
|
132
|
+
let handle;
|
|
133
|
+
const onCallerAbort = () => controller.abort(signal.reason);
|
|
134
|
+
if (signal.aborted) {
|
|
135
|
+
controller.abort(signal.reason);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
signal.addEventListener('abort', onCallerAbort, { once: true });
|
|
139
|
+
}
|
|
140
|
+
const arm = () => timers.setTimeout(() => {
|
|
141
|
+
tripped = true;
|
|
142
|
+
controller.abort(new Error(`agent call stalled for ${formatElapsed(stallMs)}`));
|
|
143
|
+
}, stallMs);
|
|
144
|
+
handle = arm();
|
|
145
|
+
return {
|
|
146
|
+
signal: controller.signal,
|
|
147
|
+
touch: () => {
|
|
148
|
+
timers.clearTimeout(handle);
|
|
149
|
+
if (!tripped && !controller.signal.aborted)
|
|
150
|
+
handle = arm();
|
|
151
|
+
},
|
|
152
|
+
get tripped() {
|
|
153
|
+
return tripped;
|
|
154
|
+
},
|
|
155
|
+
dispose: () => {
|
|
156
|
+
timers.clearTimeout(handle);
|
|
157
|
+
signal.removeEventListener('abort', onCallerAbort);
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
66
161
|
//# sourceMappingURL=cligent-agent.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cligent-agent.js","sourceRoot":"","sources":["../src/cligent-agent.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,0EAA0E;AAE1E
|
|
1
|
+
{"version":3,"file":"cligent-agent.js","sourceRoot":"","sources":["../src/cligent-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,6 +32,12 @@ export declare function createCompiledExecutor(opts: {
|
|
|
32
32
|
cwd?: string;
|
|
33
33
|
/** Stable authored phase identity used as the Playbook session's playbook id. */
|
|
34
34
|
playbookId?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Live status sink (DR-019, PHEXEC-25): streams the runtime's human status
|
|
37
|
+
* and non-trace telemetry as it occurs; absent hosts keep the drained
|
|
38
|
+
* end-of-run diagnostics.
|
|
39
|
+
*/
|
|
40
|
+
onStatus?: (line: string) => void;
|
|
35
41
|
/** Session-id seam for deterministic tests; defaults to {@link randomUUID}. */
|
|
36
42
|
createSessionId?: () => string;
|
|
37
43
|
/** Exact pinned runtime boundary; defaults to the current legacy contract. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiled-executor.d.ts","sourceRoot":"","sources":["../src/compiled-executor.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAIV,aAAa,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAOpD,OAAO,EAKL,KAAK,gCAAgC,EAKrC,KAAK,sBAAsB,EAE5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEhF;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,gCAAgC,CAAC,CAW3C;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,MAAM,EAAE,eAAe,CAAC;IACxB,oEAAoE;IACpE,KAAK,EAAE,WAAW,CAAC;IACnB,sEAAsE;IACtE,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1C,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IAC/B,8EAA8E;IAC9E,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,CACZ,YAAY,EAAE,MAAM,KACjB,OAAO,CAAC,gCAAgC,CAAC,CAAC;CAChD,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"compiled-executor.d.ts","sourceRoot":"","sources":["../src/compiled-executor.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAIV,aAAa,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAOpD,OAAO,EAKL,KAAK,gCAAgC,EAKrC,KAAK,sBAAsB,EAE5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEhF;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,gCAAgC,CAAC,CAW3C;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,MAAM,EAAE,eAAe,CAAC;IACxB,oEAAoE;IACpE,KAAK,EAAE,WAAW,CAAC;IACnB,sEAAsE;IACtE,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1C,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,MAAM,CAAC;IAC/B,8EAA8E;IAC9E,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,CACZ,YAAY,EAAE,MAAM,KACjB,OAAO,CAAC,gCAAgC,CAAC,CAAC;CAChD,GAAG,aAAa,CAgEhB"}
|
|
@@ -70,6 +70,7 @@ export function createCompiledExecutor(opts) {
|
|
|
70
70
|
// transported prompt carries the request's absolute paths and
|
|
71
71
|
// write-scope rules (PHEXEC-34).
|
|
72
72
|
captainWorkspace: composeWorkspaceContract(input),
|
|
73
|
+
onStatus: opts.onStatus,
|
|
73
74
|
});
|
|
74
75
|
// Hand the runtime only Playbook's ports — never the host-only
|
|
75
76
|
// drainDiagnostics, nor a file capability (DR-005, PHEXEC-23).
|