pi-extensible-workflows 2.0.0 → 3.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.
@@ -0,0 +1,128 @@
1
+ import { ERROR_CODES, LAUNCH_SNAPSHOT_IDENTITY_VERSION, WorkflowError } from "./types.js";
2
+ export function object(value) { return typeof value === "object" && value !== null && !Array.isArray(value); }
3
+ export { object as isObject };
4
+ export function jsonValue(value, seen = new Set()) {
5
+ if (value === null || typeof value === "boolean" || typeof value === "string")
6
+ return true;
7
+ if (typeof value === "number")
8
+ return Number.isFinite(value);
9
+ if (typeof value !== "object" || seen.has(value))
10
+ return false;
11
+ if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
12
+ return false;
13
+ const keys = Reflect.ownKeys(value);
14
+ if (keys.some((key) => typeof key !== "string"))
15
+ return false;
16
+ seen.add(value);
17
+ const valid = (Array.isArray(value) ? Array.from(value) : keys.map((key) => value[key])).every((item) => jsonValue(item, seen));
18
+ seen.delete(value);
19
+ return valid;
20
+ }
21
+ export function jsonObject(value) { return jsonValue(value) && object(value); }
22
+ export function positiveInteger(value) { return Number.isInteger(value) && value > 0; }
23
+ export function deepFreeze(value) {
24
+ if (typeof value === "object" && value !== null && !Object.isFrozen(value)) {
25
+ Object.freeze(value);
26
+ for (const child of Object.values(value))
27
+ deepFreeze(child);
28
+ }
29
+ return value;
30
+ }
31
+ export function errorText(error) { return error && typeof error === "object" && typeof error.message === "string" ? error.message : error instanceof Error ? error.message : String(error); }
32
+ export function errorCode(error) {
33
+ if (error instanceof WorkflowError)
34
+ return ERROR_CODES.includes(error.code) ? error.code : undefined;
35
+ if (!error || typeof error !== "object")
36
+ return undefined;
37
+ const code = error.code;
38
+ return typeof code === "string" && ERROR_CODES.includes(code) ? code : undefined;
39
+ }
40
+ const WORKFLOW_AUTHORED_ERROR = Symbol("workflowAuthoredError");
41
+ export function markWorkflowAuthored(error, authored = false) {
42
+ if (authored)
43
+ Object.defineProperty(error, WORKFLOW_AUTHORED_ERROR, { value: true });
44
+ return error;
45
+ }
46
+ export function isWorkflowAuthored(error) { return Boolean(error && typeof error === "object" && WORKFLOW_AUTHORED_ERROR in error); }
47
+ export function asWorkflowError(error) {
48
+ const code = errorCode(error);
49
+ return markWorkflowAuthored(error instanceof WorkflowError && code ? error : new WorkflowError(code ?? "INTERNAL_ERROR", errorText(error)), isWorkflowAuthored(error) || !code);
50
+ }
51
+ export function fail(code, message) { throw new WorkflowError(code, message); }
52
+ const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
53
+ const MODEL_ALIAS_NAME = /^[A-Za-z][A-Za-z0-9_-]*$/;
54
+ export function parseThinking(value) { return typeof value === "string" && THINKING_LEVELS.includes(value) ? value : undefined; }
55
+ export function parseModelReference(value) {
56
+ const match = /^([^/:\s]+)\/([^:\s]+)(?::([^:\s]+))?$/.exec(value);
57
+ if (!match?.[1] || !match[2])
58
+ fail("UNKNOWN_MODEL", `Invalid model spec: ${value}`);
59
+ const thinking = match[3];
60
+ if (thinking && !THINKING_LEVELS.includes(thinking))
61
+ fail("UNKNOWN_MODEL", `Invalid thinking level: ${thinking}`);
62
+ return { provider: match[1], model: match[2], ...(thinking ? { thinking: thinking } : {}) };
63
+ }
64
+ function aliasError(message, settingsPath) { fail("CONFIG_ERROR", `${message} (settings: ${settingsPath})`); }
65
+ export function modelAliasName(value, aliases) {
66
+ const name = /^([^/:\s]+)(?::[^:\s]+)?$/.exec(value)?.[1];
67
+ return name && Object.prototype.hasOwnProperty.call(aliases, name) ? name : undefined;
68
+ }
69
+ export function validateModelAliases(value, settingsPath = "workflow settings") {
70
+ if (!object(value))
71
+ aliasError("modelAliases must be an object", settingsPath);
72
+ const aliases = {};
73
+ for (const [name, target] of Object.entries(value)) {
74
+ if (!MODEL_ALIAS_NAME.test(name))
75
+ aliasError(`Invalid model alias name: ${name}`, settingsPath);
76
+ if (typeof target !== "string" || !target.trim())
77
+ aliasError(`Invalid model alias target for ${name}`, settingsPath);
78
+ aliases[name] = target;
79
+ }
80
+ for (const name of Object.keys(aliases)) {
81
+ try {
82
+ resolveModelReference(name, aliases);
83
+ }
84
+ catch (error) {
85
+ aliasError(`Invalid model alias target for ${name}: ${errorText(error)}`, settingsPath);
86
+ }
87
+ }
88
+ return Object.freeze(aliases);
89
+ }
90
+ export function unknownModel(value, target, settingsPath) {
91
+ const resolved = target ? ` resolved to ${target}` : "";
92
+ const path = settingsPath ? ` (settings: ${settingsPath})` : "";
93
+ fail("UNKNOWN_MODEL", `Unknown model${target ? " alias" : ""} ${value}${resolved}${path}`);
94
+ }
95
+ export function resolveModelReference(value, aliases = {}, knownModels, settingsPath) {
96
+ const resolveReference = (reference, chain) => {
97
+ if (reference.includes("/"))
98
+ return parseModelReference(reference);
99
+ const match = /^([^:\s]+)(?::([^:\s]+))?$/.exec(reference);
100
+ const thinking = match?.[2];
101
+ if (!match?.[1] || thinking && !THINKING_LEVELS.includes(thinking))
102
+ unknownModel(reference, undefined, settingsPath);
103
+ const alias = modelAliasName(reference, aliases);
104
+ if (alias) {
105
+ if (chain.includes(alias))
106
+ fail("UNKNOWN_MODEL", `Circular model alias: ${[...chain, alias].join(" -> ")}${settingsPath ? ` (settings: ${settingsPath})` : ""}`);
107
+ const parsed = resolveReference(aliases[alias], [...chain, alias]);
108
+ return thinking ? { ...parsed, thinking: thinking } : parsed;
109
+ }
110
+ const candidates = [...(knownModels ?? [])].filter((model) => model.slice(model.indexOf("/") + 1) === match[1]);
111
+ if (candidates.length === 1) {
112
+ const parsed = parseModelReference(candidates[0]);
113
+ return thinking ? { ...parsed, thinking: thinking } : parsed;
114
+ }
115
+ unknownModel(reference, undefined, settingsPath);
116
+ };
117
+ return resolveReference(value, []);
118
+ }
119
+ export function modelCapability(value, aliases, knownModels, settingsPath) {
120
+ const parsed = typeof value === "string" ? resolveModelReference(value, aliases, knownModels, settingsPath) : value;
121
+ return `${parsed.provider}/${parsed.model}`;
122
+ }
123
+ export function aliasDrift(previous, current) {
124
+ return [...new Set([...Object.keys(previous), ...Object.keys(current)])].sort().flatMap((name) => previous[name] === current[name] ? [] : [`${name}: ${previous[name] ?? "(missing)"} -> ${current[name] ?? "(missing)"}`]);
125
+ }
126
+ export function mergeAgentResourceExclusions(...values) { return { skills: [...new Set(values.flatMap((value) => value?.skills ?? []))], extensions: [...new Set(values.flatMap((value) => value?.extensions ?? []))] }; }
127
+ export function createLaunchSnapshot(input) { return deepFreeze(structuredClone({ ...input, launchKind: input.launchKind ?? (input.functionName ? "function" : "inline"), identityVersion: input.identityVersion ?? LAUNCH_SNAPSHOT_IDENTITY_VERSION })); }
128
+ export function loadLaunchSnapshot(input) { return deepFreeze(structuredClone(input)); }
@@ -0,0 +1,24 @@
1
+ import type { AgentDefinition, AgentResourcePolicy, CheckpointInput, JsonSchema, JsonValue, LaunchSnapshot, PreflightCapabilities, PreflightResult, ShellOptions, StaticWorkflowCall, ValidatedWorkflowLaunch, WorkflowMetadata, WorkflowSettings, WorkflowValidationContext, WorkflowValidationParameters } from "./types.js";
2
+ import type { WorkflowRegistryApi } from "./registry.js";
3
+ export declare const DEFAULT_SETTINGS: Readonly<WorkflowSettings>;
4
+ export declare function validateCheckpoint(value: unknown): CheckpointInput;
5
+ export declare function workflowSettingsPath(agentDir?: string): string;
6
+ export declare function workflowProjectSettingsPath(cwd: string): string;
7
+ export declare function loadSettings(path?: string): Readonly<WorkflowSettings>;
8
+ export declare function resolveAgentResourcePolicy(cwd: string, projectTrusted: boolean, globalSettingsPath?: string): AgentResourcePolicy;
9
+ export declare function saveModelAliases(path?: string, aliases?: Readonly<Record<string, string>>): void;
10
+ export declare function parseRoleMarkdown(content: string, strict?: boolean, rolePath?: string): AgentDefinition;
11
+ export declare function workflowRoleDirectories(agentDir?: string): readonly string[];
12
+ export declare function loadAgentDefinitions(cwd: string, agentDir?: string, projectTrusted?: boolean): Readonly<Record<string, AgentDefinition>>;
13
+ export declare function instrumentWorkflow(script: string): string;
14
+ export declare function workflowPrompt(template: string, values: Readonly<Record<string, JsonValue>>): string;
15
+ export declare function validateSchema(schema: unknown, at?: string): asserts schema is JsonSchema;
16
+ export declare function validateAgentOptions(value: unknown): Readonly<Record<string, JsonValue>>;
17
+ export declare function validateShellOptions(value: unknown): ShellOptions;
18
+ export declare function validateShellCommand(value: unknown): string;
19
+ export declare function inspectWorkflowScript(script: string): StaticWorkflowCall[];
20
+ export declare function preflight(script: string, capabilities: PreflightCapabilities, schemas?: readonly unknown[], metadata?: WorkflowMetadata, compatibility?: boolean): PreflightResult;
21
+ export declare function validateWorkflowLaunch(params: WorkflowValidationParameters, context: WorkflowValidationContext, registry?: WorkflowRegistryApi): ValidatedWorkflowLaunch;
22
+ export declare function validateWorkflowLaunchWithRegistry(params: WorkflowValidationParameters, context: WorkflowValidationContext, registry?: WorkflowRegistryApi): ValidatedWorkflowLaunch;
23
+ export declare function launchScriptForSnapshot(snapshot: Readonly<LaunchSnapshot>, registry: WorkflowRegistryApi): string;
24
+ export { createLaunchSnapshot, loadLaunchSnapshot } from "./utils.js";