@eir-labs/coltrane 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +85 -0
- package/agents/anticipation-mapper.json +34 -0
- package/agents/claim-amender.json +34 -0
- package/agents/claim-architect.json +34 -0
- package/agents/claim-rewriter.json +32 -0
- package/agents/delivery-finalizer.json +40 -0
- package/agents/diamond-cutter.json +33 -0
- package/agents/disclosure-analyst.json +26 -0
- package/agents/domain-explorer.json +37 -0
- package/agents/e2e-runner.json +34 -0
- package/agents/e2e-suite-judge.json +26 -0
- package/agents/event-clusterer.json +29 -0
- package/agents/novelty-searcher.json +40 -0
- package/agents/patent-browser-scout.json +49 -0
- package/agents/patent-examiner.json +36 -0
- package/agents/phase_agents/claim-rewriter.md +44 -0
- package/agents/phase_agents/delivery-finalizer.md +30 -0
- package/agents/phase_agents/diamond-cutter.md +47 -0
- package/agents/phase_agents/domain-explorer.md +27 -0
- package/agents/phase_agents/novelty-searcher.md +50 -0
- package/agents/phase_agents/problem-definer.md +32 -0
- package/agents/phase_agents/solution-developer.md +26 -0
- package/agents/phase_agents/verdict-judger.md +70 -0
- package/agents/players/audience-modeler.md +40 -0
- package/agents/players/chain-audit-keeper.md +41 -0
- package/agents/players/illumination-reviewer.md +42 -0
- package/agents/players/methodology-cadence-keeper.md +42 -0
- package/agents/players/substrate-edge-keeper.md +45 -0
- package/agents/prior-art-scout.json +45 -0
- package/agents/problem-definer.json +35 -0
- package/agents/seeds/steve_seed_a.json +12 -0
- package/agents/seeds/steve_seed_b.json +12 -0
- package/agents/seeds/steve_seed_c.json +12 -0
- package/agents/seeds/steve_seed_d.json +12 -0
- package/agents/sensor.json +22 -0
- package/agents/solution-developer.json +35 -0
- package/agents/source-walker.json +38 -0
- package/agents/spec-drafter.json +31 -0
- package/agents/sub_thread_soft_judge.json +26 -0
- package/agents/sub_thread_trace_sensor.json +22 -0
- package/agents/summarizer.json +25 -0
- package/agents/synthesis-writer.json +29 -0
- package/agents/triage-judge.json +39 -0
- package/agents/user_flow_judge.json +26 -0
- package/agents/user_flow_sensor.json +22 -0
- package/agents/verdict-judger.json +39 -0
- package/core_types/artifact.json +17 -0
- package/core_types/interpretation.json +16 -0
- package/core_types/judgment.json +16 -0
- package/core_types/plan.json +16 -0
- package/core_types/signal.json +16 -0
- package/core_types/verdict.json +27 -0
- package/dist/src/access_grant.d.ts +46 -0
- package/dist/src/access_grant.js +76 -0
- package/dist/src/access_grant.js.map +1 -0
- package/dist/src/acoustics.d.ts +9 -0
- package/dist/src/acoustics.js +65 -0
- package/dist/src/acoustics.js.map +1 -0
- package/dist/src/agent_profile.d.ts +36 -0
- package/dist/src/agent_profile.js +57 -0
- package/dist/src/agent_profile.js.map +1 -0
- package/dist/src/bifrost_invoker.d.ts +33 -0
- package/dist/src/bifrost_invoker.js +85 -0
- package/dist/src/bifrost_invoker.js.map +1 -0
- package/dist/src/canonical_core_types.d.ts +2 -0
- package/dist/src/canonical_core_types.js +111 -0
- package/dist/src/canonical_core_types.js.map +1 -0
- package/dist/src/canonical_form.d.ts +55 -0
- package/dist/src/canonical_form.js +93 -0
- package/dist/src/canonical_form.js.map +1 -0
- package/dist/src/charter.d.ts +37 -0
- package/dist/src/charter.js +86 -0
- package/dist/src/charter.js.map +1 -0
- package/dist/src/circle_of_fifths.d.ts +27 -0
- package/dist/src/circle_of_fifths.js +78 -0
- package/dist/src/circle_of_fifths.js.map +1 -0
- package/dist/src/claude_invoker.d.ts +102 -0
- package/dist/src/claude_invoker.js +760 -0
- package/dist/src/claude_invoker.js.map +1 -0
- package/dist/src/coltrane_profile.d.ts +87 -0
- package/dist/src/coltrane_profile.js +132 -0
- package/dist/src/coltrane_profile.js.map +1 -0
- package/dist/src/composition.d.ts +57 -0
- package/dist/src/composition.js +447 -0
- package/dist/src/composition.js.map +1 -0
- package/dist/src/core_types.d.ts +6 -0
- package/dist/src/core_types.js +25 -0
- package/dist/src/core_types.js.map +1 -0
- package/dist/src/document_factory.d.ts +89 -0
- package/dist/src/document_factory.js +176 -0
- package/dist/src/document_factory.js.map +1 -0
- package/dist/src/genome_schema.d.ts +512 -0
- package/dist/src/genome_schema.js +168 -0
- package/dist/src/genome_schema.js.map +1 -0
- package/dist/src/genome_writer.d.ts +67 -0
- package/dist/src/genome_writer.js +179 -0
- package/dist/src/genome_writer.js.map +1 -0
- package/dist/src/gig_song.d.ts +29 -0
- package/dist/src/gig_song.js +56 -0
- package/dist/src/gig_song.js.map +1 -0
- package/dist/src/gig_tracker.d.ts +54 -0
- package/dist/src/gig_tracker.js +109 -0
- package/dist/src/gig_tracker.js.map +1 -0
- package/dist/src/harmonic_validation.d.ts +11 -0
- package/dist/src/harmonic_validation.js +35 -0
- package/dist/src/harmonic_validation.js.map +1 -0
- package/dist/src/hooks.d.ts +27 -0
- package/dist/src/hooks.js +2 -0
- package/dist/src/hooks.js.map +1 -0
- package/dist/src/index.d.ts +36 -0
- package/dist/src/index.js +37 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/jsong.d.ts +47 -0
- package/dist/src/jsong.js +130 -0
- package/dist/src/jsong.js.map +1 -0
- package/dist/src/judges/user_flow_judge.d.ts +89 -0
- package/dist/src/judges/user_flow_judge.js +200 -0
- package/dist/src/judges/user_flow_judge.js.map +1 -0
- package/dist/src/learner.d.ts +37 -0
- package/dist/src/learner.js +30 -0
- package/dist/src/learner.js.map +1 -0
- package/dist/src/ledger.d.ts +225 -0
- package/dist/src/ledger.js +306 -0
- package/dist/src/ledger.js.map +1 -0
- package/dist/src/loader.d.ts +87 -0
- package/dist/src/loader.js +504 -0
- package/dist/src/loader.js.map +1 -0
- package/dist/src/mcp.d.ts +23 -0
- package/dist/src/mcp.js +125 -0
- package/dist/src/mcp.js.map +1 -0
- package/dist/src/modulation_path.d.ts +42 -0
- package/dist/src/modulation_path.js +60 -0
- package/dist/src/modulation_path.js.map +1 -0
- package/dist/src/output_validation.d.ts +19 -0
- package/dist/src/output_validation.js +51 -0
- package/dist/src/output_validation.js.map +1 -0
- package/dist/src/outputs.d.ts +125 -0
- package/dist/src/outputs.js +452 -0
- package/dist/src/outputs.js.map +1 -0
- package/dist/src/overtones.d.ts +42 -0
- package/dist/src/overtones.js +98 -0
- package/dist/src/overtones.js.map +1 -0
- package/dist/src/player_to_claude_code.d.ts +17 -0
- package/dist/src/player_to_claude_code.js +141 -0
- package/dist/src/player_to_claude_code.js.map +1 -0
- package/dist/src/playwright_cage.d.ts +28 -0
- package/dist/src/playwright_cage.js +47 -0
- package/dist/src/playwright_cage.js.map +1 -0
- package/dist/src/polyphony.d.ts +46 -0
- package/dist/src/polyphony.js +91 -0
- package/dist/src/polyphony.js.map +1 -0
- package/dist/src/portfolio.d.ts +52 -0
- package/dist/src/portfolio.js +186 -0
- package/dist/src/portfolio.js.map +1 -0
- package/dist/src/pricing.d.ts +23 -0
- package/dist/src/pricing.js +16 -0
- package/dist/src/pricing.js.map +1 -0
- package/dist/src/registry.d.ts +46 -0
- package/dist/src/registry.js +199 -0
- package/dist/src/registry.js.map +1 -0
- package/dist/src/runtime.d.ts +304 -0
- package/dist/src/runtime.js +1099 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/server.d.ts +88 -0
- package/dist/src/server.js +1692 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/server_entry.d.ts +2 -0
- package/dist/src/server_entry.js +40 -0
- package/dist/src/server_entry.js.map +1 -0
- package/dist/src/server_relay.d.ts +82 -0
- package/dist/src/server_relay.js +341 -0
- package/dist/src/server_relay.js.map +1 -0
- package/dist/src/simulate.d.ts +60 -0
- package/dist/src/simulate.js +72 -0
- package/dist/src/simulate.js.map +1 -0
- package/dist/src/skill_runner.mjs +34 -0
- package/dist/src/skill_subprocess.d.ts +65 -0
- package/dist/src/skill_subprocess.js +132 -0
- package/dist/src/skill_subprocess.js.map +1 -0
- package/dist/src/skills.d.ts +85 -0
- package/dist/src/skills.js +258 -0
- package/dist/src/skills.js.map +1 -0
- package/dist/src/subthread_recorder.d.ts +68 -0
- package/dist/src/subthread_recorder.js +166 -0
- package/dist/src/subthread_recorder.js.map +1 -0
- package/dist/src/tensor_read.d.ts +38 -0
- package/dist/src/tensor_read.js +60 -0
- package/dist/src/tensor_read.js.map +1 -0
- package/dist/src/test_honest_broker.d.ts +34 -0
- package/dist/src/test_honest_broker.js +155 -0
- package/dist/src/test_honest_broker.js.map +1 -0
- package/dist/src/test_topology.d.ts +22 -0
- package/dist/src/test_topology.js +137 -0
- package/dist/src/test_topology.js.map +1 -0
- package/dist/src/tones.d.ts +20 -0
- package/dist/src/tones.js +81 -0
- package/dist/src/tones.js.map +1 -0
- package/dist/src/tool_providers.d.ts +45 -0
- package/dist/src/tool_providers.js +104 -0
- package/dist/src/tool_providers.js.map +1 -0
- package/dist/src/type_versioning.d.ts +23 -0
- package/dist/src/type_versioning.js +31 -0
- package/dist/src/type_versioning.js.map +1 -0
- package/dist/src/version.d.ts +28 -0
- package/dist/src/version.js +86 -0
- package/dist/src/version.js.map +1 -0
- package/domain_types/claim-draft.json +34 -0
- package/domain_types/coverage-report.json +31 -0
- package/domain_types/draft-agent-profile.json +31 -0
- package/domain_types/draft-domain-type.json +28 -0
- package/domain_types/draft-standard.json +46 -0
- package/domain_types/e2e-observation.json +32 -0
- package/domain_types/e2e-report.json +30 -0
- package/domain_types/e2e-target.json +26 -0
- package/domain_types/e2e-verdict.json +26 -0
- package/domain_types/examine-round-record.json +40 -0
- package/domain_types/examiner-rejection.json +28 -0
- package/domain_types/failure-modes.json +31 -0
- package/domain_types/invention-analysis.json +34 -0
- package/domain_types/invention-spec.json +34 -0
- package/domain_types/novelty-analysis.json +28 -0
- package/domain_types/novelty-verdict.json +35 -0
- package/domain_types/parsed-conversation-trace.json +38 -0
- package/domain_types/pattern-extraction.json +62 -0
- package/domain_types/prior-art-hit.json +50 -0
- package/domain_types/project-charter.json +71 -0
- package/domain_types/provisional-draft.json +34 -0
- package/domain_types/raw-note.json +19 -0
- package/domain_types/repo-survey.json +28 -0
- package/domain_types/seeding-verdict.json +70 -0
- package/domain_types/soft-verdict.json +55 -0
- package/domain_types/summary.json +19 -0
- package/domain_types/triage-verdict.json +59 -0
- package/domain_types/user-flow-transcript.json +43 -0
- package/domain_types/user-flow-verdict.json +60 -0
- package/domain_types/verdict-record.json +39 -0
- package/package.json +82 -0
- package/skills/citation-verify/fixtures/basic.json +14 -0
- package/skills/citation-verify/meta.json +10 -0
- package/skills/citation-verify/skill.mjs +26 -0
- package/skills/claim-element-decompose/fixtures/basic.json +11 -0
- package/skills/claim-element-decompose/meta.json +10 -0
- package/skills/claim-element-decompose/skill.mjs +14 -0
- package/skills/diamond-cutting-discipline/fixtures/basic.json +13 -0
- package/skills/diamond-cutting-discipline/meta.json +19 -0
- package/skills/diamond-cutting-discipline/skill.md +46 -0
- package/skills/element-mapping-matrix/fixtures/basic.json +13 -0
- package/skills/element-mapping-matrix/meta.json +10 -0
- package/skills/element-mapping-matrix/skill.mjs +20 -0
- package/skills/number-adder/fixtures/basic.json +9 -0
- package/skills/number-adder/meta.json +10 -0
- package/skills/number-adder/skill.mjs +12 -0
- package/skills/patent-fetch/fixtures/parse.json +18 -0
- package/skills/patent-fetch/meta.json +11 -0
- package/skills/patent-fetch/skill.mjs +34 -0
- package/skills/query-expand/fixtures/basic.json +14 -0
- package/skills/query-expand/meta.json +10 -0
- package/skills/query-expand/skill.mjs +29 -0
- package/skills/run-vitest-band/fixtures/basic.json +9 -0
- package/skills/run-vitest-band/meta.json +18 -0
- package/skills/run-vitest-band/skill.mjs +22 -0
- package/skills/statutory-checklist/fixtures/basic.json +16 -0
- package/skills/statutory-checklist/meta.json +10 -0
- package/skills/statutory-checklist/skill.mjs +25 -0
- package/skills/summarize-tight/fixtures/basic.json +13 -0
- package/skills/summarize-tight/meta.json +20 -0
- package/skills/summarize-tight/skill.md +1 -0
- package/skills/verdict-gate/fixtures/basic.json +9 -0
- package/skills/verdict-gate/meta.json +10 -0
- package/skills/verdict-gate/skill.mjs +82 -0
- package/standards/e2e-suite-v0.json +44 -0
- package/standards/patent-triage-v0.json +98 -0
- package/standards/patent-triage-v1.json +84 -0
- package/standards/seed-from-local-repos-v0.json +115 -0
- package/standards/sub_thread_invocation.json +50 -0
- package/standards/summarize.json +40 -0
- package/standards/synthesis-walk-v0.json +108 -0
- package/standards/user_flow_correctness.json +57 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const DEPTH_MULTIPLIER = { skim: 0.5, quick: 0.75, standard: 1.0, deep: 2.0 };
|
|
2
|
+
export const MODEL_MULTIPLIER = { economy: 0.5, standard: 1.0, premium: 2.0 };
|
|
3
|
+
// The admissible depth values, derived from the multiplier table so the two cannot drift.
|
|
4
|
+
// #237 — `depth` was advertised on gig_dispatch and silently discarded; a dispatch-time depth
|
|
5
|
+
// now has to BE one of these or the call fails loudly, because "silently ran at full depth"
|
|
6
|
+
// is exactly the failure the parameter existed to prevent.
|
|
7
|
+
export const DEPTHS = Object.keys(DEPTH_MULTIPLIER);
|
|
8
|
+
export function isDepth(v) {
|
|
9
|
+
return typeof v === "string" && DEPTHS.includes(v);
|
|
10
|
+
}
|
|
11
|
+
export function computeCredits(input) {
|
|
12
|
+
return (input.base_cost * DEPTH_MULTIPLIER[input.depth] * MODEL_MULTIPLIER[input.model_tier] +
|
|
13
|
+
input.agents * 0.5 +
|
|
14
|
+
input.external_tool_calls * 0.1);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=pricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/pricing.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAW,CAAC;AAC9F,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAW,CAAC;AAKvF,0FAA0F;AAC1F,8FAA8F;AAC9F,4FAA4F;AAC5F,2DAA2D;AAC3D,MAAM,CAAC,MAAM,MAAM,GAAqB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAY,CAAC;AACjF,MAAM,UAAU,OAAO,CAAC,CAAU;IAChC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAK,MAA4B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC;AAUD,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,OAAO,CACL,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC;QACpF,KAAK,CAAC,MAAM,GAAG,GAAG;QAClB,KAAK,CAAC,mBAAmB,GAAG,GAAG,CAChC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type DomainTypeOutput } from "./genome_schema.js";
|
|
2
|
+
import type { LoadedGenome } from "./loader.js";
|
|
3
|
+
export declare const RESOLVE_WEIGHTS: {
|
|
4
|
+
readonly field_coverage: 0.4;
|
|
5
|
+
readonly usage_gravity: 0.15;
|
|
6
|
+
readonly downstream_satisfaction: 0.2;
|
|
7
|
+
readonly domain_affinity: 0.15;
|
|
8
|
+
readonly recency: 0.1;
|
|
9
|
+
};
|
|
10
|
+
export type DomainType = Pick<DomainTypeOutput, "slug" | "extends" | "domain" | "schema" | "required_fields">;
|
|
11
|
+
export interface ResolveQuery {
|
|
12
|
+
extends: string;
|
|
13
|
+
domain: string;
|
|
14
|
+
required_fields: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface ResolveResult {
|
|
17
|
+
score: number;
|
|
18
|
+
action: "use" | "extend" | "create";
|
|
19
|
+
candidates: DomainType[];
|
|
20
|
+
}
|
|
21
|
+
export interface OutputToValidate {
|
|
22
|
+
core_type: string;
|
|
23
|
+
domain_type: string;
|
|
24
|
+
input_refs?: string[];
|
|
25
|
+
data: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
export interface RegistryValidationResult {
|
|
28
|
+
valid: boolean;
|
|
29
|
+
errors: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface Registry {
|
|
32
|
+
registerType(def: DomainType): {
|
|
33
|
+
registered: true;
|
|
34
|
+
version: number;
|
|
35
|
+
};
|
|
36
|
+
resolveType(query: ResolveQuery): ResolveResult;
|
|
37
|
+
validate(output: OutputToValidate): RegistryValidationResult;
|
|
38
|
+
listTypes(): DomainType[];
|
|
39
|
+
replaceTypes(defs: readonly DomainType[]): {
|
|
40
|
+
added: string[];
|
|
41
|
+
modified: string[];
|
|
42
|
+
removed: string[];
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export declare function createRegistry(initial?: DomainType[]): Registry;
|
|
46
|
+
export declare function loadRegistry(genome: LoadedGenome): Registry;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import Ajv from "ajv";
|
|
2
|
+
import { CORE_TYPES } from "./core_types.js";
|
|
3
|
+
import { CANONICAL_CORE_TYPES } from "./canonical_core_types.js";
|
|
4
|
+
// Base-type property inheritance (docs/genome-extension.md). A domain type extending
|
|
5
|
+
// a core type inherits the core's schema PROPERTIES — the base fields are "around at
|
|
6
|
+
// runtime" because the core is always loaded — so a subtype instance may carry them.
|
|
7
|
+
// The subtype OVERLOADS (same-named field wins) and EXTENDS (adds new fields). The 6
|
|
8
|
+
// cores are immutable, so we read their properties straight from the canonical set.
|
|
9
|
+
const CORE_SCHEMA_PROPS = Object.fromEntries(CANONICAL_CORE_TYPES.map((c) => [
|
|
10
|
+
c.slug,
|
|
11
|
+
(c.schema.properties ?? {}),
|
|
12
|
+
]));
|
|
13
|
+
export const RESOLVE_WEIGHTS = {
|
|
14
|
+
field_coverage: 0.4,
|
|
15
|
+
usage_gravity: 0.15,
|
|
16
|
+
downstream_satisfaction: 0.2,
|
|
17
|
+
domain_affinity: 0.15,
|
|
18
|
+
recency: 0.1,
|
|
19
|
+
};
|
|
20
|
+
function isCoreType(slug) {
|
|
21
|
+
return CORE_TYPES.includes(slug);
|
|
22
|
+
}
|
|
23
|
+
export function createRegistry(initial = []) {
|
|
24
|
+
const ajv = new Ajv({ allErrors: true, strict: false });
|
|
25
|
+
const types = new Map();
|
|
26
|
+
for (const def of initial)
|
|
27
|
+
types.set(def.slug, def);
|
|
28
|
+
function score(query) {
|
|
29
|
+
const candidates = [...types.values()].filter((t) => t.extends === query.extends);
|
|
30
|
+
if (candidates.length === 0)
|
|
31
|
+
return { score: 0, action: "create", candidates: [] };
|
|
32
|
+
let best = 0;
|
|
33
|
+
for (const c of candidates) {
|
|
34
|
+
const covered = query.required_fields.filter((f) => c.required_fields.includes(f)).length;
|
|
35
|
+
const coverage = query.required_fields.length === 0 ? 1 : covered / query.required_fields.length;
|
|
36
|
+
const affinity = c.domain === query.domain ? 1 : 0;
|
|
37
|
+
// usage_gravity, downstream_satisfaction, recency default to 1 until usage stats exist
|
|
38
|
+
const s = 100 *
|
|
39
|
+
(RESOLVE_WEIGHTS.field_coverage * coverage +
|
|
40
|
+
RESOLVE_WEIGHTS.usage_gravity * 1 +
|
|
41
|
+
RESOLVE_WEIGHTS.downstream_satisfaction * 1 +
|
|
42
|
+
RESOLVE_WEIGHTS.domain_affinity * affinity +
|
|
43
|
+
RESOLVE_WEIGHTS.recency * 1);
|
|
44
|
+
if (s > best)
|
|
45
|
+
best = s;
|
|
46
|
+
}
|
|
47
|
+
const action = best >= 80 ? "use" : best >= 50 ? "extend" : "create";
|
|
48
|
+
return { score: best, action, candidates };
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
registerType(def) {
|
|
52
|
+
if (!isCoreType(def.extends)) {
|
|
53
|
+
throw new Error(`extends must be a core type, got "${def.extends}"`);
|
|
54
|
+
}
|
|
55
|
+
const resolved = score({ extends: def.extends, domain: def.domain, required_fields: def.required_fields });
|
|
56
|
+
if (resolved.score >= 80) {
|
|
57
|
+
throw new Error(`reuse enforcement: an existing type scores ${resolved.score} (>=80)`);
|
|
58
|
+
}
|
|
59
|
+
types.set(def.slug, def);
|
|
60
|
+
return { registered: true, version: 1 };
|
|
61
|
+
},
|
|
62
|
+
resolveType(query) {
|
|
63
|
+
return score(query);
|
|
64
|
+
},
|
|
65
|
+
replaceTypes(defs) {
|
|
66
|
+
const before = new Map(types);
|
|
67
|
+
const added = [];
|
|
68
|
+
const modified = [];
|
|
69
|
+
const removed = [];
|
|
70
|
+
types.clear();
|
|
71
|
+
for (const def of defs) {
|
|
72
|
+
if (!isCoreType(def.extends))
|
|
73
|
+
continue; // soft-skip; mirrors loader's stance
|
|
74
|
+
types.set(def.slug, def);
|
|
75
|
+
const prior = before.get(def.slug);
|
|
76
|
+
if (!prior)
|
|
77
|
+
added.push(def.slug);
|
|
78
|
+
else if (JSON.stringify(prior) !== JSON.stringify(def))
|
|
79
|
+
modified.push(def.slug);
|
|
80
|
+
}
|
|
81
|
+
for (const slug of before.keys()) {
|
|
82
|
+
if (!types.has(slug))
|
|
83
|
+
removed.push(slug);
|
|
84
|
+
}
|
|
85
|
+
return { added, modified, removed };
|
|
86
|
+
},
|
|
87
|
+
validate(output) {
|
|
88
|
+
// Rob #133 — domain_type is OPTIONAL. Empty / missing means the output
|
|
89
|
+
// is freeform vs. its core type (Interpretation, Plan, Artifact, …) but
|
|
90
|
+
// doesn't conform to any registered domain schema. Examples that need
|
|
91
|
+
// this: a discover-phase domain-model document, an analytical plan that
|
|
92
|
+
// doesn't fit a typed plan-shape yet. The core_type discipline still
|
|
93
|
+
// holds; only the domain-schema strictness is bypassed.
|
|
94
|
+
if (!output.domain_type)
|
|
95
|
+
return { valid: true, errors: [] };
|
|
96
|
+
// A bare CORE type as the domain_type is a freeform output of that core (e.g. a
|
|
97
|
+
// skill-backed chair that produces a plain Signal, no domain subtype). The core_type
|
|
98
|
+
// discipline still holds; there's just no domain schema to enforce — same as above.
|
|
99
|
+
// "Still holds" is now a fact rather than a claim: outputs.write runs validateOutput
|
|
100
|
+
// on every seal, so a bare core meets the same substance floor as its subtypes (#227).
|
|
101
|
+
if (isCoreType(output.domain_type))
|
|
102
|
+
return { valid: true, errors: [] };
|
|
103
|
+
const dt = types.get(output.domain_type);
|
|
104
|
+
if (!dt)
|
|
105
|
+
return { valid: false, errors: [`unknown domain_type "${output.domain_type}"`] };
|
|
106
|
+
// Inherit the base core type's properties, then let the subtype overload + extend.
|
|
107
|
+
//
|
|
108
|
+
// MAINTAINER RULING (#227) — "There's no subtype thing. It's all the way top to
|
|
109
|
+
// bottom." This REPLACES the stance that used to be documented here: that a core's
|
|
110
|
+
// base fields are "available, not forced" on a subtype, so `required` stays the
|
|
111
|
+
// subtype's own and existing instances that carry no base field still validate.
|
|
112
|
+
//
|
|
113
|
+
// That stance is wrong. Every core carries ONE substance floor — the declared field
|
|
114
|
+
// that makes its output answerable to someone else (Signal.source, Interpretation.claims,
|
|
115
|
+
// Plan.steps, Judgment.criteria, Artifact.validation_criteria, Verdict.checks) — and
|
|
116
|
+
// that floor is FORCED on every sealed output of that core, bare core or domain
|
|
117
|
+
// subtype alike. See src/output_validation.ts for the table and the per-core reasoning.
|
|
118
|
+
//
|
|
119
|
+
// The forcing lives at the seal boundary (outputs.write → validateOutput), not here,
|
|
120
|
+
// for a reason: it must hold on the paths this function deliberately does not reach —
|
|
121
|
+
// an absent domain_type (line 140), a bare core type as the domain_type (line 144),
|
|
122
|
+
// and a subtype that overloads an inherited floor away (#230). Enforcing it here as
|
|
123
|
+
// well would leave those three holes open. What this function still owns is the
|
|
124
|
+
// subtype's OWN declared contract; `required` below stays the subtype's own because
|
|
125
|
+
// the core's floor is already enforced unconditionally one layer out — not because
|
|
126
|
+
// base fields are optional.
|
|
127
|
+
const baseProps = CORE_SCHEMA_PROPS[dt.extends] ?? {};
|
|
128
|
+
const ownProps = dt.schema.properties ?? {};
|
|
129
|
+
// #200 — honor the type's declared additionalProperties. Closed-by-default
|
|
130
|
+
// stays the discipline (undeclared → false), but a type that opts into open
|
|
131
|
+
// extension with `additionalProperties: true` accepts agent-added contextual
|
|
132
|
+
// fields at seal instead of aborting the terminal chair.
|
|
133
|
+
const additionalProperties = dt.schema.additionalProperties ?? false;
|
|
134
|
+
// #229 — a type's required fields may be declared in EITHER place, and both are
|
|
135
|
+
// honored. Two authoring conventions exist in the genome and nothing reconciles
|
|
136
|
+
// them: most types populate `required_fields` and leave `schema.required` empty;
|
|
137
|
+
// the hand-authored seeding/bootstrap types do the reverse. Reading only
|
|
138
|
+
// `required_fields` (as this did) silently discarded the declaration of every type
|
|
139
|
+
// in the second group, so `{}` sealed as a well-formed instance of a type declaring
|
|
140
|
+
// 3-6 required fields.
|
|
141
|
+
//
|
|
142
|
+
// UNION, not precedence. `type_extend` (src/server.ts:609) resolves the same
|
|
143
|
+
// ambiguity as `schema.required ?? required_fields`, but precedence is the wrong
|
|
144
|
+
// rule at seal time: it makes one declaration silently void the other. No type in
|
|
145
|
+
// the genome populates both today, so the two rules are indistinguishable on
|
|
146
|
+
// current data — which is exactly why the safer rule should be the one that gets
|
|
147
|
+
// frozen in. Everything an author wrote down is enforced.
|
|
148
|
+
const declaredRequired = [
|
|
149
|
+
...new Set([
|
|
150
|
+
...((dt.schema.required) ?? []),
|
|
151
|
+
...dt.required_fields,
|
|
152
|
+
]),
|
|
153
|
+
];
|
|
154
|
+
const schema = {
|
|
155
|
+
type: "object",
|
|
156
|
+
properties: { ...baseProps, ...ownProps },
|
|
157
|
+
required: declaredRequired,
|
|
158
|
+
additionalProperties,
|
|
159
|
+
};
|
|
160
|
+
const validateFn = ajv.compile(schema);
|
|
161
|
+
const ok = validateFn(output.data);
|
|
162
|
+
// Preserve instancePath + keyword in the error projection so operators see
|
|
163
|
+
// the failing field path, not just a type-class message. For property-level
|
|
164
|
+
// failures Ajv puts the field in `params.missingProperty` (required) or
|
|
165
|
+
// in `instancePath` (type mismatch) or `params.additionalProperty` (extras).
|
|
166
|
+
return {
|
|
167
|
+
valid: ok === true,
|
|
168
|
+
errors: (validateFn.errors ?? []).map((e) => {
|
|
169
|
+
const path = e.instancePath ?? "";
|
|
170
|
+
const keyword = e.keyword ?? "";
|
|
171
|
+
const message = e.message ?? "invalid";
|
|
172
|
+
const params = e.params ?? {};
|
|
173
|
+
const missing = typeof params["missingProperty"] === "string"
|
|
174
|
+
? ` '${params["missingProperty"]}'`
|
|
175
|
+
: "";
|
|
176
|
+
const additional = typeof params["additionalProperty"] === "string"
|
|
177
|
+
? ` '${params["additionalProperty"]}'`
|
|
178
|
+
: "";
|
|
179
|
+
const fieldHint = path ? ` at ${path}` : "";
|
|
180
|
+
return `${keyword}${fieldHint}: ${message}${missing}${additional}`.trim();
|
|
181
|
+
}),
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
listTypes() {
|
|
185
|
+
return [...types.values()];
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
export function loadRegistry(genome) {
|
|
190
|
+
const defs = [...genome.domain_types.values()].map((d) => ({
|
|
191
|
+
slug: d.slug,
|
|
192
|
+
extends: d.extends,
|
|
193
|
+
domain: d.domain,
|
|
194
|
+
schema: d.schema,
|
|
195
|
+
required_fields: [...d.required_fields],
|
|
196
|
+
}));
|
|
197
|
+
return createRegistry(defs);
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import type { Standard, Agent, Chair } from "./composition.js";
|
|
2
|
+
import type { OutputStore, OutputRecord } from "./outputs.js";
|
|
3
|
+
import { type Ledger, type GigUsage } from "./ledger.js";
|
|
4
|
+
import type { Depth } from "./pricing.js";
|
|
5
|
+
import type { SkillRecord, EvalRecord } from "./loader.js";
|
|
6
|
+
export interface AgentInvocationContext {
|
|
7
|
+
agent: Agent;
|
|
8
|
+
phase: string;
|
|
9
|
+
inputs: readonly OutputRecord[];
|
|
10
|
+
gig_input: Record<string, unknown>;
|
|
11
|
+
output_types?: readonly string[];
|
|
12
|
+
skills?: readonly SkillRecord[];
|
|
13
|
+
missing_skills?: readonly string[];
|
|
14
|
+
onEvent?: (ev: AgentStreamEvent) => void;
|
|
15
|
+
signal?: AbortSignal | undefined;
|
|
16
|
+
depth?: Depth | undefined;
|
|
17
|
+
}
|
|
18
|
+
export interface AgentStreamEvent {
|
|
19
|
+
type: string;
|
|
20
|
+
tool?: string | undefined;
|
|
21
|
+
text?: string | undefined;
|
|
22
|
+
raw?: unknown;
|
|
23
|
+
}
|
|
24
|
+
export type GigProgressEvent = {
|
|
25
|
+
type: "phase_start";
|
|
26
|
+
phase: string;
|
|
27
|
+
roles: string[];
|
|
28
|
+
} | {
|
|
29
|
+
type: "chair_start";
|
|
30
|
+
phase: string;
|
|
31
|
+
role: string;
|
|
32
|
+
producer: string;
|
|
33
|
+
} | {
|
|
34
|
+
type: "chair_complete";
|
|
35
|
+
phase: string;
|
|
36
|
+
role: string;
|
|
37
|
+
producer: string;
|
|
38
|
+
/** types actually SEALED */
|
|
39
|
+
output_types: string[];
|
|
40
|
+
duration_ms: number;
|
|
41
|
+
/** #243 — types the chair's output_contract PROMISED. Equal to output_types when the
|
|
42
|
+
* chair delivered everything; the difference is what `missing_output_types` names. */
|
|
43
|
+
promised_output_types?: string[];
|
|
44
|
+
/** #243 — promised but not sealed. Legal (conditional outputs) but never silent. */
|
|
45
|
+
missing_output_types?: string[];
|
|
46
|
+
/** #240 — `*_sha` fields the engine could not tie to any consumed input or the gig
|
|
47
|
+
* payload. Sealed as "" rather than guessed; listed here so the gap is visible. */
|
|
48
|
+
unresolved_sha_fields?: string[];
|
|
49
|
+
} | {
|
|
50
|
+
type: "chair_failed";
|
|
51
|
+
phase: string;
|
|
52
|
+
role: string;
|
|
53
|
+
error: string;
|
|
54
|
+
} | {
|
|
55
|
+
type: "skills_unresolved";
|
|
56
|
+
phase: string;
|
|
57
|
+
role: string;
|
|
58
|
+
agent: string;
|
|
59
|
+
missing: string[];
|
|
60
|
+
} | {
|
|
61
|
+
type: "agent_event";
|
|
62
|
+
phase: string;
|
|
63
|
+
role: string;
|
|
64
|
+
event: AgentStreamEvent;
|
|
65
|
+
} | {
|
|
66
|
+
type: "gig_complete";
|
|
67
|
+
outputs: number;
|
|
68
|
+
} | {
|
|
69
|
+
type: "gig_failed";
|
|
70
|
+
error: string;
|
|
71
|
+
} | {
|
|
72
|
+
type: "gig_aborted";
|
|
73
|
+
reason: string;
|
|
74
|
+
};
|
|
75
|
+
export type AgentInvoker = (ctx: AgentInvocationContext) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
76
|
+
export interface ChairSelectionView {
|
|
77
|
+
phase: string;
|
|
78
|
+
ready: readonly Chair[];
|
|
79
|
+
produced: readonly OutputRecord[];
|
|
80
|
+
budget: Readonly<BudgetState> | null;
|
|
81
|
+
standard: Standard;
|
|
82
|
+
}
|
|
83
|
+
export type ChairSelector = (view: ChairSelectionView) => readonly Chair[] | Promise<readonly Chair[]>;
|
|
84
|
+
export interface RunDeps {
|
|
85
|
+
outputs: OutputStore;
|
|
86
|
+
ledger: Ledger;
|
|
87
|
+
invoke: AgentInvoker;
|
|
88
|
+
model_version?: string | undefined;
|
|
89
|
+
skills?: ReadonlyMap<string, SkillRecord> | undefined;
|
|
90
|
+
skill_dirs?: ReadonlyMap<string, string> | undefined;
|
|
91
|
+
evals?: ReadonlyMap<string, EvalRecord> | undefined;
|
|
92
|
+
/**
|
|
93
|
+
* Optional cost-budget input. When omitted (default), no budget enforcement
|
|
94
|
+
* runs — preserving v0 back-compat. When present, the runtime tracks
|
|
95
|
+
* per-gig BudgetState matching budget-state.json schema: balance =
|
|
96
|
+
* opening - spent + credit.
|
|
97
|
+
*
|
|
98
|
+
* The cycle is RESERVE → SETTLE (#232). At chair-prep the runtime computes
|
|
99
|
+
* cost-of-append (base + k*size(input)) and compares it against
|
|
100
|
+
* `balance - reserved`; short → BudgetExhausted. Passing chairs RESERVE the
|
|
101
|
+
* cost. `spent` moves only when a chair's invocation SUCCEEDS, which is what
|
|
102
|
+
* the contract always claimed and what the code did not do: prep runs
|
|
103
|
+
* eagerly for the whole ready batch, so a batch member tripping the gate
|
|
104
|
+
* used to leave every earlier member of that batch charged for work no
|
|
105
|
+
* invoker ever started.
|
|
106
|
+
*
|
|
107
|
+
* The final BudgetState is returned in GigResult.budget_state, and is also
|
|
108
|
+
* attached to a BudgetExhausted / mid-gig error so a FAILED gig can still
|
|
109
|
+
* report what it cost.
|
|
110
|
+
*/
|
|
111
|
+
budget?: BudgetInput | undefined;
|
|
112
|
+
onProgress?: ((ev: GigProgressEvent) => void) | undefined;
|
|
113
|
+
gig_id?: string | undefined;
|
|
114
|
+
selectChairs?: ChairSelector | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* #249/#250 — the cancellation seam. Abort it and the run stops at its next checkpoint
|
|
117
|
+
* (between phases and between dispatch batches) and rejects with `GigAborted`. The same
|
|
118
|
+
* signal is threaded into every AgentInvocationContext, so an invoker that wires it to its
|
|
119
|
+
* subprocess also stops the in-flight chair. Absent = an uncancellable run (the v0 shape).
|
|
120
|
+
*
|
|
121
|
+
* Known bound: a SKILL-backed chair runs `spawnSync` (src/skill_subprocess.ts), which
|
|
122
|
+
* blocks the event loop, so an abort delivered while one is executing is not even RECEIVED
|
|
123
|
+
* until it returns. Skill chairs are therefore a hard uncancellable window of up to their
|
|
124
|
+
* declared `meta.timeout_ms` (default 120s). Deliberate for now — see #253.
|
|
125
|
+
*/
|
|
126
|
+
signal?: AbortSignal | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* #237 — the depth this gig was dispatched at, threaded to every invocation so it reaches
|
|
129
|
+
* the thing that actually spends. Absent = each agent's own `depth_profile` stands.
|
|
130
|
+
*/
|
|
131
|
+
depth?: Depth | undefined;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Per-gig cost-budget input. Honors budget-state.json schema (PR #56). Only
|
|
135
|
+
* `opening` is required for v0 enforcement; the rest are recomputed.
|
|
136
|
+
*
|
|
137
|
+
* COST FORMULA (v0, tunable):
|
|
138
|
+
* cost = base_cost + k * size_bytes(input)
|
|
139
|
+
* defaults: base_cost = 1, k = 0.1
|
|
140
|
+
*
|
|
141
|
+
* Where size_bytes(input) = JSON.stringify(canonical context).length.
|
|
142
|
+
*
|
|
143
|
+
* WHAT THIS IS AND IS NOT (#233). `opening`/`spent`/`balance` are SYNTHETIC APPEND UNITS —
|
|
144
|
+
* see `BudgetState.unit`. They are not dollars and were never converted to dollars; an
|
|
145
|
+
* `opening: 1000` that reads like a dollar figure to an operator is a coincidence of scale.
|
|
146
|
+
* The real, settled figure is `BudgetState.settled_usd`, reconciled from the model's own
|
|
147
|
+
* `result` events at each batch boundary. Two honest limits on the synthetic gate:
|
|
148
|
+
*
|
|
149
|
+
* 1. It is a proxy for prompt size, not a price. It has no model tier, no output side, no
|
|
150
|
+
* skills/charter/schema bytes — only the agent slug, phase, consumed input CONTENT and
|
|
151
|
+
* the gig payload. It is a rate limiter on context growth, nothing more.
|
|
152
|
+
* 2. A USD figure cannot gate a chair before that chair runs, because `prepareChair` runs
|
|
153
|
+
* for the WHOLE ready batch before any invocation — a chair cannot see its batch
|
|
154
|
+
* siblings' settled cost. So reconciliation happens at BATCH BOUNDARIES, and any dollar
|
|
155
|
+
* bound built on it would be a cap plus one batch of slack, never a hard stop. No such
|
|
156
|
+
* bound is wired: there is no per-chair dollar estimator, and inventing one would be
|
|
157
|
+
* guessing. `settled_usd` reports; it does not enforce.
|
|
158
|
+
*/
|
|
159
|
+
export interface BudgetInput {
|
|
160
|
+
opening: number;
|
|
161
|
+
/** base cost per agent invocation, in append units. Default 1. */
|
|
162
|
+
base_cost?: number;
|
|
163
|
+
/** per-byte multiplier on consumed-input size, in append units. Default 0.1. */
|
|
164
|
+
k?: number;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Per-gig budget snapshot. Mirrors fields of domain_types/budget-state.json
|
|
168
|
+
* (PR #56) that are runtime-tractable in v0. balance = opening - spent + credit.
|
|
169
|
+
*
|
|
170
|
+
* The `agent_state` mirrors the budget-state.json enum:
|
|
171
|
+
* active — currently spending, balance > cost-of-next-append
|
|
172
|
+
* yielding — below cost-of-next-append, paused (used when partial)
|
|
173
|
+
* depleted — balance <= 0 OR < cost-of-next-append, hard stop
|
|
174
|
+
* awaiting_grade — work shipped, external grader contacted (v0 unused)
|
|
175
|
+
* settled — cycle closed, closing populated (v0 set on success)
|
|
176
|
+
*/
|
|
177
|
+
export interface BudgetState {
|
|
178
|
+
opening: number;
|
|
179
|
+
/** Cost of chairs that ACTUALLY RAN AND SUCCEEDED. Reserved-but-unsettled cost is not here. */
|
|
180
|
+
spent: number;
|
|
181
|
+
credit: number;
|
|
182
|
+
balance: number;
|
|
183
|
+
agent_state: "active" | "yielding" | "depleted" | "awaiting_grade" | "settled";
|
|
184
|
+
/** Slug of the agent whose invocation tripped depletion. null when solvent. */
|
|
185
|
+
depleted_agent: string | null;
|
|
186
|
+
/** Wall-clock when balance first crossed below cost-of-next-append. null while solvent. */
|
|
187
|
+
depleted_at: string | null;
|
|
188
|
+
base_cost: number;
|
|
189
|
+
k: number;
|
|
190
|
+
/**
|
|
191
|
+
* #233 — the denomination of opening/spent/balance/base_cost/k, stated rather than assumed.
|
|
192
|
+
* These are a synthetic proxy for consumed context bytes. They are NOT dollars, and nothing
|
|
193
|
+
* converts between the two. Read `settled_usd` for money.
|
|
194
|
+
*/
|
|
195
|
+
unit: "append-units";
|
|
196
|
+
/**
|
|
197
|
+
* #233 — REAL settled model spend for this gig so far, in USD, reconciled from the invokers'
|
|
198
|
+
* own `result` events at each dispatch-batch boundary. This is the number `src/ledger.ts`
|
|
199
|
+
* calls settled spend; the budget gate above never used it, even though it was live and
|
|
200
|
+
* in-scope. Reporting only — see the BudgetInput docstring for why it cannot gate.
|
|
201
|
+
* 0 when no invoker reported cost (stubbed invokers, skill-only gigs).
|
|
202
|
+
*/
|
|
203
|
+
settled_usd: number;
|
|
204
|
+
}
|
|
205
|
+
export interface GigResult {
|
|
206
|
+
gig_id: string;
|
|
207
|
+
standard_slug: string;
|
|
208
|
+
genome_hash: string;
|
|
209
|
+
run_fingerprint: string;
|
|
210
|
+
outputs: readonly OutputRecord[];
|
|
211
|
+
eval_scores: Record<string, number>;
|
|
212
|
+
/**
|
|
213
|
+
* #246 — declared eval_slugs that resolved to NO eval definition. They still appear in
|
|
214
|
+
* `eval_scores` at 0.0 (back-compat: callers key off presence), but a 0.0 that means
|
|
215
|
+
* "no such eval" is not the same claim as a 0.0 that means "the contract did not hold",
|
|
216
|
+
* and the two used to be indistinguishable — including inside `run_fingerprint`.
|
|
217
|
+
* Present only when non-empty.
|
|
218
|
+
*/
|
|
219
|
+
unresolved_evals?: readonly string[];
|
|
220
|
+
/**
|
|
221
|
+
* #243 — chairs that sealed FEWER types than their output_contract promised. The runtime
|
|
222
|
+
* treats output_contract as a selector, not a floor, because a keyed output can legitimately
|
|
223
|
+
* be conditional. For a chair with a downstream consumer the shortfall surfaces as an
|
|
224
|
+
* input_contract failure; for a TERMINAL chair nothing consumes it and the promise used to
|
|
225
|
+
* evaporate into `status: "complete"`. Recording it is not enforcement — see the note at the
|
|
226
|
+
* seal loop. Present only when non-empty.
|
|
227
|
+
*/
|
|
228
|
+
unfulfilled_outputs?: ReadonlyArray<{
|
|
229
|
+
role: string;
|
|
230
|
+
phase: string;
|
|
231
|
+
missing: readonly string[];
|
|
232
|
+
}>;
|
|
233
|
+
status: "complete";
|
|
234
|
+
/** Final budget snapshot. Present only when a budget was supplied. */
|
|
235
|
+
budget_state?: BudgetState;
|
|
236
|
+
/** Settled model spend (#195). Present when ≥1 real model invocation ran this gig. */
|
|
237
|
+
usage?: GigUsage;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* #236 — settled spend used to be discarded on every failed gig: `usage` was written only on
|
|
241
|
+
* the success path, and the async dispatcher's `.catch` set status/error and nothing else. A
|
|
242
|
+
* gig that burned $6 across four chairs and died on the fifth reported zero dollars, everywhere
|
|
243
|
+
* — and failed gigs are exactly the ones whose cost an operator most needs. runGig now attaches
|
|
244
|
+
* the partial accounting to whatever it throws; these read it back safely.
|
|
245
|
+
*/
|
|
246
|
+
export declare function partialGigUsage(e: unknown): GigUsage | undefined;
|
|
247
|
+
export declare function partialBudgetState(e: unknown): BudgetState | undefined;
|
|
248
|
+
export declare class RuntimeError extends Error {
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Raised when a gig is cancelled through `RunDeps.signal` (#249). Distinct from RuntimeError
|
|
252
|
+
* so a caller can tell "an operator stopped this" from "this crashed" — #251's point that a
|
|
253
|
+
* killed gig surfacing as `failed` with a kill-shaped error is indistinguishable from a
|
|
254
|
+
* genuine crash.
|
|
255
|
+
*
|
|
256
|
+
* Carries the spend accrued BEFORE the cancellation. Today abort does nothing, so the gig
|
|
257
|
+
* completes and its cost IS recorded; a fix that kills children without capturing accrued
|
|
258
|
+
* usage would improve cost control while regressing accounting. The dispatcher folds this
|
|
259
|
+
* onto the run state so `gig_monitor` still answers "what did this cost me".
|
|
260
|
+
*/
|
|
261
|
+
export declare class GigAborted extends Error {
|
|
262
|
+
readonly gig_id: string;
|
|
263
|
+
readonly reason: string;
|
|
264
|
+
readonly usage: GigUsage | undefined;
|
|
265
|
+
readonly outputs: readonly OutputRecord[];
|
|
266
|
+
constructor(gig_id: string, reason: string, usage: GigUsage | undefined, outputs: readonly OutputRecord[]);
|
|
267
|
+
}
|
|
268
|
+
/** The human-readable cause behind an AbortSignal, whatever shape the aborter used. */
|
|
269
|
+
export declare function abortReasonText(signal: AbortSignal): string;
|
|
270
|
+
/**
|
|
271
|
+
* Raised when a gig's budget cannot cover the next agent's cost-of-append.
|
|
272
|
+
* Carries the agent_slug, the available balance, and the required cost so
|
|
273
|
+
* the caller can render the exact reason. The in-memory BudgetState is
|
|
274
|
+
* also attached for downstream telemetry.
|
|
275
|
+
*/
|
|
276
|
+
export declare class BudgetExhausted extends Error {
|
|
277
|
+
readonly agent_slug: string;
|
|
278
|
+
readonly balance: number;
|
|
279
|
+
readonly cost: number;
|
|
280
|
+
readonly state: BudgetState;
|
|
281
|
+
constructor(agent_slug: string, balance: number, cost: number, state: BudgetState);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Cost-of-append for an agent invocation, in synthetic append units (see BudgetState.unit).
|
|
285
|
+
* Deterministic function of the input context size — same input → same cost. Keeps cost
|
|
286
|
+
* calculation inside the runtime (not the invoker) so budget enforcement cannot be spoofed by
|
|
287
|
+
* a misbehaving invoker.
|
|
288
|
+
*
|
|
289
|
+
* #233 — this used to serialize `input_ids`: the UUIDs of the upstream outputs a chair
|
|
290
|
+
* consumes, not their data. An upstream output contributed exactly 36 bytes whether it was a
|
|
291
|
+
* one-line signal or a 40-page draft, so the proxy was not even monotonic in the thing that
|
|
292
|
+
* drives real cost. It now measures the CONTENT the invoker actually receives.
|
|
293
|
+
*
|
|
294
|
+
* Still excluded, honestly: resolved skills, the agent charter, type schemas, model tier,
|
|
295
|
+
* max_tool_calls, and the entire output side. This is a rate limiter on consumed context, not
|
|
296
|
+
* a price. Money is `BudgetState.settled_usd`.
|
|
297
|
+
*/
|
|
298
|
+
export declare function computeAppendCost(ctx: {
|
|
299
|
+
agent: Agent;
|
|
300
|
+
phase: string;
|
|
301
|
+
inputs: readonly OutputRecord[];
|
|
302
|
+
gig_input: Record<string, unknown>;
|
|
303
|
+
}, base_cost: number, k: number): number;
|
|
304
|
+
export declare function runGig(standard: Standard, gigInput: Record<string, unknown>, deps: RunDeps): Promise<GigResult>;
|