@davidorex/pi-jit-agents 0.14.6 → 0.28.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/CHANGELOG.md +49 -0
- package/README.md +2 -2
- package/dist/agent-spec.d.ts.map +1 -1
- package/dist/agent-spec.js +69 -5
- package/dist/agent-spec.js.map +1 -1
- package/dist/budget-enforcer.d.ts +43 -0
- package/dist/budget-enforcer.d.ts.map +1 -0
- package/dist/budget-enforcer.js +172 -0
- package/dist/budget-enforcer.js.map +1 -0
- package/dist/compile.d.ts +39 -0
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +363 -24
- package/dist/compile.js.map +1 -1
- package/dist/dispatch-inline.d.ts +25 -0
- package/dist/dispatch-inline.d.ts.map +1 -0
- package/dist/dispatch-inline.js +41 -0
- package/dist/dispatch-inline.js.map +1 -0
- package/dist/field-path.d.ts +32 -0
- package/dist/field-path.d.ts.map +1 -0
- package/dist/field-path.js +48 -0
- package/dist/field-path.js.map +1 -0
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -4
- package/dist/index.js.map +1 -1
- package/dist/jit-runtime.d.ts +14 -3
- package/dist/jit-runtime.d.ts.map +1 -1
- package/dist/jit-runtime.js +41 -5
- package/dist/jit-runtime.js.map +1 -1
- package/dist/markers.d.ts +28 -0
- package/dist/markers.d.ts.map +1 -0
- package/dist/markers.js +36 -0
- package/dist/markers.js.map +1 -0
- package/dist/renderer-registry.d.ts +60 -0
- package/dist/renderer-registry.d.ts.map +1 -0
- package/dist/renderer-registry.js +141 -0
- package/dist/renderer-registry.js.map +1 -0
- package/dist/template.d.ts +15 -0
- package/dist/template.d.ts.map +1 -1
- package/dist/template.js +29 -3
- package/dist/template.js.map +1 -1
- package/dist/trace-redactor.d.ts +1 -1
- package/dist/trace-redactor.js +1 -1
- package/dist/trace-writer.js +2 -2
- package/dist/types.d.ts +86 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +11 -4
- package/schemas/agent-trace.schema.json +30 -2
- package/templates/analyzers/base-analyzer.md +9 -0
- package/templates/analyzers/patterns-task.md +11 -0
- package/templates/analyzers/patterns.md +15 -0
- package/templates/analyzers/quality-task.md +11 -0
- package/templates/analyzers/quality.md +15 -0
- package/templates/analyzers/structure-task.md +17 -0
- package/templates/analyzers/structure.md +15 -0
- package/templates/architecture-designer/task.md +117 -0
- package/templates/architecture-inferrer/task.md +61 -0
- package/templates/audit-finding-verifier/task.md +59 -0
- package/templates/audit-fixer/task.md +67 -0
- package/templates/audit-results-router/task.md +37 -0
- package/templates/decomposer/task.md +56 -0
- package/templates/explorer/system.md +3 -0
- package/templates/explorer/task.md +9 -0
- package/templates/gap-identifier/task.md +103 -0
- package/templates/gap-resolution-assessor/task.md +48 -0
- package/templates/handoff-writer/task.md +101 -0
- package/templates/investigator/task.md +30 -0
- package/templates/items/architecture.md +33 -0
- package/templates/items/conformance.md +26 -0
- package/templates/items/conventions.md +19 -0
- package/templates/items/decisions.md +47 -0
- package/templates/items/domain.md +21 -0
- package/templates/items/features.md +63 -0
- package/templates/items/framework-gaps.md +43 -0
- package/templates/items/issues.md +21 -0
- package/templates/items/layer-plans.md +50 -0
- package/templates/items/project.md +48 -0
- package/templates/items/requirements.md +20 -0
- package/templates/items/research.md +57 -0
- package/templates/items/spec-reviews.md +51 -0
- package/templates/items/tasks.md +29 -0
- package/templates/phase-author/task.md +82 -0
- package/templates/plan-creator/task.md +143 -0
- package/templates/plan-decomposer/task.md +46 -0
- package/templates/project-definer/task.md +67 -0
- package/templates/project-inferrer/task.md +56 -0
- package/templates/requirements-gatherer/task.md +90 -0
- package/templates/researcher/task.md +26 -0
- package/templates/shared/macros.md +169 -0
- package/templates/shared/render-helpers.md +106 -0
- package/templates/spec-implementer/task.md +53 -0
- package/templates/synthesizer/system.md +3 -0
- package/templates/synthesizer/task.md +38 -0
- package/templates/task-verifier/task.md +44 -0
- package/templates/task-worker/task.md +52 -0
- package/templates/verifier/task.md +57 -0
package/dist/template.js
CHANGED
|
@@ -18,7 +18,27 @@
|
|
|
18
18
|
import fs from "node:fs";
|
|
19
19
|
import os from "node:os";
|
|
20
20
|
import path from "node:path";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
22
|
+
import { tryResolveContextDir } from "@davidorex/pi-context/context-dir";
|
|
21
23
|
import nunjucks from "nunjucks";
|
|
24
|
+
/**
|
|
25
|
+
* Absolute path to this package's bundled `templates/` directory — the canonical
|
|
26
|
+
* package-layer root for the 3-tier template search (tier 3 / builtinDir).
|
|
27
|
+
*
|
|
28
|
+
* Per DEC-0049 uniform-agent axiom, agent-prompt rendering assets (per-item
|
|
29
|
+
* macros + whole-block delegators + per-agent template directories) live in
|
|
30
|
+
* pi-jit-agents. Consumers (pi-workflows, pi-behavior-monitors, pi-agent-
|
|
31
|
+
* dispatch) import this function rather than computing their own
|
|
32
|
+
* package-relative paths.
|
|
33
|
+
*
|
|
34
|
+
* Resolves via `import.meta.url` so the path works under both source and
|
|
35
|
+
* built (dist) modes — the dist/ directory and the src/ directory sit at the
|
|
36
|
+
* same depth relative to the package root.
|
|
37
|
+
*/
|
|
38
|
+
export function bundledTemplateDir() {
|
|
39
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
40
|
+
return path.resolve(here, "..", "templates");
|
|
41
|
+
}
|
|
22
42
|
/**
|
|
23
43
|
* Create a Nunjucks environment with three-tier template discovery.
|
|
24
44
|
*
|
|
@@ -27,11 +47,17 @@ import nunjucks from "nunjucks";
|
|
|
27
47
|
* inline prompt uses no templates at all.
|
|
28
48
|
*/
|
|
29
49
|
export function createTemplateEnv(ctx) {
|
|
30
|
-
const projectDir = path.join(ctx.cwd, ".project", "templates");
|
|
31
50
|
const userDir = ctx.userDir ?? path.join(os.homedir(), ".pi", "agent", "templates");
|
|
32
51
|
const searchPaths = [];
|
|
33
|
-
|
|
34
|
-
|
|
52
|
+
// Project tier (FGAP-074 C3): pointer-less repos omit it; user/builtin tiers
|
|
53
|
+
// unaffected. `contextTemplatesDir(cwd)` was `<contextDir>/templates`, so the
|
|
54
|
+
// inline equivalent is `path.join(base, "templates")`.
|
|
55
|
+
const base = tryResolveContextDir(ctx.cwd);
|
|
56
|
+
if (base !== null) {
|
|
57
|
+
const projectTemplates = path.join(base, "templates");
|
|
58
|
+
if (fs.existsSync(projectTemplates))
|
|
59
|
+
searchPaths.push(projectTemplates);
|
|
60
|
+
}
|
|
35
61
|
if (fs.existsSync(userDir))
|
|
36
62
|
searchPaths.push(userDir);
|
|
37
63
|
if (ctx.builtinDir && fs.existsSync(ctx.builtinDir))
|
package/dist/template.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"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"}
|
package/dist/trace-redactor.d.ts
CHANGED
|
@@ -39,5 +39,5 @@ export declare function redactLlmResponse<T extends {
|
|
|
39
39
|
* Compiles each `regex` string to a RegExp with the `g` flag.
|
|
40
40
|
* Throws if the file does not exist, parses to invalid JSON, or contains malformed entries.
|
|
41
41
|
*/
|
|
42
|
-
export declare function
|
|
42
|
+
export declare function loadContextRedactionConfig(configPath: string): RedactionPattern[];
|
|
43
43
|
//# sourceMappingURL=trace-redactor.d.ts.map
|
package/dist/trace-redactor.js
CHANGED
|
@@ -123,7 +123,7 @@ function redactContentItem(item, config) {
|
|
|
123
123
|
* Compiles each `regex` string to a RegExp with the `g` flag.
|
|
124
124
|
* Throws if the file does not exist, parses to invalid JSON, or contains malformed entries.
|
|
125
125
|
*/
|
|
126
|
-
export function
|
|
126
|
+
export function loadContextRedactionConfig(configPath) {
|
|
127
127
|
if (!existsSync(configPath)) {
|
|
128
128
|
throw new Error(`trace redaction config not found: ${configPath}`);
|
|
129
129
|
}
|
package/dist/trace-writer.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// pi-coding-agent's transitive dependency tree). Node 23.x exposes node:fs flockSync as
|
|
16
16
|
// `undefined` in the version this repo targets, so the userspace lockfile approach is
|
|
17
17
|
// the working option; the lock is held only for the duration of the append.
|
|
18
|
-
// - Schema validation reuses validateFromFile from @davidorex/pi-
|
|
18
|
+
// - Schema validation reuses validateFromFile from @davidorex/pi-context/schema-validator
|
|
19
19
|
// so the AJV runtime, error format, and ESM/CJS interop shim live in one place.
|
|
20
20
|
//
|
|
21
21
|
// Size-rotation strategy:
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
import { appendFileSync, existsSync, mkdirSync, statSync } from "node:fs";
|
|
27
27
|
import path from "node:path";
|
|
28
28
|
import { fileURLToPath } from "node:url";
|
|
29
|
-
import { validateFromFile } from "@davidorex/pi-
|
|
29
|
+
import { validateFromFile } from "@davidorex/pi-context/schema-validator";
|
|
30
30
|
// proper-lockfile is CommonJS — under Node16 module resolution + ESM consumer the default
|
|
31
31
|
// import resolves to the module namespace, so lockSync hangs off the default export.
|
|
32
32
|
import _properLockfile from "proper-lockfile";
|
package/dist/types.d.ts
CHANGED
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
* Implements the jit-agents-spec.md §2 boundary contract: four public surfaces
|
|
5
5
|
* (load, compile, execute, introspect) with typed inputs and outputs.
|
|
6
6
|
*/
|
|
7
|
-
import type {
|
|
7
|
+
import type { ItemLocation } from "@davidorex/pi-context";
|
|
8
|
+
import type { Api, AssistantMessage, Model } from "@earendil-works/pi-ai";
|
|
8
9
|
import type nunjucks from "nunjucks";
|
|
10
|
+
import type { BudgetWarning } from "./budget-enforcer.js";
|
|
11
|
+
import type { RendererRegistry } from "./renderer-registry.js";
|
|
9
12
|
/**
|
|
10
13
|
* A loaded agent specification.
|
|
11
14
|
*
|
|
@@ -39,13 +42,50 @@ export interface AgentSpec {
|
|
|
39
42
|
* against the invocation cwd.
|
|
40
43
|
*/
|
|
41
44
|
outputSchema?: string;
|
|
42
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Block-context references injected into the agent's template environment.
|
|
47
|
+
*
|
|
48
|
+
* Two element shapes are accepted:
|
|
49
|
+
*
|
|
50
|
+
* - **Bare string** (e.g. `"requirements"`): whole-block injection — the
|
|
51
|
+
* entire `.project/<name>.json` payload is read at compile time and
|
|
52
|
+
* surfaced to the template under `_<name>`. This is the established
|
|
53
|
+
* surface and remains unchanged for existing specs.
|
|
54
|
+
*
|
|
55
|
+
* - **Object** ({@link ContextBlockRef}): per-item or scoped injection —
|
|
56
|
+
* declares a specific item id and/or kind-specific focus hints to be
|
|
57
|
+
* resolved by the compile-time injector. Plan 4 (Wave 2) owns the
|
|
58
|
+
* resolution semantics; the parser only typechecks the shape here.
|
|
59
|
+
*/
|
|
60
|
+
contextBlocks?: (string | ContextBlockRef)[];
|
|
43
61
|
/**
|
|
44
62
|
* Directory the spec was loaded from. Internal use — exposed on the type
|
|
45
63
|
* for tier-aware operations but never relied on by consumers directly.
|
|
46
64
|
*/
|
|
47
65
|
readonly loadedFrom: string;
|
|
48
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Typed object form for {@link AgentSpec.contextBlocks} entries.
|
|
69
|
+
*
|
|
70
|
+
* Bare-string entries in `contextBlocks` denote whole-block injection
|
|
71
|
+
* (existing behaviour); object entries denote per-item or scoped injection
|
|
72
|
+
* — the surface Plan 4 (Wave 2) consumes to inject specific block items
|
|
73
|
+
* (e.g. one decision, one feature) rather than entire blocks.
|
|
74
|
+
*
|
|
75
|
+
* `compileAgent` does not yet honour these fields; this interface defines
|
|
76
|
+
* the parsing-time contract only. Plan 4 wires resolution through the
|
|
77
|
+
* cross-block resolver and per-item macros.
|
|
78
|
+
*/
|
|
79
|
+
export interface ContextBlockRef {
|
|
80
|
+
/** Block name, e.g. "decisions", "features". Required. */
|
|
81
|
+
name: string;
|
|
82
|
+
/** Optional ID of a specific item to inject. Plan 4 resolves via cross-block resolver. */
|
|
83
|
+
item?: string;
|
|
84
|
+
/** Optional kind-specific scope hints (e.g., { story: "STORY-001" }). Plan 4 passes through to macros. */
|
|
85
|
+
focus?: Record<string, string>;
|
|
86
|
+
/** Optional traversal depth. 0 = bare-ID refs (default), 1 = inline direct, 2+ recurse. */
|
|
87
|
+
depth?: number;
|
|
88
|
+
}
|
|
49
89
|
/**
|
|
50
90
|
* Options for loadAgent / createAgentLoader.
|
|
51
91
|
*
|
|
@@ -66,6 +106,10 @@ export interface LoadContext {
|
|
|
66
106
|
}
|
|
67
107
|
/**
|
|
68
108
|
* Options for compileAgent.
|
|
109
|
+
*
|
|
110
|
+
* Plan 4 (Wave 2) extends this with two optional fields supporting object-form
|
|
111
|
+
* `contextBlocks` resolution. Both default to internal lazy construction when
|
|
112
|
+
* absent so existing callers (string-only `contextBlocks`) require no changes.
|
|
69
113
|
*/
|
|
70
114
|
export interface CompileContext {
|
|
71
115
|
/** Nunjucks environment from createTemplateEnv — used to render template references. */
|
|
@@ -74,6 +118,22 @@ export interface CompileContext {
|
|
|
74
118
|
input: unknown;
|
|
75
119
|
/** Project root. Used for `.project/` block reads during contextBlocks injection. */
|
|
76
120
|
cwd: string;
|
|
121
|
+
/**
|
|
122
|
+
* Optional renderer registry for per-item macro resolution. When absent,
|
|
123
|
+
* object-form `contextBlocks` entries still inject the resolved item under
|
|
124
|
+
* `_<name>_item`, but the `render_recursive` Nunjucks global cannot
|
|
125
|
+
* dispatch — recursive rendering returns a `[unrendered: <kind>/<id>]`
|
|
126
|
+
* fallback marker rather than throwing.
|
|
127
|
+
*/
|
|
128
|
+
rendererRegistry?: RendererRegistry;
|
|
129
|
+
/**
|
|
130
|
+
* Optional pre-built ID index. When absent and any object-form
|
|
131
|
+
* `contextBlocks` entry needs item resolution (or the `resolve`/
|
|
132
|
+
* `render_recursive` Nunjucks globals are invoked), `compileAgent` builds
|
|
133
|
+
* one on demand via `buildIdIndex(cwd)`. Callers performing many compiles
|
|
134
|
+
* in one pass should build once and pass it in for reuse.
|
|
135
|
+
*/
|
|
136
|
+
idIndex?: Map<string, ItemLocation>;
|
|
77
137
|
}
|
|
78
138
|
/**
|
|
79
139
|
* A compiled agent ready for dispatch.
|
|
@@ -102,6 +162,26 @@ export interface CompiledAgent {
|
|
|
102
162
|
* inspection, not the rendered string.
|
|
103
163
|
*/
|
|
104
164
|
contextValues: Record<string, unknown>;
|
|
165
|
+
/**
|
|
166
|
+
* Optional list of budget-truncation warnings collected during compile.
|
|
167
|
+
*
|
|
168
|
+
* Populated by the `enforceBudget` Nunjucks global registered by
|
|
169
|
+
* `compileAgent`: every macro invocation that exceeds the field's
|
|
170
|
+
* `x-prompt-budget` annotation appends one entry naming the field path,
|
|
171
|
+
* the declared budget, the actual measured token/word counts, and whether
|
|
172
|
+
* truncation was applied. Surfaces composition-time prompt-size signals
|
|
173
|
+
* to callers without breaking existing consumers (optional field; absent
|
|
174
|
+
* when no enforceBudget call has produced a warning during this compile).
|
|
175
|
+
*
|
|
176
|
+
* Distinct from runtime errors — a warning here means the rendered prompt
|
|
177
|
+
* is fully formed but a budgeted field carried more text than its
|
|
178
|
+
* annotation declared. The truncated text appears in the rendered prompt
|
|
179
|
+
* with the `[…truncated to budget]` marker; this array preserves the
|
|
180
|
+
* full warning record for trace / inspection consumers.
|
|
181
|
+
*/
|
|
182
|
+
budgetWarnings?: BudgetWarning[];
|
|
183
|
+
/** Tool grant carried from AgentSpec.tools — operation-granular per DEC-0047; the clamp at executeAgent enforces child ⊆ parent at dispatch boundary. */
|
|
184
|
+
tools?: string[];
|
|
105
185
|
}
|
|
106
186
|
/**
|
|
107
187
|
* Dispatch-time context for executeAgent.
|
|
@@ -111,6 +191,8 @@ export interface DispatchContext {
|
|
|
111
191
|
model: Model<Api>;
|
|
112
192
|
/** API auth — apiKey and headers from the consumer's model registry. */
|
|
113
193
|
auth: JitAgentAuth;
|
|
194
|
+
/** Parent agent's tool grant (caller-supplied). executeAgent clamps compiled.tools ⊆ parentGrant. Undefined = empty set (default-empty per DEC-0047). */
|
|
195
|
+
parentGrant?: string[];
|
|
114
196
|
/** Max tokens for the LLM call. Defaults to 1024. */
|
|
115
197
|
maxTokens?: number;
|
|
116
198
|
/** Abort signal for cancellation. */
|
|
@@ -128,7 +210,7 @@ export interface DispatchContext {
|
|
|
128
210
|
/**
|
|
129
211
|
* Optional path to a project-extension trace redaction config
|
|
130
212
|
* (`.workflows/monitors/<name>/trace-config.json` shape). When set,
|
|
131
|
-
* `
|
|
213
|
+
* `loadContextRedactionConfig` is invoked once per executeAgent call and
|
|
132
214
|
* the resulting custom patterns are layered atop `BUILTIN_PATTERNS` for
|
|
133
215
|
* every redacted field. When unset / null, only the builtin pattern set
|
|
134
216
|
* applies. Independent of `tracePath` — config loading is a no-op when
|
|
@@ -178,7 +260,7 @@ export interface AgentContract {
|
|
|
178
260
|
name: string;
|
|
179
261
|
role?: string;
|
|
180
262
|
inputSchema?: Record<string, unknown>;
|
|
181
|
-
contextBlocks?: string[];
|
|
263
|
+
contextBlocks?: (string | ContextBlockRef)[];
|
|
182
264
|
outputFormat?: "json" | "text";
|
|
183
265
|
outputSchema?: string;
|
|
184
266
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@davidorex/pi-jit-agents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
4
7
|
"description": "Agent spec compilation and in-process dispatch runtime — the package that owns everything between 'I have a spec' and 'I have a typed result'",
|
|
5
8
|
"license": "MIT",
|
|
6
9
|
"author": "David Ryan",
|
|
@@ -49,17 +52,18 @@
|
|
|
49
52
|
"files": [
|
|
50
53
|
"dist/",
|
|
51
54
|
"schemas/",
|
|
55
|
+
"templates/",
|
|
52
56
|
"*.md"
|
|
53
57
|
],
|
|
54
58
|
"scripts": {
|
|
55
59
|
"clean": "rm -rf dist",
|
|
56
|
-
"build": "tsc -p tsconfig.build.json",
|
|
60
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
57
61
|
"prepublishOnly": "npm run clean && npm run build",
|
|
58
62
|
"test": "tsx --test src/*.test.ts"
|
|
59
63
|
},
|
|
60
64
|
"dependencies": {
|
|
61
|
-
"@davidorex/pi-
|
|
62
|
-
"@
|
|
65
|
+
"@davidorex/pi-context": "^0.28.0",
|
|
66
|
+
"@earendil-works/pi-ai": "^0.75.4",
|
|
63
67
|
"nunjucks": "^3.2.4",
|
|
64
68
|
"proper-lockfile": "^4.1.2",
|
|
65
69
|
"yaml": "^2.7.1"
|
|
@@ -67,5 +71,8 @@
|
|
|
67
71
|
"devDependencies": {
|
|
68
72
|
"@types/nunjucks": "^3.2.6",
|
|
69
73
|
"@types/proper-lockfile": "^4.1.4"
|
|
74
|
+
},
|
|
75
|
+
"engines": {
|
|
76
|
+
"node": ">=22.19.0"
|
|
70
77
|
}
|
|
71
78
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"title": "Agent Trace Entry",
|
|
4
|
-
"description": "Discriminated union of trace events emitted during pi-jit-agents executeAgent invocations for monitor-classify pipelines. Each entry validates a single JSONL line; the .jsonl file as a whole is not a single JSON document.
|
|
4
|
+
"description": "Discriminated union of trace events emitted during pi-jit-agents executeAgent invocations for monitor-classify pipelines. Each entry validates a single JSONL line; the .jsonl file as a whole is not a single JSON document. The structural shape ({ type, id, parentId, timestamp, ...extra }) mirrors pi-coding-agent's SessionEntry but is deliberately a separate schema namespace — there is no literal inheritance. Entries are produced by a push-write trace stream divergent from pi-mono's pull/replay model, so each variant is fired at the moment of occurrence inside executeAgent rather than reconstructed after the fact. The six variants form a parent-chained tree: session_start (root) → classify_call → { classify_response, context_collection } → verdict_decision; trace_end closes the session at the executeAgent exit boundary.",
|
|
5
5
|
"oneOf": [
|
|
6
6
|
{ "$ref": "#/definitions/session_start" },
|
|
7
7
|
{ "$ref": "#/definitions/classify_call" },
|
|
8
8
|
{ "$ref": "#/definitions/classify_response" },
|
|
9
9
|
{ "$ref": "#/definitions/context_collection" },
|
|
10
10
|
{ "$ref": "#/definitions/verdict_decision" },
|
|
11
|
-
{ "$ref": "#/definitions/trace_end" }
|
|
11
|
+
{ "$ref": "#/definitions/trace_end" },
|
|
12
|
+
{ "$ref": "#/definitions/extension_load_warning" }
|
|
12
13
|
],
|
|
13
14
|
"definitions": {
|
|
14
15
|
"traceId": {
|
|
@@ -186,6 +187,33 @@
|
|
|
186
187
|
"totalDurationMs": { "type": "number" },
|
|
187
188
|
"verdict": { "$ref": "#/definitions/verdictResult" }
|
|
188
189
|
}
|
|
190
|
+
},
|
|
191
|
+
"extension_load_warning": {
|
|
192
|
+
"type": "object",
|
|
193
|
+
"additionalProperties": false,
|
|
194
|
+
"required": ["type", "id", "parentId", "timestamp", "extension_name", "message", "severity"],
|
|
195
|
+
"properties": {
|
|
196
|
+
"type": { "const": "extension_load_warning" },
|
|
197
|
+
"id": { "$ref": "#/definitions/traceId" },
|
|
198
|
+
"parentId": {
|
|
199
|
+
"type": ["null", "string"],
|
|
200
|
+
"description": "Extension-load events are typically root events (no parent classify session); null when emitted at extension factory boundary. May reference a parent trace when emitted from within a dispatched agent's lifecycle."
|
|
201
|
+
},
|
|
202
|
+
"timestamp": { "$ref": "#/definitions/isoTimestamp" },
|
|
203
|
+
"extension_name": {
|
|
204
|
+
"type": "string",
|
|
205
|
+
"description": "Name of the Pi extension emitting the warning (e.g., pi-agent-dispatch)."
|
|
206
|
+
},
|
|
207
|
+
"message": {
|
|
208
|
+
"type": "string",
|
|
209
|
+
"description": "Human-readable description of the observed condition (e.g., 'substrate config absent — composites empty')."
|
|
210
|
+
},
|
|
211
|
+
"severity": {
|
|
212
|
+
"type": "string",
|
|
213
|
+
"enum": ["info", "warning", "error"],
|
|
214
|
+
"description": "Severity classification per the canonical pi.ui.notify levels."
|
|
215
|
+
}
|
|
216
|
+
}
|
|
189
217
|
}
|
|
190
218
|
}
|
|
191
219
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{% block identity %}You are a code analyst.{% endblock %} Given an exploration summary and a code path to analyze:
|
|
2
|
+
|
|
3
|
+
{% block checklist %}
|
|
4
|
+
1. Analyze the code thoroughly
|
|
5
|
+
{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block constraints %}
|
|
8
|
+
Be specific — cite files and line ranges where applicable.
|
|
9
|
+
{% endblock %}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Analyze design patterns at `{{ path }}`.
|
|
2
|
+
|
|
3
|
+
{% if exploration.files is defined %}
|
|
4
|
+
## Codebase
|
|
5
|
+
{% for file in exploration.files %}
|
|
6
|
+
- `{{ file.path }}` ({{ file.lines }} lines)
|
|
7
|
+
{% endfor %}
|
|
8
|
+
{% endif %}
|
|
9
|
+
|
|
10
|
+
Identify patterns, conventions, and anti-patterns. Provide recommendations.
|
|
11
|
+
Write your analysis as JSON conforming to the output schema.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{% extends "analyzers/base-analyzer.md" %}
|
|
2
|
+
|
|
3
|
+
{% block identity %}You are a design pattern analyst.{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block checklist %}
|
|
6
|
+
1. **Design patterns**: What patterns are used? Are they applied correctly?
|
|
7
|
+
2. **Idioms**: What language/framework idioms are followed or violated?
|
|
8
|
+
3. **Conventions**: Naming, file organization, import style — are they consistent?
|
|
9
|
+
4. **Anti-patterns**: Are there patterns that work against the codebase?
|
|
10
|
+
5. **Recommendations**: What patterns would improve the codebase?
|
|
11
|
+
{% endblock %}
|
|
12
|
+
|
|
13
|
+
{% block constraints %}
|
|
14
|
+
Focus on patterns and conventions, not raw quality or architecture. Be specific — cite examples.
|
|
15
|
+
{% endblock %}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Analyze code quality at `{{ path }}`.
|
|
2
|
+
|
|
3
|
+
{% if exploration.files is defined %}
|
|
4
|
+
## Codebase
|
|
5
|
+
{% for file in exploration.files %}
|
|
6
|
+
- `{{ file.path }}` ({{ file.lines }} lines)
|
|
7
|
+
{% endfor %}
|
|
8
|
+
{% endif %}
|
|
9
|
+
|
|
10
|
+
Assess test coverage, error handling, code smells, and maintainability.
|
|
11
|
+
Write your analysis as JSON conforming to the output schema.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{% extends "analyzers/base-analyzer.md" %}
|
|
2
|
+
|
|
3
|
+
{% block identity %}You are a code quality analyst.{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block checklist %}
|
|
6
|
+
1. **Test coverage**: What is tested? What isn't? Are tests meaningful?
|
|
7
|
+
2. **Error handling**: How are errors handled? Are there gaps?
|
|
8
|
+
3. **Code smells**: Duplicated logic, overly complex functions, magic numbers?
|
|
9
|
+
4. **Documentation**: Is the code documented? Are the docs accurate?
|
|
10
|
+
5. **Maintainability**: How easy would it be to modify this code?
|
|
11
|
+
{% endblock %}
|
|
12
|
+
|
|
13
|
+
{% block constraints %}
|
|
14
|
+
Focus on quality concerns, not architecture or design patterns. Be specific — cite files and line ranges.
|
|
15
|
+
{% endblock %}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Analyze the code at `{{ path }}`.
|
|
2
|
+
|
|
3
|
+
{% if exploration.files is defined %}
|
|
4
|
+
## Prior Exploration
|
|
5
|
+
{% for file in exploration.files %}
|
|
6
|
+
- `{{ file.path }}` ({{ file.lines }} lines){% if file.exports %}: {{ file.exports | length }} exports{% endif %}
|
|
7
|
+
{% endfor %}
|
|
8
|
+
{% endif %}
|
|
9
|
+
|
|
10
|
+
{% if exploration.types is defined %}
|
|
11
|
+
## Known Types
|
|
12
|
+
{% for t in exploration.types %}
|
|
13
|
+
- `{{ t.name }}` ({{ t.kind }}) in `{{ t.file }}`
|
|
14
|
+
{% endfor %}
|
|
15
|
+
{% endif %}
|
|
16
|
+
|
|
17
|
+
Write your analysis as JSON conforming to the output schema.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{% extends "analyzers/base-analyzer.md" %}
|
|
2
|
+
|
|
3
|
+
{% block identity %}You are a code structure analyst.{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block checklist %}
|
|
6
|
+
1. **Architecture**: How is the code organized? What patterns are used?
|
|
7
|
+
2. **Module boundaries**: Are responsibilities clearly separated?
|
|
8
|
+
3. **Dependencies**: What are the key dependency relationships?
|
|
9
|
+
4. **Entry points**: How does execution flow through the code?
|
|
10
|
+
5. **Configuration**: How is the system configured?
|
|
11
|
+
{% endblock %}
|
|
12
|
+
|
|
13
|
+
{% block constraints %}
|
|
14
|
+
Focus on structural concerns, not code quality or patterns. Be specific — cite files and directories.
|
|
15
|
+
{% endblock %}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
## Project Identity
|
|
2
|
+
|
|
3
|
+
**Name:** {{ project.name }}
|
|
4
|
+
**Description:** {{ project.description }}
|
|
5
|
+
**Core Value:** {{ project.core_value }}
|
|
6
|
+
{% if project.stack %}
|
|
7
|
+
|
|
8
|
+
### Stack
|
|
9
|
+
{% for item in project.stack %}
|
|
10
|
+
- {{ item }}
|
|
11
|
+
{% endfor %}
|
|
12
|
+
{% endif %}
|
|
13
|
+
|
|
14
|
+
### Constraints
|
|
15
|
+
{% for constraint in project.constraints %}
|
|
16
|
+
- [{{ constraint.type }}] {{ constraint.description }}
|
|
17
|
+
{% endfor %}
|
|
18
|
+
|
|
19
|
+
### Scope Boundaries
|
|
20
|
+
|
|
21
|
+
**In scope:**
|
|
22
|
+
{% for item in project.scope_boundaries.in %}
|
|
23
|
+
- {{ item }}
|
|
24
|
+
{% endfor %}
|
|
25
|
+
|
|
26
|
+
**Out of scope:**
|
|
27
|
+
{% for item in project.scope_boundaries.out %}
|
|
28
|
+
- {{ item }}
|
|
29
|
+
{% endfor %}
|
|
30
|
+
|
|
31
|
+
## Requirements
|
|
32
|
+
|
|
33
|
+
### Must
|
|
34
|
+
{% for req in requirements.requirements %}
|
|
35
|
+
{% if req.priority == "must" %}
|
|
36
|
+
- **{{ req.id }}** [{{ req.type }}]: {{ req.description }}
|
|
37
|
+
{% endif %}
|
|
38
|
+
{% endfor %}
|
|
39
|
+
|
|
40
|
+
### Should
|
|
41
|
+
{% for req in requirements.requirements %}
|
|
42
|
+
{% if req.priority == "should" %}
|
|
43
|
+
- **{{ req.id }}** [{{ req.type }}]: {{ req.description }}
|
|
44
|
+
{% endif %}
|
|
45
|
+
{% endfor %}
|
|
46
|
+
|
|
47
|
+
### Could
|
|
48
|
+
{% for req in requirements.requirements %}
|
|
49
|
+
{% if req.priority == "could" %}
|
|
50
|
+
- **{{ req.id }}** [{{ req.type }}]: {{ req.description }}
|
|
51
|
+
{% endif %}
|
|
52
|
+
{% endfor %}
|
|
53
|
+
|
|
54
|
+
## Instructions
|
|
55
|
+
|
|
56
|
+
Design the initial architecture for this project. Produce modules, patterns, and boundaries that satisfy the requirements above — starting with "must" requirements and ensuring "should" requirements have a clear home.
|
|
57
|
+
|
|
58
|
+
### For each module, provide:
|
|
59
|
+
|
|
60
|
+
1. **name** — short identifier (e.g., "api", "auth", "storage", "cli")
|
|
61
|
+
2. **file** — primary file path relative to project root (e.g., "src/api.ts")
|
|
62
|
+
3. **responsibility** — one sentence: what this module owns and what it does not
|
|
63
|
+
4. **dependencies** — array of other module names this depends on (empty if none)
|
|
64
|
+
5. **lines** — estimated lines of code (rough order of magnitude)
|
|
65
|
+
|
|
66
|
+
### For each pattern, provide:
|
|
67
|
+
|
|
68
|
+
1. **name** — recognized pattern name (e.g., "Repository Pattern", "Event Sourcing", "Middleware Pipeline")
|
|
69
|
+
2. **description** — why this pattern is appropriate for this project's specific needs
|
|
70
|
+
3. **used_in** — array of module names that implement this pattern
|
|
71
|
+
|
|
72
|
+
### For boundaries, provide:
|
|
73
|
+
|
|
74
|
+
An array of strings — each describing a hard architectural constraint. These should be specific to this project, not generic ("All database access goes through the storage module", not "separate concerns").
|
|
75
|
+
|
|
76
|
+
### Design principles
|
|
77
|
+
|
|
78
|
+
- Module count should be proportional to requirements — a 5-requirement project needs 3-5 modules, not 15
|
|
79
|
+
- Every "must" functional requirement should map to at least one module's responsibility
|
|
80
|
+
- Every "must" non-functional requirement should be addressed by a pattern or boundary
|
|
81
|
+
- Dependencies should flow in one direction — avoid circular module dependencies
|
|
82
|
+
- If the project has a stated stack, modules should use file extensions and conventions matching that stack
|
|
83
|
+
- Prefer explicit boundaries over implicit conventions
|
|
84
|
+
|
|
85
|
+
### Overview
|
|
86
|
+
|
|
87
|
+
Write an `overview` paragraph (required) summarizing:
|
|
88
|
+
- The architectural style (layered, modular, pipeline, etc.)
|
|
89
|
+
- The key structural decisions and why they fit this project
|
|
90
|
+
- How the architecture supports the core_value
|
|
91
|
+
|
|
92
|
+
### Output format
|
|
93
|
+
|
|
94
|
+
Produce a single JSON object:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"overview": "string (required)",
|
|
99
|
+
"modules": [
|
|
100
|
+
{
|
|
101
|
+
"name": "string (required)",
|
|
102
|
+
"file": "string (required)",
|
|
103
|
+
"responsibility": "string (required)",
|
|
104
|
+
"dependencies": ["string"],
|
|
105
|
+
"lines": 100
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
"patterns": [
|
|
109
|
+
{
|
|
110
|
+
"name": "string (required)",
|
|
111
|
+
"description": "string (required)",
|
|
112
|
+
"used_in": ["module-name"]
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
"boundaries": ["string"]
|
|
116
|
+
}
|
|
117
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Infer the architecture of the project at `{{ path }}`.
|
|
2
|
+
|
|
3
|
+
## Codebase Analysis
|
|
4
|
+
|
|
5
|
+
{% if exploration.files is defined %}
|
|
6
|
+
### Files
|
|
7
|
+
{% for file in exploration.files %}
|
|
8
|
+
- `{{ file.path }}` ({{ file.language | default("unknown") }}, {{ file.lines | default("?") }} lines){% if file.exports %} — {{ file.exports | length }} exports{% endif %}
|
|
9
|
+
{% endfor %}
|
|
10
|
+
{% endif %}
|
|
11
|
+
|
|
12
|
+
{% if exploration.types is defined %}
|
|
13
|
+
### Types
|
|
14
|
+
{% for t in exploration.types %}
|
|
15
|
+
- `{{ t.name }}` ({{ t.kind }}) in `{{ t.file }}`
|
|
16
|
+
{% endfor %}
|
|
17
|
+
{% endif %}
|
|
18
|
+
|
|
19
|
+
{% if exploration.dependencies is defined %}
|
|
20
|
+
### Dependencies
|
|
21
|
+
{% for d in exploration.dependencies %}
|
|
22
|
+
- `{{ d.from }}` → `{{ d.to }}` ({{ d.type | default("import") }})
|
|
23
|
+
{% endfor %}
|
|
24
|
+
{% endif %}
|
|
25
|
+
|
|
26
|
+
{% if exploration.entryPoints is defined %}
|
|
27
|
+
### Entry Points
|
|
28
|
+
{% for ep in exploration.entryPoints %}
|
|
29
|
+
- `{{ ep }}`
|
|
30
|
+
{% endfor %}
|
|
31
|
+
{% endif %}
|
|
32
|
+
|
|
33
|
+
## Instructions
|
|
34
|
+
|
|
35
|
+
From the analysis above and targeted code reads, produce an architecture block:
|
|
36
|
+
|
|
37
|
+
1. **Modules** — each cohesive unit with a clear responsibility. For each:
|
|
38
|
+
- `name`: concise identifier (e.g., "block-api", "expression-engine")
|
|
39
|
+
- `file`: primary file path relative to project root
|
|
40
|
+
- `responsibility`: one-sentence description of what this module does
|
|
41
|
+
- `dependencies`: array of other module names this module depends on
|
|
42
|
+
- `lines`: approximate line count
|
|
43
|
+
|
|
44
|
+
2. **Patterns** — design patterns evidenced in the code. For each:
|
|
45
|
+
- `name`: pattern name (e.g., "registry", "factory", "middleware")
|
|
46
|
+
- `description`: how this pattern is applied in this codebase
|
|
47
|
+
- `used_in`: array of module names that use this pattern
|
|
48
|
+
|
|
49
|
+
3. **Boundaries** — architectural seams where modules interact through defined interfaces (e.g., "block-api validates all writes before persistence", "dispatch spawns subprocesses through a single entry point")
|
|
50
|
+
|
|
51
|
+
4. **Overview** — one paragraph summarizing the architecture: what the system does, how it's organized, and what the key design decisions are
|
|
52
|
+
|
|
53
|
+
Read entry points, config files, and module interfaces to confirm the exploration. Do not read every file.
|
|
54
|
+
|
|
55
|
+
## Required Output Schema
|
|
56
|
+
|
|
57
|
+
You MUST produce JSON conforming exactly to this schema. Every required field must be present.
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{{ output_schema }}
|
|
61
|
+
```
|