@barnum/barnum 0.0.0-main-45fcbab9 → 0.0.0-main-94079f39
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/artifacts/linux-arm64/barnum +0 -0
- package/artifacts/linux-x64/barnum +0 -0
- package/artifacts/macos-arm64/barnum +0 -0
- package/artifacts/macos-x64/barnum +0 -0
- package/artifacts/win-x64/barnum.exe +0 -0
- package/barnum-config-schema.json +4 -0
- package/barnum-config-schema.zod.ts +1 -0
- package/index.ts +5 -0
- package/package.json +4 -2
- package/run.ts +107 -4
- package/types.ts +19 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -89,6 +89,10 @@
|
|
|
89
89
|
"stepConfig": {
|
|
90
90
|
"description": "Step configuration passed through to the handler. Rust stores this as-is and includes it in the envelope.",
|
|
91
91
|
"default": null
|
|
92
|
+
},
|
|
93
|
+
"valueSchema": {
|
|
94
|
+
"description": "JSON Schema for this step's input value. Produced by JS from Zod. Used to validate transition values targeting this step.",
|
|
95
|
+
"default": null
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
98
|
}
|
|
@@ -10,6 +10,7 @@ const ActionKind = z.discriminatedUnion("kind", [
|
|
|
10
10
|
kind: z.literal("TypeScript"),
|
|
11
11
|
path: z.string().describe("Path to the handler file (absolute — JS layer resolves before passing to Rust)."),
|
|
12
12
|
stepConfig: z.any().optional().default(null).describe("Step configuration passed through to the handler. Rust stores this as-is and includes it in the envelope."),
|
|
13
|
+
valueSchema: z.any().optional().default(null).describe("JSON Schema for this step's input value. Produced by JS from Zod. Used to validate transition values targeting this step."),
|
|
13
14
|
}).describe("Run a TypeScript handler."),
|
|
14
15
|
]).describe("How a step processes tasks.");
|
|
15
16
|
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barnum/barnum",
|
|
3
|
-
"version": "0.0.0-main-
|
|
3
|
+
"version": "0.0.0-main-94079f39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Barnum CLI - workflow engine for agents.",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -40,13 +40,15 @@
|
|
|
40
40
|
"barnum-config-schema.zod.ts",
|
|
41
41
|
"barnum-cli-schema.zod.ts",
|
|
42
42
|
"run.ts",
|
|
43
|
+
"types.ts",
|
|
43
44
|
"actions/**/*.ts"
|
|
44
45
|
],
|
|
45
46
|
"scripts": {
|
|
46
47
|
"typecheck": "tsc --noEmit"
|
|
47
48
|
},
|
|
48
49
|
"dependencies": {
|
|
49
|
-
"zod": "^3.0.0"
|
|
50
|
+
"zod": "^3.0.0",
|
|
51
|
+
"zod-to-json-schema": "^3.25.1"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
54
|
"@types/node": "^25.5.0",
|
package/run.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { createRequire } from "node:module";
|
|
|
4
4
|
import { dirname, resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { configSchema } from "./barnum-config-schema.zod.js";
|
|
7
|
-
import
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
8
9
|
|
|
9
10
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
const require = createRequire(import.meta.url);
|
|
@@ -40,6 +41,67 @@ export interface RunOptions {
|
|
|
40
41
|
cwd?: string;
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
// ==================== Zod subset validation ====================
|
|
45
|
+
|
|
46
|
+
const UNSUPPORTED_ZOD_TYPES = new Set([
|
|
47
|
+
"ZodEffects", // .transform(), .refine(), .superRefine(), .preprocess()
|
|
48
|
+
"ZodPipeline", // .pipe()
|
|
49
|
+
"ZodBranded", // .brand()
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
function assertSerializableZod(schema: z.ZodType, stepName: string): void {
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
|
+
const def = (schema as any)._def;
|
|
55
|
+
if (!def) return;
|
|
56
|
+
|
|
57
|
+
const typeName: string | undefined = def.typeName;
|
|
58
|
+
|
|
59
|
+
if (typeName && UNSUPPORTED_ZOD_TYPES.has(typeName)) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`Step "${stepName}": Zod schema uses unsupported type "${typeName}". ` +
|
|
62
|
+
`Only JSON-Schema-representable types are allowed. ` +
|
|
63
|
+
`Remove .transform(), .refine(), .preprocess(), .pipe(), or .brand().`,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Recurse into compound types
|
|
68
|
+
if (def.innerType) assertSerializableZod(def.innerType, stepName);
|
|
69
|
+
if (def.schema) assertSerializableZod(def.schema, stepName);
|
|
70
|
+
if (def.left) assertSerializableZod(def.left, stepName);
|
|
71
|
+
if (def.right) assertSerializableZod(def.right, stepName);
|
|
72
|
+
|
|
73
|
+
// z.object() — check each value
|
|
74
|
+
if (def.shape) {
|
|
75
|
+
const shape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
76
|
+
for (const value of Object.values(shape)) {
|
|
77
|
+
assertSerializableZod(value as z.ZodType, stepName);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// z.array(), z.set()
|
|
82
|
+
if (def.type) assertSerializableZod(def.type, stepName);
|
|
83
|
+
|
|
84
|
+
// z.union(), z.discriminatedUnion()
|
|
85
|
+
if (def.options) {
|
|
86
|
+
for (const option of def.options) {
|
|
87
|
+
assertSerializableZod(option as z.ZodType, stepName);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// z.tuple()
|
|
92
|
+
if (def.items) {
|
|
93
|
+
for (const item of def.items) {
|
|
94
|
+
assertSerializableZod(item as z.ZodType, stepName);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// z.record()
|
|
99
|
+
if (def.keyType) assertSerializableZod(def.keyType, stepName);
|
|
100
|
+
if (def.valueType) assertSerializableZod(def.valueType, stepName);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ==================== BarnumConfig ====================
|
|
104
|
+
|
|
43
105
|
export class BarnumConfig {
|
|
44
106
|
private readonly config: z.output<typeof configSchema>;
|
|
45
107
|
|
|
@@ -51,11 +113,52 @@ export class BarnumConfig {
|
|
|
51
113
|
return new BarnumConfig(configSchema.parse(config));
|
|
52
114
|
}
|
|
53
115
|
|
|
54
|
-
|
|
116
|
+
private async resolveConfig(): Promise<z.output<typeof configSchema>> {
|
|
117
|
+
const config = structuredClone(this.config);
|
|
118
|
+
|
|
119
|
+
for (const step of config.steps) {
|
|
120
|
+
if (step.action.kind !== "TypeScript") continue;
|
|
121
|
+
const action = step.action;
|
|
122
|
+
|
|
123
|
+
// Import the handler module
|
|
124
|
+
const mod = await import(action.path);
|
|
125
|
+
const handler = mod[action.exportedAs ?? "default"];
|
|
126
|
+
|
|
127
|
+
if (!handler?.stepConfigValidator || !handler?.getStepValueValidator) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
`Step "${step.name}": handler at "${action.path}" is missing required ` +
|
|
130
|
+
`"stepConfigValidator" or "getStepValueValidator". ` +
|
|
131
|
+
`See HandlerDefinition interface.`,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Validate step config
|
|
136
|
+
const parsedStepConfig = handler.stepConfigValidator.parse(
|
|
137
|
+
action.stepConfig ?? {},
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// Get value validator
|
|
141
|
+
const valueValidator = handler.getStepValueValidator(parsedStepConfig);
|
|
142
|
+
|
|
143
|
+
// Reject non-serializable Zod features
|
|
144
|
+
assertSerializableZod(valueValidator, step.name);
|
|
145
|
+
|
|
146
|
+
// Convert Zod → JSON Schema and embed in config
|
|
147
|
+
action.valueSchema = zodToJsonSchema(valueValidator, {
|
|
148
|
+
target: "jsonSchema7",
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return config;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async run(opts?: RunOptions): Promise<ChildProcess> {
|
|
156
|
+
const config = await this.resolveConfig();
|
|
55
157
|
const args = opts?.resumeFrom
|
|
56
158
|
? ["run", "--resume-from", opts.resumeFrom]
|
|
57
|
-
: ["run", "--config", JSON.stringify(
|
|
58
|
-
if (opts?.entrypointValue)
|
|
159
|
+
: ["run", "--config", JSON.stringify(config)];
|
|
160
|
+
if (opts?.entrypointValue)
|
|
161
|
+
args.push("--entrypoint-value", opts.entrypointValue);
|
|
59
162
|
if (opts?.logLevel) args.push("--log-level", opts.logLevel);
|
|
60
163
|
if (opts?.logFile) args.push("--log-file", opts.logFile);
|
|
61
164
|
if (opts?.stateLog) args.push("--state-log", opts.stateLog);
|
package/types.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export interface HandlerDefinition<C = unknown, V = unknown> {
|
|
4
|
+
stepConfigValidator: z.ZodType<C>;
|
|
5
|
+
getStepValueValidator: (stepConfig: C) => z.ZodType<V>;
|
|
6
|
+
handle: (context: HandlerContext<C, V>) => Promise<FollowUpTask[]>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface HandlerContext<C, V> {
|
|
10
|
+
stepConfig: C;
|
|
11
|
+
value: V;
|
|
12
|
+
config: unknown;
|
|
13
|
+
stepName: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface FollowUpTask {
|
|
17
|
+
kind: string;
|
|
18
|
+
value: unknown;
|
|
19
|
+
}
|