@darkhorseprojects/circuitry 0.2.33 → 0.2.99

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 CHANGED
@@ -1,5 +1,5 @@
1
- export declare const CIRCUITRY_SPEC_VERSION: "0.2";
2
- export type CircuitrySpecVersion = typeof CIRCUITRY_SPEC_VERSION;
1
+ export declare const CIRCUITRY_SPEC_VERSION: "0.2.99";
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;
5
5
  export type CircuitryInputKind = "text" | "file" | "url" | "image" | "uri" | "canvas" | "mcp" | string;
@@ -170,12 +170,20 @@ 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
+ export type CircuitryGraphLink = string | {
174
+ /** Path to another .circuitry.yaml/.json file, resolved relative to this file. */
175
+ path: string;
176
+ /** Optional id prefix applied to imported resources. */
177
+ prefix?: string;
178
+ };
173
179
  export type CircuitryGraph = {
174
- /** Spec version. Use "0.2" for new graphs. */
180
+ /** Spec version. Use "0.2.99" for linked graph files. */
175
181
  circuitry: CircuitrySpecVersion | string;
176
182
  id?: string;
177
183
  title?: string;
178
184
  description?: string;
185
+ /** Files whose resources are merged into this graph before validation/execution. */
186
+ links?: CircuitryGraphLink[];
179
187
  resources?: Record<string, CircuitryResourceEntry>;
180
188
  /** Internal normalized execution nodes. Authored graph files must not set this. */
181
189
  nodes?: CircuitryNode[];
@@ -215,7 +223,7 @@ export type CircuitryValidationResult = {
215
223
  };
216
224
  export declare const DEFAULT_CIRCUITRY_VALIDATION_RULES: CircuitryValidationRuleEntry[];
217
225
  export declare const DEFAULT_CIRCUITRY_VALIDATION_STANDARD: {
218
- readonly version: "0.2";
226
+ readonly version: "0.2.99";
219
227
  readonly requireSpecVersion: true;
220
228
  readonly rules: CircuitryValidationRuleEntry[];
221
229
  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.2";
30
+ var CIRCUITRY_SPEC_VERSION = "0.2.99";
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([CIRCUITRY_SPEC_VERSION]);
139
+ var VALID_SPEC_VERSIONS = /* @__PURE__ */ new Set(["0.2", CIRCUITRY_SPEC_VERSION]);
140
140
  var validateCircuitryGraphInternal = (graph, standard = {}, options) => {
141
141
  const resolvedStandard = createCircuitryValidationStandard(
142
142
  standard,
package/dist/node.d.ts CHANGED
@@ -8,6 +8,12 @@ export declare class NodeCircuitryHost implements CircuitryHost {
8
8
  private exists;
9
9
  private parseIssue;
10
10
  private parseGraphForValidation;
11
+ private linkPath;
12
+ private linkPrefix;
13
+ private prefixResourceIds;
14
+ private mergeResources;
15
+ private resolveGraphLinks;
16
+ private parseAndResolveGraph;
11
17
  private readGraphFile;
12
18
  readGraph(input?: {
13
19
  filename?: string;
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.2";
11
+ var CIRCUITRY_SPEC_VERSION = "0.2.99";
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([CIRCUITRY_SPEC_VERSION]);
120
+ var VALID_SPEC_VERSIONS = /* @__PURE__ */ new Set(["0.2", CIRCUITRY_SPEC_VERSION]);
121
121
  var validateCircuitryGraphInternal = (graph, standard = {}, options) => {
122
122
  const resolvedStandard = createCircuitryValidationStandard(
123
123
  standard,
@@ -837,11 +837,84 @@ var NodeCircuitryHost = class {
837
837
  return { error: this.parseIssue(error, filename) };
838
838
  }
839
839
  }
840
+ linkPath(link) {
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 = []) {
868
+ const graphFile = path.resolve(filename);
869
+ if (stack.includes(graphFile)) {
870
+ throw new Error(`Circuitry graph link cycle: ${[...stack, graphFile].join(" -> ")}`);
871
+ }
872
+ const linkedResources = {};
873
+ const nextStack = [...stack, graphFile];
874
+ for (const link of graph.links || []) {
875
+ const rawPath = this.linkPath(link);
876
+ if (!rawPath) throw new Error(`Circuitry graph link is missing path in ${graphFile}`);
877
+ const linkedFile = path.resolve(path.dirname(graphFile), rawPath);
878
+ const linkedText = await readFile(linkedFile, "utf8");
879
+ const parsed = parseCircuitryText(linkedText, linkedFile, standard, { validate: false });
880
+ const resolved = await this.resolveGraphLinks(parsed, linkedFile, standard, nextStack);
881
+ this.mergeResources(
882
+ linkedResources,
883
+ this.prefixResourceIds(resolved.resources || {}, this.linkPrefix(link)),
884
+ linkedFile
885
+ );
886
+ }
887
+ return {
888
+ ...graph,
889
+ resources: {
890
+ ...linkedResources,
891
+ ...graph.resources || {}
892
+ }
893
+ };
894
+ }
895
+ async parseAndResolveGraph(text, filename, standard) {
896
+ const parsed = this.parseGraphForValidation(text, filename, standard);
897
+ if (!parsed.graph) return parsed;
898
+ try {
899
+ return { graph: await this.resolveGraphLinks(parsed.graph, filename, standard) };
900
+ } catch (error) {
901
+ return { error: this.parseIssue(error, filename) };
902
+ }
903
+ }
840
904
  async readGraphFile(filename) {
841
905
  const graphFile = this.resolveGraphFile(filename);
842
906
  const text = await readFile(graphFile, "utf8");
843
- const graph = parseCircuitryText(text, graphFile);
844
- return { graphFile, text, graph };
907
+ const parsed = await this.parseAndResolveGraph(text, graphFile);
908
+ if (!parsed.graph) throw new Error(`Invalid Circuitry graph:
909
+ ${parsed.error?.message}`);
910
+ const validation = validateCircuitryGraphWithStandard(parsed.graph);
911
+ if (validation.errors.length) {
912
+ throw new Error(
913
+ `Invalid Circuitry graph:
914
+ ${validation.errors.map((e) => e.message).join("\n")}`
915
+ );
916
+ }
917
+ return { graphFile, text, graph: normalizeCircuitryGraph(parsed.graph) };
845
918
  }
846
919
  async readGraph(input = {}) {
847
920
  const { graphFile, text, graph } = await this.readGraphFile(input.filename);
@@ -853,8 +926,8 @@ var NodeCircuitryHost = class {
853
926
  if (input.graph)
854
927
  return validateCircuitryGraphWithStandard(input.graph, input.standard);
855
928
  const filename = input.filename || defaultFilename;
856
- const parsed = this.parseGraphForValidation(input.text, filename, input.standard);
857
- if (parsed.error) {
929
+ const parsed = await this.parseAndResolveGraph(input.text, filename, input.standard);
930
+ if ("error" in parsed) {
858
931
  return {
859
932
  ok: false,
860
933
  errors: [parsed.error],
@@ -865,7 +938,7 @@ var NodeCircuitryHost = class {
865
938
  }
866
939
  async writeGraph(input) {
867
940
  const graphFile = this.resolveGraphFile(input.filename);
868
- const parsed = input.graph ? { graph: input.graph } : this.parseGraphForValidation(
941
+ const parsed = input.graph ? { graph: input.graph } : await this.parseAndResolveGraph(
869
942
  input.text,
870
943
  input.filename || graphFile,
871
944
  input.standard
@@ -896,7 +969,7 @@ ${validation.errors.map((e) => e.message).join("\n")}`
896
969
  async runGraph(input = {}) {
897
970
  const source = input.source || (input.text ? "text" : "current");
898
971
  const graphFile = this.resolveGraphFile(input.filename);
899
- const parsed = source === "text" ? this.parseGraphForValidation(
972
+ const parsed = source === "text" ? await this.parseAndResolveGraph(
900
973
  input.text,
901
974
  input.filename || graphFile,
902
975
  input.standard
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkhorseprojects/circuitry",
3
- "version": "0.2.33",
3
+ "version": "0.2.99",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",