@ego-z/contracts 0.15.11 → 0.15.13
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 +1 -1
- package/src/ask.d.ts +126 -0
- package/src/draft-conv.d.ts +53 -0
- package/src/index.d.ts +5 -0
- package/src/model.d.ts +64 -0
package/package.json
CHANGED
package/src/ask.d.ts
CHANGED
|
@@ -90,6 +90,36 @@ export interface AskRequestBody {
|
|
|
90
90
|
*/
|
|
91
91
|
externalUserId?: string;
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Run THIS turn on a specific chat model, instead of the project's
|
|
95
|
+
* configured default.
|
|
96
|
+
*
|
|
97
|
+
* Only honoured on a project whose owner has turned model switching on and
|
|
98
|
+
* curated a menu (Console → LLM Settings). Read the menu from
|
|
99
|
+
* `GET /egoz/models`, which returns every model this project offers along
|
|
100
|
+
* with which one is the default, and echo an `id` back here verbatim.
|
|
101
|
+
*
|
|
102
|
+
* - omitted → the project's default model, exactly as before.
|
|
103
|
+
* - `"openai:gpt-4o-mini"` → the canonical, always-unambiguous form.
|
|
104
|
+
* - `"gpt-4o-mini"` → accepted while that id is offered by only
|
|
105
|
+
* one provider on this project.
|
|
106
|
+
*
|
|
107
|
+
* A model this project does not offer — and ANY value at all on a project
|
|
108
|
+
* where switching is off — is rejected with `ModelNotAllowed` (400). It is
|
|
109
|
+
* deliberately not ignored: a caller whose override is silently dropped
|
|
110
|
+
* believes it took effect, and the only trace of the truth is a model
|
|
111
|
+
* field on a usage row nobody reads until the invoice arrives.
|
|
112
|
+
*
|
|
113
|
+
* Scope, and what it does NOT change:
|
|
114
|
+
* - Embeddings are pinned to the project. The knowledge base's vectors
|
|
115
|
+
* were written in one embedding space, and retrieving against another
|
|
116
|
+
* returns confident nonsense — so RAG is unaffected by this field.
|
|
117
|
+
* - A voice call ignores it. A call is a latency budget; the tenant's
|
|
118
|
+
* `voiceModel` still wins there. The value is still validated, so a
|
|
119
|
+
* bad one is a 400 rather than a surprise.
|
|
120
|
+
*/
|
|
121
|
+
model?: string;
|
|
122
|
+
|
|
93
123
|
/** Override the tenant's default response format for this single call. */
|
|
94
124
|
responseFormat?: ResponseFormat;
|
|
95
125
|
|
|
@@ -211,6 +241,102 @@ export interface AskRequestBody {
|
|
|
211
241
|
* Optional and additive: omit it and nothing changes.
|
|
212
242
|
*/
|
|
213
243
|
contextItems?: InitContextItem[];
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Output a MACHINE produced for this turn — the result of something the
|
|
247
|
+
* user asked to have run, not anything the user said.
|
|
248
|
+
*
|
|
249
|
+
* ── Why this needs a channel of its own ──────────────────────────────
|
|
250
|
+
*
|
|
251
|
+
* Before this field there were exactly two ways in, and both are wrong
|
|
252
|
+
* for a machine:
|
|
253
|
+
*
|
|
254
|
+
* - `message` persists as `role: 'user'`. A script that prints a
|
|
255
|
+
* customer's CSV row arrives labelled as the account owner speaking,
|
|
256
|
+
* and **every protection that keys off who is speaking is bypassed by
|
|
257
|
+
* a program printing a sentence.**
|
|
258
|
+
* - `contextItems` is worse, because it does not merely keep the user's
|
|
259
|
+
* voice — it upgrades it. Those items are rendered as things the user
|
|
260
|
+
* *chose deliberately* and *likely referents for anything they mention*,
|
|
261
|
+
* so routing `stderr` there promotes program output to something
|
|
262
|
+
* adjacent to instruction.
|
|
263
|
+
*
|
|
264
|
+
* `role: 'tool'` exists internally, but only EgoZ mints those and only
|
|
265
|
+
* from its own executions; nothing on the wire can produce one. So this
|
|
266
|
+
* is the channel: it is rendered to the agent as **quoted data with an
|
|
267
|
+
* explicit statement that a machine produced it**, never as speech and
|
|
268
|
+
* never as instruction.
|
|
269
|
+
*
|
|
270
|
+
* ⚠️ **You are asserting provenance when you send this.** Put here only
|
|
271
|
+
* what your own system produced. Anything a person typed belongs in
|
|
272
|
+
* `message`, whatever it is about — mislabelling user text as machine
|
|
273
|
+
* output is the same failure as the reverse, pointed the other way.
|
|
274
|
+
*
|
|
275
|
+
* Optional and additive: omit it and nothing changes.
|
|
276
|
+
*/
|
|
277
|
+
machineOutput?: AskMachineOutput[];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* One piece of output a machine produced for this turn.
|
|
282
|
+
*
|
|
283
|
+
* ── Truncated, never dropped — the opposite of `InitContextItem` ─────────
|
|
284
|
+
*
|
|
285
|
+
* An over-long `excerpt` on a context item is DROPPED, because a shortened
|
|
286
|
+
* address is a different valid address and acting on it is worse than not
|
|
287
|
+
* having it. Output is the other case entirely: **a clipped `stderr` is
|
|
288
|
+
* still evidence, and a missing one is a lie.** So this is capped by
|
|
289
|
+
* truncation and the truncation is declared — the agent is told the text was
|
|
290
|
+
* cut rather than left to conclude a command printed nothing.
|
|
291
|
+
*
|
|
292
|
+
* That asymmetry is deliberate and it is the reason these are two shapes
|
|
293
|
+
* rather than one generous one.
|
|
294
|
+
*
|
|
295
|
+
* ── No acceptance receipt, unlike `contextItems` ─────────────────────────
|
|
296
|
+
*
|
|
297
|
+
* `contextItemsAccepted` exists because acceptance there is lossy in ways
|
|
298
|
+
* the caller cannot observe — items vanish, excerpts disappear — so a
|
|
299
|
+
* "shared with the agent" display would otherwise be confidently wrong.
|
|
300
|
+
* Nothing here vanishes: an entry is either rendered or the request is
|
|
301
|
+
* rejected, and the one lossy case declares itself **to the reader who
|
|
302
|
+
* matters**, in-band, where the agent is told the text was cut. Adding a
|
|
303
|
+
* receipt would be a second copy of that fact, for a caller that already
|
|
304
|
+
* holds the full output it just sent.
|
|
305
|
+
*/
|
|
306
|
+
export interface AskMachineOutput {
|
|
307
|
+
/**
|
|
308
|
+
* Your own name for whatever produced this — `"terminal"`, `"build"`.
|
|
309
|
+
*
|
|
310
|
+
* ⚠️ Free-form, and **never rendered into the prompt**, exactly like
|
|
311
|
+
* `InitContextItem.kind` and for the same reason: free-form caller text
|
|
312
|
+
* in the instruction block is an injection surface. Used for grouping
|
|
313
|
+
* and for your own logs.
|
|
314
|
+
*/
|
|
315
|
+
source?: string;
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* What was run, in the user's terms — a command line, a job name.
|
|
319
|
+
* Rendered, because output with no statement of what produced it invites
|
|
320
|
+
* the agent to guess which of its own suggestions ran.
|
|
321
|
+
*/
|
|
322
|
+
invocation?: string;
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* The text the machine produced. Required — an entry with nothing in it
|
|
326
|
+
* says a program ran and reported nothing, which is a claim, not an
|
|
327
|
+
* omission. Truncated to a server cap if long; see the header.
|
|
328
|
+
*/
|
|
329
|
+
output: string;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* The producer's own result status, when it has one — a process exit
|
|
333
|
+
* code, conventionally 0 for success.
|
|
334
|
+
*
|
|
335
|
+
* Worth sending even when `output` is empty, and especially then: it is
|
|
336
|
+
* the difference between *"it worked and printed nothing"* and *"it
|
|
337
|
+
* failed silently"*, which no amount of text can express.
|
|
338
|
+
*/
|
|
339
|
+
exitCode?: number;
|
|
214
340
|
}
|
|
215
341
|
|
|
216
342
|
/**
|
package/src/draft-conv.d.ts
CHANGED
|
@@ -113,6 +113,46 @@ export interface InitContextItem {
|
|
|
113
113
|
* `contextItemsAccepted` on the response tells you when it happened.
|
|
114
114
|
*/
|
|
115
115
|
excerpt?: string;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The exact string a tool needs to act on this item — a file path, a
|
|
119
|
+
* record id, whatever your tools take. Optional.
|
|
120
|
+
*
|
|
121
|
+
* ── Why this is not just an `excerpt` ────────────────────────────────
|
|
122
|
+
*
|
|
123
|
+
* Because the two are read differently and fail differently, and until
|
|
124
|
+
* this field existed they shared one. An excerpt is prose ABOUT the
|
|
125
|
+
* thing; an address is a HANDLE TO it, and the agent is expected to
|
|
126
|
+
* carry it verbatim into a tool call. Shortening prose loses a few
|
|
127
|
+
* words. Shortening an address produces a **different valid address** —
|
|
128
|
+
* so the caps differ, and so does what a consumer may do with the value.
|
|
129
|
+
*
|
|
130
|
+
* ⚠️ AN OVER-LONG ADDRESS IS DROPPED, NOT TRUNCATED, and the item still
|
|
131
|
+
* rides without it, exactly like `excerpt`. `addressOmitted` on the
|
|
132
|
+
* receipt tells you it happened — worth reading, because the agent then
|
|
133
|
+
* has the item's NAME and no way to act on it, which usually reads to a
|
|
134
|
+
* user as the agent being unable rather than under-informed.
|
|
135
|
+
*
|
|
136
|
+
* ── Send the address, or the agent will construct one ────────────────
|
|
137
|
+
*
|
|
138
|
+
* Measured, twice, on live traffic: given an item it can name but not
|
|
139
|
+
* address, an agent does not stop — it produces a plausible-looking
|
|
140
|
+
* identifier from the meaning it has. A product slug built from the
|
|
141
|
+
* product's name, a window key passed where a record id was wanted.
|
|
142
|
+
* Both fail at the tool, and the failure reads as a broken feature.
|
|
143
|
+
*
|
|
144
|
+
* So an absent address is not neutral. It is the condition under which
|
|
145
|
+
* an agent invents one.
|
|
146
|
+
*
|
|
147
|
+
* ── It is rendered, and that is a deliberate exception ───────────────
|
|
148
|
+
*
|
|
149
|
+
* `kind` and `id` never reach the prompt: free-form caller text in the
|
|
150
|
+
* instruction block is an injection surface. `address` does reach it,
|
|
151
|
+
* for the same reason `label` does — a handle nobody can read is not a
|
|
152
|
+
* handle. Send an identifier or a path, never a sentence, and never
|
|
153
|
+
* anything a user typed and you did not resolve.
|
|
154
|
+
*/
|
|
155
|
+
address?: string;
|
|
116
156
|
}
|
|
117
157
|
|
|
118
158
|
/**
|
|
@@ -159,6 +199,19 @@ export interface InitContextItemAccepted {
|
|
|
159
199
|
* detail, instead of implying it got both.
|
|
160
200
|
*/
|
|
161
201
|
excerptOmitted?: boolean;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* The item was accepted but its `address` was not — it exceeded the cap
|
|
205
|
+
* and was dropped rather than truncated (see `InitContextItem.address`).
|
|
206
|
+
*
|
|
207
|
+
* ⚠️ Worth surfacing more loudly than `excerptOmitted`. A lost excerpt
|
|
208
|
+
* costs detail; a lost address costs the agent the only way to ACT on
|
|
209
|
+
* the item, and what a user sees is not "it knew less about this" but
|
|
210
|
+
* "it couldn't do it" — or, worse, an invented identifier that fails at
|
|
211
|
+
* the tool. If you show a "shared with the agent" display at all, this
|
|
212
|
+
* is the flag that changes what the user should expect.
|
|
213
|
+
*/
|
|
214
|
+
addressOmitted?: boolean;
|
|
162
215
|
}
|
|
163
216
|
|
|
164
217
|
/** One open window in the caller's UI. */
|
package/src/index.d.ts
CHANGED
|
@@ -74,6 +74,10 @@
|
|
|
74
74
|
* create / update / clone bodies,
|
|
75
75
|
* `ActiveTenantPersonalityWire`. Shared:
|
|
76
76
|
* `PersonalityTraitsWire`, `PresetType`.
|
|
77
|
+
* - `model.d.ts` — `GET /egoz/models`: the menu of chat models a
|
|
78
|
+
* project offers for `AskRequestBody.model`.
|
|
79
|
+
* `SwitchableModelWire`,
|
|
80
|
+
* `SwitchableModelsResponseData`.
|
|
77
81
|
* - `user-memory.d.ts` — Per-end-user learning (Phase 15 / exURM).
|
|
78
82
|
* `UserMemoryWire`, `UserMemoryUserSummaryWire`,
|
|
79
83
|
* `UpdateUserMemoryFactBody`, list / detail / fact /
|
|
@@ -93,6 +97,7 @@
|
|
|
93
97
|
|
|
94
98
|
export * from './envelope';
|
|
95
99
|
export * from './ask';
|
|
100
|
+
export * from './model';
|
|
96
101
|
export * from './stream';
|
|
97
102
|
export * from './questions';
|
|
98
103
|
export * from './tool';
|
package/src/model.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ego-z/contracts — `GET /egoz/models` wire types.
|
|
3
|
+
*
|
|
4
|
+
* The menu of chat models a project offers for `AskRequestBody.model`. Read
|
|
5
|
+
* this to build a model picker; echo an entry's `id` back verbatim.
|
|
6
|
+
*
|
|
7
|
+
* ── Why this endpoint exists at all ──────────────────────────────────────
|
|
8
|
+
*
|
|
9
|
+
* The alternative was for integrators to hardcode the model ids their picker
|
|
10
|
+
* offers. That list is a copy of one a project owner edits in the Console,
|
|
11
|
+
* with nothing connecting the two: the day the owner drops a model, every
|
|
12
|
+
* caller's picker keeps offering it and every pick 400s, in someone else's
|
|
13
|
+
* deployment, with no signal on the Console side that anything broke.
|
|
14
|
+
*
|
|
15
|
+
* ── Authentication ───────────────────────────────────────────────────────
|
|
16
|
+
*
|
|
17
|
+
* Same trusted-server pattern as `/ask`: the tenant API key in `X-API-Key`
|
|
18
|
+
* (plus `X-Tenant-Id`). It is deliberately NOT anonymous — the menu names a
|
|
19
|
+
* project's providers and model tiers, which is commercial detail, not public
|
|
20
|
+
* information.
|
|
21
|
+
*
|
|
22
|
+
* ── What it is not ───────────────────────────────────────────────────────
|
|
23
|
+
*
|
|
24
|
+
* Not a provider catalogue. It returns exactly what the owner curated, and
|
|
25
|
+
* makes no call to OpenAI/Anthropic/Azure to do so — a hot path on every chat
|
|
26
|
+
* panel open must not fan out to third parties. The Console's model dropdowns
|
|
27
|
+
* are the surface that browses live catalogues
|
|
28
|
+
* (`GET /egoz/tenants/:tenantId/models`); this one publishes the decision.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/** One model this project will run. */
|
|
32
|
+
export interface SwitchableModelWire {
|
|
33
|
+
/**
|
|
34
|
+
* Canonical handle, `"<provider>:<model>"` (e.g. `"openai:gpt-4o-mini"`).
|
|
35
|
+
* Send this back as `AskRequestBody.model`. Stable for as long as the
|
|
36
|
+
* owner keeps the entry on the menu.
|
|
37
|
+
*/
|
|
38
|
+
id: string;
|
|
39
|
+
/** BYOK provider that will serve the turn — `"openai"`, `"anthropic"`, … */
|
|
40
|
+
provider: string;
|
|
41
|
+
/**
|
|
42
|
+
* Provider-side model id. On Azure this is the DEPLOYMENT name, which is
|
|
43
|
+
* private to the tenant — do not assume it matches a public model name.
|
|
44
|
+
*/
|
|
45
|
+
model: string;
|
|
46
|
+
/** True for the model used when `AskRequestBody.model` is omitted. Exactly one entry has it. */
|
|
47
|
+
isDefault: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** `data` payload of `GET /egoz/models`. */
|
|
51
|
+
export interface SwitchableModelsResponseData {
|
|
52
|
+
/**
|
|
53
|
+
* Whether `AskRequestBody.model` will be honoured. When `false`, `models`
|
|
54
|
+
* still holds exactly one entry — the project default — so a picker can
|
|
55
|
+
* render the same way either way and simply has nothing to switch to.
|
|
56
|
+
*
|
|
57
|
+
* Sending `model` while this is `false` is an error, not a no-op.
|
|
58
|
+
*/
|
|
59
|
+
switchable: boolean;
|
|
60
|
+
/** `id` of the default entry. Convenience — it is also the entry with `isDefault: true`. */
|
|
61
|
+
defaultId: string;
|
|
62
|
+
/** The default first, then the owner's curated alternatives. Never empty. */
|
|
63
|
+
models: SwitchableModelWire[];
|
|
64
|
+
}
|