@irisrun/bundle-coding 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/coding.d.ts +38 -0
- package/dist/coding.js +101 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +5 -0
- package/package.json +32 -0
package/dist/coding.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Bundle, Tactic } from "@irisrun/core";
|
|
2
|
+
/** The stable id pinned into `Lock.tactics.bundle` and journaled as the tacticId. */
|
|
3
|
+
export declare const BUNDLE_ID = "iris/coding";
|
|
4
|
+
export interface CodingBundleOptions {
|
|
5
|
+
/** Extra read-only tools to allow-list (merged with the coding defaults). */
|
|
6
|
+
readOnlyTools?: string[];
|
|
7
|
+
/** shouldCompact trailing-window size (passed to windowCompaction). */
|
|
8
|
+
keepLast?: number;
|
|
9
|
+
/** onToolError retry cap (passed to toolRepair). */
|
|
10
|
+
maxAttempts?: number;
|
|
11
|
+
invariants?: {
|
|
12
|
+
maxStepsPerTurn?: number;
|
|
13
|
+
maxToolCalls?: number;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The coding-specialized gateAction tactic: read-only / codebase-search tools are
|
|
18
|
+
* a safe ALLOW; every other tool — writes (`write_file`), shell (`run_shell`),
|
|
19
|
+
* and anything unknown/irreversible — is gated to "ask" (HITL). A host-side
|
|
20
|
+
* factory function (not a bare object), matching core's convention.
|
|
21
|
+
*/
|
|
22
|
+
export declare function codingGate(readOnlyTools?: string[]): Tactic<"gateAction">;
|
|
23
|
+
/**
|
|
24
|
+
* The coding bundle's decideNext: it DELEGATES verbatim to the proven ReAct
|
|
25
|
+
* tool-loop (continue while the model still requests tools, finish when it stops) —
|
|
26
|
+
* which is the CORRECT policy for a coding tool-loop agent, so there is nothing to
|
|
27
|
+
* "tune" today. The coding-specific behavior lives in `codingGate` (the
|
|
28
|
+
* read-only-allow / write-gate split). This is kept as a DISTINCT factory only so a
|
|
29
|
+
* future coding heuristic (e.g. a max-edit budget) can layer in here without
|
|
30
|
+
* touching core or the bundle's call sites — it is a pass-through for now.
|
|
31
|
+
*/
|
|
32
|
+
export declare function codingDecideNext(): Tactic<"decideNext">;
|
|
33
|
+
/**
|
|
34
|
+
* Assemble the coding bundle: the SAME structure as core's `defaultBundle`, with
|
|
35
|
+
* the coding-specialized gate + decideNext and the reused window-compaction /
|
|
36
|
+
* tool-repair tactics, returning `{ tacticPerformer, invariants }`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function codingBundle(opts?: CodingBundleOptions): Bundle;
|
package/dist/coding.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// @irisrun/bundle-coding — the first domain (coding) tactic bundle. HOST-SIDE: it
|
|
2
|
+
// composes coding-specialized tactics on the 5 harness seams from @irisrun/core's
|
|
3
|
+
// EXPORTED primitives ([[lrn-core-exports-functions-only]]), so @irisrun/core stays
|
|
4
|
+
// byte-untouched. The assembled `codingBundle()` returns the SAME shape as core's
|
|
5
|
+
// `defaultBundle()` — a pure `tacticPerformer` (a Performer answering a
|
|
6
|
+
// {seam, payload} request with {seam, tacticId:"iris/coding", choice}) plus the
|
|
7
|
+
// kernel invariant caps. The journaled {seam, tacticId, choice} outcome rides the
|
|
8
|
+
// `tactic` effect's result value exactly like the default bundle, so the ADR-0007
|
|
9
|
+
// quarantine (replay folds the journaled choice, never re-invokes a tactic)
|
|
10
|
+
// applies to this external bundle unchanged.
|
|
11
|
+
//
|
|
12
|
+
// Pure composition over core's surface — no host/Node imports (the @irisrun/core
|
|
13
|
+
// dependency is the ONLY dependency; this package is NOT a host/transport package).
|
|
14
|
+
import { composeAssemble, composeDecideNext, composeGate, reactAssembleContext, reactDecideNext, windowCompaction, toolRepair, defaultInvariants, } from "@irisrun/core";
|
|
15
|
+
/** The stable id pinned into `Lock.tactics.bundle` and journaled as the tacticId. */
|
|
16
|
+
export const BUNDLE_ID = "iris/coding";
|
|
17
|
+
// The read-only / reversible tools a coding agent may run without a gate. Writes
|
|
18
|
+
// and shell are NOT here — they default to "ask" (HITL approval), the secure
|
|
19
|
+
// gate-irreversible-by-default floor for a coding workflow.
|
|
20
|
+
const DEFAULT_READ_ONLY_TOOLS = ["read_file", "search", "list", "grep", "glob"];
|
|
21
|
+
/**
|
|
22
|
+
* The coding-specialized gateAction tactic: read-only / codebase-search tools are
|
|
23
|
+
* a safe ALLOW; every other tool — writes (`write_file`), shell (`run_shell`),
|
|
24
|
+
* and anything unknown/irreversible — is gated to "ask" (HITL). A host-side
|
|
25
|
+
* factory function (not a bare object), matching core's convention.
|
|
26
|
+
*/
|
|
27
|
+
export function codingGate(readOnlyTools = []) {
|
|
28
|
+
const safe = new Set([...DEFAULT_READ_ONLY_TOOLS, ...readOnlyTools]);
|
|
29
|
+
return {
|
|
30
|
+
id: "iris/coding-gate",
|
|
31
|
+
seam: "gateAction",
|
|
32
|
+
decide: ({ call }) => (safe.has(call.name) ? "allow" : "ask"),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The coding bundle's decideNext: it DELEGATES verbatim to the proven ReAct
|
|
37
|
+
* tool-loop (continue while the model still requests tools, finish when it stops) —
|
|
38
|
+
* which is the CORRECT policy for a coding tool-loop agent, so there is nothing to
|
|
39
|
+
* "tune" today. The coding-specific behavior lives in `codingGate` (the
|
|
40
|
+
* read-only-allow / write-gate split). This is kept as a DISTINCT factory only so a
|
|
41
|
+
* future coding heuristic (e.g. a max-edit budget) can layer in here without
|
|
42
|
+
* touching core or the bundle's call sites — it is a pass-through for now.
|
|
43
|
+
*/
|
|
44
|
+
export function codingDecideNext() {
|
|
45
|
+
const react = reactDecideNext();
|
|
46
|
+
return {
|
|
47
|
+
id: "iris/coding-decide",
|
|
48
|
+
seam: "decideNext",
|
|
49
|
+
decide: ({ state }) => react.decide({ state }),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Assemble the coding bundle: the SAME structure as core's `defaultBundle`, with
|
|
54
|
+
* the coding-specialized gate + decideNext and the reused window-compaction /
|
|
55
|
+
* tool-repair tactics, returning `{ tacticPerformer, invariants }`.
|
|
56
|
+
*/
|
|
57
|
+
export function codingBundle(opts = {}) {
|
|
58
|
+
const assembleChain = [reactAssembleContext()];
|
|
59
|
+
const decideChain = [codingDecideNext()];
|
|
60
|
+
const gateChain = [codingGate(opts.readOnlyTools)];
|
|
61
|
+
const compact = windowCompaction(opts.keepLast);
|
|
62
|
+
const repair = toolRepair(opts.maxAttempts);
|
|
63
|
+
const tacticPerformer = async (request) => {
|
|
64
|
+
const req = request;
|
|
65
|
+
const seam = req.seam ?? "";
|
|
66
|
+
const payload = req.payload ?? null;
|
|
67
|
+
let choice;
|
|
68
|
+
switch (seam) {
|
|
69
|
+
case "assembleContext": {
|
|
70
|
+
const pl = payload;
|
|
71
|
+
choice = composeAssemble(assembleChain, pl.state, pl.ctx);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
case "shouldCompact": {
|
|
75
|
+
const pl = payload;
|
|
76
|
+
choice = compact.decide(pl);
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case "gateAction": {
|
|
80
|
+
const pl = payload;
|
|
81
|
+
choice = composeGate(gateChain, pl.call);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case "onToolError": {
|
|
85
|
+
const pl = payload;
|
|
86
|
+
choice = repair.decide(pl);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case "decideNext": {
|
|
90
|
+
const pl = payload;
|
|
91
|
+
choice = composeDecideNext(decideChain, pl.state);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
default:
|
|
95
|
+
return { ok: false, error: { message: `codingBundle: unknown seam '${seam}'` } };
|
|
96
|
+
}
|
|
97
|
+
return { ok: true, value: { seam, tacticId: BUNDLE_ID, choice } };
|
|
98
|
+
};
|
|
99
|
+
const invariants = defaultInvariants(opts.invariants);
|
|
100
|
+
return { tacticPerformer, invariants };
|
|
101
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @irisrun/bundle-coding — public surface (host-side; composes from @irisrun/core's
|
|
2
|
+
// exported tactic primitives only — @irisrun/core is the ONLY dependency, and this
|
|
3
|
+
// is NOT a host/transport package).
|
|
4
|
+
export const PACKAGE = "@irisrun/bundle-coding";
|
|
5
|
+
export { codingBundle, codingGate, codingDecideNext, BUNDLE_ID, } from "./coding.js";
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@irisrun/bundle-coding",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Iris first domain tactic bundle — coding-specialized seam tactics (read-only tools allow / writes+shell gated to ask, a tool-loop decideNext, window-compaction + tool-repair) composed HOST-SIDE from @irisrun/core's exported primitives. Produces the defaultBundle shape {tacticPerformer, invariants}; journaled {seam, tacticId, choice} outcomes inherit the ADR-0007 replay quarantine. @irisrun/core dependency only; core stays byte-untouched.",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"iris-src": "./src/index.ts",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@irisrun/core": "^0.1.0"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=24"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/xoai/iris.git",
|
|
26
|
+
"directory": "packages/bundle-coding"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/xoai/iris#readme",
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
]
|
|
32
|
+
}
|