@darkhorseprojects/circuitry 0.3.9 → 0.4.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/LICENSE +345 -276
- package/SPEC.md +96 -0
- package/dist/cli.js +132 -142
- package/dist/graph.d.ts +155 -156
- package/dist/index.js +144 -141
- package/dist/node.js +131 -145
- package/examples/agent.circuitry.yaml +24 -0
- package/examples/imports.circuitry.yaml +13 -0
- package/examples/minimal.circuitry.yaml +20 -0
- package/examples/run-resource.circuitry.yaml +24 -0
- package/package.json +5 -2
- package/schema.json +65 -0
package/dist/node.js
CHANGED
|
@@ -9,165 +9,142 @@ import YAML2 from "yaml";
|
|
|
9
9
|
|
|
10
10
|
// src/graph.ts
|
|
11
11
|
import YAML from "yaml";
|
|
12
|
-
var CIRCUITRY_SPEC_VERSION = "0.
|
|
13
|
-
var DEFAULT_CIRCUITRY_VALIDATION_RULES = [
|
|
14
|
-
"no-self-loops",
|
|
15
|
-
"no-unknown-edge-endpoints",
|
|
16
|
-
"require-executable-inputs",
|
|
17
|
-
"no-cycles"
|
|
18
|
-
];
|
|
12
|
+
var CIRCUITRY_SPEC_VERSION = "0.4";
|
|
19
13
|
var DEFAULT_CIRCUITRY_VALIDATION_STANDARD = {
|
|
20
14
|
version: CIRCUITRY_SPEC_VERSION,
|
|
21
|
-
requireSpecVersion: true
|
|
22
|
-
rules: DEFAULT_CIRCUITRY_VALIDATION_RULES,
|
|
23
|
-
executableKinds: ["agent", "tool", "output"]
|
|
15
|
+
requireSpecVersion: true
|
|
24
16
|
};
|
|
25
|
-
var
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
17
|
+
var createCircuitryValidationStandard = (standard = {}) => ({
|
|
18
|
+
version: standard.version || DEFAULT_CIRCUITRY_VALIDATION_STANDARD.version,
|
|
19
|
+
requireSpecVersion: standard.requireSpecVersion ?? DEFAULT_CIRCUITRY_VALIDATION_STANDARD.requireSpecVersion
|
|
20
|
+
});
|
|
21
|
+
var getResourceInputs = (resource) => {
|
|
22
|
+
const inputs = resource.inputs;
|
|
23
|
+
if (!inputs) return [];
|
|
24
|
+
if (Array.isArray(inputs)) return inputs.map((from) => ({ from, to: "" }));
|
|
25
|
+
return Object.entries(inputs).map(([name, from]) => ({ from, to: "", name }));
|
|
29
26
|
};
|
|
30
|
-
var
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (resource.type !== "text") throw new Error(`arg is not text: ${id}`);
|
|
36
|
-
next.resources[id] = { ...resource, value: runtimeInputToText(value) };
|
|
27
|
+
var resourceInputIds = (resource) => getResourceInputs(resource).map((dependency) => dependency.from);
|
|
28
|
+
var getCircuitryDependencies = (graph) => {
|
|
29
|
+
const dependencies = [];
|
|
30
|
+
for (const [to, resource] of Object.entries(graph.resources || {})) {
|
|
31
|
+
for (const dependency of getResourceInputs(resource)) dependencies.push({ ...dependency, to });
|
|
37
32
|
}
|
|
38
|
-
return
|
|
33
|
+
return dependencies;
|
|
39
34
|
};
|
|
40
|
-
var
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
var getCircuitryRunSet = (graph, entry = graph.entry) => {
|
|
36
|
+
if (!entry) return [];
|
|
37
|
+
const visited = /* @__PURE__ */ new Set();
|
|
38
|
+
const visit = (id) => {
|
|
39
|
+
if (visited.has(id)) return;
|
|
40
|
+
const resource = graph.resources?.[id];
|
|
41
|
+
if (!resource) return;
|
|
42
|
+
for (const input of resourceInputIds(resource)) visit(input);
|
|
43
|
+
visited.add(id);
|
|
49
44
|
};
|
|
45
|
+
visit(entry);
|
|
46
|
+
return [...visited];
|
|
50
47
|
};
|
|
51
|
-
var
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
48
|
+
var toposortCircuitryResources = (graph, entry) => {
|
|
49
|
+
const ids = entry ? new Set(getCircuitryRunSet(graph, entry)) : new Set(Object.keys(graph.resources || {}));
|
|
50
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
51
|
+
const visited = /* @__PURE__ */ new Set();
|
|
52
|
+
const ordered = [];
|
|
53
|
+
const visit = (id) => {
|
|
54
|
+
if (!ids.has(id) || visited.has(id)) return;
|
|
55
|
+
if (visiting.has(id)) throw new Error(`Circuitry resource dependency cycle at ${id}`);
|
|
56
|
+
visiting.add(id);
|
|
57
|
+
const resource = graph.resources?.[id];
|
|
58
|
+
if (resource) for (const input of resourceInputIds(resource)) visit(input);
|
|
59
|
+
visiting.delete(id);
|
|
60
|
+
visited.add(id);
|
|
61
|
+
ordered.push(id);
|
|
62
|
+
};
|
|
63
|
+
for (const id of ids) visit(id);
|
|
64
|
+
return ordered;
|
|
65
|
+
};
|
|
66
|
+
var runtimeInputToText = (value) => {
|
|
67
|
+
if (typeof value === "string") return value;
|
|
68
|
+
if (value === void 0) return "";
|
|
69
|
+
return YAML.stringify(value).trimEnd();
|
|
70
|
+
};
|
|
71
|
+
var resolveCircuitrySource = (graph) => {
|
|
72
|
+
const inputs = graph.inputs || graph.args || {};
|
|
73
|
+
const resources = { ...graph.resources || {} };
|
|
74
|
+
for (const [id, input] of Object.entries(inputs)) {
|
|
75
|
+
if (!resources[id]) {
|
|
76
|
+
resources[id] = {
|
|
77
|
+
type: "input",
|
|
78
|
+
from: id,
|
|
79
|
+
label: input.label,
|
|
80
|
+
description: input.description,
|
|
81
|
+
mime: input.mime || input.mimeType
|
|
82
|
+
};
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
|
-
return {
|
|
85
|
+
return { ...graph, circuitry: CIRCUITRY_SPEC_VERSION, imports: graph.imports || [], inputs, resources };
|
|
85
86
|
};
|
|
86
|
-
var
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
var applyCircuitryRuntimeInputs = (graph, inputs = {}) => {
|
|
88
|
+
const next = resolveCircuitrySource(graph);
|
|
89
|
+
const resources = { ...next.resources || {} };
|
|
90
|
+
for (const [id, value] of Object.entries(inputs)) {
|
|
91
|
+
const resource = resources[id];
|
|
92
|
+
if (!resource) throw new Error(`unknown input: ${id}`);
|
|
93
|
+
if (resource.type === "input") resources[id] = { ...resource, value, from: resource.from || id };
|
|
94
|
+
else resources[id] = { ...resource, value: runtimeInputToText(value) };
|
|
95
|
+
}
|
|
96
|
+
return { ...next, resources };
|
|
89
97
|
};
|
|
90
|
-
var
|
|
91
|
-
const
|
|
98
|
+
var validateCircuitrySource = (graph, standard = {}) => {
|
|
99
|
+
const resolvedStandard = createCircuitryValidationStandard(standard);
|
|
92
100
|
const errors = [];
|
|
93
101
|
const issue = (code, message = code, path2) => errors.push({ code, message, ...path2 ? { path: path2 } : {} });
|
|
94
|
-
if (!graph || typeof graph !== "object" || Array.isArray(graph))
|
|
102
|
+
if (!graph || typeof graph !== "object" || Array.isArray(graph)) {
|
|
103
|
+
return { ok: false, errors: [{ code: "invalid_graph", message: "invalid graph" }], standard: resolvedStandard };
|
|
104
|
+
}
|
|
95
105
|
const g = graph;
|
|
96
|
-
if (
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
issue("
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (!
|
|
117
|
-
}
|
|
118
|
-
const adjacency = /* @__PURE__ */ new Map();
|
|
119
|
-
const incoming = /* @__PURE__ */ new Map();
|
|
120
|
-
for (const id of ids) {
|
|
121
|
-
adjacency.set(id, []);
|
|
122
|
-
incoming.set(id, 0);
|
|
123
|
-
}
|
|
124
|
-
for (const [index, edge] of (normalized.edges || []).entries()) {
|
|
125
|
-
if (!edge.from || !edge.to) {
|
|
126
|
-
issue("missing_edge_endpoint", "missing edge endpoint", ["edges", index]);
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
if (rules.has("no-self-loops") && edge.from === edge.to) {
|
|
130
|
-
issue("self_loop", "self loop", ["edges", index]);
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
const ok = ids.has(edge.from) && ids.has(edge.to);
|
|
134
|
-
if (rules.has("no-unknown-edge-endpoints")) {
|
|
135
|
-
if (!ids.has(edge.from)) issue("unknown_edge_source", "unknown edge source", ["edges", index, "from"]);
|
|
136
|
-
if (!ids.has(edge.to)) issue("unknown_edge_target", "unknown edge target", ["edges", index, "to"]);
|
|
137
|
-
}
|
|
138
|
-
if (ok) {
|
|
139
|
-
adjacency.get(edge.from).push(edge.to);
|
|
140
|
-
incoming.set(edge.to, (incoming.get(edge.to) || 0) + 1);
|
|
141
|
-
}
|
|
106
|
+
if (resolvedStandard.requireSpecVersion && g.circuitry !== resolvedStandard.version) issue("invalid_version", "invalid version", ["circuitry"]);
|
|
107
|
+
if (!g.resources || Object.keys(g.resources).length === 0) issue("missing_resources", "missing resources", ["resources"]);
|
|
108
|
+
if (g.nodes) issue("forbidden_nodes", "forbidden nodes", ["nodes"]);
|
|
109
|
+
if (g.edges) issue("forbidden_edges", "forbidden edges", ["edges"]);
|
|
110
|
+
if (g.agents) issue("forbidden_agents", "forbidden agents", ["agents"]);
|
|
111
|
+
const resolved = resolveCircuitrySource(g);
|
|
112
|
+
const ids = new Set(Object.keys(resolved.resources || {}));
|
|
113
|
+
if (resolved.entry && !ids.has(resolved.entry)) issue("unknown_entry", "unknown entry", ["entry"]);
|
|
114
|
+
for (const [name, target] of Object.entries(resolved.entries || {})) {
|
|
115
|
+
if (!ids.has(target)) issue("unknown_entry", `unknown entry: ${name}`, ["entries", name]);
|
|
116
|
+
}
|
|
117
|
+
for (const [id, resource] of Object.entries(resolved.resources || {})) {
|
|
118
|
+
if (!resource.type) issue("missing_resource_type", "missing resource type", ["resources", id, "type"]);
|
|
119
|
+
for (const input of resourceInputIds(resource)) {
|
|
120
|
+
if (!ids.has(input)) issue("unknown_resource_input", `unknown resource input: ${input}`, ["resources", id, "inputs"]);
|
|
121
|
+
if (input === id) issue("self_input", "self input", ["resources", id, "inputs"]);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
for (const [name, output] of Object.entries(resolved.outputs || {})) {
|
|
125
|
+
const root = output.from.split(".")[0];
|
|
126
|
+
if (!ids.has(root)) issue("unknown_output_source", `unknown output source: ${output.from}`, ["outputs", name, "from"]);
|
|
142
127
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
128
|
+
try {
|
|
129
|
+
toposortCircuitryResources(resolved);
|
|
130
|
+
} catch {
|
|
131
|
+
issue("cycle", "cycle");
|
|
148
132
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
};
|
|
161
|
-
for (const id of ids) if (visit(id)) {
|
|
162
|
-
issue("cycle", "cycle");
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
133
|
+
return { ok: errors.length === 0, errors, standard: resolvedStandard };
|
|
134
|
+
};
|
|
135
|
+
var validateCircuitryGraphWithStandard = validateCircuitrySource;
|
|
136
|
+
var validateCircuitryExecutionGraphWithStandard = validateCircuitrySource;
|
|
137
|
+
var validateCircuitryGraph = (graph, standard = {}) => validateCircuitrySource(graph, standard).errors.map((error) => error.message);
|
|
138
|
+
var normalizeCircuitryGraph = (graph) => {
|
|
139
|
+
const resolved = resolveCircuitrySource(graph);
|
|
140
|
+
const nodes = [];
|
|
141
|
+
for (const [id, resource] of Object.entries(resolved.resources || {})) {
|
|
142
|
+
if (resource.type === "agent") nodes.push({ id, kind: "agent", label: resource.label || resource.identity || id, agent: { identity: resource.identity, model: resource.model, tools: resource.tools, instructions: resource.instructions, personality: resource.personality, context: resource.context }, skills: resource.skills, expect: resource.expect });
|
|
143
|
+
else nodes.push({ id, kind: resource.type === "tool" ? "tool" : "input", label: resource.label || id, input: { type: resource.type, value: typeof resource.value === "string" ? resource.value : void 0, uri: resource.uri || resource.path, mimeType: resource.mime || resource.mimeType, data: resource.data } });
|
|
165
144
|
}
|
|
166
|
-
|
|
145
|
+
const edges = getCircuitryDependencies(resolved).map(({ from, to }) => ({ from, to, kind: "dependency" }));
|
|
146
|
+
return { ...resolved, nodes, edges };
|
|
167
147
|
};
|
|
168
|
-
var validateCircuitryGraphWithStandard = (graph, standard = {}) => validateCircuitryGraphInternal(graph, standard, true);
|
|
169
|
-
var validateCircuitryExecutionGraphWithStandard = (graph, standard = {}) => validateCircuitryGraphInternal(graph, standard, false);
|
|
170
|
-
var validateCircuitryGraph = (graph, standard = {}) => validateCircuitryGraphWithStandard(graph, standard).errors.map((error) => error.message);
|
|
171
148
|
|
|
172
149
|
// src/yaml.ts
|
|
173
150
|
var parseYamlData = (text) => {
|
|
@@ -446,7 +423,7 @@ var runCircuitryGraphExecution = async ({
|
|
|
446
423
|
const executionGraph = buildCircuitryExecutionGraph(graph);
|
|
447
424
|
const runs = [];
|
|
448
425
|
const parallelism = Math.max(1, Math.floor(maxParallelRuns));
|
|
449
|
-
const defaultModel = graph.runtime?.model;
|
|
426
|
+
const defaultModel = typeof graph.runtime?.model === "string" ? graph.runtime.model : void 0;
|
|
450
427
|
const runOne = async (nodeId, outputs2) => {
|
|
451
428
|
const cycle = false;
|
|
452
429
|
const item = executionGraph.nodes.get(nodeId);
|
|
@@ -645,10 +622,19 @@ var runNodeWithPiSDK = async ({
|
|
|
645
622
|
}
|
|
646
623
|
};
|
|
647
624
|
var defaultFilename = "graph.circuitry.yaml";
|
|
648
|
-
var resourceInputs = (resource) =>
|
|
649
|
-
|
|
625
|
+
var resourceInputs = (resource) => {
|
|
626
|
+
if (!("inputs" in resource) || !resource.inputs) return [];
|
|
627
|
+
return Array.isArray(resource.inputs) ? resource.inputs : Object.values(resource.inputs);
|
|
628
|
+
};
|
|
629
|
+
var withResourceInputs = (resource, inputs) => {
|
|
630
|
+
if (!("inputs" in resource) || !resource.inputs) return resource;
|
|
631
|
+
if (Array.isArray(resource.inputs)) return { ...resource, inputs };
|
|
632
|
+
const inputMap = resource.inputs;
|
|
633
|
+
const names = Object.keys(inputMap);
|
|
634
|
+
return { ...resource, inputs: Object.fromEntries(names.map((name, index) => [name, inputs[index] || inputMap[name]])) };
|
|
635
|
+
};
|
|
650
636
|
var selectedImportResources = (imp, resources) => {
|
|
651
|
-
if (imp.resources === "*") return Object.fromEntries(Object.keys(resources).map((id) => [id, id]));
|
|
637
|
+
if (!imp.resources || imp.resources === "*") return Object.fromEntries(Object.keys(resources).map((id) => [id, id]));
|
|
652
638
|
if (Array.isArray(imp.resources)) return Object.fromEntries(imp.resources.map((id) => [id, id]));
|
|
653
639
|
return imp.resources;
|
|
654
640
|
};
|
|
@@ -686,7 +672,7 @@ var resolveCircuitryGraph = async (parsed, graphFile, text, standard, stack = []
|
|
|
686
672
|
resources[id] = resource;
|
|
687
673
|
origins[id] = graphFile;
|
|
688
674
|
}
|
|
689
|
-
const graph =
|
|
675
|
+
const graph = { ...parsed, circuitry: "0.4", imports: [], inputs: parsed.inputs || parsed.args || {}, resources };
|
|
690
676
|
if (stack.length === 0) {
|
|
691
677
|
const validation = validateCircuitryExecutionGraphWithStandard(graph, standard);
|
|
692
678
|
if (validation.errors.length) {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
circuitry: "0.4"
|
|
2
|
+
title: Agent with prompt input
|
|
3
|
+
inputs:
|
|
4
|
+
user_turn:
|
|
5
|
+
type: text
|
|
6
|
+
required: true
|
|
7
|
+
entry: assistant
|
|
8
|
+
resources:
|
|
9
|
+
user_turn:
|
|
10
|
+
type: input
|
|
11
|
+
from: user_turn
|
|
12
|
+
guide:
|
|
13
|
+
type: text
|
|
14
|
+
value: Be direct, accurate, and natural.
|
|
15
|
+
assistant:
|
|
16
|
+
type: agent
|
|
17
|
+
inputs: [guide, user_turn]
|
|
18
|
+
tools: [read, write, bash, run_graph]
|
|
19
|
+
instructions: Use the guide and answer the user.
|
|
20
|
+
expect:
|
|
21
|
+
response: str
|
|
22
|
+
outputs:
|
|
23
|
+
response:
|
|
24
|
+
from: assistant.response
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
circuitry: "0.4"
|
|
2
|
+
title: Imports and entries
|
|
3
|
+
imports:
|
|
4
|
+
- path: ./agent.circuitry.yaml
|
|
5
|
+
resources: "*"
|
|
6
|
+
prefix: imported_
|
|
7
|
+
entry: imported_assistant
|
|
8
|
+
entries:
|
|
9
|
+
default: imported_assistant
|
|
10
|
+
resources:
|
|
11
|
+
local_note:
|
|
12
|
+
type: text
|
|
13
|
+
value: Local resource.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
circuitry: "0.4"
|
|
2
|
+
title: Minimal
|
|
3
|
+
inputs:
|
|
4
|
+
user_turn:
|
|
5
|
+
type: text
|
|
6
|
+
required: true
|
|
7
|
+
entry: assistant
|
|
8
|
+
resources:
|
|
9
|
+
user_turn:
|
|
10
|
+
type: input
|
|
11
|
+
from: user_turn
|
|
12
|
+
assistant:
|
|
13
|
+
type: agent
|
|
14
|
+
inputs: [user_turn]
|
|
15
|
+
instructions: Answer the user.
|
|
16
|
+
expect:
|
|
17
|
+
response: str
|
|
18
|
+
outputs:
|
|
19
|
+
response:
|
|
20
|
+
from: assistant.response
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
circuitry: "0.4"
|
|
2
|
+
title: Run resource
|
|
3
|
+
inputs:
|
|
4
|
+
user_turn:
|
|
5
|
+
type: text
|
|
6
|
+
required: true
|
|
7
|
+
entry: assistant
|
|
8
|
+
resources:
|
|
9
|
+
user_turn:
|
|
10
|
+
type: input
|
|
11
|
+
from: user_turn
|
|
12
|
+
recovered_context:
|
|
13
|
+
type: run
|
|
14
|
+
graph: ./context-recovery.circuitry.yaml
|
|
15
|
+
entry: recovery
|
|
16
|
+
inputs:
|
|
17
|
+
user_turn: user_turn
|
|
18
|
+
assistant:
|
|
19
|
+
type: agent
|
|
20
|
+
inputs: [user_turn, recovered_context]
|
|
21
|
+
instructions: Answer with recovered context when useful.
|
|
22
|
+
outputs:
|
|
23
|
+
response:
|
|
24
|
+
from: assistant
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@darkhorseprojects/circuitry",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -17,9 +17,12 @@
|
|
|
17
17
|
"bin": {
|
|
18
18
|
"circuitry": "./dist/cli.js"
|
|
19
19
|
},
|
|
20
|
-
"license": "
|
|
20
|
+
"license": "MPL-2.0",
|
|
21
21
|
"files": [
|
|
22
22
|
"dist",
|
|
23
|
+
"SPEC.md",
|
|
24
|
+
"schema.json",
|
|
25
|
+
"examples",
|
|
23
26
|
"LICENSE"
|
|
24
27
|
],
|
|
25
28
|
"scripts": {
|
package/schema.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://darkhorseprojects.github.io/circuitry/schema/0.4/schema.json",
|
|
4
|
+
"title": "Circuitry 0.4",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["circuitry", "resources"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"circuitry": { "const": "0.4" },
|
|
9
|
+
"title": { "type": "string" },
|
|
10
|
+
"description": { "type": "string" },
|
|
11
|
+
"imports": { "type": "array" },
|
|
12
|
+
"inputs": { "type": "object" },
|
|
13
|
+
"entry": { "type": "string" },
|
|
14
|
+
"entries": { "type": "object", "additionalProperties": { "type": "string" } },
|
|
15
|
+
"resources": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"additionalProperties": { "$ref": "#/$defs/resource" }
|
|
18
|
+
},
|
|
19
|
+
"outputs": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"additionalProperties": { "$ref": "#/$defs/output" }
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"additionalProperties": true,
|
|
25
|
+
"$defs": {
|
|
26
|
+
"resource": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"required": ["type"],
|
|
29
|
+
"properties": {
|
|
30
|
+
"type": { "type": "string" },
|
|
31
|
+
"label": { "type": "string" },
|
|
32
|
+
"description": { "type": "string" },
|
|
33
|
+
"inputs": {
|
|
34
|
+
"oneOf": [
|
|
35
|
+
{ "type": "array", "items": { "type": "string" } },
|
|
36
|
+
{ "type": "object", "additionalProperties": { "type": "string" } }
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
"from": { "type": "string" },
|
|
40
|
+
"value": true,
|
|
41
|
+
"path": { "type": "string" },
|
|
42
|
+
"uri": { "type": "string" },
|
|
43
|
+
"mime": { "type": "string" },
|
|
44
|
+
"identity": { "type": "string" },
|
|
45
|
+
"instructions": { "type": "string" },
|
|
46
|
+
"tools": { "type": "array", "items": { "type": "string" } },
|
|
47
|
+
"graph": { "type": "string" },
|
|
48
|
+
"entry": { "type": "string" },
|
|
49
|
+
"expect": true
|
|
50
|
+
},
|
|
51
|
+
"additionalProperties": true
|
|
52
|
+
},
|
|
53
|
+
"output": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"required": ["from"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"from": { "type": "string" },
|
|
58
|
+
"type": { "type": "string" },
|
|
59
|
+
"mime": { "type": "string" },
|
|
60
|
+
"schema": true
|
|
61
|
+
},
|
|
62
|
+
"additionalProperties": true
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|