@boardwalk-labs/workflow 0.1.1 → 0.1.3
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 +1 -1
- package/dist/events.js +1 -0
- package/dist/extract.js +37 -0
- package/dist/host.js +1 -11
- package/dist/index.d.ts +17 -10
- package/dist/index.js +7 -11
- package/dist/manifest.js +1 -0
- package/dist/meta.js +1 -7
- package/dist/runtime.js +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ A workflow is **a script**: the `meta` export is a **pure literal** (engines der
|
|
|
27
27
|
|
|
28
28
|
| Import | What it is |
|
|
29
29
|
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
30
|
-
| `@boardwalk-labs/workflow` | The author API: `agent()`, `sleep()`, `workflows.call()`, `secrets.get()`, `artifacts.write()`, `parallel()`, `input` / `output()` / `config`, `
|
|
30
|
+
| `@boardwalk-labs/workflow` | The author API: `agent()`, `sleep()`, `workflows.call()`, `secrets.get()`, `artifacts.write()`, `parallel()`, `input` / `output()` / `config`, `phase()` — plus the manifest schema and run-event wire format |
|
|
31
31
|
| `@boardwalk-labs/workflow/runtime` | The **engine-facing** API: install a `WorkflowHost` before evaluating a program. Authors never import this |
|
|
32
32
|
| `@boardwalk-labs/workflow/extract` | Static `meta` → manifest extraction (AST-based, never executes the program). Used by engines and tooling |
|
|
33
33
|
|
package/dist/events.js
CHANGED
package/dist/extract.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
1
2
|
// @boardwalk-labs/workflow/extract — static extraction of a workflow program's `meta` → manifest.
|
|
2
3
|
//
|
|
3
4
|
// A workflow is a TS/JS program file whose `export const meta = { … }` is a PURE LITERAL.
|
|
@@ -36,6 +37,13 @@ const DEFAULT_FILE_NAME = "index.ts";
|
|
|
36
37
|
export function extractMetaLiteral(source, options = {}) {
|
|
37
38
|
const fileName = options.fileName ?? DEFAULT_FILE_NAME;
|
|
38
39
|
const sf = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, /*setParentNodes*/ true);
|
|
40
|
+
// A syntax error otherwise falls through to "No `meta` declaration found" (the parser produced no
|
|
41
|
+
// usable `meta` node) — misleading. Report the real syntax error, with position, first.
|
|
42
|
+
const syntaxError = firstSyntaxError(sf);
|
|
43
|
+
if (syntaxError !== undefined) {
|
|
44
|
+
const text = ts.flattenDiagnosticMessageText(syntaxError.messageText, "\n");
|
|
45
|
+
throw failAt(`syntax error: ${text}`, sf, syntaxError.start);
|
|
46
|
+
}
|
|
39
47
|
const initializer = findMetaInitializer(sf);
|
|
40
48
|
if (initializer === null) {
|
|
41
49
|
throw fail("No `meta` declaration found — a workflow program must export a pure-literal " +
|
|
@@ -190,3 +198,32 @@ function fail(message, node, sf) {
|
|
|
190
198
|
}
|
|
191
199
|
return new MetaExtractionError(message);
|
|
192
200
|
}
|
|
201
|
+
/** Like {@link fail}, but positioned at a raw source offset (a diagnostic's `start`). */
|
|
202
|
+
function failAt(message, sf, start) {
|
|
203
|
+
if (start === undefined)
|
|
204
|
+
return new MetaExtractionError(message);
|
|
205
|
+
const { line, character } = sf.getLineAndCharacterOfPosition(start);
|
|
206
|
+
return new MetaExtractionError(`${sf.fileName}:${String(line + 1)}:${String(character + 1)} — ${message}`);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* The first syntax error TS recorded while parsing, or undefined. The parser stores these on the
|
|
210
|
+
* source file's `parseDiagnostics` (an internal field), so read it through `Reflect` + a runtime
|
|
211
|
+
* guard rather than a cast — a future TS that drops/renames it simply yields "no error".
|
|
212
|
+
*/
|
|
213
|
+
function firstSyntaxError(sf) {
|
|
214
|
+
const raw = Reflect.get(sf, "parseDiagnostics");
|
|
215
|
+
if (!Array.isArray(raw))
|
|
216
|
+
return undefined;
|
|
217
|
+
for (const d of raw) {
|
|
218
|
+
if (isErrorDiagnostic(d))
|
|
219
|
+
return d;
|
|
220
|
+
}
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
function isErrorDiagnostic(d) {
|
|
224
|
+
return (typeof d === "object" &&
|
|
225
|
+
d !== null &&
|
|
226
|
+
"messageText" in d &&
|
|
227
|
+
"category" in d &&
|
|
228
|
+
d.category === ts.DiagnosticCategory.Error);
|
|
229
|
+
}
|
package/dist/host.js
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// `@boardwalk-labs/workflow` is a host-backed package: the hooks authors import (agent, sleep,
|
|
4
|
-
// workflows.call, secrets.get, input) are thin facades over a `WorkflowHost` the *engine*
|
|
5
|
-
// installs at runtime. hosted Boardwalk installs its hosted adapter; the local engine installs
|
|
6
|
-
// one backed by the developer's environment. The author's program is identical either way —
|
|
7
|
-
// explicit hooks instead of injected globals.
|
|
8
|
-
//
|
|
9
|
-
// State is a module-level singleton. Node ESM caches a module by resolved path, so the
|
|
10
|
-
// program (which imports the hooks) and the engine (which installs the host) share ONE
|
|
11
|
-
// instance of this module and therefore one host + one `input`.
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
12
2
|
let currentHost = null;
|
|
13
3
|
/**
|
|
14
4
|
* The trigger payload for the current run, exposed to the program as
|
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
|
-
import type { AgentOptions, ArtifactBody, ArtifactRef, CallOptions, JsonValue, PhaseOptions, SleepArg } from "./types.js";
|
|
1
|
+
import type { AgentOptions, ArtifactBody, ArtifactRef, CallOptions, JsonSchema, JsonValue, PhaseOptions, SleepArg } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Mark the current run phase for live-tail and run-log grouping. Everything after this call
|
|
4
|
-
* belongs to the named phase until the next `
|
|
4
|
+
* belongs to the named phase until the next `phase(...)` marker or the run ends. This is
|
|
5
5
|
* observability-only; it does not checkpoint or skip code on restart.
|
|
6
6
|
*/
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function phase(name: string, opts?: PhaseOptions): void;
|
|
8
8
|
/**
|
|
9
|
-
* Run an agent leaf to completion.
|
|
10
|
-
* (`
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
9
|
+
* Run an agent leaf to completion. Two typed forms, by whether you pass a `schema`:
|
|
10
|
+
* - `agent(prompt, opts?)` (no `schema`) → the leaf's final text (`Promise<string>`).
|
|
11
|
+
* - `agent<Shape>(prompt, { schema })` → the schema-validated object (`Promise<Shape>`); name the
|
|
12
|
+
* expected type. The run fails if the model's output doesn't validate.
|
|
13
|
+
*
|
|
14
|
+
* Asking for a typed result WITHOUT a schema (`agent<Shape>(prompt)`) is a type error: there would
|
|
15
|
+
* be nothing to validate against, so the value would really be a string. Omit `opts.model` to let
|
|
16
|
+
* the provider route automatically (the default `boardwalk` provider on every engine; your own keys
|
|
17
|
+
* only via an explicit provider). Capabilities (`tools`, `mcp`, `skills`, `memory`) are PER-AGENT —
|
|
18
|
+
* each call brings its own; the manifest declares none of them.
|
|
15
19
|
*/
|
|
16
|
-
export declare function agent<T
|
|
20
|
+
export declare function agent<T>(prompt: string, opts: AgentOptions & {
|
|
21
|
+
schema: JsonSchema;
|
|
22
|
+
}): Promise<T>;
|
|
23
|
+
export declare function agent(prompt: string, opts?: AgentOptions): Promise<string>;
|
|
17
24
|
/** Cross-workflow composition: `call` (await the result) and `run` (fire-and-forget). */
|
|
18
25
|
export declare const workflows: {
|
|
19
26
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
1
2
|
// @boardwalk-labs/workflow — the author-facing API a workflow program imports.
|
|
2
3
|
//
|
|
3
4
|
// import { agent, workflows, sleep, secrets, input, type WorkflowMeta } from "@boardwalk-labs/workflow"
|
|
@@ -13,25 +14,20 @@
|
|
|
13
14
|
import { requireHost, recordOutput } from "./host.js";
|
|
14
15
|
/**
|
|
15
16
|
* Mark the current run phase for live-tail and run-log grouping. Everything after this call
|
|
16
|
-
* belongs to the named phase until the next `
|
|
17
|
+
* belongs to the named phase until the next `phase(...)` marker or the run ends. This is
|
|
17
18
|
* observability-only; it does not checkpoint or skip code on restart.
|
|
18
19
|
*/
|
|
19
|
-
export function
|
|
20
|
+
export function phase(name, opts) {
|
|
20
21
|
const host = requireHost();
|
|
21
22
|
if (host.setPhase === undefined) {
|
|
22
|
-
throw new Error("
|
|
23
|
+
throw new Error("phase is not supported by the installed engine");
|
|
23
24
|
}
|
|
24
25
|
host.setPhase(name, opts);
|
|
25
26
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Run an agent leaf to completion. Without `opts.schema`, resolves to the leaf's final text
|
|
28
|
-
* (`T` defaults to `string`); with a schema, resolves to the validated object — pass the
|
|
29
|
-
* expected type, e.g. `await agent<Groups>(prompt, { schema })`. Omit `opts.model` to let the
|
|
30
|
-
* provider route automatically (the default `boardwalk` provider on every engine; your own
|
|
31
|
-
* keys only via an explicit provider). Capabilities (`tools`, `mcp`, `skills`, `memory`) are
|
|
32
|
-
* PER-AGENT — each call brings its own; the manifest declares none of them.
|
|
33
|
-
*/
|
|
34
27
|
export async function agent(prompt, opts) {
|
|
28
|
+
// The host returns `unknown`; the overloads above are the public contract. With a `schema` the
|
|
29
|
+
// host validated the value (best-effort; the run fails on mismatch) → `T`; without one it is the
|
|
30
|
+
// leaf's final text → `string` (the `T = string` default). The cast is confined to this boundary.
|
|
35
31
|
return (await requireHost().agent(prompt, opts));
|
|
36
32
|
}
|
|
37
33
|
/** Cross-workflow composition: `call` (await the result) and `run` (fire-and-forget). */
|
package/dist/manifest.js
CHANGED
package/dist/meta.js
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// A workflow program declares `export const meta = { … } satisfies WorkflowMeta`. The
|
|
4
|
-
// `satisfies` operator is type-only and erased at compile time, so it does NOT break the
|
|
5
|
-
// pure-literal static extraction engines perform over the source (see extract.ts). This type
|
|
6
|
-
// is the author-facing typing; `workflowManifestSchema` (manifest.ts) is the validator of
|
|
7
|
-
// record — the two are kept faithful to each other.
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
8
2
|
export {};
|
package/dist/runtime.js
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -97,7 +97,7 @@ export type SleepArg = number | {
|
|
|
97
97
|
} | {
|
|
98
98
|
until: string | Date;
|
|
99
99
|
};
|
|
100
|
-
/** Options for {@link import("./index.js").
|
|
100
|
+
/** Options for {@link import("./index.js").phase}, the run-timeline marker. */
|
|
101
101
|
export interface PhaseOptions {
|
|
102
102
|
/**
|
|
103
103
|
* Optional stable identifier for the phase. Omit for the engine to assign one in marker order.
|
package/dist/types.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
//
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
2
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@boardwalk-labs/workflow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Author Boardwalk workflows in TypeScript: agent(), sleep(), workflows.call(), secrets, the manifest schema, and the run-event wire format.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"lint": "eslint . --max-warnings 0",
|
|
38
38
|
"format": "prettier --write .",
|
|
39
39
|
"format:check": "prettier --check .",
|
|
40
|
-
"test": "vitest run",
|
|
40
|
+
"test": "vitest run --coverage",
|
|
41
41
|
"test:watch": "vitest"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@eslint/js": "^9.18.0",
|
|
49
49
|
"@types/node": "^24.0.0",
|
|
50
|
+
"@vitest/coverage-v8": "^3.2.6",
|
|
50
51
|
"eslint": "^9.18.0",
|
|
51
52
|
"prettier": "^3.4.0",
|
|
52
53
|
"typescript-eslint": "^8.20.0",
|