@darkhorseprojects/circuitry 0.2.99 → 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/dist/graph.d.ts +11 -8
- package/dist/index.js +10 -7
- package/dist/node.d.ts +3 -5
- package/dist/node.js +39 -49
- package/package.json +1 -1
package/dist/graph.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const CIRCUITRY_SPEC_VERSION: "0.
|
|
1
|
+
export declare const CIRCUITRY_SPEC_VERSION: "0.3.0";
|
|
2
2
|
export type CircuitrySpecVersion = typeof CIRCUITRY_SPEC_VERSION | "0.2";
|
|
3
3
|
export type CircuitryNodeKind = "agent" | "input" | "tool" | "output" | string;
|
|
4
4
|
export type CircuitryEdgeKind = "context" | "dependency" | "message" | "control" | string;
|
|
@@ -170,20 +170,23 @@ export type CircuitryRuntimeInputs = Record<string, unknown>;
|
|
|
170
170
|
* graph source stable and catches misspelled input names before execution.
|
|
171
171
|
*/
|
|
172
172
|
export declare const applyCircuitryRuntimeInputs: (graph: CircuitryGraph, inputs?: CircuitryRuntimeInputs) => CircuitryGraph;
|
|
173
|
-
|
|
173
|
+
/** Import declaration for bringing resources from another graph file. */
|
|
174
|
+
export type CircuitryImport = {
|
|
174
175
|
/** Path to another .circuitry.yaml/.json file, resolved relative to this file. */
|
|
175
176
|
path: string;
|
|
176
|
-
/**
|
|
177
|
-
|
|
177
|
+
/** Resource id to import from the source file. */
|
|
178
|
+
resource: string;
|
|
179
|
+
/** Optional local name (alias) for the imported resource. */
|
|
180
|
+
as?: string;
|
|
178
181
|
};
|
|
179
182
|
export type CircuitryGraph = {
|
|
180
|
-
/** Spec version. Use "0.
|
|
183
|
+
/** Spec version. Use "0.3.0" for import-based graph files. */
|
|
181
184
|
circuitry: CircuitrySpecVersion | string;
|
|
182
185
|
id?: string;
|
|
183
186
|
title?: string;
|
|
184
187
|
description?: string;
|
|
185
|
-
/**
|
|
186
|
-
|
|
188
|
+
/** Explicit imports of specific resources from other graph files. */
|
|
189
|
+
imports?: CircuitryImport[];
|
|
187
190
|
resources?: Record<string, CircuitryResourceEntry>;
|
|
188
191
|
/** Internal normalized execution nodes. Authored graph files must not set this. */
|
|
189
192
|
nodes?: CircuitryNode[];
|
|
@@ -223,7 +226,7 @@ export type CircuitryValidationResult = {
|
|
|
223
226
|
};
|
|
224
227
|
export declare const DEFAULT_CIRCUITRY_VALIDATION_RULES: CircuitryValidationRuleEntry[];
|
|
225
228
|
export declare const DEFAULT_CIRCUITRY_VALIDATION_STANDARD: {
|
|
226
|
-
readonly version: "0.
|
|
229
|
+
readonly version: "0.3.0";
|
|
227
230
|
readonly requireSpecVersion: true;
|
|
228
231
|
readonly rules: CircuitryValidationRuleEntry[];
|
|
229
232
|
readonly executableKinds: ["agent", "tool", "output"];
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ var isNodeElement = (element) => {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
// src/graph.ts
|
|
30
|
-
var CIRCUITRY_SPEC_VERSION = "0.
|
|
30
|
+
var CIRCUITRY_SPEC_VERSION = "0.3.0";
|
|
31
31
|
var runtimeInputToText = (value) => {
|
|
32
32
|
if (typeof value === "string") return value;
|
|
33
33
|
if (value === void 0) return "";
|
|
@@ -136,7 +136,7 @@ var normalizeCircuitryGraph = (graph) => {
|
|
|
136
136
|
const { nodes, edges } = expandResources(graph.resources);
|
|
137
137
|
return { ...graph, nodes, edges };
|
|
138
138
|
};
|
|
139
|
-
var VALID_SPEC_VERSIONS = /* @__PURE__ */ new Set(["0.
|
|
139
|
+
var VALID_SPEC_VERSIONS = /* @__PURE__ */ new Set(["0.3"]);
|
|
140
140
|
var validateCircuitryGraphInternal = (graph, standard = {}, options) => {
|
|
141
141
|
const resolvedStandard = createCircuitryValidationStandard(
|
|
142
142
|
standard,
|
|
@@ -160,19 +160,22 @@ var validateCircuitryGraphInternal = (graph, standard = {}, options) => {
|
|
|
160
160
|
}
|
|
161
161
|
if (options.sourceFormat) {
|
|
162
162
|
if (!graphObject.resources || Object.keys(graphObject.resources).length === 0) {
|
|
163
|
-
addError("missing_resources", "Circuitry v0.
|
|
163
|
+
addError("missing_resources", "Circuitry v0.3 graphs must use a resources: section", ["resources"]);
|
|
164
164
|
}
|
|
165
165
|
if (graphObject.agents && Object.keys(graphObject.agents).length > 0) {
|
|
166
|
-
addError("forbidden_agents", "Circuitry v0.
|
|
166
|
+
addError("forbidden_agents", "Circuitry v0.3 graph files must not use top-level agents:; use resources:", ["agents"]);
|
|
167
167
|
}
|
|
168
168
|
if (graphObject.inputs && Object.keys(graphObject.inputs).length > 0) {
|
|
169
|
-
addError("forbidden_inputs", "Circuitry v0.
|
|
169
|
+
addError("forbidden_inputs", "Circuitry v0.3 graph files must not use top-level inputs:; use resources:", ["inputs"]);
|
|
170
170
|
}
|
|
171
171
|
if (graphObject.nodes && graphObject.nodes.length > 0) {
|
|
172
|
-
addError("forbidden_nodes", "Circuitry v0.
|
|
172
|
+
addError("forbidden_nodes", "Circuitry v0.3 graph files must not use top-level nodes:; use resources:", ["nodes"]);
|
|
173
173
|
}
|
|
174
174
|
if (graphObject.edges && graphObject.edges.length > 0) {
|
|
175
|
-
addError("forbidden_edges", "Circuitry v0.
|
|
175
|
+
addError("forbidden_edges", "Circuitry v0.3 graph files must not use top-level edges:; use resource inputs:", ["edges"]);
|
|
176
|
+
}
|
|
177
|
+
if (graphObject.links && graphObject.links.length > 0) {
|
|
178
|
+
addError("forbidden_links", "Circuitry v0.3 graph files must use imports: instead of links:", ["links"]);
|
|
176
179
|
}
|
|
177
180
|
}
|
|
178
181
|
const normalized = normalizeCircuitryGraph(graphObject);
|
package/dist/node.d.ts
CHANGED
|
@@ -8,11 +8,9 @@ export declare class NodeCircuitryHost implements CircuitryHost {
|
|
|
8
8
|
private exists;
|
|
9
9
|
private parseIssue;
|
|
10
10
|
private parseGraphForValidation;
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
private
|
|
14
|
-
private mergeResources;
|
|
15
|
-
private resolveGraphLinks;
|
|
11
|
+
private resolveGraphImports;
|
|
12
|
+
/** Rewrite inputs in imported resource to use aliased resource ids. */
|
|
13
|
+
private rewriteImportInputs;
|
|
16
14
|
private parseAndResolveGraph;
|
|
17
15
|
private readGraphFile;
|
|
18
16
|
readGraph(input?: {
|
package/dist/node.js
CHANGED
|
@@ -8,7 +8,7 @@ import os from "node:os";
|
|
|
8
8
|
import YAML from "yaml";
|
|
9
9
|
|
|
10
10
|
// src/graph.ts
|
|
11
|
-
var CIRCUITRY_SPEC_VERSION = "0.
|
|
11
|
+
var CIRCUITRY_SPEC_VERSION = "0.3.0";
|
|
12
12
|
var runtimeInputToText = (value) => {
|
|
13
13
|
if (typeof value === "string") return value;
|
|
14
14
|
if (value === void 0) return "";
|
|
@@ -117,7 +117,7 @@ var normalizeCircuitryGraph = (graph) => {
|
|
|
117
117
|
const { nodes, edges } = expandResources(graph.resources);
|
|
118
118
|
return { ...graph, nodes, edges };
|
|
119
119
|
};
|
|
120
|
-
var VALID_SPEC_VERSIONS = /* @__PURE__ */ new Set(["0.
|
|
120
|
+
var VALID_SPEC_VERSIONS = /* @__PURE__ */ new Set(["0.3"]);
|
|
121
121
|
var validateCircuitryGraphInternal = (graph, standard = {}, options) => {
|
|
122
122
|
const resolvedStandard = createCircuitryValidationStandard(
|
|
123
123
|
standard,
|
|
@@ -141,19 +141,22 @@ var validateCircuitryGraphInternal = (graph, standard = {}, options) => {
|
|
|
141
141
|
}
|
|
142
142
|
if (options.sourceFormat) {
|
|
143
143
|
if (!graphObject.resources || Object.keys(graphObject.resources).length === 0) {
|
|
144
|
-
addError("missing_resources", "Circuitry v0.
|
|
144
|
+
addError("missing_resources", "Circuitry v0.3 graphs must use a resources: section", ["resources"]);
|
|
145
145
|
}
|
|
146
146
|
if (graphObject.agents && Object.keys(graphObject.agents).length > 0) {
|
|
147
|
-
addError("forbidden_agents", "Circuitry v0.
|
|
147
|
+
addError("forbidden_agents", "Circuitry v0.3 graph files must not use top-level agents:; use resources:", ["agents"]);
|
|
148
148
|
}
|
|
149
149
|
if (graphObject.inputs && Object.keys(graphObject.inputs).length > 0) {
|
|
150
|
-
addError("forbidden_inputs", "Circuitry v0.
|
|
150
|
+
addError("forbidden_inputs", "Circuitry v0.3 graph files must not use top-level inputs:; use resources:", ["inputs"]);
|
|
151
151
|
}
|
|
152
152
|
if (graphObject.nodes && graphObject.nodes.length > 0) {
|
|
153
|
-
addError("forbidden_nodes", "Circuitry v0.
|
|
153
|
+
addError("forbidden_nodes", "Circuitry v0.3 graph files must not use top-level nodes:; use resources:", ["nodes"]);
|
|
154
154
|
}
|
|
155
155
|
if (graphObject.edges && graphObject.edges.length > 0) {
|
|
156
|
-
addError("forbidden_edges", "Circuitry v0.
|
|
156
|
+
addError("forbidden_edges", "Circuitry v0.3 graph files must not use top-level edges:; use resource inputs:", ["edges"]);
|
|
157
|
+
}
|
|
158
|
+
if (graphObject.links && graphObject.links.length > 0) {
|
|
159
|
+
addError("forbidden_links", "Circuitry v0.3 graph files must use imports: instead of links:", ["links"]);
|
|
157
160
|
}
|
|
158
161
|
}
|
|
159
162
|
const normalized = normalizeCircuitryGraph(graphObject);
|
|
@@ -837,66 +840,53 @@ var NodeCircuitryHost = class {
|
|
|
837
840
|
return { error: this.parseIssue(error, filename) };
|
|
838
841
|
}
|
|
839
842
|
}
|
|
840
|
-
|
|
841
|
-
return typeof link === "string" ? link : link.path;
|
|
842
|
-
}
|
|
843
|
-
linkPrefix(link) {
|
|
844
|
-
return typeof link === "string" ? "" : link.prefix || "";
|
|
845
|
-
}
|
|
846
|
-
prefixResourceIds(resources, prefix) {
|
|
847
|
-
if (!prefix) return resources;
|
|
848
|
-
const ids = new Set(Object.keys(resources));
|
|
849
|
-
const prefixed = {};
|
|
850
|
-
for (const [id, resource] of Object.entries(resources)) {
|
|
851
|
-
const next = { ...resource };
|
|
852
|
-
if ((next.type === "agent" || next.type === "tool") && next.inputs) {
|
|
853
|
-
next.inputs = next.inputs.map((input) => ids.has(input) ? `${prefix}${input}` : input);
|
|
854
|
-
}
|
|
855
|
-
prefixed[`${prefix}${id}`] = next;
|
|
856
|
-
}
|
|
857
|
-
return prefixed;
|
|
858
|
-
}
|
|
859
|
-
mergeResources(target, source, fromFile) {
|
|
860
|
-
for (const [id, resource] of Object.entries(source)) {
|
|
861
|
-
if (target[id]) {
|
|
862
|
-
throw new Error(`Linked Circuitry resource id collision: ${id} from ${fromFile}`);
|
|
863
|
-
}
|
|
864
|
-
target[id] = resource;
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
async resolveGraphLinks(graph, filename, standard, stack = []) {
|
|
843
|
+
async resolveGraphImports(graph, filename, standard, stack = []) {
|
|
868
844
|
const graphFile = path.resolve(filename);
|
|
869
845
|
if (stack.includes(graphFile)) {
|
|
870
|
-
throw new Error(`Circuitry graph
|
|
846
|
+
throw new Error(`Circuitry graph import cycle: ${[...stack, graphFile].join(" -> ")}`);
|
|
871
847
|
}
|
|
872
|
-
const
|
|
848
|
+
const importedResources = {};
|
|
849
|
+
const aliasMap = {};
|
|
873
850
|
const nextStack = [...stack, graphFile];
|
|
874
|
-
for (const
|
|
875
|
-
const
|
|
876
|
-
if (!rawPath) throw new Error(`Circuitry graph link is missing path in ${graphFile}`);
|
|
877
|
-
const linkedFile = path.resolve(path.dirname(graphFile), rawPath);
|
|
851
|
+
for (const imp of graph.imports || []) {
|
|
852
|
+
const linkedFile = path.resolve(path.dirname(graphFile), imp.path);
|
|
878
853
|
const linkedText = await readFile(linkedFile, "utf8");
|
|
879
854
|
const parsed = parseCircuitryText(linkedText, linkedFile, standard, { validate: false });
|
|
880
|
-
const resolved = await this.
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
855
|
+
const resolved = await this.resolveGraphImports(parsed, linkedFile, standard, nextStack);
|
|
856
|
+
const resourceId = imp.resource;
|
|
857
|
+
const resource = resolved.resources?.[resourceId];
|
|
858
|
+
if (!resource) {
|
|
859
|
+
throw new Error(`Imported resource not found: ${resourceId} in ${imp.path}`);
|
|
860
|
+
}
|
|
861
|
+
const localId = imp.as || resourceId;
|
|
862
|
+
if (importedResources[localId]) {
|
|
863
|
+
throw new Error(`Imported Circuitry resource id collision: ${localId} from ${imp.path}`);
|
|
864
|
+
}
|
|
865
|
+
if (imp.as) aliasMap[resourceId] = localId;
|
|
866
|
+
const resourceWithRewrittenInputs = this.rewriteImportInputs(resource, aliasMap);
|
|
867
|
+
importedResources[localId] = resourceWithRewrittenInputs;
|
|
886
868
|
}
|
|
887
869
|
return {
|
|
888
870
|
...graph,
|
|
889
871
|
resources: {
|
|
890
|
-
...
|
|
872
|
+
...importedResources,
|
|
891
873
|
...graph.resources || {}
|
|
892
874
|
}
|
|
893
875
|
};
|
|
894
876
|
}
|
|
877
|
+
/** Rewrite inputs in imported resource to use aliased resource ids. */
|
|
878
|
+
rewriteImportInputs(resource, aliasMap) {
|
|
879
|
+
if (resource.type === "agent" || resource.type === "tool") {
|
|
880
|
+
const newInputs = (resource.inputs || []).map((input) => aliasMap[input] || input);
|
|
881
|
+
return { ...resource, inputs: newInputs };
|
|
882
|
+
}
|
|
883
|
+
return resource;
|
|
884
|
+
}
|
|
895
885
|
async parseAndResolveGraph(text, filename, standard) {
|
|
896
886
|
const parsed = this.parseGraphForValidation(text, filename, standard);
|
|
897
887
|
if (!parsed.graph) return parsed;
|
|
898
888
|
try {
|
|
899
|
-
return { graph: await this.
|
|
889
|
+
return { graph: await this.resolveGraphImports(parsed.graph, filename, standard) };
|
|
900
890
|
} catch (error) {
|
|
901
891
|
return { error: this.parseIssue(error, filename) };
|
|
902
892
|
}
|