@ego-z/contracts 0.15.3 → 0.15.6
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/README.md +24 -0
- package/package.json +1 -1
- package/src/ask.d.ts +15 -0
- package/src/draft-conv.d.ts +49 -0
- package/src/thread.d.ts +12 -0
package/README.md
CHANGED
|
@@ -58,6 +58,30 @@ import type { AskRequestBody, AskResponseData, AskStreamEvent } from '@ego-z/con
|
|
|
58
58
|
their generated `.d.ts` automatically — end users see the types as if
|
|
59
59
|
they were declared in the SDK itself.
|
|
60
60
|
|
|
61
|
+
## ⚠️ Do not pin `0.15.5`
|
|
62
|
+
|
|
63
|
+
`0.15.5` was published with a `dependencies` entry naming **itself**
|
|
64
|
+
(`"@ego-z/contracts": "^0.15.0"`). It is harmless while 0.15.5 is the newest
|
|
65
|
+
0.15.x — npm resolves that range back to the same copy and dedupes it:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
`-- @ego-z/contracts@0.15.5
|
|
69
|
+
`-- @ego-z/contracts@0.15.5 deduped
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**It stops being harmless the moment a newer 0.15.x exists.** That range can
|
|
73
|
+
then resolve a *different* version nested underneath 0.15.5, putting two
|
|
74
|
+
copies of the same types in one tree — the classic "these two identical
|
|
75
|
+
interfaces are not assignable" failure, from a cause nobody would think to
|
|
76
|
+
look for.
|
|
77
|
+
|
|
78
|
+
So: **when the next patch ships, move off 0.15.5 rather than staying on it.**
|
|
79
|
+
Don't pin it, and don't leave a lockfile resolving to it.
|
|
80
|
+
|
|
81
|
+
The source is already fixed — the package declares no runtime dependencies at
|
|
82
|
+
all — so the next publish for any reason clears it. It was not worth a
|
|
83
|
+
version bump on its own mid-integration.
|
|
84
|
+
|
|
61
85
|
## When to bump
|
|
62
86
|
|
|
63
87
|
- **Adding** an optional field — non-breaking, no version bump required
|
package/package.json
CHANGED
package/src/ask.d.ts
CHANGED
|
@@ -25,6 +25,21 @@ import type { Intent, JsonSchemaDefinition, ResponseFormat, TokenUsage } from '.
|
|
|
25
25
|
* These are intentionally NOT body fields — they live where HTTP puts them.
|
|
26
26
|
*/
|
|
27
27
|
export interface AskRequestBody {
|
|
28
|
+
/**
|
|
29
|
+
* The CALLER'S own tenant for this turn, in their id space — required on
|
|
30
|
+
* a `gateway` integration (see `TenantScope`), meaningless otherwise.
|
|
31
|
+
*
|
|
32
|
+
* Scopes every per-user read on the turn and guards the resume: a
|
|
33
|
+
* conversation belonging to a different one of the caller's tenants
|
|
34
|
+
* fails as `ThreadMismatch` (409) rather than `NotFound`, because a
|
|
35
|
+
* gateway that hears "not found" for a real conversation bootstraps its
|
|
36
|
+
* own record under the wrong tenant and forks the transcript.
|
|
37
|
+
*
|
|
38
|
+
* On the wire rather than derived from `metadata`: a scoping key
|
|
39
|
+
* inferred from one caller's metadata field name would make EgoZ's
|
|
40
|
+
* privacy boundary depend on that caller's vocabulary.
|
|
41
|
+
*/
|
|
42
|
+
externalTenantId?: string;
|
|
28
43
|
/** End-user's message for this turn. Required, non-empty. */
|
|
29
44
|
message: string;
|
|
30
45
|
|
package/src/draft-conv.d.ts
CHANGED
|
@@ -242,6 +242,53 @@ export interface InitContextTenant {
|
|
|
242
242
|
features?: Record<string, boolean>;
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
/**
|
|
246
|
+
* A short recap of the user's PREVIOUS conversation, so the agent can open
|
|
247
|
+
* with continuity instead of as though it has never met them.
|
|
248
|
+
*
|
|
249
|
+
* ── Supplied by the caller, deliberately ─────────────────────────────────
|
|
250
|
+
*
|
|
251
|
+
* EgoZ stores conversations too, so it looks like EgoZ should resolve this
|
|
252
|
+
* itself — but on a gateway integration EgoZ's own copy is keyed by
|
|
253
|
+
* `(tenantId, externalUserId)`, which spans every one of the caller's
|
|
254
|
+
* tenants a person belongs to. Sourcing it there would recap store B's
|
|
255
|
+
* conversation into store A's prompt. The caller's store is per-tenant by
|
|
256
|
+
* construction, so it can answer the question safely, and a conversation the
|
|
257
|
+
* user deleted stops being quotable immediately with no propagation chain.
|
|
258
|
+
*
|
|
259
|
+
* ── Keep it SHORT ────────────────────────────────────────────────────────
|
|
260
|
+
*
|
|
261
|
+
* `lastMessage` is a truncated snippet, not a transcript. It rides in the
|
|
262
|
+
* system prompt on every turn of the new conversation, so a long one buys
|
|
263
|
+
* a little continuity at the cost of crowding out the context that makes
|
|
264
|
+
* the agent useful. Cap it at the sender.
|
|
265
|
+
*
|
|
266
|
+
* ── Recency matters more than it looks ───────────────────────────────────
|
|
267
|
+
*
|
|
268
|
+
* "Last time we spoke…" about a conversation from three months ago reads as
|
|
269
|
+
* the assistant having lost the plot, not as continuity. Callers should omit
|
|
270
|
+
* this entirely past a sensible window rather than send something stale.
|
|
271
|
+
*/
|
|
272
|
+
export interface InitContextLastConversation {
|
|
273
|
+
/** The previous conversation's title, if it has one. */
|
|
274
|
+
title?: string | null;
|
|
275
|
+
/** ISO 8601 — when it was last active. Lets the agent judge recency. */
|
|
276
|
+
updatedAt?: string | null;
|
|
277
|
+
/**
|
|
278
|
+
* A TRUNCATED snippet of the last message in it. Not a transcript —
|
|
279
|
+
* see the type docs on why the cap belongs at the sender.
|
|
280
|
+
*/
|
|
281
|
+
lastMessage?: string | null;
|
|
282
|
+
/**
|
|
283
|
+
* Whether the agent replied to that last message.
|
|
284
|
+
*
|
|
285
|
+
* `false` is the interesting value: the user said something and never
|
|
286
|
+
* got an answer, which is worth opening on. Distinguishing it from
|
|
287
|
+
* "unknown" is why this is optional rather than defaulting to `true`.
|
|
288
|
+
*/
|
|
289
|
+
answered?: boolean;
|
|
290
|
+
}
|
|
291
|
+
|
|
245
292
|
/**
|
|
246
293
|
* The full init context. Every field optional — see the file header on
|
|
247
294
|
* additive evolution.
|
|
@@ -251,6 +298,8 @@ export interface InitContext {
|
|
|
251
298
|
locale?: InitContextLocale;
|
|
252
299
|
ui?: InitContextUi;
|
|
253
300
|
tenant?: InitContextTenant;
|
|
301
|
+
/** A short recap of the user's previous conversation, if there is one. */
|
|
302
|
+
lastConversation?: InitContextLastConversation;
|
|
254
303
|
/** Anything the contract doesn't model yet. Rendered as untrusted data. */
|
|
255
304
|
notes?: string | null;
|
|
256
305
|
/**
|
package/src/thread.d.ts
CHANGED
|
@@ -115,6 +115,18 @@ export interface ThreadWire {
|
|
|
115
115
|
* migration 017.
|
|
116
116
|
*/
|
|
117
117
|
externalThreadId: string | null;
|
|
118
|
+
/**
|
|
119
|
+
* The CALLER'S own tenant this conversation belongs to, in their id
|
|
120
|
+
* space (migration 056). Populated on `gateway` projects — where one
|
|
121
|
+
* EgoZ project fronts many of the caller's tenants — and `null`
|
|
122
|
+
* otherwise, including for every row predating the column.
|
|
123
|
+
*
|
|
124
|
+
* It supplies the third part of the per-user scoping key. Without it,
|
|
125
|
+
* `(tenantId, externalUserId)` spans every one of the caller's tenants
|
|
126
|
+
* a person belongs to, because their end-user id is identical across
|
|
127
|
+
* all of them. See `TenantScope`.
|
|
128
|
+
*/
|
|
129
|
+
externalTenantId?: string | null;
|
|
118
130
|
title: string | null;
|
|
119
131
|
metadata: Record<string, unknown>;
|
|
120
132
|
isActive: boolean;
|