@tangle-network/agent-app 0.43.43 → 0.43.44

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.
@@ -1,194 +0,0 @@
1
- /**
2
- * Wire contract between the chat client (composer + `streamChatTurn`) and the
3
- * assembled server vertical (`createChatTurnRoutes`). Import-free on purpose:
4
- * `/web-react` re-exports these types into browser bundles, so nothing here may
5
- * reach a Node builtin or an engine package.
6
- *
7
- * The part shape mirrors the sandbox SDK's `PromptInputPart` structurally
8
- * (text | image | file with filename/mediaType/url/path/content) — derived
9
- * here, not imported, so the client bundle never touches the SDK.
10
- */
11
- interface ChatTurnTextPartInput {
12
- type: 'text';
13
- text: string;
14
- }
15
- /** A non-text prompt part the upload route hands back and the client echoes
16
- * on send. `url` carries an inline `data:` URI for small files; `path` is a
17
- * sandbox workspace reference for large ones (the >1 MiB gateway body cap
18
- * makes the two-step upload mandatory). */
19
- interface ChatTurnFilePartInput {
20
- type: 'image' | 'file';
21
- filename?: string;
22
- mediaType?: string;
23
- url?: string;
24
- path?: string;
25
- content?: string;
26
- }
27
- type ChatTurnPartInput = ChatTurnTextPartInput | ChatTurnFilePartInput;
28
- /** POST body for the turn route. `content` may be empty when `parts` carry the
29
- * message (an image-only send). Product routing fields (workspaceId etc.) ride
30
- * alongside and are read by the product's `authorize` seam. */
31
- interface ChatTurnRequestPayload {
32
- threadId: string;
33
- content?: string;
34
- /** Non-text parts from the upload route, echoed back verbatim. */
35
- parts?: ChatTurnFilePartInput[];
36
- model?: string;
37
- effort?: 'auto' | 'low' | 'medium' | 'high';
38
- harness?: string;
39
- /** Client-generated idempotency key for the logical turn (retry-safe). */
40
- turnId?: string;
41
- [key: string]: unknown;
42
- }
43
- /** `fetch` init for the turn route — the one place the client wire shape is
44
- * serialized, so composer glue and products never drift from the server's
45
- * parser. */
46
- declare function chatTurnRequestInit(payload: ChatTurnRequestPayload): RequestInit;
47
- declare const INLINE_PARTS_MAX_BYTES = 950000;
48
- declare class ChatTurnInputError extends Error {
49
- readonly status: number;
50
- readonly code: string;
51
- constructor(message: string, status?: number, code?: string);
52
- }
53
- declare function promptPartsByteSize(parts: ChatTurnPartInput[]): number;
54
- /** Throws `ChatTurnInputError` (413) when the parts' inline payload would blow
55
- * the gateway cap. Path-ref parts are tiny by construction and always pass. */
56
- declare function assertPromptPartsWithinCap(parts: ChatTurnPartInput[], maxBytes?: number): void;
57
- /** A file mention resolved from the composer's `@`-picker: the
58
- * workspace-relative path plus enough metadata to build a prompt part and
59
- * pointer text. `path` is the canonical identity — the mention pill's
60
- * `MentionItem.id` for the file kind (`/web-react`'s `useFileMentions`). */
61
- interface FileMention {
62
- path: string;
63
- name: string;
64
- size?: number;
65
- }
66
- /** The `image/*` mime for a mention path by extension, or `undefined` for
67
- * anything not in the known image set (dispatched as `type: 'file'`). */
68
- declare function mediaTypeForMentionPath(path: string): string | undefined;
69
- interface FileMentionsToPartsOptions {
70
- /** Resolve a mention's workspace-relative path to the absolute path the
71
- * dispatched part should carry (e.g. a host prefixing the in-box vault
72
- * root). Default: identity — the path travels unchanged. */
73
- resolvePath?: (path: string) => string;
74
- }
75
- /** Maps resolved file mentions to path-only `ChatTurnFilePartInput`s —
76
- * `image` vs `file` by extension, and always a `path`, never a `url` (the
77
- * url/path XOR invariant: a mention is a sandbox path reference, never
78
- * inline bytes). */
79
- declare function fileMentionsToParts(mentions: readonly FileMention[], opts?: FileMentionsToPartsOptions): ChatTurnFilePartInput[];
80
- /** The agent-facing pointer block appended to the dispatched prompt — never
81
- * persisted in message `content`. Empty array → `''` so callers can append
82
- * unconditionally. This is the sole producer of that text: the current
83
- * turn's dispatch and any history projection built from the same mention
84
- * list both route through here, so the two can't drift apart. */
85
- declare function buildMentionPromptBlock(mentions: readonly Pick<FileMention, 'name' | 'path'>[]): string;
86
- /** Validates the untyped `parts` array off the wire. Returns the typed parts
87
- * or throws `ChatTurnInputError` (400) naming the offending entry. */
88
- declare function parseChatTurnParts(raw: unknown): ChatTurnFilePartInput[];
89
-
90
- /**
91
- * `createSandboxFileIndexRoute` — server side of `@`-file-mentions
92
- * (companion to sandbox-ui#184's composer mention primitive). Serves a flat,
93
- * ignore-filtered listing of the workspace sandbox so `useFileMentions`
94
- * (`/web-react`) can filter it client-side without a round trip per
95
- * keystroke.
96
- *
97
- * Same seam style as `createUploadRoute`: `authorize({ request })` resolves a
98
- * structural `{ tree(path, opts) }` handle (the shape of the sandbox SDK's
99
- * `box.fs.tree`) — no SDK import here. `authorize` also carries the
100
- * cold-box signal: a sandbox that isn't running yet answers `{ status:
101
- * 'warming' }` directly, never provisions-and-waits inside this route.
102
- */
103
-
104
- /** One entry from a structural `tree()` scan. Mirrors the sandbox SDK's
105
- * `FileTreeFile` (`path`, `size`, `mtime`) — `mtime` is unused here so it's
106
- * omitted from the structural match. */
107
- interface SandboxTreeFile {
108
- path: string;
109
- size: number;
110
- }
111
- /** Structural match of the sandbox SDK's `box.fs.tree` result shape
112
- * (`FileTreeResult`). `stats.truncated` is the only stat this route reads;
113
- * the rest ride through unread on the real SDK type. */
114
- interface SandboxTreeResult {
115
- root: string;
116
- files: SandboxTreeFile[];
117
- stats: {
118
- truncated: boolean;
119
- };
120
- }
121
- /** Structural match of the sandbox SDK's `box.fs` tree surface. */
122
- interface SandboxFileTreeSource {
123
- tree(path: string, options?: {
124
- maxDepth?: number;
125
- }): Promise<SandboxTreeResult>;
126
- }
127
- interface FileIndexReadyResponse {
128
- status: 'ready';
129
- /** Workspace-relative entries. Same shape as `FileMention` (`./wire`) so a
130
- * client can hand a response entry straight to `fileMentionsToParts` /
131
- * `buildMentionPromptBlock` without remapping. */
132
- files: FileMention[];
133
- /** True when either the underlying scan truncated (SDK-side cap) or this
134
- * route's own `maxEntries` cap trimmed the filtered list. The client
135
- * should show "showing first N files" rather than imply completeness. */
136
- truncated: boolean;
137
- generatedAt: string;
138
- }
139
- /** Cold-box answer: no provisioning happened, no files were scanned. The
140
- * client shows a warming state and retries — this route never blocks on a
141
- * box coming up. */
142
- interface FileIndexWarmingResponse {
143
- status: 'warming';
144
- }
145
- type FileIndexResponse = FileIndexReadyResponse | FileIndexWarmingResponse;
146
- /** Short-TTL cache seam so repeat popover opens in the same session don't
147
- * re-scan the workspace. Host-provided (e.g. a KV binding); `key` is
148
- * whatever `authorize` returns as `cacheKey` — this route treats it opaquely. */
149
- interface FileIndexCache {
150
- get(key: string): Promise<FileIndexReadyResponse | null> | FileIndexReadyResponse | null;
151
- put(key: string, value: FileIndexReadyResponse, options?: {
152
- ttlSeconds?: number;
153
- }): Promise<void> | void;
154
- }
155
- type FileIndexAuthorization = {
156
- status: 'ready';
157
- /** Structural sandbox `fs` handle, usually `ensureWorkspaceSandbox(...)` → `box.fs`. */
158
- fs: SandboxFileTreeSource;
159
- /** Workspace root to index (e.g. `/home/agent`). */
160
- root: string;
161
- /** Extra ignore segments for this request, merged with the route's
162
- * defaults + `CreateSandboxFileIndexRouteOptions.ignore`. */
163
- ignore?: string[];
164
- /** Opaque cache key for the optional cache seam. Omit to skip caching
165
- * for this request (e.g. a workspace the host chooses not to cache). */
166
- cacheKey?: string;
167
- } | {
168
- status: 'warming';
169
- } | {
170
- status: 'denied';
171
- response: Response;
172
- };
173
- interface CreateSandboxFileIndexRouteOptions {
174
- /** Authenticate the caller, resolve the sandbox `fs` handle, and signal a
175
- * cold box — never provisions or waits. */
176
- authorize(args: {
177
- request: Request;
178
- }): Promise<FileIndexAuthorization>;
179
- /** Extra ignore segments beyond the route's defaults (node_modules, .git,
180
- * dotfiles/dot-dirs, common build dirs). Matched as exact path-segment
181
- * names, same rule as the defaults. */
182
- ignore?: string[];
183
- /** Passed to `fs.tree` as `options.maxDepth`. Default 12. */
184
- maxDepth?: number;
185
- /** Hard cap on entries returned after filtering. Default 5000. */
186
- maxEntries?: number;
187
- /** Optional host-provided cache seam. */
188
- cache?: FileIndexCache;
189
- /** Cache TTL in seconds when `cache` is set. Default 20. */
190
- cacheTtlSeconds?: number;
191
- }
192
- declare function createSandboxFileIndexRoute(options: CreateSandboxFileIndexRouteOptions): (request: Request) => Promise<Response>;
193
-
194
- export { type ChatTurnRequestPayload as C, type FileIndexAuthorization as F, INLINE_PARTS_MAX_BYTES as I, type SandboxFileTreeSource as S, type ChatTurnPartInput as a, type ChatTurnFilePartInput as b, ChatTurnInputError as c, type ChatTurnTextPartInput as d, type CreateSandboxFileIndexRouteOptions as e, type FileIndexCache as f, type FileIndexReadyResponse as g, type FileIndexResponse as h, type FileIndexWarmingResponse as i, type FileMention as j, type FileMentionsToPartsOptions as k, type SandboxTreeFile as l, type SandboxTreeResult as m, assertPromptPartsWithinCap as n, buildMentionPromptBlock as o, chatTurnRequestInit as p, createSandboxFileIndexRoute as q, fileMentionsToParts as r, mediaTypeForMentionPath as s, parseChatTurnParts as t, promptPartsByteSize as u };
@@ -1,182 +0,0 @@
1
- import { Part } from '@tangle-network/agent-interface';
2
- import { a as ChatInteractionField, b as ChatInteractionStatus, h as InteractionAnswers, N as NoticeKind } from './contract-KfqJh_au.js';
3
- import { ChatPlanPersistedPart } from './plans/index.js';
4
-
5
- /**
6
- * The stored shape of `message.parts` — one typed vocabulary for every part a
7
- * product persists into a chat transcript. NOT an ad-hoc union reverse-
8
- * engineered from product schemas; each member is matched field-for-field to
9
- * its canonical source:
10
- *
11
- * - `text` / `reasoning` / `tool`: the persisted projection `/stream`'s
12
- * `normalizePersistedPart` produces from the harness lane's
13
- * `message.part.updated` events (ADC sidecar
14
- * `apps/sidecar/src/events/session-events.ts:56` wraps the canonical part in
15
- * an `{id, sessionID, messageID}` envelope; the projection strips the
16
- * session/message ids and keeps the per-segment part id).
17
- * - `file` / `image` / `step-start` / `step-finish`: the sidecar's canonical
18
- * `MessagePartSchema` members (ADC
19
- * `apps/sidecar/src/schemas/agent-schemas.ts:50-154`); `step-finish` carries
20
- * the harness's per-step usage receipt — tokens
21
- * `{total, input, output, reasoning, cache{write, read}}` + `cost` — which is
22
- * also the shape the message-level token/cost columns mirror.
23
- * - `subtask`: `@tangle-network/agent-interface`'s `SubtaskPart` (a spawned
24
- * sub-agent task).
25
- * - `interaction` / `notice`: the persisted-part codecs in
26
- * `/web-react`'s chat-interactions contract (`interactionToPersistedPart`,
27
- * `noticePart`) — type-only imports, one source of truth for their statuses
28
- * and field shapes.
29
- * - `plan`: the durable-plan projection in `/plans`, derived from the sandbox
30
- * SDK's authoritative plan lifecycle.
31
- *
32
- * `@tangle-network/agent-interface` exports the canonical wire `Part` union,
33
- * but its `PartBase` requires the `sessionID`/`messageID` stream envelope that
34
- * is deliberately NOT persisted, so the stored union is defined here as the
35
- * envelope-free projection (a type-level coverage check against the peer's
36
- * `Part['type']` lives in the tests). Contribute-down candidate: if
37
- * agent-interface grows envelope-free persisted-part types, re-export them
38
- * here and delete these definitions.
39
- *
40
- * Two transport lanes serialize into this SAME stored shape:
41
- * - harness lane: canonical `message.part.updated` parts, merged/normalized by
42
- * `/stream` (`mergePersistedPart`, `finalizeAssistantParts`);
43
- * - router/openai-compat lane: `text_delta`/`tool_call` stream events are
44
- * mapped INTO canonical part events first (`/runtime`'s `toLoopEvents` +
45
- * `/stream`'s `normalizeToolEvent`) and then persisted identically — the
46
- * store never sees a router-specific shape.
47
- */
48
-
49
- /** Start/end wall-clock millis, as normalized by `/stream`'s `normalizeTime`. */
50
- interface ChatPartTime {
51
- start?: number;
52
- end?: number;
53
- }
54
- /** `id` is the harness's per-segment identity; absent on legacy/router parts,
55
- * which collapse to a single logical text stream. Never invented client-side. */
56
- interface ChatTextPart {
57
- type: 'text';
58
- text: string;
59
- id?: string;
60
- }
61
- interface ChatReasoningPart {
62
- type: 'reasoning';
63
- text: string;
64
- id?: string;
65
- time?: ChatPartTime;
66
- }
67
- /** Superset of the sidecar's status enum (`pending|running|completed|failed`)
68
- * and agent-interface's `ToolState` statuses; `error` is the persisted
69
- * terminal form `/stream`'s `normalizePersistedPart` settles on. */
70
- type ChatToolStatus = 'pending' | 'running' | 'completed' | 'error' | 'failed';
71
- interface ChatToolState {
72
- status: ChatToolStatus;
73
- input?: unknown;
74
- output?: unknown;
75
- error?: string;
76
- title?: string;
77
- metadata?: Record<string, unknown>;
78
- time?: ChatPartTime;
79
- }
80
- interface ChatToolPart {
81
- type: 'tool';
82
- id: string;
83
- tool: string;
84
- callID?: string;
85
- state: ChatToolState;
86
- }
87
- /** Union of the sidecar's legacy (path-based) and AI-SDK (url-based) file
88
- * shapes; response-side every field besides `type` is optional. */
89
- interface ChatFilePart {
90
- type: 'file';
91
- id?: string;
92
- filename?: string;
93
- mediaType?: string;
94
- url?: string;
95
- path?: string;
96
- content?: string;
97
- }
98
- interface ChatImagePart {
99
- type: 'image';
100
- filename?: string;
101
- mediaType?: string;
102
- url?: string;
103
- path?: string;
104
- }
105
- interface ChatSubtaskPart {
106
- type: 'subtask';
107
- prompt: string;
108
- description: string;
109
- agent: string;
110
- id?: string;
111
- }
112
- /** OpenCode step-boundary marker — no renderable text; preserved so mappers
113
- * never coerce it into a "[object Object]" text part. */
114
- interface ChatStepStartPart {
115
- type: 'step-start';
116
- }
117
- /** Per-step usage receipt as the harness reports it (sidecar
118
- * `StepFinishPartSchema`). The message-level token/cost columns are this
119
- * shape flattened. */
120
- interface ChatUsageTokens {
121
- total?: number;
122
- input?: number;
123
- output?: number;
124
- reasoning?: number;
125
- cache?: {
126
- write?: number;
127
- read?: number;
128
- };
129
- }
130
- interface ChatStepFinishPart {
131
- type: 'step-finish';
132
- reason?: string;
133
- tokens?: ChatUsageTokens;
134
- cost?: number;
135
- }
136
- /** Persisted human-in-the-loop ask — byte-matches
137
- * `interactionToPersistedPart` in `/web-react`'s chat-interactions contract. */
138
- interface ChatInteractionPart {
139
- type: 'interaction';
140
- id: string;
141
- kind: string;
142
- title: string;
143
- body?: string;
144
- answerSpec: {
145
- fields: ChatInteractionField[];
146
- };
147
- status: ChatInteractionStatus;
148
- answers?: InteractionAnswers;
149
- cancelReason?: string;
150
- }
151
- type ChatPlanPart = ChatPlanPersistedPart;
152
- /** Persisted one-line transcript notice — byte-matches `noticePart` in
153
- * `/web-react`'s chat-interactions contract. */
154
- interface ChatNoticePart {
155
- type: 'notice';
156
- id: string;
157
- noticeKind: NoticeKind;
158
- text: string;
159
- }
160
- type ChatMessagePart = ChatTextPart | ChatReasoningPart | ChatToolPart | ChatFilePart | ChatImagePart | ChatSubtaskPart | ChatStepStartPart | ChatStepFinishPart | ChatInteractionPart | ChatNoticePart | ChatPlanPart;
161
- /** Every canonical harness wire-part kind must be storable — compile-time
162
- * guarantee that a new agent-interface part kind cannot silently fall out of
163
- * the persisted vocabulary. */
164
- type StorableHarnessPartKind = Part['type'] & ChatMessagePart['type'];
165
- /**
166
- * The typed projection at the `/stream` → `/chat-store` boundary. The stream
167
- * normalizers (`normalizePersistedPart`/`mergePersistedPart`/
168
- * `finalizeAssistantParts`) deliberately produce untyped `JsonRecord`s — they
169
- * normalize wire shapes and do not own the stored vocabulary. THIS module
170
- * owns it, so this is where rows gain the `ChatMessagePart` type: each entry
171
- * is validated against its kind's required fields and narrowed, junk is
172
- * dropped, and — enforced by the exhaustiveness check below — no storable
173
- * kind can silently fall out (the step-finish/interaction trap).
174
- */
175
- declare function toChatMessageParts(parts: Array<Record<string, unknown>>): ChatMessagePart[];
176
- declare function isChatToolPart(part: ChatMessagePart): part is ChatToolPart;
177
- declare function isChatTextPart(part: ChatMessagePart): part is ChatTextPart;
178
- declare function isChatInteractionPart(part: ChatMessagePart): part is ChatInteractionPart;
179
- declare function isChatPlanPart(part: ChatMessagePart): part is ChatPlanPart;
180
- declare function isChatStepFinishPart(part: ChatMessagePart): part is ChatStepFinishPart;
181
-
182
- export { type ChatFilePart as C, type StorableHarnessPartKind as S, type ChatImagePart as a, type ChatInteractionPart as b, type ChatMessagePart as c, type ChatNoticePart as d, type ChatPartTime as e, type ChatPlanPart as f, type ChatReasoningPart as g, type ChatStepFinishPart as h, type ChatStepStartPart as i, type ChatSubtaskPart as j, type ChatTextPart as k, type ChatToolPart as l, type ChatToolState as m, type ChatToolStatus as n, type ChatUsageTokens as o, isChatInteractionPart as p, isChatPlanPart as q, isChatStepFinishPart as r, isChatTextPart as s, isChatToolPart as t, toChatMessageParts as u };