@ego-z/contracts 0.11.2 → 0.13.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ego-z/contracts",
3
- "version": "0.11.2",
3
+ "version": "0.13.0",
4
4
  "description": "Wire-format type contracts shared between EgoZ backend, SDK, MCP and console. Type-only — no runtime artifacts.",
5
5
  "types": "./src/index.d.ts",
6
6
  "exports": {
@@ -15,7 +15,9 @@
15
15
  "NOTICE"
16
16
  ],
17
17
  "scripts": {
18
- "typecheck": "tsc --noEmit"
18
+ "typecheck": "tsc --noEmit",
19
+ "check:consumers": "node scripts/check-consumer-ranges.js",
20
+ "prepublishOnly": "npm run check:consumers"
19
21
  },
20
22
  "keywords": [
21
23
  "egoz",
@@ -0,0 +1,145 @@
1
+ /**
2
+ * @ego-z/contracts — controlled orchestration mode.
3
+ *
4
+ * Wire vocabulary for the staged turn machine. Everything here is metadata:
5
+ * stage names, outcomes, counts, timings, a verdict and a score. The plan's
6
+ * `evidenceQueries` strings NEVER cross the wire and are never persisted.
7
+ */
8
+
9
+ // ============================================================================
10
+ // Locked vocabularies. THIS FILE IS THEIR ONLY DECLARATION — 02/03/04/05/07/08
11
+ // cite it, none of them restate it. VerifyMode (050), VerifyVerdict (051, on
12
+ // egoz_eval_results.verdict only), VerifyCheck (051, containment check on
13
+ // egoz_eval_results.failed_checks), EvalRunMode (051) and EvalRunStatus (051)
14
+ // have a DB CHECK; the rest are JSONB keys / wire enums (D16).
15
+ // OrchestrationMode and MessageFailureReason are CHECKed too but are declared
16
+ // elsewhere — OrchestrationMode in tenant.d.ts — so this file does not own them.
17
+ // ============================================================================
18
+
19
+ /** Mirrors `egoz_tenant_configs.verify_mode` CHECK (migration 050). */
20
+ export type VerifyMode = 'off' | 'observe' | 'enforce';
21
+
22
+ /** The nine canonical stages, in execution order. */
23
+ export type ControlledStage =
24
+ | 'admit' | 'assess' | 'retrieve' | 'rank' | 'compose'
25
+ | 'execute' | 'verify' | 'repair' | 'finalize';
26
+
27
+ /**
28
+ * What happened to a stage. SPLIT from the *reason* deliberately: fusing them
29
+ * (`'skipped_budget' | 'skipped_voice' | …`) makes "degradation rate by reason"
30
+ * unqueryable from JSONB without a LIKE on the enum, and it makes every new
31
+ * reason a change to the outcome vocabulary. `outcome` answers "did it run",
32
+ * `reason` answers "why not" — see `StageSkipReason`.
33
+ *
34
+ * `short_circuited` is a REASON, not an outcome: an extension hook returning a
35
+ * result means the stage did not run, which is `'skipped'`.
36
+ */
37
+ export type ControlledStageOutcome = 'ran' | 'skipped' | 'degraded' | 'aborted';
38
+
39
+ /** Present iff `outcome` is `'skipped'` or `'degraded'`. Never on `'ran'`. */
40
+ export type StageSkipReason =
41
+ | 'budget_exhausted' // wall-clock or assist-call budget spent
42
+ | 'voice_mode' // voiceMode reduced path (D5)
43
+ | 'plan_not_required' // the TurnPlan said this stage is unnecessary
44
+ | 'config_off' // verify_mode='off', ragEnabled=false, …
45
+ | 'short_circuited' // an extension hook returned a result
46
+ | 'parse_failed' // assist model returned prose; fell back to a default
47
+ | 'provider_error'; // the assist call itself failed
48
+
49
+ /** Mirrors `egoz_eval_results.verdict` CHECK (migration 051). */
50
+ export type VerifyVerdict = 'pass' | 'repairable' | 'degraded';
51
+
52
+ export type VerifyCheck =
53
+ | 'schema' | 'tool_honesty' | 'plan_completion' | 'grounding';
54
+
55
+ export type TurnComplexity = 'trivial' | 'standard' | 'complex';
56
+
57
+ /**
58
+ * Mirrors `egoz_eval_runs.mode` CHECK (migration 051). `dry` stubs every tool
59
+ * call from the case fixture; `live` executes for real. Anything that defaults
60
+ * this value defaults it to `'dry'`.
61
+ */
62
+ export type EvalRunMode = 'dry' | 'live';
63
+
64
+ /** Mirrors `egoz_eval_runs.status` CHECK (migration 051). */
65
+ export type EvalRunStatus =
66
+ | 'queued' | 'running' | 'completed' | 'failed' | 'cancelled';
67
+
68
+ // ============================================================================
69
+ // Wire shapes
70
+ // ============================================================================
71
+
72
+ /** Routing decision from `assess`. `evidenceQueries` is deliberately absent. */
73
+ export interface TurnPlanWire {
74
+ complexity: TurnComplexity;
75
+ needsEvidence: boolean;
76
+ needsTools: boolean;
77
+ verify: 'none' | 'schema' | 'grounding';
78
+ }
79
+
80
+ export interface ControlledStageReport {
81
+ name: ControlledStage;
82
+ ms: number;
83
+ outcome: ControlledStageOutcome;
84
+ /** Why it did not run. Present iff outcome is 'skipped' or 'degraded'. */
85
+ reason?: StageSkipReason;
86
+ }
87
+
88
+ /**
89
+ * Per-turn controlled-mode report. Mirrors `egoz_messages.metadata.controlled`
90
+ * exactly, so the wire and the durable record can never drift.
91
+ *
92
+ * THIS INTERFACE IS THE COMPLETE KEY SET. `metadata.controlled` is the always-on
93
+ * durable channel (D12) and `GET_CONTROLLED_SUMMARY`
94
+ * (`07-observability-and-evaluation.md`) reads it by literal JSONB key — a metric
95
+ * that reads a key not declared here returns NULL for every row, silently. Docs
96
+ * 03/05/07/08 cite this type; they do not maintain parallel key lists.
97
+ *
98
+ * WHY SO MANY OPTIONALS: the batch that produces a field ships after the batch
99
+ * that publishes this type. `stages` is the only key a controlled turn can
100
+ * always produce (B2). `plan` / `assistCalls` / `assistTokens` arrive with
101
+ * `assess` (B3); the chunk counts with `retrieve`/`rank` (B4); the verdict block
102
+ * with `verify` (B5); the repair block with `repair` (B6). They are optional
103
+ * because they are genuinely ABSENT, not zero — 07's metric 7
104
+ * (`chunksKept / chunksRetrieved`) and metric 4 (`assistTokens / total_tokens`)
105
+ * cannot tell a stamped placeholder from a measurement, so a required field
106
+ * would enter every turn in the B2→B4 window into those metrics as fabricated
107
+ * data. `IS NULL` separates "that batch had not shipped" from "we retrieved
108
+ * nothing"; `= 0` does not.
109
+ */
110
+ export interface ControlledTurnMeta {
111
+ /** Absent until B3 — a turn with no `assess` stage has no plan, not an empty one. */
112
+ plan?: TurnPlanWire;
113
+ /** Always present on a controlled turn: all nine stages, in order (D12). */
114
+ stages: ControlledStageReport[];
115
+
116
+ /** How many evidence queries `assess` produced (0-3). COUNT ONLY (D17). */
117
+ evidenceQueries?: number;
118
+ /** Raw chunks returned by `retrieve` across all queries, pre-`rank`. */
119
+ chunksRetrieved?: number;
120
+ /**
121
+ * Chunks that survived `rank`'s dedup + cap and entered the prompt.
122
+ * The canonical name for what 07's metric 7 calls "evidence yield"
123
+ * (`chunksKept / chunksRetrieved`) and what 03 drafted as `evidenceChunks`.
124
+ * Counted separately from the existing `kbSearchCalls` / `kbChunksUsed`,
125
+ * which stay the KB-tool-during-`execute` counters.
126
+ */
127
+ chunksKept?: number;
128
+
129
+ /** LLM calls made by assess + verify + repair-critique. Bounded at 3. */
130
+ assistCalls?: number;
131
+ assistTokens?: number;
132
+ /** Resolved assist model id. Absent when it fell back to the main model. */
133
+ assistModel?: string;
134
+
135
+ verdict?: VerifyVerdict;
136
+ /** 0..1 from `computeVerdictScore`. Absent when verify_mode = 'off'. */
137
+ score?: number;
138
+ /** Named `failedChecks` everywhere. Not `checksFailed`. */
139
+ failedChecks?: VerifyCheck[];
140
+
141
+ /** True when one bounded repair attempt ran (enforce mode only). */
142
+ repaired?: boolean;
143
+ /** Which check drove the repair. Absent when `repaired` is false. */
144
+ repairReason?: VerifyCheck;
145
+ }
package/src/index.d.ts CHANGED
@@ -92,3 +92,4 @@ export * from './thread';
92
92
  export * from './personality';
93
93
  export * from './user-memory';
94
94
  export * from './search';
95
+ export * from './controlled';
package/src/stream.d.ts CHANGED
@@ -55,6 +55,24 @@ export interface AskStreamDeltaEvent {
55
55
  type: 'delta';
56
56
  /** Token (or token-like fragment) appended to the running answer. */
57
57
  content: string;
58
+ /**
59
+ * Whether this delta is part of the model's pre-tool narration
60
+ * ('thinking' — text emitted by an iteration that also asked for a
61
+ * tool call) or the terminal reply ('final' — the last iteration's
62
+ * text, no further tool calls follow).
63
+ *
64
+ * Consumers can use this to render two channels: a secondary
65
+ * "thinking out loud" strip and the primary answer body. A single
66
+ * 'thinking' iteration streams live token-by-token; the 'final'
67
+ * delta is flushed as one event at iteration end so its label is
68
+ * known when it lands (the alternative would be a post-hoc
69
+ * correction event, which was rejected).
70
+ *
71
+ * Optional so a consumer pinned to an older contract version still
72
+ * parses the frame. Absent only on the pre-phase emit sites that
73
+ * predate the field.
74
+ */
75
+ phase?: 'thinking' | 'final';
58
76
  }
59
77
 
60
78
  export interface AskStreamToolCallingEvent {
package/src/tenant.d.ts CHANGED
@@ -59,6 +59,24 @@ export type TenantStatus =
59
59
  | 'suspended'
60
60
  | 'terminated';
61
61
 
62
+ /**
63
+ * Per-tenant `/ask` pipeline (mirrors `egoz_tenant_configs.orchestration_mode`
64
+ * CHECK constraint, migrations 022 + 050). Promoted here from
65
+ * `backend/egoz/modules/tenant-config/interfaces.ts` in B1 (D15) so the backend,
66
+ * the console, the SDK and MCP stop hand-copying the literal pair.
67
+ *
68
+ * - `classic` — rule intent classifier + pre-fetched RAG. The DB default;
69
+ * no tenant moves off it automatically.
70
+ * - `agentic` — single base prompt, KB offered as a tool, LLM-driven
71
+ * retrieval (Phase 10).
72
+ * - `controlled` — the nine-stage machine: admit → assess → retrieve → rank →
73
+ * compose → execute → verify → repair → finalize.
74
+ *
75
+ * Widening this union is additive for producers and breaking for a consumer
76
+ * doing an exhaustive `never` switch — which is why it moved as a minor bump.
77
+ */
78
+ export type OrchestrationMode = 'classic' | 'agentic' | 'controlled';
79
+
62
80
  /**
63
81
  * Billing plan (Phase 1.5, two-plan model — migration 035). Drives usage
64
82
  * quotas (e.g. monthly /ask limit).