@parcha/agentrun-pi 0.1.0-beta.1
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 +202 -0
- package/NOTICE +2 -0
- package/README.md +209 -0
- package/dist/admission.d.ts +6 -0
- package/dist/admission.js +51 -0
- package/dist/author.d.ts +21 -0
- package/dist/author.js +72 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +68 -0
- package/dist/demo-data.d.ts +361 -0
- package/dist/demo-data.js +386 -0
- package/dist/demo.d.ts +13 -0
- package/dist/demo.js +44 -0
- package/dist/extension-service.d.ts +110 -0
- package/dist/extension-service.js +477 -0
- package/dist/extension.d.ts +41 -0
- package/dist/extension.js +419 -0
- package/dist/host-session.d.ts +5 -0
- package/dist/host-session.js +80 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/presentation.d.ts +4 -0
- package/dist/presentation.js +34 -0
- package/dist/runner.d.ts +12 -0
- package/dist/runner.js +256 -0
- package/dist/skill-bundle.d.ts +5 -0
- package/dist/skill-bundle.js +15 -0
- package/dist/tool-input-error.d.ts +10 -0
- package/dist/tool-input-error.js +40 -0
- package/dist/types.d.ts +119 -0
- package/dist/types.js +1 -0
- package/package.json +73 -0
- package/skills/author/SKILL.md +102 -0
- package/skills/author/examples/evidence-gate.input.json +6 -0
- package/skills/author/examples/evidence-gate.json +125 -0
- package/skills/author/examples/read-file.input.json +1 -0
- package/skills/author/examples/read-file.json +44 -0
- package/skills/author/examples/read-source-decision.input.json +4 -0
- package/skills/author/examples/read-source-decision.json +37 -0
- package/skills/author/examples/release-note.txt +10 -0
- package/skills/author/examples/review-release-notes.input.json +6 -0
- package/skills/author/examples/review-release-notes.json +123 -0
- package/skills/author/references/jev-decisions.md +112 -0
- package/skills/author/references/sdk-authoring.md +16 -0
- package/skills/author/references/workflow-format.md +145 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
{
|
|
2
|
+
"v": 2,
|
|
3
|
+
"name": "fictional-evidence-gate",
|
|
4
|
+
"schemas": {
|
|
5
|
+
"Record": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"claim",
|
|
10
|
+
"evidence"
|
|
11
|
+
],
|
|
12
|
+
"properties": {
|
|
13
|
+
"claim": {
|
|
14
|
+
"type": "string"
|
|
15
|
+
},
|
|
16
|
+
"evidence": {
|
|
17
|
+
"type": "string"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"Input": {
|
|
22
|
+
"type": "object",
|
|
23
|
+
"additionalProperties": false,
|
|
24
|
+
"required": [
|
|
25
|
+
"record"
|
|
26
|
+
],
|
|
27
|
+
"properties": {
|
|
28
|
+
"record": {
|
|
29
|
+
"$ref": "#/definitions/Record"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"Questions": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"additionalProperties": false,
|
|
36
|
+
"required": [
|
|
37
|
+
"supported"
|
|
38
|
+
],
|
|
39
|
+
"properties": {
|
|
40
|
+
"supported": {
|
|
41
|
+
"type": "boolean",
|
|
42
|
+
"description": "Does the supplied evidence explicitly support every factual detail in the claim, without adding assumptions or contradicting it?"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"Gate": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"additionalProperties": false,
|
|
49
|
+
"required": [
|
|
50
|
+
"accepted"
|
|
51
|
+
],
|
|
52
|
+
"properties": {
|
|
53
|
+
"accepted": {
|
|
54
|
+
"type": "boolean"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"Result": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"additionalProperties": false,
|
|
61
|
+
"required": [
|
|
62
|
+
"record",
|
|
63
|
+
"accepted"
|
|
64
|
+
],
|
|
65
|
+
"properties": {
|
|
66
|
+
"record": {
|
|
67
|
+
"$ref": "#/definitions/Record"
|
|
68
|
+
},
|
|
69
|
+
"accepted": {
|
|
70
|
+
"type": "boolean"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"input": {
|
|
76
|
+
"schemaId": "Input"
|
|
77
|
+
},
|
|
78
|
+
"output": {
|
|
79
|
+
"schemaId": "Result",
|
|
80
|
+
"path": "result"
|
|
81
|
+
},
|
|
82
|
+
"root": {
|
|
83
|
+
"node": "chain",
|
|
84
|
+
"steps": [
|
|
85
|
+
{
|
|
86
|
+
"node": "code",
|
|
87
|
+
"label": "retain-record",
|
|
88
|
+
"code": "(s) => ({ original: s.record })"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"node": "judge",
|
|
92
|
+
"label": "check-evidence",
|
|
93
|
+
"state": {
|
|
94
|
+
"record": "{original}"
|
|
95
|
+
},
|
|
96
|
+
"out": "Questions",
|
|
97
|
+
"as": "check"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"node": "code",
|
|
101
|
+
"label": "probability-gate",
|
|
102
|
+
"code": "(s) => { const p = s['check$answers']?.answers?.supported?.noul; return { accepted: typeof p === 'number' && Number.isFinite(p) && p >= 0.90 && p <= 1 }; }",
|
|
103
|
+
"as": "gate"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"node": "escalate",
|
|
107
|
+
"label": "request-better-evidence",
|
|
108
|
+
"when": {
|
|
109
|
+
"predicate": "field_equals",
|
|
110
|
+
"path": "gate.accepted",
|
|
111
|
+
"value": false
|
|
112
|
+
},
|
|
113
|
+
"kind": "needs_evidence",
|
|
114
|
+
"stage": "verification",
|
|
115
|
+
"summary": "Evidence did not meet the required yes-probability threshold."
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"node": "code",
|
|
119
|
+
"label": "assemble-result",
|
|
120
|
+
"code": "(s) => ({ record: s.original, accepted: s.gate.accepted })",
|
|
121
|
+
"as": "result"
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "path": "README.md" }
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"v": 2,
|
|
3
|
+
"name": "read-file",
|
|
4
|
+
"schemas": {
|
|
5
|
+
"Input": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": { "path": { "type": "string", "minLength": 1 } },
|
|
8
|
+
"required": ["path"],
|
|
9
|
+
"additionalProperties": false
|
|
10
|
+
},
|
|
11
|
+
"ToolResult": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"properties": {
|
|
14
|
+
"content": {
|
|
15
|
+
"type": "array",
|
|
16
|
+
"items": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"properties": {
|
|
19
|
+
"type": { "type": "string", "enum": ["text", "image"] },
|
|
20
|
+
"text": { "type": "string" },
|
|
21
|
+
"data": { "type": "string" },
|
|
22
|
+
"mimeType": { "type": "string" }
|
|
23
|
+
},
|
|
24
|
+
"required": ["type"]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"details": {}
|
|
28
|
+
},
|
|
29
|
+
"required": ["content"]
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"input": { "schemaId": "Input" },
|
|
33
|
+
"output": { "schemaId": "ToolResult", "path": "file" },
|
|
34
|
+
"root": {
|
|
35
|
+
"node": "call",
|
|
36
|
+
"label": "read-file",
|
|
37
|
+
"via": "tool",
|
|
38
|
+
"tool": "read",
|
|
39
|
+
"args": { "path": "{path}" },
|
|
40
|
+
"out": "ToolResult",
|
|
41
|
+
"as": "file",
|
|
42
|
+
"deadline_s": 10
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"v": 2,
|
|
3
|
+
"name": "fictional-read-source-decision",
|
|
4
|
+
"schemas": {
|
|
5
|
+
"Input": { "type": "object", "properties": {
|
|
6
|
+
"question": { "type": "string", "minLength": 1 },
|
|
7
|
+
"paths": { "type": "array", "items": { "type": "string", "minLength": 1 } }
|
|
8
|
+
}, "required": ["question", "paths"], "additionalProperties": false },
|
|
9
|
+
"ToolResult": { "type": "object", "properties": {
|
|
10
|
+
"content": { "type": "array", "items": { "type": "object", "properties": {
|
|
11
|
+
"type": { "const": "text" }, "text": { "type": "string" }
|
|
12
|
+
}, "required": ["type", "text"] } }, "details": {}
|
|
13
|
+
}, "required": ["content"] },
|
|
14
|
+
"Questions": { "type": "object", "properties": {
|
|
15
|
+
"matches": { "type": "boolean", "description": "Does the original source text satisfy the condition asked in question, taking account of its headings, scope and exclusions rather than keyword overlap?" }
|
|
16
|
+
}, "required": ["matches"], "additionalProperties": false },
|
|
17
|
+
"Results": { "type": "array", "items": { "type": "object", "properties": {
|
|
18
|
+
"path": { "type": "string" }, "source": { "$ref": "#/definitions/ToolResult" },
|
|
19
|
+
"probability": { "type": "number", "minimum": 0, "maximum": 1 }
|
|
20
|
+
}, "required": ["path", "source", "probability"], "additionalProperties": false } }
|
|
21
|
+
},
|
|
22
|
+
"input": { "schemaId": "Input" },
|
|
23
|
+
"output": { "schemaId": "Results", "path": "results" },
|
|
24
|
+
"root": {
|
|
25
|
+
"node": "map", "label": "read-and-judge-originals", "itemsPath": "paths", "maxConcurrency": 2,
|
|
26
|
+
"as": "results", "resultPath": "record",
|
|
27
|
+
"body": { "node": "chain", "steps": [
|
|
28
|
+
{ "node": "call", "label": "read-original", "via": "tool", "tool": "read",
|
|
29
|
+
"args": { "path": "{item}" }, "out": "ToolResult", "as": "source", "deadline_s": 30 },
|
|
30
|
+
{ "node": "judge", "label": "source-membership", "state": {
|
|
31
|
+
"question": "{question}", "source": "{source}"
|
|
32
|
+
}, "out": "Questions", "as": "decision" },
|
|
33
|
+
{ "node": "code", "label": "retain-source-and-probability", "as": "record",
|
|
34
|
+
"code": "(s) => ({ path: s.item, source: s.source, probability: s['decision$answers'].answers.matches.noul })" }
|
|
35
|
+
] }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
FICTIONAL EXAMPLE — not a real product release
|
|
2
|
+
|
|
3
|
+
# Current release
|
|
4
|
+
|
|
5
|
+
Clients MUST send the X-Workspace header with their workspace slug.
|
|
6
|
+
|
|
7
|
+
# Future proposals — not approved
|
|
8
|
+
|
|
9
|
+
Changing the authentication mechanism remains a proposal. No authentication
|
|
10
|
+
migration is required by this release.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"v": 2,
|
|
3
|
+
"name": "review-release-notes",
|
|
4
|
+
"schemas": {
|
|
5
|
+
"Input": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"notes": {
|
|
9
|
+
"type": "array",
|
|
10
|
+
"items": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"minLength": 1
|
|
13
|
+
},
|
|
14
|
+
"minItems": 1,
|
|
15
|
+
"maxItems": 5
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"required": [
|
|
19
|
+
"notes"
|
|
20
|
+
],
|
|
21
|
+
"additionalProperties": false
|
|
22
|
+
},
|
|
23
|
+
"Change": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"properties": {
|
|
26
|
+
"breakingChange": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"minLength": 1
|
|
29
|
+
},
|
|
30
|
+
"migrationAction": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"minLength": 1
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"required": [
|
|
36
|
+
"breakingChange",
|
|
37
|
+
"migrationAction"
|
|
38
|
+
],
|
|
39
|
+
"additionalProperties": false
|
|
40
|
+
},
|
|
41
|
+
"Report": {
|
|
42
|
+
"type": "object",
|
|
43
|
+
"properties": {
|
|
44
|
+
"summary": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"minLength": 1
|
|
47
|
+
},
|
|
48
|
+
"changes": {
|
|
49
|
+
"type": "array",
|
|
50
|
+
"items": {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"properties": {
|
|
53
|
+
"breakingChange": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"minLength": 1
|
|
56
|
+
},
|
|
57
|
+
"migrationAction": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"minLength": 1
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"required": [
|
|
63
|
+
"breakingChange",
|
|
64
|
+
"migrationAction"
|
|
65
|
+
],
|
|
66
|
+
"additionalProperties": false
|
|
67
|
+
},
|
|
68
|
+
"minItems": 1
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"required": [
|
|
72
|
+
"summary",
|
|
73
|
+
"changes"
|
|
74
|
+
],
|
|
75
|
+
"additionalProperties": false
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"input": {
|
|
79
|
+
"schemaId": "Input"
|
|
80
|
+
},
|
|
81
|
+
"output": {
|
|
82
|
+
"schemaId": "Report",
|
|
83
|
+
"path": "report"
|
|
84
|
+
},
|
|
85
|
+
"root": {
|
|
86
|
+
"node": "chain",
|
|
87
|
+
"steps": [
|
|
88
|
+
{
|
|
89
|
+
"node": "map",
|
|
90
|
+
"label": "extract-each-release-note",
|
|
91
|
+
"itemsPath": "notes",
|
|
92
|
+
"as": "changes",
|
|
93
|
+
"maxConcurrency": 2,
|
|
94
|
+
"body": {
|
|
95
|
+
"node": "extract",
|
|
96
|
+
"label": "extract-change",
|
|
97
|
+
"instructions": "Extract the breaking change and its migration action from the supplied release note. Preserve the exact header name and required action. Do not invent a migration step.",
|
|
98
|
+
"state": {
|
|
99
|
+
"text": "{item}"
|
|
100
|
+
},
|
|
101
|
+
"requires": [
|
|
102
|
+
"item"
|
|
103
|
+
],
|
|
104
|
+
"out": "Change",
|
|
105
|
+
"as": "change"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"node": "extract",
|
|
110
|
+
"label": "summarize-migration",
|
|
111
|
+
"instructions": "Summarize these migration actions for a client maintainer. Return the supplied changes unchanged alongside the summary. Do not invent steps.",
|
|
112
|
+
"state": {
|
|
113
|
+
"changes": "{changes}"
|
|
114
|
+
},
|
|
115
|
+
"requires": [
|
|
116
|
+
"changes"
|
|
117
|
+
],
|
|
118
|
+
"out": "Report",
|
|
119
|
+
"as": "report"
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Design Jev decisions in AgentRun
|
|
2
|
+
|
|
3
|
+
Jev returns typed judgments and probabilities, not generated prose, tool calls or
|
|
4
|
+
multi-step research. The host supplies its adapter and credentials. Do not write
|
|
5
|
+
HTTP requests or SDK setup into workflow code. This guide maps the TypeSafe
|
|
6
|
+
programming model to the installed DSL; the general TypeSafe skill is optional.
|
|
7
|
+
|
|
8
|
+
## Choose the boundary
|
|
9
|
+
|
|
10
|
+
Work backward from the action the result controls. Code handles exact lookups,
|
|
11
|
+
parsing, arithmetic, joins, grouping and constraints. An agent handles open-ended
|
|
12
|
+
research or generation. Jev can select relevant evidence, interpret a boundary,
|
|
13
|
+
compare a claim to its source or choose among known actions. It need not be a
|
|
14
|
+
final approval stage, and a workflow without a semantic decision need not use it.
|
|
15
|
+
|
|
16
|
+
Ask one coherent judgment per property. Separate independently useful conditions;
|
|
17
|
+
keep related context together. Avoid asking whether a whole complex answer is
|
|
18
|
+
"correct" when no source supporting that answer is supplied. Question descriptions
|
|
19
|
+
must carry their meaning; property names alone are not instructions.
|
|
20
|
+
|
|
21
|
+
## Construct the evidence, not another opinion
|
|
22
|
+
|
|
23
|
+
For source-grounded work, a useful pattern is:
|
|
24
|
+
|
|
25
|
+
1. A tool or agent locates candidate references, retaining their identities.
|
|
26
|
+
2. Direct tool calls fetch the original text at those references.
|
|
27
|
+
3. Jev sees the question or full selection rule **and that original text**.
|
|
28
|
+
4. Code uses the returned values; an agent may repair missing evidence or synthesize.
|
|
29
|
+
|
|
30
|
+
Keep source text separate from a candidate extraction, paraphrase or claim. An
|
|
31
|
+
agent's field named `quote`, `headerContext` or `verified` does not make it original
|
|
32
|
+
evidence. Re-read the cited source through the host tool when independent checking
|
|
33
|
+
matters. Include relevant headings, units, dates, neighboring rows, exclusions and
|
|
34
|
+
section boundaries. An exact quote match checks presence, not interpretation.
|
|
35
|
+
|
|
36
|
+
Judge only what the supplied context can establish. If a source is truncated,
|
|
37
|
+
follow its continuation when relevant; if it is missing, retrieve or surface the
|
|
38
|
+
gap. Do not silently substitute a summary to fit a size limit. Narrow or partition
|
|
39
|
+
large contexts at meaningful boundaries while retaining their qualifiers.
|
|
40
|
+
The adapter has no default byte ceiling. A host may explicitly configure
|
|
41
|
+
`maxStateBytes`; local size errors then report the measured UTF-8 JSON bytes and
|
|
42
|
+
that host's limit before any HTTP request is sent. Provider context limits are
|
|
43
|
+
separate and token-based, not a fixed bytes-to-tokens conversion. Jev 1.13's
|
|
44
|
+
documented contract, checked on 2026-09-22, allows 32k tokens for state plus the
|
|
45
|
+
longest question and 64k for state plus all questions combined; check the selected
|
|
46
|
+
model's current contract. Oversized provider requests remain
|
|
47
|
+
errors, not permission to truncate evidence or silently retry a different graph.
|
|
48
|
+
|
|
49
|
+
`sift` sends **all items together in one request**. Shared `state` is added to
|
|
50
|
+
that batch; it does not replace or narrow each item. `describe` adds an item
|
|
51
|
+
summary, but the full original item is still sent. A tool envelope can contain
|
|
52
|
+
the same text in both `content` and `details`, so character limits on individual
|
|
53
|
+
reads do not establish the final serialized size.
|
|
54
|
+
|
|
55
|
+
When judgments are independent, explicitly use `map` with a `judge` body for one
|
|
56
|
+
request per original. For records that already contain `document`, `page` and
|
|
57
|
+
`text`, a body can use `state: {rule: "{question}", original: "{item}"}`. For tool
|
|
58
|
+
envelopes, select the host's actual original-text and provenance fields instead
|
|
59
|
+
of sending duplicate representations. Retain the full reviewed rule, relevant
|
|
60
|
+
headers, units, dates, exclusions and neighboring rows. If an individual original
|
|
61
|
+
is still too large, retrieve or partition it at meaningful boundaries; do not
|
|
62
|
+
silently truncate it or replace it with an agent's interpretation. This explicit
|
|
63
|
+
graph change changes request count; no automatic batching or truncation occurs.
|
|
64
|
+
|
|
65
|
+
The fictional [read-source decision](../examples/read-source-decision.json) and
|
|
66
|
+
[input](../examples/read-source-decision.input.json) demonstrate direct `read`
|
|
67
|
+
results passed to Jev unchanged, followed by deterministic probability projection.
|
|
68
|
+
Its paths are inputs, not a built-in corpus. Place the bundled fictional
|
|
69
|
+
[release note](../examples/release-note.txt) at `release-note.txt` in the working
|
|
70
|
+
directory (or change the input path to its location) before running that input.
|
|
71
|
+
Adapt the tool and return schema to
|
|
72
|
+
`describe`; an agent locator can produce those paths earlier in the same graph.
|
|
73
|
+
|
|
74
|
+
## Use the installed primitives
|
|
75
|
+
|
|
76
|
+
- `judge`: a flat output schema describes several independent questions over one
|
|
77
|
+
explicit `state` map. Boolean properties become yes-probabilities (Noul); enums
|
|
78
|
+
become Choice; integer properties with minimum 0, maximum N−1 and N described
|
|
79
|
+
levels in `criteria` (2–10 levels) become Score. Put the complete question in each
|
|
80
|
+
`description`.
|
|
81
|
+
- `sift`: ask questions about each candidate and retain originals. Pass shared task
|
|
82
|
+
context in `state`; each item also needs its own original evidence. Candidate
|
|
83
|
+
coverage matters: no judge can recover a source absent from the candidate set.
|
|
84
|
+
- `pick`: choose from known candidates, with `allowNone` when none may fit.
|
|
85
|
+
- `route`: choose a semantic branch. Its uncertainty gate concerns that new
|
|
86
|
+
decision, not an earlier judge's probability.
|
|
87
|
+
|
|
88
|
+
Batch independent questions over the same state. They cannot read each other's
|
|
89
|
+
answers. Use another step when a decision is needed to retrieve new evidence or
|
|
90
|
+
construct new state. Inspect the assembled state and questions, not just node names.
|
|
91
|
+
|
|
92
|
+
## Consume uncertainty honestly
|
|
93
|
+
|
|
94
|
+
`judge` stores decoded values at its `as` key and raw answers at `<as>$answers`.
|
|
95
|
+
A boolean is true at yes-probability 0.5; to enforce another threshold, read the
|
|
96
|
+
raw `.answers.<property>.noul` number and compare in code. A Noul near 0.5 means
|
|
97
|
+
uncertainty between yes and no, not medium intensity. Choice/Score confidence is
|
|
98
|
+
distribution concentration, not proof that the workflow is right.
|
|
99
|
+
|
|
100
|
+
Use thresholds appropriate to the task, with an explicit missing/uncertain path.
|
|
101
|
+
An example threshold is not calibrated policy. Low probability can justify
|
|
102
|
+
exclusion, another retrieval, cheap-agent repair or escalation, depending on the
|
|
103
|
+
question. Do not reject an entire result just because an unused condition is
|
|
104
|
+
uncertain. Preserve raw decisions so these policies can be inspected separately.
|
|
105
|
+
|
|
106
|
+
Typed output proves an interface, not truth. Test source coverage, semantics and
|
|
107
|
+
the downstream action independently. A fake-judge fixture proves wiring only.
|
|
108
|
+
|
|
109
|
+
Maintained against TypeSafe's state, primitives/Noul, confidence and citation-check
|
|
110
|
+
documentation, reviewed 2026-09-22. Upstream reference locations:
|
|
111
|
+
`https://docs.typesafe.ai/concepts/state`, `https://docs.typesafe.ai/primitives`,
|
|
112
|
+
`https://docs.typesafe.ai/confidence`, `https://docs.typesafe.ai/cookbooks/citation_check`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Demo commands and standalone SDK
|
|
2
|
+
|
|
3
|
+
## Demonstrations
|
|
4
|
+
|
|
5
|
+
`/agentrun demo` runs the interpreter with scripted responses over fictional sources. `/agentrun demo empty` exercises insufficient evidence. Neither makes model calls. `/agentrun demo live` uses real Pi agent calls and Jev system one decisions over the same fictional sources; TypeSafe access is required. It is still not web research.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## SDK authoring only
|
|
9
|
+
|
|
10
|
+
Use this path when the host invokes `authorWorkflow` rather than the native `agentrun` tool. The SDK supplies a `submit` tool; deliver `{"value": workflow}` through it. Read validation and acceptance feedback, then repair within that session. The host retains each version and rejection. Acceptance does not activate or execute a replacement.
|
|
11
|
+
|
|
12
|
+
With `rubricSections`, every generated LLM node must reference every supplied section, including child workflows. This conservative author policy rejects Jev nodes, semantic `ask` predicates, and `verify` clauses until the host has a separately reviewed question contract. Execution must receive the same authoritative SOP text. A schema field named `node`, `verify`, or `predicate` is ordinary data, not a judgment clause.
|
|
13
|
+
|
|
14
|
+
Host-owned acceptance callbacks and fixtures remain outside generated workflows. Do not edit them to obtain a pass. Structural acceptance alone does not establish behavior. Keep request text, rubric text, candidates, and reviews in storage appropriate for their contents.
|
|
15
|
+
|
|
16
|
+
SDK configuration and file retention are not features the native author must reimplement. The installed Pi package README documents `authorWorkflow`, `createPiHostRunner`, and the separate CLI.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Workflow format
|
|
2
|
+
|
|
3
|
+
AgentRun documents are JSON data: `v: 2`, `name`, `schemas`, optional `input: {schemaId}`, `output: {schemaId, path}`, and `root`. Schema identifiers refer to the document's own catalog. Define the input and expected output before adding nodes. The installed `@parcha/agentrun-dsl/schema` is the complete editor schema; execution performs additional semantic checks.
|
|
4
|
+
|
|
5
|
+
## Minimal typed answer
|
|
6
|
+
|
|
7
|
+
The complete [inline typed example](../SKILL.md#minimal-typed-example) shows the minimal extraction pattern and its input. The model must extract the stated facts; the example itself is not a passed quality test.
|
|
8
|
+
|
|
9
|
+
Important fields:
|
|
10
|
+
|
|
11
|
+
- `requires` names paths in workflow state, not renamed keys in the prompt map. It is a **nonempty-evidence guard**, not a field-existence check: missing/null values, blank strings, empty arrays and objects without concrete values fail before model construction. `false` and `0` are concrete values. If an empty search result is valid input to a recovery step, handle it explicitly rather than declaring it nonempty.
|
|
12
|
+
- LLM `instructions` are literal prose. They do not substitute `{text}`.
|
|
13
|
+
- `state: {text: "{text}"}` explicitly chooses the JSON user message. Omitted `state` sends accumulated state, excluding legacy reference catalogs.
|
|
14
|
+
- `out` names the node's schema; `as` stores its value in state. For agent/extract/decide nodes, omitting `as` stores under the node's `label`; fields are not merged into top-level state. `output.path` selects the final value to validate.
|
|
15
|
+
|
|
16
|
+
For repository work, an agent can declare `tools: ["read", "grep"]` only if those tools are available. Read the host's tool argument schemas; do not invent parameters. Use `tools: []` for a tool-free agent or extraction. Omitting the list inherits the runner's allowed tools; it does not mean tool-free execution.
|
|
17
|
+
|
|
18
|
+
## One direct tool operation
|
|
19
|
+
|
|
20
|
+
Read [read-file.json](../examples/read-file.json) and its [input](../examples/read-file.input.json). This performs one active built-in `read` call; it needs no model or Jev system one decision. Replace the input path with the file the user asked to read.
|
|
21
|
+
|
|
22
|
+
A built-in returns a Pi tool result: `content` is an array of text/image blocks and `details` is optional. Give `call.out` a schema for that tool return, rather than the final answer or a plain string. A later extraction can transform it into a different output schema. The bundled fictional `search` tool is the exception: its direct effect result is `{sources}`. A `call` needs its host tool name, typed `args`, result `out`, state key `as`, and positive `deadline_s`.
|
|
23
|
+
|
|
24
|
+
## Composition and decisions
|
|
25
|
+
|
|
26
|
+
Read the complete [release-note review](../examples/review-release-notes.json) and its [input](../examples/review-release-notes.input.json) before composing nodes. It maps a typed extraction over two notes, collects only each `change`, then summarizes the collected changes. This needs Pi, but no Jev or external tools.
|
|
27
|
+
|
|
28
|
+
Use `chain.steps` for dependencies. Each `parallel.branches` entry receives the same input; branches must write different top-level keys. In `map`, `itemsPath` selects the list and the body sees `item` and `item_index`; set `as` and bound `maxConcurrency`. A body with `as` already returns that value per item. Use `resultPath` to select a different path, or to avoid retaining whole parent states from a chain body without `as`. A `loop` needs `until` and integer `maxIters` from 1 through 20; reaching the bound is not proof of success.
|
|
29
|
+
|
|
30
|
+
A Jev `judge` has a nonempty `state` map, `out`, and `as`. Its schema is flat: descriptions state questions, booleans yield yes-probabilities, enums yield choices, and integers with 2 to 10 explicit level descriptions in `criteria` yield scores. Scores range from 0 to the last level index. Raw answers are retained at `<as>$answers`; confidence is not calibrated accuracy. `sift` applies questions to each item, and `route` chooses a branch. Use an explicit uncertainty gate or escalation rather than inventing evidence. Supply the complete reviewed rubric; Jev question text is not a substitute for an unavailable SOP.
|
|
31
|
+
|
|
32
|
+
For `sift`, add a flat question schema to `schemas`, then a node such as:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"node": "sift", "label": "select-migration-notes",
|
|
37
|
+
"itemsPath": "notes", "out": "MigrationQuestions", "as": "selected",
|
|
38
|
+
"keep": { "path": "actionable", "gte": 0.8 }
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`MigrationQuestions` can declare `actionable` as `{"type":"boolean","description":"Does this release note state a concrete change a client maintainer must make, rather than only announce a feature?"}` inside its object `properties`. Set `required: ["actionable"]`. Read selected originals from `selected.items`, retained decisions from `selected.values`, and evidence sidecars from `selected.answers`. The `gte` value gates the yes-probability; it is an example threshold to review, not a calibrated guarantee. Handle empty results explicitly with an `escalate` node using `when: {predicate: "empty", path: "selected.items"}` before synthesis.
|
|
43
|
+
|
|
44
|
+
A `sift` batches all full items into one Jev request; `state` adds shared context
|
|
45
|
+
and `describe` adds summaries, neither replaces the items. The assembled request
|
|
46
|
+
must fit the selected provider's token context and any explicit host byte guard;
|
|
47
|
+
the adapter does not impose a default byte ceiling. A local `jev_state_too_large`
|
|
48
|
+
report names the node, measured bytes and configured host limit; it means no HTTP
|
|
49
|
+
request was sent. For independent judgments over larger originals,
|
|
50
|
+
use an explicit `map` with a `judge` body and selected original-text/provenance
|
|
51
|
+
fields, preserving the full rubric and necessary headers/qualifiers. See the
|
|
52
|
+
[Jev guide](jev-decisions.md); no automatic splitting or truncation occurs.
|
|
53
|
+
|
|
54
|
+
### Check the edges before running
|
|
55
|
+
|
|
56
|
+
For each connection, name the actual value produced and the exact path consumed.
|
|
57
|
+
These are different contracts; do not make them all the final answer schema:
|
|
58
|
+
|
|
59
|
+
Inspection displays typed state keys and the final selection. It rejects nested
|
|
60
|
+
paths excluded by known closed producer schemas before execution. Dynamic code,
|
|
61
|
+
open schemas, unions and conditional control flow may leave shapes unknown;
|
|
62
|
+
passing inspection does not prove those paths exist at runtime.
|
|
63
|
+
|
|
64
|
+
| Producer | Value available downstream |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| Host tool called with `as: "read"` | `read.content` and optional `read.details`; not the fields inside `details` at top level |
|
|
67
|
+
| Agent/extract with `out: "Row", as: "row"` | The schema-valid Row at `row`, not `{row: Row}` inside it |
|
|
68
|
+
| Code with `as: "total"` returning a number | The number at `total`; returning `{total: number}` adds a second wrapper |
|
|
69
|
+
| Map with an agent body using `as: "row"` | An array of Row values; no `row` wrapper on each item |
|
|
70
|
+
| Map with a chain body and `resultPath: "row"` | An array of Row values selected from each completed body state |
|
|
71
|
+
|
|
72
|
+
Without `resultPath`, a chain map body retains the whole item state. That is not
|
|
73
|
+
the same as collecting its last step. After mapping, an array is still an array:
|
|
74
|
+
if the final contract is an object, explicitly assemble that object and point
|
|
75
|
+
`output.path` to it. Preserve the same distinction for tool result schemas and
|
|
76
|
+
final answer schemas. Inspection does not execute transforms or prove these
|
|
77
|
+
runtime shapes; check the reported value and contract when execution fails.
|
|
78
|
+
|
|
79
|
+
An `escalate` node always requires `when`. Inside a route branch, the branch-taken predicate below makes escalation unconditional for that branch; outside a branch, provide a predicate for the actual stopping condition.
|
|
80
|
+
|
|
81
|
+
A `route` needs a nonempty `state` map and at least two named branch objects with `body` nodes. This fragment uses the release review's `changes` state and `Report` schema:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"node": "route", "label": "check-migration-detail", "as": "routing",
|
|
86
|
+
"state": { "changes": "{changes}" },
|
|
87
|
+
"instructions": "Can a maintainer follow every supplied migration action without guessing missing details?",
|
|
88
|
+
"branches": {
|
|
89
|
+
"ready": {
|
|
90
|
+
"criteria": "Every action specifies the concrete client change needed.",
|
|
91
|
+
"body": {
|
|
92
|
+
"node": "extract", "label": "summarize-ready-changes",
|
|
93
|
+
"instructions": "Summarize the supplied migration actions and return changes unchanged.",
|
|
94
|
+
"state": { "changes": "{changes}" }, "out": "Report", "as": "report"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"needs_details": {
|
|
98
|
+
"criteria": "Any action lacks a required detail or the supplied changes conflict.",
|
|
99
|
+
"body": {
|
|
100
|
+
"node": "escalate", "label": "request-migration-details",
|
|
101
|
+
"when": { "predicate": "field_equals", "path": "routing.taken", "value": "needs_details" },
|
|
102
|
+
"kind": "needs_input", "stage": "migration", "summary": "Migration details need clarification."
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"unsure": { "branch": "needs_details", "gte": 0.8 }
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`unsure` selects the conservative branch below its confidence gate. Preserve the raw decision evidence; reaching `ready` does not prove migration correctness.
|
|
111
|
+
|
|
112
|
+
Mechanical checks belong in predicates; semantic questions belong in agent/Jev nodes. Code is trusted JavaScript, not a sandbox, and requires the user's trusted run in the extension. Do not turn an unavailable tool or missing verifier into generated code that bypasses the host.
|
|
113
|
+
|
|
114
|
+
## Code transforms and schema references
|
|
115
|
+
|
|
116
|
+
Read the complete fictional [evidence gate](../examples/evidence-gate.json) and its [input](../examples/evidence-gate.input.json). It preserves a supplied claim and evidence, asks one Jev question, and gates the raw yes-probability in code before returning a typed record. It uses no agent or tool; running it with a real judge still needs Jev. The repository test uses a fake judge and proves interface behavior, not semantic quality.
|
|
117
|
+
|
|
118
|
+
A code node permits **only** `node`, `label`, `code`, and optional `as`. Its `code` is a single synchronous function expression, such as `(s) => ({ count: s.items.length })`, not a bare statement body. The function receives the **full accumulated workflow state** as its first argument; it does not receive a scoped prompt map. Do not add `state`, `requires`, `out`, or `instructions` to a code node.
|
|
119
|
+
|
|
120
|
+
Native inspection uses nonexecuting syntax/mechanical validation, equivalent to SDK `validateWorkflow(workflow, {executeCode: false})`. It neither evaluates code factories nor probes their outputs. The ordinary SDK validation default is for trusted code and may execute factories/probes. Neither mode is a sandbox or a proof that the eventual result will satisfy the output schema.
|
|
121
|
+
|
|
122
|
+
Use synchronous data operations such as `Math`, `JSON`, `Array`, `Object`, `Map`, and `Set`. The current executor shadows `Date`, `Promise`, timers, host/network globals, and `Function`; they are unavailable even in a trusted run. For example, derive calendar-month sequences from integer year/month pairs rather than `new Date(...)`. This catches accidental host dependencies; it is not an isolation or security boundary.
|
|
123
|
+
|
|
124
|
+
- With `as: "result"`, the returned value is stored at `state.result`; do not also wrap it in `{result: ...}`.
|
|
125
|
+
- Without `as`, return an object patch: its top-level fields shallow-merge into state. Other state keys remain; returning a nested object replaces that entire top-level value. A non-object or array return is stored under the node's label instead, so use an object for patch semantics.
|
|
126
|
+
- Do not mutate the input state. Return new values; do not return a Promise. Code remains trusted host JavaScript, not a sandbox.
|
|
127
|
+
|
|
128
|
+
A node's `out: "Record"` names a sibling catalog schema directly. Inside a schema, the same sibling is referenced as `{"$ref":"#/definitions/Record"}`, **not** `{"$ref":"Record"}`. The example's input and result schemas both use this form. A `judge` has no `instructions` field: put each complete question in its output schema property's `description` (and its decision criteria in `criteria`, when needed).
|
|
129
|
+
|
|
130
|
+
### Gate the raw probability, not the decoded boolean
|
|
131
|
+
|
|
132
|
+
For a judge with `as: "check"` and boolean question `supported`, read:
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
(s) => {
|
|
136
|
+
const p = s['check$answers']?.answers?.supported?.noul;
|
|
137
|
+
return {
|
|
138
|
+
accepted: typeof p === 'number' && Number.isFinite(p) && p >= 0.90 && p <= 1
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
With `as: "gate"`, this stores `gate.accepted`. Missing, malformed, nonfinite, or out-of-range probabilities fail closed. Follow it with an `escalate` whose `when` is `{predicate: "field_equals", path: "gate.accepted", value: false}`, as in the example. The threshold is illustrative policy, not a calibrated accuracy guarantee.
|
|
144
|
+
|
|
145
|
+
`check.supported` is only the decoded boolean (yes at probability 0.5); it does **not** prove a 0.90 threshold. Likewise, `route.unsure.gte` gates the route's **own new choice confidence**, not an upstream judge's yes-probability. Giving a route the earlier boolean or asking it to enforce a number is not this deterministic gate.
|