@tangle-network/agent-runtime 0.72.0 → 0.73.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.
Files changed (46) hide show
  1. package/dist/agent.d.ts +1 -1
  2. package/dist/agent.js +4 -3
  3. package/dist/agent.js.map +1 -1
  4. package/dist/analyst-loop.d.ts +1 -1
  5. package/dist/analyst-loop.js +3 -2
  6. package/dist/{chunk-VYXBFWHZ.js → chunk-7ODB76J5.js} +2 -2
  7. package/dist/{chunk-PHKNOAOU.js → chunk-HPYWEFVY.js} +25 -7
  8. package/dist/chunk-HPYWEFVY.js.map +1 -0
  9. package/dist/{chunk-P5OKDSLB.js → chunk-IODKUOBA.js} +5 -3
  10. package/dist/{chunk-P5OKDSLB.js.map → chunk-IODKUOBA.js.map} +1 -1
  11. package/dist/chunk-NBV35BR6.js +68 -0
  12. package/dist/chunk-NBV35BR6.js.map +1 -0
  13. package/dist/{chunk-55WKGOGU.js → chunk-NCH4XUZ7.js} +111 -31
  14. package/dist/chunk-NCH4XUZ7.js.map +1 -0
  15. package/dist/{chunk-VLF5RHEQ.js → chunk-T2HVQVB4.js} +1 -66
  16. package/dist/chunk-T2HVQVB4.js.map +1 -0
  17. package/dist/{chunk-HXVMLRYU.js → chunk-U56XGKVY.js} +7 -7
  18. package/dist/{coordination-CFVF0OzX.d.ts → coordination-DU0saWeg.d.ts} +8 -2
  19. package/dist/index.d.ts +6 -6
  20. package/dist/index.js +10 -9
  21. package/dist/index.js.map +1 -1
  22. package/dist/intelligence.d.ts +1 -1
  23. package/dist/lifecycle.d.ts +281 -0
  24. package/dist/lifecycle.js +174 -0
  25. package/dist/lifecycle.js.map +1 -0
  26. package/dist/{loop-runner-bin-B7biH0Gk.d.ts → loop-runner-bin-eD3m0rHW.d.ts} +2 -2
  27. package/dist/loop-runner-bin.d.ts +4 -4
  28. package/dist/loop-runner-bin.js +6 -5
  29. package/dist/loops.d.ts +45 -9
  30. package/dist/loops.js +6 -3
  31. package/dist/mcp/bin.js +6 -5
  32. package/dist/mcp/bin.js.map +1 -1
  33. package/dist/mcp/index.d.ts +6 -6
  34. package/dist/mcp/index.js +5 -4
  35. package/dist/mcp/index.js.map +1 -1
  36. package/dist/{openai-tools-DOI5mKNw.d.ts → openai-tools-CBurv8Cu.d.ts} +1 -1
  37. package/dist/profiles.d.ts +1 -1
  38. package/dist/{types-K8-xkiw1.d.ts → types-JufmXF2a.d.ts} +80 -1
  39. package/dist/{worktree-JXGJ1MxQ.d.ts → worktree-DaxOvw-C.d.ts} +1 -1
  40. package/dist/{worktree-fanout-DJHQy7Ux.d.ts → worktree-fanout-DIffZohV.d.ts} +15 -5
  41. package/package.json +6 -1
  42. package/dist/chunk-55WKGOGU.js.map +0 -1
  43. package/dist/chunk-PHKNOAOU.js.map +0 -1
  44. package/dist/chunk-VLF5RHEQ.js.map +0 -1
  45. /package/dist/{chunk-VYXBFWHZ.js.map → chunk-7ODB76J5.js.map} +0 -0
  46. /package/dist/{chunk-HXVMLRYU.js.map → chunk-U56XGKVY.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import { c as LoopTraceEvent } from './types-K8-xkiw1.js';
1
+ import { c as LoopTraceEvent } from './types-JufmXF2a.js';
2
2
  import { AgentProfileMcpServer } from '@tangle-network/agent-interface';
3
3
  import { T as ToolSpec } from './router-client-C7kp_ECN.js';
4
4
  import '@tangle-network/agent-eval';
@@ -0,0 +1,281 @@
1
+ import { AgentProfileResourceRef, AgentProfileMcpServer, AgentProfileHookCommand, AgentSubagentProfile, AgentProfile } from '@tangle-network/agent-interface';
2
+
3
+ /**
4
+ * `@tangle-network/agent-runtime/lifecycle` — artifact-lifecycle FOUNDATION.
5
+ *
6
+ * The §1.5 law says an agent IS its `AgentProfile`, and the profile is the WHOLE
7
+ * agent: prompt + skills + tools + mcp + hooks + subagents. This module names the
8
+ * discrete, individually-promotable PIECES of that profile — "artifacts" — and
9
+ * gives them stable ids so the rest of a self-improvement lifecycle (propose →
10
+ * measure → promote → ship) has something concrete to hang off.
11
+ *
12
+ * This is PHASE 1: just the two primitives the rest hangs off.
13
+ * 1. `ArtifactRegistry` — a typed catalog of profile artifacts with stable ids.
14
+ * 2. `measureMarginalLift` — the with-vs-without ablation: how much score/cost a
15
+ * single artifact adds on top of a baseline profile.
16
+ *
17
+ * The per-surface lifecycles, the `BuildableSurface` author contract, and the
18
+ * promotion-gate wiring are deferred to later phases.
19
+ */
20
+
21
+ /**
22
+ * The profile levers an artifact can target. One-to-one with the §1.5 profile
23
+ * surface (`prompt + skills + tools + mcp + hooks + subagents`). Each kind maps to
24
+ * exactly one field of `AgentProfile`, so an artifact can be applied onto a
25
+ * baseline profile deterministically (see `applyArtifact`).
26
+ */
27
+ type ArtifactKind = 'skill' | 'tool' | 'mcp' | 'hook' | 'subagent' | 'prompt';
28
+ /**
29
+ * The payload for each `ArtifactKind`. The shapes are the SAME types the
30
+ * `AgentProfile` field carries, so applying an artifact is a structural merge
31
+ * onto the profile — never a bespoke per-kind transform.
32
+ *
33
+ * - `prompt` — an instruction line appended to `profile.prompt.instructions`.
34
+ * - `skill` — a `SKILL.md`-style resource ref added to `profile.resources.skills`.
35
+ * - `tool` — a tool grant: `{ enabled }` set under `profile.tools[name]`.
36
+ * - `mcp` — one MCP server added under `profile.mcp[name]`.
37
+ * - `hook` — one or more hook commands added under `profile.hooks[event]`.
38
+ * - `subagent` — one subagent profile added under `profile.subagents[name]`.
39
+ */
40
+ interface ArtifactPayloads {
41
+ prompt: {
42
+ instruction: string;
43
+ };
44
+ skill: {
45
+ resource: AgentProfileResourceRef;
46
+ };
47
+ tool: {
48
+ enabled: boolean;
49
+ };
50
+ mcp: {
51
+ server: AgentProfileMcpServer;
52
+ };
53
+ hook: {
54
+ event: string;
55
+ commands: AgentProfileHookCommand[];
56
+ };
57
+ subagent: {
58
+ profile: AgentSubagentProfile;
59
+ };
60
+ }
61
+ /**
62
+ * A discrete, individually-promotable piece of an agent profile.
63
+ *
64
+ * `kind` selects the profile lever; `payload` is the kind-specific value; `key`
65
+ * is the profile-field key the payload lands under (the tool name, the MCP server
66
+ * name, the subagent name — unused for `prompt`, which appends). `id` is stable:
67
+ * once registered, it never changes, so a marginal-lift measurement, a promotion
68
+ * decision, and a ship record all reference the same artifact.
69
+ */
70
+ interface ProfileArtifact<K extends ArtifactKind = ArtifactKind> {
71
+ /** Stable id. Assigned by the registry at register time; never reassigned. */
72
+ id: string;
73
+ kind: K;
74
+ /**
75
+ * The profile-field key this artifact lands under (e.g. the tool name, the MCP
76
+ * server name, the subagent name, the hook event). Optional for `prompt`
77
+ * (instructions append, they have no key). Defaults to `id` when applying a
78
+ * keyed artifact without an explicit key.
79
+ */
80
+ key?: string;
81
+ /** Human-facing label for review surfaces. */
82
+ name: string;
83
+ /** Optional one-line description of what this artifact does. */
84
+ description?: string;
85
+ payload: ArtifactPayloads[K];
86
+ /**
87
+ * Lifecycle status. Phase 1 tracks only `candidate` (registered, not yet
88
+ * promoted) and `promoted` (passed whatever gate the caller ran). The
89
+ * registry never auto-promotes; promotion is an explicit `promote(id)` call.
90
+ */
91
+ status: ArtifactStatus;
92
+ /** Free-form metadata (provenance, generation id, the measured lift, …). */
93
+ metadata?: Record<string, unknown>;
94
+ }
95
+ type ArtifactStatus = 'candidate' | 'promoted';
96
+ /** The input to `register` — everything on `ProfileArtifact` except the
97
+ * registry-owned `id` and `status`. An explicit `id` may be supplied for
98
+ * deterministic/idempotent registration; otherwise the registry assigns one. */
99
+ type ArtifactInput<K extends ArtifactKind = ArtifactKind> = Omit<ProfileArtifact<K>, 'id' | 'status'> & {
100
+ id?: string;
101
+ status?: ArtifactStatus;
102
+ };
103
+
104
+ /**
105
+ * `applyArtifact` — merge one `ProfileArtifact` onto an `AgentProfile`.
106
+ *
107
+ * This is the deterministic bridge between the artifact catalog and the §1.5
108
+ * profile law: each `ArtifactKind` lands on exactly one profile field. The merge
109
+ * is shallow-immutable — the input profile is never mutated; a new profile with
110
+ * the artifact applied is returned. This is the ONE place that knows how a
111
+ * `kind` maps to a profile field, so both the registry's `compose` and
112
+ * `measureMarginalLift`'s with/without ablation share a single source of truth.
113
+ */
114
+
115
+ /**
116
+ * Return a new profile with `artifact` merged onto `base`. Keyed kinds
117
+ * (`tool`/`mcp`/`hook`/`subagent`) land under `artifact.key` (falling back to
118
+ * `artifact.id`). `prompt` appends an instruction line; `skill` appends a
119
+ * resource ref. Existing keys are overwritten by the artifact (the artifact is
120
+ * the candidate being measured/promoted, so it wins on conflict).
121
+ */
122
+ declare function applyArtifact(base: AgentProfile, artifact: ProfileArtifact): AgentProfile;
123
+ /** Apply many artifacts left-to-right; later artifacts win on key conflicts. */
124
+ declare function applyArtifacts(base: AgentProfile, artifacts: readonly ProfileArtifact[]): AgentProfile;
125
+
126
+ /**
127
+ * `measureMarginalLift` — the with-vs-without ablation for one artifact.
128
+ *
129
+ * "What does THIS one piece add?" is the question a lifecycle has to answer
130
+ * before it can promote anything. The answer is an ablation: score the baseline
131
+ * profile, score the baseline-plus-candidate profile, and report the delta. This
132
+ * is the marginal contribution of the artifact — the same shape the project's
133
+ * `OutcomeMeasurement` reports for an apply pass, but isolated to ONE artifact so
134
+ * a registry can rank candidates by what they individually earn.
135
+ *
136
+ * The measurement is selector-agnostic: it takes an `EvalRunner` the caller
137
+ * supplies (any function that scores a profile and reports cost), runs it twice,
138
+ * and subtracts. It never judges, never picks a winner, never re-scores on a
139
+ * holdout — those are the gate's job. It only quantifies the ablation so the gate
140
+ * has a real number to decide on.
141
+ */
142
+
143
+ /**
144
+ * The result of running an eval over ONE profile: a composite score and the cost
145
+ * to obtain it. This mirrors the project's score/cost convention (`composite`
146
+ * from `OutcomeMeasurement`, `costUsd` from `LoopResult`), so a caller can pass a
147
+ * thin wrapper over `runLoop` / `runBenchmark` / `runAgentEval` directly.
148
+ */
149
+ interface EvalResult {
150
+ /** Composite score in `[0, 1]` (higher is better) for the profile under test. */
151
+ composite: number;
152
+ /** USD cost to produce this result. */
153
+ costUsd: number;
154
+ /** Optional opaque passthrough (per-task cells, the raw report, …). */
155
+ details?: unknown;
156
+ }
157
+ /**
158
+ * Scores a profile. The caller wires this to whatever eval they run — a
159
+ * `runLoop` rollout, a `runBenchmark` campaign, a `runAgentEval` cohort — and
160
+ * returns the composite + cost. `signal` is forwarded for cancellation.
161
+ */
162
+ type EvalRunner = (profile: AgentProfile, signal?: AbortSignal) => Promise<EvalResult>;
163
+ interface MeasureMarginalLiftOptions {
164
+ /** The profile the artifact is measured ON TOP OF (the "without" arm). */
165
+ baseline: AgentProfile;
166
+ /** The single artifact whose marginal contribution we want. */
167
+ candidate: ProfileArtifact;
168
+ /** The eval that scores a profile. Run once per arm (twice total). */
169
+ evalRunner: EvalRunner;
170
+ /**
171
+ * A pre-computed baseline result, to skip the "without" run when the caller
172
+ * already scored the baseline (e.g. measuring several candidates against the
173
+ * same baseline). When set, the baseline arm is NOT re-run.
174
+ */
175
+ baselineResult?: EvalResult;
176
+ /** Forwarded to both `evalRunner` invocations for cancellation. */
177
+ signal?: AbortSignal;
178
+ }
179
+ /**
180
+ * The marginal lift of one artifact: the with/without ablation.
181
+ *
182
+ * `scoreDelta = with.composite − without.composite`. A positive `scoreDelta` is
183
+ * the evidence a gate needs to promote; a negative one is the signal to drop the
184
+ * artifact. `costDelta` is the extra USD the artifact costs (often positive — a
185
+ * new tool/MCP adds calls) and lets the gate weigh lift against spend.
186
+ */
187
+ interface MarginalLift {
188
+ /** The artifact id this measurement is for (stable, from the registry). */
189
+ artifactId: string;
190
+ /** Eval of `applyArtifact(baseline, candidate)`. */
191
+ withArtifact: EvalResult;
192
+ /** Eval of `baseline` alone. */
193
+ withoutArtifact: EvalResult;
194
+ /** `withArtifact.composite − withoutArtifact.composite`. */
195
+ scoreDelta: number;
196
+ /** `withArtifact.costUsd − withoutArtifact.costUsd`. */
197
+ costDelta: number;
198
+ }
199
+ /**
200
+ * Run the with/without ablation for `candidate` over `baseline` and return its
201
+ * marginal score/cost contribution.
202
+ *
203
+ * The "without" arm scores the baseline profile unchanged; the "with" arm scores
204
+ * `applyArtifact(baseline, candidate)`. Both use the same `evalRunner`, so the
205
+ * delta isolates the artifact's effect (eval method held constant). The baseline
206
+ * arm is skipped when `baselineResult` is supplied.
207
+ *
208
+ * @example
209
+ * const lift = await measureMarginalLift({
210
+ * baseline,
211
+ * candidate: registry.get(id)!,
212
+ * evalRunner: (profile) => scoreProfileOnCohort(profile),
213
+ * })
214
+ * if (lift.scoreDelta > 0) registry.promote(lift.artifactId)
215
+ */
216
+ declare function measureMarginalLift(opts: MeasureMarginalLiftOptions): Promise<MarginalLift>;
217
+
218
+ /**
219
+ * `ArtifactRegistry` — a typed catalog of profile artifacts with stable ids.
220
+ *
221
+ * The registry is the lifecycle's source of truth for "what pieces could go into
222
+ * this agent's profile". It holds `register` / `list` / `get` / `promote`, assigns
223
+ * stable ids, and can `compose` a subset of artifacts onto a baseline profile via
224
+ * the single `applyArtifact` bridge. It owns NO measurement, NO gate, NO LLM — it
225
+ * is a pure in-memory store so callers can persist/snapshot it however they like.
226
+ */
227
+
228
+ /** Filter for `list`. Omit a field to leave that dimension unconstrained. */
229
+ interface ArtifactQuery {
230
+ kind?: ArtifactKind;
231
+ status?: ArtifactStatus;
232
+ }
233
+ /**
234
+ * A typed, in-memory registry of `ProfileArtifact`s with stable ids.
235
+ *
236
+ * Ids are stable for the life of the registry: `register` assigns one (or honors
237
+ * a caller-supplied id idempotently), and no later operation reassigns it.
238
+ * Re-registering the same id REPLACES the artifact's mutable fields but preserves
239
+ * the id, so a re-proposed candidate keeps its identity across generations.
240
+ */
241
+ declare class ArtifactRegistry {
242
+ private readonly artifacts;
243
+ private counter;
244
+ /**
245
+ * Register an artifact, returning the stored record (with its assigned id).
246
+ * When `input.id` is set it is honored (idempotent re-registration replaces
247
+ * the record under the same id); otherwise a stable id is minted as
248
+ * `<kind>-<n>`. `status` defaults to `'candidate'`.
249
+ */
250
+ register<K extends ArtifactKind>(input: ArtifactInput<K>): ProfileArtifact<K>;
251
+ /** Get an artifact by id, or `undefined` if it was never registered. */
252
+ get(id: string): ProfileArtifact | undefined;
253
+ /**
254
+ * List artifacts, optionally filtered by `kind` and/or `status`. Returns a new
255
+ * array in registration order; callers may safely sort/mutate the result.
256
+ */
257
+ list(query?: ArtifactQuery): ProfileArtifact[];
258
+ /**
259
+ * Mark an artifact `promoted`. Fails loud on an unknown id — promoting a
260
+ * non-existent artifact is a caller bug, not a no-op. Returns the updated
261
+ * record. Idempotent: promoting an already-promoted artifact is a no-op
262
+ * return.
263
+ */
264
+ promote(id: string): ProfileArtifact;
265
+ /**
266
+ * Compose a set of registered artifacts onto a baseline profile. With no ids
267
+ * given, composes every `promoted` artifact (the "ship the passing set"
268
+ * default). With explicit ids, composes exactly those (in id order given),
269
+ * failing loud on any unknown id. The applied order is the order passed (or
270
+ * registration order for the promoted-default), and later artifacts win on key
271
+ * conflicts — same semantics as `applyArtifacts`.
272
+ */
273
+ compose(base: AgentProfile, ids?: readonly string[]): AgentProfile;
274
+ /** Number of registered artifacts (any status). */
275
+ get size(): number;
276
+ private mintId;
277
+ }
278
+ /** Construct an empty `ArtifactRegistry`. */
279
+ declare function createArtifactRegistry(): ArtifactRegistry;
280
+
281
+ export { type ArtifactInput, type ArtifactKind, type ArtifactPayloads, type ArtifactQuery, ArtifactRegistry, type ArtifactStatus, type EvalResult, type EvalRunner, type MarginalLift, type MeasureMarginalLiftOptions, type ProfileArtifact, applyArtifact, applyArtifacts, createArtifactRegistry, measureMarginalLift };
@@ -0,0 +1,174 @@
1
+ import {
2
+ ValidationError
3
+ } from "./chunk-NBV35BR6.js";
4
+ import "./chunk-DGUM43GV.js";
5
+
6
+ // src/lifecycle/apply.ts
7
+ function applyArtifact(base, artifact) {
8
+ switch (artifact.kind) {
9
+ case "prompt": {
10
+ const payload = artifact.payload;
11
+ const instructions = [...base.prompt?.instructions ?? [], payload.instruction];
12
+ return { ...base, prompt: { ...base.prompt, instructions } };
13
+ }
14
+ case "skill": {
15
+ const payload = artifact.payload;
16
+ const skills = [...base.resources?.skills ?? [], payload.resource];
17
+ return { ...base, resources: { ...base.resources, skills } };
18
+ }
19
+ case "tool": {
20
+ const payload = artifact.payload;
21
+ const key = keyOf(artifact);
22
+ return { ...base, tools: { ...base.tools, [key]: payload.enabled } };
23
+ }
24
+ case "mcp": {
25
+ const payload = artifact.payload;
26
+ const key = keyOf(artifact);
27
+ return { ...base, mcp: { ...base.mcp, [key]: payload.server } };
28
+ }
29
+ case "hook": {
30
+ const payload = artifact.payload;
31
+ const existing = base.hooks?.[payload.event] ?? [];
32
+ return {
33
+ ...base,
34
+ hooks: { ...base.hooks, [payload.event]: [...existing, ...payload.commands] }
35
+ };
36
+ }
37
+ case "subagent": {
38
+ const payload = artifact.payload;
39
+ const key = keyOf(artifact);
40
+ return { ...base, subagents: { ...base.subagents, [key]: payload.profile } };
41
+ }
42
+ }
43
+ }
44
+ function applyArtifacts(base, artifacts) {
45
+ return artifacts.reduce((profile, artifact) => applyArtifact(profile, artifact), base);
46
+ }
47
+ function keyOf(artifact) {
48
+ return artifact.key ?? artifact.id;
49
+ }
50
+
51
+ // src/lifecycle/marginal-lift.ts
52
+ async function measureMarginalLift(opts) {
53
+ const { baseline, candidate, evalRunner, baselineResult, signal } = opts;
54
+ const withoutArtifact = baselineResult ?? await evalRunner(baseline, signal);
55
+ const withProfile = applyArtifact(baseline, candidate);
56
+ const withArtifact = await evalRunner(withProfile, signal);
57
+ return {
58
+ artifactId: candidate.id,
59
+ withArtifact,
60
+ withoutArtifact,
61
+ scoreDelta: withArtifact.composite - withoutArtifact.composite,
62
+ costDelta: withArtifact.costUsd - withoutArtifact.costUsd
63
+ };
64
+ }
65
+
66
+ // src/lifecycle/registry.ts
67
+ var ArtifactRegistry = class {
68
+ artifacts = /* @__PURE__ */ new Map();
69
+ counter = 0;
70
+ /**
71
+ * Register an artifact, returning the stored record (with its assigned id).
72
+ * When `input.id` is set it is honored (idempotent re-registration replaces
73
+ * the record under the same id); otherwise a stable id is minted as
74
+ * `<kind>-<n>`. `status` defaults to `'candidate'`.
75
+ */
76
+ register(input) {
77
+ const id = input.id ?? this.mintId(input.kind);
78
+ if (input.id !== void 0 && (input.id.length === 0 || input.id.trim() !== input.id)) {
79
+ throw new ValidationError(
80
+ `ArtifactRegistry.register: explicit id must be a non-empty, untrimmed-free string (got ${JSON.stringify(input.id)})`
81
+ );
82
+ }
83
+ const record = {
84
+ id,
85
+ kind: input.kind,
86
+ key: input.key,
87
+ name: input.name,
88
+ description: input.description,
89
+ payload: input.payload,
90
+ status: input.status ?? "candidate",
91
+ metadata: input.metadata
92
+ };
93
+ this.artifacts.set(id, record);
94
+ return record;
95
+ }
96
+ /** Get an artifact by id, or `undefined` if it was never registered. */
97
+ get(id) {
98
+ return this.artifacts.get(id);
99
+ }
100
+ /**
101
+ * List artifacts, optionally filtered by `kind` and/or `status`. Returns a new
102
+ * array in registration order; callers may safely sort/mutate the result.
103
+ */
104
+ list(query = {}) {
105
+ const out = [];
106
+ for (const artifact of this.artifacts.values()) {
107
+ if (query.kind !== void 0 && artifact.kind !== query.kind) continue;
108
+ if (query.status !== void 0 && artifact.status !== query.status) continue;
109
+ out.push(artifact);
110
+ }
111
+ return out;
112
+ }
113
+ /**
114
+ * Mark an artifact `promoted`. Fails loud on an unknown id — promoting a
115
+ * non-existent artifact is a caller bug, not a no-op. Returns the updated
116
+ * record. Idempotent: promoting an already-promoted artifact is a no-op
117
+ * return.
118
+ */
119
+ promote(id) {
120
+ const artifact = this.artifacts.get(id);
121
+ if (!artifact) {
122
+ throw new ValidationError(
123
+ `ArtifactRegistry.promote: no artifact with id ${JSON.stringify(id)} is registered`
124
+ );
125
+ }
126
+ if (artifact.status === "promoted") return artifact;
127
+ const promoted = { ...artifact, status: "promoted" };
128
+ this.artifacts.set(id, promoted);
129
+ return promoted;
130
+ }
131
+ /**
132
+ * Compose a set of registered artifacts onto a baseline profile. With no ids
133
+ * given, composes every `promoted` artifact (the "ship the passing set"
134
+ * default). With explicit ids, composes exactly those (in id order given),
135
+ * failing loud on any unknown id. The applied order is the order passed (or
136
+ * registration order for the promoted-default), and later artifacts win on key
137
+ * conflicts — same semantics as `applyArtifacts`.
138
+ */
139
+ compose(base, ids) {
140
+ const selected = ids === void 0 ? this.list({ status: "promoted" }) : ids.map((id) => {
141
+ const artifact = this.artifacts.get(id);
142
+ if (!artifact) {
143
+ throw new ValidationError(
144
+ `ArtifactRegistry.compose: no artifact with id ${JSON.stringify(id)} is registered`
145
+ );
146
+ }
147
+ return artifact;
148
+ });
149
+ return applyArtifacts(base, selected);
150
+ }
151
+ /** Number of registered artifacts (any status). */
152
+ get size() {
153
+ return this.artifacts.size;
154
+ }
155
+ mintId(kind) {
156
+ let id;
157
+ do {
158
+ this.counter += 1;
159
+ id = `${kind}-${this.counter}`;
160
+ } while (this.artifacts.has(id));
161
+ return id;
162
+ }
163
+ };
164
+ function createArtifactRegistry() {
165
+ return new ArtifactRegistry();
166
+ }
167
+ export {
168
+ ArtifactRegistry,
169
+ applyArtifact,
170
+ applyArtifacts,
171
+ createArtifactRegistry,
172
+ measureMarginalLift
173
+ };
174
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lifecycle/apply.ts","../src/lifecycle/marginal-lift.ts","../src/lifecycle/registry.ts"],"sourcesContent":["/**\n * `applyArtifact` — merge one `ProfileArtifact` onto an `AgentProfile`.\n *\n * This is the deterministic bridge between the artifact catalog and the §1.5\n * profile law: each `ArtifactKind` lands on exactly one profile field. The merge\n * is shallow-immutable — the input profile is never mutated; a new profile with\n * the artifact applied is returned. This is the ONE place that knows how a\n * `kind` maps to a profile field, so both the registry's `compose` and\n * `measureMarginalLift`'s with/without ablation share a single source of truth.\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport type { ProfileArtifact } from './types'\n\n/**\n * Return a new profile with `artifact` merged onto `base`. Keyed kinds\n * (`tool`/`mcp`/`hook`/`subagent`) land under `artifact.key` (falling back to\n * `artifact.id`). `prompt` appends an instruction line; `skill` appends a\n * resource ref. Existing keys are overwritten by the artifact (the artifact is\n * the candidate being measured/promoted, so it wins on conflict).\n */\nexport function applyArtifact(base: AgentProfile, artifact: ProfileArtifact): AgentProfile {\n switch (artifact.kind) {\n case 'prompt': {\n const payload = artifact.payload as { instruction: string }\n const instructions = [...(base.prompt?.instructions ?? []), payload.instruction]\n return { ...base, prompt: { ...base.prompt, instructions } }\n }\n case 'skill': {\n const payload = artifact.payload as ProfileArtifact<'skill'>['payload']\n const skills = [...(base.resources?.skills ?? []), payload.resource]\n return { ...base, resources: { ...base.resources, skills } }\n }\n case 'tool': {\n const payload = artifact.payload as ProfileArtifact<'tool'>['payload']\n const key = keyOf(artifact)\n return { ...base, tools: { ...base.tools, [key]: payload.enabled } }\n }\n case 'mcp': {\n const payload = artifact.payload as ProfileArtifact<'mcp'>['payload']\n const key = keyOf(artifact)\n return { ...base, mcp: { ...base.mcp, [key]: payload.server } }\n }\n case 'hook': {\n const payload = artifact.payload as ProfileArtifact<'hook'>['payload']\n const existing = base.hooks?.[payload.event] ?? []\n return {\n ...base,\n hooks: { ...base.hooks, [payload.event]: [...existing, ...payload.commands] },\n }\n }\n case 'subagent': {\n const payload = artifact.payload as ProfileArtifact<'subagent'>['payload']\n const key = keyOf(artifact)\n return { ...base, subagents: { ...base.subagents, [key]: payload.profile } }\n }\n }\n}\n\n/** Apply many artifacts left-to-right; later artifacts win on key conflicts. */\nexport function applyArtifacts(\n base: AgentProfile,\n artifacts: readonly ProfileArtifact[],\n): AgentProfile {\n return artifacts.reduce((profile, artifact) => applyArtifact(profile, artifact), base)\n}\n\n/** The profile-field key a keyed artifact lands under: explicit `key` or `id`. */\nfunction keyOf(artifact: ProfileArtifact): string {\n return artifact.key ?? artifact.id\n}\n","/**\n * `measureMarginalLift` — the with-vs-without ablation for one artifact.\n *\n * \"What does THIS one piece add?\" is the question a lifecycle has to answer\n * before it can promote anything. The answer is an ablation: score the baseline\n * profile, score the baseline-plus-candidate profile, and report the delta. This\n * is the marginal contribution of the artifact — the same shape the project's\n * `OutcomeMeasurement` reports for an apply pass, but isolated to ONE artifact so\n * a registry can rank candidates by what they individually earn.\n *\n * The measurement is selector-agnostic: it takes an `EvalRunner` the caller\n * supplies (any function that scores a profile and reports cost), runs it twice,\n * and subtracts. It never judges, never picks a winner, never re-scores on a\n * holdout — those are the gate's job. It only quantifies the ablation so the gate\n * has a real number to decide on.\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { applyArtifact } from './apply'\nimport type { ProfileArtifact } from './types'\n\n/**\n * The result of running an eval over ONE profile: a composite score and the cost\n * to obtain it. This mirrors the project's score/cost convention (`composite`\n * from `OutcomeMeasurement`, `costUsd` from `LoopResult`), so a caller can pass a\n * thin wrapper over `runLoop` / `runBenchmark` / `runAgentEval` directly.\n */\nexport interface EvalResult {\n /** Composite score in `[0, 1]` (higher is better) for the profile under test. */\n composite: number\n /** USD cost to produce this result. */\n costUsd: number\n /** Optional opaque passthrough (per-task cells, the raw report, …). */\n details?: unknown\n}\n\n/**\n * Scores a profile. The caller wires this to whatever eval they run — a\n * `runLoop` rollout, a `runBenchmark` campaign, a `runAgentEval` cohort — and\n * returns the composite + cost. `signal` is forwarded for cancellation.\n */\nexport type EvalRunner = (profile: AgentProfile, signal?: AbortSignal) => Promise<EvalResult>\n\nexport interface MeasureMarginalLiftOptions {\n /** The profile the artifact is measured ON TOP OF (the \"without\" arm). */\n baseline: AgentProfile\n /** The single artifact whose marginal contribution we want. */\n candidate: ProfileArtifact\n /** The eval that scores a profile. Run once per arm (twice total). */\n evalRunner: EvalRunner\n /**\n * A pre-computed baseline result, to skip the \"without\" run when the caller\n * already scored the baseline (e.g. measuring several candidates against the\n * same baseline). When set, the baseline arm is NOT re-run.\n */\n baselineResult?: EvalResult\n /** Forwarded to both `evalRunner` invocations for cancellation. */\n signal?: AbortSignal\n}\n\n/**\n * The marginal lift of one artifact: the with/without ablation.\n *\n * `scoreDelta = with.composite − without.composite`. A positive `scoreDelta` is\n * the evidence a gate needs to promote; a negative one is the signal to drop the\n * artifact. `costDelta` is the extra USD the artifact costs (often positive — a\n * new tool/MCP adds calls) and lets the gate weigh lift against spend.\n */\nexport interface MarginalLift {\n /** The artifact id this measurement is for (stable, from the registry). */\n artifactId: string\n /** Eval of `applyArtifact(baseline, candidate)`. */\n withArtifact: EvalResult\n /** Eval of `baseline` alone. */\n withoutArtifact: EvalResult\n /** `withArtifact.composite − withoutArtifact.composite`. */\n scoreDelta: number\n /** `withArtifact.costUsd − withoutArtifact.costUsd`. */\n costDelta: number\n}\n\n/**\n * Run the with/without ablation for `candidate` over `baseline` and return its\n * marginal score/cost contribution.\n *\n * The \"without\" arm scores the baseline profile unchanged; the \"with\" arm scores\n * `applyArtifact(baseline, candidate)`. Both use the same `evalRunner`, so the\n * delta isolates the artifact's effect (eval method held constant). The baseline\n * arm is skipped when `baselineResult` is supplied.\n *\n * @example\n * const lift = await measureMarginalLift({\n * baseline,\n * candidate: registry.get(id)!,\n * evalRunner: (profile) => scoreProfileOnCohort(profile),\n * })\n * if (lift.scoreDelta > 0) registry.promote(lift.artifactId)\n */\nexport async function measureMarginalLift(opts: MeasureMarginalLiftOptions): Promise<MarginalLift> {\n const { baseline, candidate, evalRunner, baselineResult, signal } = opts\n\n const withoutArtifact = baselineResult ?? (await evalRunner(baseline, signal))\n const withProfile = applyArtifact(baseline, candidate)\n const withArtifact = await evalRunner(withProfile, signal)\n\n return {\n artifactId: candidate.id,\n withArtifact,\n withoutArtifact,\n scoreDelta: withArtifact.composite - withoutArtifact.composite,\n costDelta: withArtifact.costUsd - withoutArtifact.costUsd,\n }\n}\n","/**\n * `ArtifactRegistry` — a typed catalog of profile artifacts with stable ids.\n *\n * The registry is the lifecycle's source of truth for \"what pieces could go into\n * this agent's profile\". It holds `register` / `list` / `get` / `promote`, assigns\n * stable ids, and can `compose` a subset of artifacts onto a baseline profile via\n * the single `applyArtifact` bridge. It owns NO measurement, NO gate, NO LLM — it\n * is a pure in-memory store so callers can persist/snapshot it however they like.\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport { ValidationError } from '../errors'\nimport { applyArtifacts } from './apply'\nimport type { ArtifactInput, ArtifactKind, ArtifactStatus, ProfileArtifact } from './types'\n\n/** Filter for `list`. Omit a field to leave that dimension unconstrained. */\nexport interface ArtifactQuery {\n kind?: ArtifactKind\n status?: ArtifactStatus\n}\n\n/**\n * A typed, in-memory registry of `ProfileArtifact`s with stable ids.\n *\n * Ids are stable for the life of the registry: `register` assigns one (or honors\n * a caller-supplied id idempotently), and no later operation reassigns it.\n * Re-registering the same id REPLACES the artifact's mutable fields but preserves\n * the id, so a re-proposed candidate keeps its identity across generations.\n */\nexport class ArtifactRegistry {\n private readonly artifacts = new Map<string, ProfileArtifact>()\n private counter = 0\n\n /**\n * Register an artifact, returning the stored record (with its assigned id).\n * When `input.id` is set it is honored (idempotent re-registration replaces\n * the record under the same id); otherwise a stable id is minted as\n * `<kind>-<n>`. `status` defaults to `'candidate'`.\n */\n register<K extends ArtifactKind>(input: ArtifactInput<K>): ProfileArtifact<K> {\n const id = input.id ?? this.mintId(input.kind)\n if (input.id !== undefined && (input.id.length === 0 || input.id.trim() !== input.id)) {\n throw new ValidationError(\n `ArtifactRegistry.register: explicit id must be a non-empty, untrimmed-free string (got ${JSON.stringify(input.id)})`,\n )\n }\n const record: ProfileArtifact<K> = {\n id,\n kind: input.kind,\n key: input.key,\n name: input.name,\n description: input.description,\n payload: input.payload,\n status: input.status ?? 'candidate',\n metadata: input.metadata,\n }\n this.artifacts.set(id, record as ProfileArtifact)\n return record\n }\n\n /** Get an artifact by id, or `undefined` if it was never registered. */\n get(id: string): ProfileArtifact | undefined {\n return this.artifacts.get(id)\n }\n\n /**\n * List artifacts, optionally filtered by `kind` and/or `status`. Returns a new\n * array in registration order; callers may safely sort/mutate the result.\n */\n list(query: ArtifactQuery = {}): ProfileArtifact[] {\n const out: ProfileArtifact[] = []\n for (const artifact of this.artifacts.values()) {\n if (query.kind !== undefined && artifact.kind !== query.kind) continue\n if (query.status !== undefined && artifact.status !== query.status) continue\n out.push(artifact)\n }\n return out\n }\n\n /**\n * Mark an artifact `promoted`. Fails loud on an unknown id — promoting a\n * non-existent artifact is a caller bug, not a no-op. Returns the updated\n * record. Idempotent: promoting an already-promoted artifact is a no-op\n * return.\n */\n promote(id: string): ProfileArtifact {\n const artifact = this.artifacts.get(id)\n if (!artifact) {\n throw new ValidationError(\n `ArtifactRegistry.promote: no artifact with id ${JSON.stringify(id)} is registered`,\n )\n }\n if (artifact.status === 'promoted') return artifact\n const promoted: ProfileArtifact = { ...artifact, status: 'promoted' }\n this.artifacts.set(id, promoted)\n return promoted\n }\n\n /**\n * Compose a set of registered artifacts onto a baseline profile. With no ids\n * given, composes every `promoted` artifact (the \"ship the passing set\"\n * default). With explicit ids, composes exactly those (in id order given),\n * failing loud on any unknown id. The applied order is the order passed (or\n * registration order for the promoted-default), and later artifacts win on key\n * conflicts — same semantics as `applyArtifacts`.\n */\n compose(base: AgentProfile, ids?: readonly string[]): AgentProfile {\n const selected =\n ids === undefined\n ? this.list({ status: 'promoted' })\n : ids.map((id) => {\n const artifact = this.artifacts.get(id)\n if (!artifact) {\n throw new ValidationError(\n `ArtifactRegistry.compose: no artifact with id ${JSON.stringify(id)} is registered`,\n )\n }\n return artifact\n })\n return applyArtifacts(base, selected)\n }\n\n /** Number of registered artifacts (any status). */\n get size(): number {\n return this.artifacts.size\n }\n\n private mintId(kind: ArtifactKind): string {\n let id: string\n do {\n this.counter += 1\n id = `${kind}-${this.counter}`\n } while (this.artifacts.has(id))\n return id\n }\n}\n\n/** Construct an empty `ArtifactRegistry`. */\nexport function createArtifactRegistry(): ArtifactRegistry {\n return new ArtifactRegistry()\n}\n"],"mappings":"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","names":[]}
@@ -2,8 +2,8 @@ import { Scenario } from '@tangle-network/agent-eval/campaign';
2
2
  import { SelfImproveOptions, SelfImproveResult } from '@tangle-network/agent-eval/contract';
3
3
  import { R as RunAnalystLoopOpts, a as RunAnalystLoopResult } from './types-BC3bZpH0.js';
4
4
  import { F as FactCandidate, C as CreateKbGateOptions } from './kb-gate-CuzMYGYM.js';
5
- import { B as Budget } from './worktree-JXGJ1MxQ.js';
6
- import { A as AuthoredHarness, W as WinnerStrategy, a as WorktreeFanoutOptions, b as WorktreePatchArtifact } from './worktree-fanout-DJHQy7Ux.js';
5
+ import { B as Budget } from './worktree-DaxOvw-C.js';
6
+ import { A as AuthoredHarness, W as WinnerStrategy, a as WorktreeFanoutOptions, b as WorktreePatchArtifact } from './worktree-fanout-DIffZohV.js';
7
7
 
8
8
  /**
9
9
  * @experimental
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
- export { L as LoopRunnerCliArgs, e as LoopRunnerCliResult, p as parseLoopRunnerArgv, k as runLoopRunnerCli } from './loop-runner-bin-B7biH0Gk.js';
2
+ export { L as LoopRunnerCliArgs, e as LoopRunnerCliResult, p as parseLoopRunnerArgv, k as runLoopRunnerCli } from './loop-runner-bin-eD3m0rHW.js';
3
3
  import '@tangle-network/agent-eval/campaign';
4
4
  import '@tangle-network/agent-eval/contract';
5
5
  import './types-BC3bZpH0.js';
6
6
  import '@tangle-network/agent-eval';
7
7
  import './kb-gate-CuzMYGYM.js';
8
- import './worktree-JXGJ1MxQ.js';
8
+ import './worktree-DaxOvw-C.js';
9
9
  import 'node:child_process';
10
10
  import '@tangle-network/agent-interface';
11
11
  import '@tangle-network/sandbox';
12
- import './types-K8-xkiw1.js';
13
- import './worktree-fanout-DJHQy7Ux.js';
12
+ import './types-JufmXF2a.js';
13
+ import './worktree-fanout-DIffZohV.js';
@@ -2,13 +2,14 @@
2
2
  import {
3
3
  parseLoopRunnerArgv,
4
4
  runLoopRunnerCli
5
- } from "./chunk-HXVMLRYU.js";
6
- import "./chunk-P5OKDSLB.js";
5
+ } from "./chunk-U56XGKVY.js";
7
6
  import "./chunk-FNMGYYSS.js";
8
- import "./chunk-PHKNOAOU.js";
9
- import "./chunk-55WKGOGU.js";
7
+ import "./chunk-HPYWEFVY.js";
8
+ import "./chunk-NCH4XUZ7.js";
10
9
  import "./chunk-VMNEQHJR.js";
11
- import "./chunk-VLF5RHEQ.js";
10
+ import "./chunk-IODKUOBA.js";
11
+ import "./chunk-T2HVQVB4.js";
12
+ import "./chunk-NBV35BR6.js";
12
13
  import "./chunk-WIR4HOOJ.js";
13
14
  import "./chunk-DGUM43GV.js";
14
15
  export {