@tangle-network/agent-app 0.43.53 → 0.43.55
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 +41 -35
- package/dist/assistant/index.d.ts +2 -2
- package/dist/assistant/index.js +3 -3
- package/dist/{attachment-validation-DX2KIzMC.d.ts → attachment-validation-D0csjCvz.d.ts} +1 -1
- package/dist/chat-routes/index.d.ts +12 -9
- package/dist/chat-routes/index.js +328 -146
- package/dist/chat-routes/index.js.map +1 -1
- package/dist/chat-store/index.d.ts +2 -2
- package/dist/chat-store/index.js +1 -1
- package/dist/{chunk-3EKOSBYL.js → chunk-K63OWUDJ.js} +2 -2
- package/dist/{chunk-EIG7ZQW2.js → chunk-RVUISYUE.js} +15 -3
- package/dist/chunk-RVUISYUE.js.map +1 -0
- package/dist/{chunk-JGYOYY5D.js → chunk-XKBIYSSM.js} +1 -1
- package/dist/chunk-XKBIYSSM.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{parts-IB-Kbb7z.d.ts → parts-1sRYSPjF.d.ts} +58 -1
- package/dist/web-react/index.d.ts +16 -4
- package/dist/web-react/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-EIG7ZQW2.js.map +0 -1
- package/dist/chunk-JGYOYY5D.js.map +0 -1
- /package/dist/{chunk-3EKOSBYL.js.map → chunk-K63OWUDJ.js.map} +0 -0
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@ The application-shell layer for building agent products on the Tangle stack.
|
|
|
8
8
|
|
|
9
9
|
The substrate packages — `@tangle-network/agent-runtime`, `agent-eval`, `agent-integrations`, `tcloud`, `sandbox` — are the **engine**. This package is the **shell**: the chat tool-loop, the structured agent→app side channel, the integration-hub client, per-workspace billing, field crypto, and the web boundary utilities that every agent app otherwise rewrites by hand. You supply your domain through typed seams; the package supplies the mechanism and imports none of your code.
|
|
10
10
|
|
|
11
|
+
**Who it's for:** engineers building an agent product on the Tangle sandbox — a chat app, a copilot, an autonomous worker — who want the shell (chat routes, streaming, durability, approvals, billing, the tool side channel) as composable pieces instead of a per-app rewrite. It is **not** an agent framework or a model SDK: the reasoning lives in the sandbox agent; agent-app is everything around it — the turn plumbing, durability, and money.
|
|
12
|
+
|
|
11
13
|
## Highlights
|
|
12
14
|
|
|
13
15
|
- **Structured tool side channel** — `submit_proposal` (approval-gated), `schedule_followup`, `render_ui`, `add_citation`, exposed as validated tool calls over three surfaces (HTTP route, per-turn MCP server, agent-runtime executor). No fenced-text parsing.
|
|
@@ -109,43 +111,47 @@ One rule decides where anything lives:
|
|
|
109
111
|
|
|
110
112
|
Everything here is reached through a typed seam — `AppToolHandlers`, `AppToolTaxonomy`, `streamTurn`, `executeToolCall`, `verifyToken`, `KeyProvisioner` / `WorkspaceKeyStore` / `KeyCrypto`. The package never imports product code and never hard-codes a domain value (a proposal type, a premium, a disclaimer); each is a parameter. New capability arrives as a new subpath, never a breaking change to an existing one.
|
|
111
113
|
|
|
114
|
+
## Choosing a path
|
|
115
|
+
|
|
116
|
+
Three decisions cover most of the surface.
|
|
117
|
+
|
|
118
|
+
**1. How does the turn run?** Pick the transport by who's watching, not by feature.
|
|
119
|
+
|
|
120
|
+
| Your turn | Use | Why |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| **Interactive** — a user is watching a chat or copilot | `streamPrompt` held open for the turn; the sandbox gateway lets the browser attach directly | Worker lifetime ≈ turn length; a dropped tab replays the buffered tail on reconnect. |
|
|
123
|
+
| **Autonomous** — a mission step, queue job, cron, or inbound email, with nobody watching | `dispatchPrompt({ detach: true })` + poll from a durable driver. `runDetachedTurn` (`/chat-routes`) bridges that detached run into the live buffer, so a browser opening the session mid-run still tails it token-by-token | No consumer exists and Workers die in minutes; the platform runs the turn server-side and a crash re-dispatch is a lookup, not a second run. |
|
|
124
|
+
| **Eval / CI** — a long-lived harness process | `runAppToolLoop` / `streamPrompt` in-process | The process outlives the run; durability adds nothing — a failed run is re-run, not resumed. |
|
|
125
|
+
|
|
126
|
+
**2. Assembled or à la carte?** `createChatTurnRoutes` (`/chat-routes`) wires the whole server chat turn — auth, store, streaming, replay, uploads, interactions — over typed seams. Reach for the individual modules (`/stream`, `/chat-store`, `/interactions`) only to compose something the assembled route doesn't cover.
|
|
127
|
+
|
|
128
|
+
**3. Sandbox or sandbox-free?** The tools, billing, eval, and loop all work without a container: `createOpenAICompatStreamTurn` maps any OpenAI-compatible endpoint into the loop for a browser or edge copilot. Reach for `/sandbox` only when the turn needs a real container — bash, files, sub-agents, MCP.
|
|
129
|
+
|
|
112
130
|
## Modules
|
|
113
131
|
|
|
114
|
-
Each is an independent entry point — import only what you use.
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|---|---|
|
|
138
|
-
| [`/chat-routes`](src/chat-routes) | `createChatTurnRoutes` — the assembled turn vertical: NDJSON `turn` + buffered `replay` + `running` reconnect-discovery + composed `interactions` answer endpoints, over `authorize` / `produce` / `store` seams. Plus `createSandboxChatProducer`, `createUploadRoute`, `createSandboxFileIndexRoute`, `withDurableChatProjection`, and the import-free `./wire` contract (`chatTurnRequestInit`, `ChatTurnRequestPayload`). Composes agent-runtime's `handleChatTurn`; subpath-only (not re-exported from the root). |
|
|
139
|
-
| [`/chat-store`](src/chat-store) | `createChatTables` + `createChatStore` — drizzle thread/message persistence behind the `ChatStore` port, and the canonical `ChatMessagePart` parts vocabulary (`toChatMessageParts`, part guards). The drizzle store/schema is subpath-only. |
|
|
140
|
-
| [`/interactions`](src/interactions) | Human-in-the-loop ask channel: `createInteractionAnswerRoute` (list/answer endpoint factory — validation, 410 mapping, duplicate-answer safety), the server sidecar client, and the shared `ChatInteraction` wire/persisted-part contract + codecs. Composes `@tangle-network/agent-interface` types. |
|
|
141
|
-
| [`/durable-chat`](src/durable-chat) | Durable plan/question workflow around the authoritative channels: `createDurablePlanRoutes`, `createDurableChatScope`, `createDurableChatEventProjection`, `createDurableInteractionRoutePersistence`, the `DurablePlanStore` port, and `InMemoryDurableChatStateStore` (tests/demos only — production supplies the store). |
|
|
142
|
-
| [`/plans`](src/plans) | Browser-safe durable-plan chat projection: `parsePlanSubmittedEvent`, `planToPersistedPart` / `persistedPartToPlan`, `canTransitionPlanStatus`, and the `ChatPlan` union. Byte-matches the SDK's `SandboxSession.plan()`. |
|
|
143
|
-
| [`/object-store`](src/object-store) | Content-addressed durable attachment store: the `ObjectStore` port + `createR2ObjectStore`, `signObjectUrl` / `verifyObjectUrl`, `createProxiedArtifactRoute`, `objectKey`. |
|
|
144
|
-
| [`/app-auth`](src/app-auth) | `createAppAuth` — better-auth config factory + request guards (`requireApiUser`) over the standard users/sessions/accounts/verifications tables; composes `/platform`'s SSO cookie minter. Optional `better-auth` peer; subpath-only. |
|
|
145
|
-
| [`/sandbox`](src/sandbox) | Workspace sandbox provisioning + turn streaming: `ensureWorkspaceSandbox` / `peekWorkspaceSandbox`, `streamSandboxPrompt` / `runSandboxPrompt`, `createWorkspaceSandboxManager`, and terminal / runtime-proxy handlers. Peer `@tangle-network/sandbox`; subpath-only. |
|
|
146
|
-
| [`/platform`](src/platform) | Tangle platform glue: cross-site SSO (`createTangleSsoHandlers`), request guards (`createAuthGuard`, `guardResolution`), the hub proxy, and seat billing. |
|
|
147
|
-
|
|
148
|
-
The root entry (`@tangle-network/agent-app`) re-exports every module, but importing the subpath keeps your bundle to what you use.
|
|
132
|
+
Each subpath is an independent entry point — import only what you use; the root re-exports everything, but a subpath import keeps your bundle to what you touch.
|
|
133
|
+
|
|
134
|
+
The **complete, always-current reference** — every published subpath, its exported symbols, and its internal dependencies — is generated into **[`docs/CODEMAP.md`](./docs/CODEMAP.md)** and kept honest by a CI check (regenerate with `pnpm docs:gen`). Start with the core entry points:
|
|
135
|
+
|
|
136
|
+
**Run a turn**
|
|
137
|
+
- [`/tools`](src/tools) — the structured agent→app side channel (proposals, follow-ups, citations, UI) as validated tool calls, over HTTP / MCP / runtime-executor surfaces.
|
|
138
|
+
- [`/runtime`](src/runtime) — the bounded tool loop; the same loop drives a sandbox agent, a Worker, or an in-browser copilot behind one `streamTurn` seam.
|
|
139
|
+
|
|
140
|
+
**The server chat vertical** ([`examples/chat-app.md`](./examples/chat-app.md))
|
|
141
|
+
- [`/chat-routes`](src/chat-routes) — `createChatTurnRoutes`: auth → store → streaming turn with buffered replay → uploads → sidecar question answering, assembled. Plus `runDetachedTurn` for autonomous turns a browser can still watch live.
|
|
142
|
+
- [`/chat-store`](src/chat-store) · [`/interactions`](src/interactions) · [`/durable-chat`](src/durable-chat) · [`/plans`](src/plans) — persistence, human-in-the-loop asks, and the durable plan/question workflow around them.
|
|
143
|
+
|
|
144
|
+
**On the sandbox**
|
|
145
|
+
- [`/sandbox`](src/sandbox) — workspace provisioning + turn streaming.
|
|
146
|
+
- [`/missions`](src/missions) — durable multi-step orchestration: sequencing, budgets, approval gates, schedules.
|
|
147
|
+
|
|
148
|
+
**React surfaces**
|
|
149
|
+
- [`/web-react`](src/web-react) — router-safe chat + observability components (never imports sandbox-only UI); [`/composer`](src/composer) when the chat owns a full sandbox profile.
|
|
150
|
+
|
|
151
|
+
**Utilities (zero-dependency)**
|
|
152
|
+
- [`/web`](src/web) · [`/stream`](src/stream) · [`/crypto`](src/crypto) · [`/redact`](src/redact) — request boundary, SSE normalization, field crypto, PII redaction.
|
|
153
|
+
|
|
154
|
+
See **[`docs/CODEMAP.md`](./docs/CODEMAP.md)** for the rest — `/billing`, `/tangle`, `/object-store`, `/trace`, `/theme`, `/eval`, `/app-auth`, `/platform`, and more.
|
|
149
155
|
|
|
150
156
|
### Missions: id shape and product columns
|
|
151
157
|
|
|
@@ -4,13 +4,13 @@ import { ToolDetailRenderers, ChatUiMessage } from '../web-react/index.js';
|
|
|
4
4
|
import '../contract-KfqJh_au.js';
|
|
5
5
|
import '@tangle-network/agent-interface';
|
|
6
6
|
import '../plans/index.js';
|
|
7
|
-
import '../parts-
|
|
7
|
+
import '../parts-1sRYSPjF.js';
|
|
8
8
|
import '../agent-activity-C8ZG0F0M.js';
|
|
9
9
|
import '../flow-types-Cb_AblZs.js';
|
|
10
10
|
import '../sandbox-terminal-BIIC__CP.js';
|
|
11
11
|
import '../catalog/index.js';
|
|
12
12
|
import '../harness/index.js';
|
|
13
|
-
import '../attachment-validation-
|
|
13
|
+
import '../attachment-validation-D0csjCvz.js';
|
|
14
14
|
import '../stream-normalizer-DWvtmY6F.js';
|
|
15
15
|
|
|
16
16
|
/**
|
package/dist/assistant/index.js
CHANGED
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
ChatMessages,
|
|
4
4
|
ModelPicker,
|
|
5
5
|
ProviderLogo
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-RVUISYUE.js";
|
|
7
7
|
import "../chunk-65P3HJY3.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-K63OWUDJ.js";
|
|
9
9
|
import "../chunk-2QI7XV2T.js";
|
|
10
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-XKBIYSSM.js";
|
|
11
11
|
import "../chunk-5MG74GVQ.js";
|
|
12
12
|
import "../chunk-XAWFPMAR.js";
|
|
13
13
|
import "../chunk-SIXYZ2FB.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { L as ChatTurnRequestPayload, M as ChatTurnPartInput, g as ChatMessagePart, N as ChatTurnFilePartInput, a as ChatAttachmentPart, C as ChatAttachmentKind, f as ChatMentionPart } from '../parts-
|
|
2
|
-
export { O as ChatAttachmentInput, e as ChatMentionKind, P as ChatTurnInputError, Q as ChatTurnTextPartInput, R as DISPATCH_MAX_MEDIA_PARTS, T as DISPATCH_MAX_PARTS, U as DISPATCH_REQUEST_MAX_BYTES, V as DISPATCH_STRUCTURAL_RESERVE_BYTES, K as FileMention, W as FileMentionsToPartsOptions, X as INLINE_PARTS_MAX_BYTES, Y as MENTION_MAX_COUNT, Z as
|
|
3
|
-
export { A as ALLOWED_ATTACHMENT_SNIFFED_MIMES, a as ATTACHMENT_ACCEPT, b as ATTACHMENT_MAX_COUNT, c as AttachmentTypeCheckResult, C as CreateSandboxFileIndexRouteOptions, F as FileIndexAuthorization, d as FileIndexCache, e as FileIndexReadyResponse, f as FileIndexResponse, g as FileIndexWarmingResponse, M as MAX_ATTACHMENT_TOTAL_BYTES, h as MAX_BINARY_ATTACHMENT_BYTES, i as MAX_TEXT_ATTACHMENT_BYTES, S as SandboxFileTreeSource, j as SandboxTreeFile, k as SandboxTreeResult, l as SniffResult, m as attachmentSizeErrorMessage, n as attachmentTotalSizeErrorMessage, o as checkAttachmentType, p as createSandboxFileIndexRoute, s as sanitizeAttachmentFileName, q as sniffBinary } from '../attachment-validation-
|
|
1
|
+
import { L as ChatTurnRequestPayload, M as ChatTurnPartInput, g as ChatMessagePart, N as ChatTurnFilePartInput, a as ChatAttachmentPart, C as ChatAttachmentKind, f as ChatMentionPart } from '../parts-1sRYSPjF.js';
|
|
2
|
+
export { O as ChatAttachmentInput, e as ChatMentionKind, P as ChatTurnInputError, Q as ChatTurnTextPartInput, R as DISPATCH_MAX_MEDIA_PARTS, T as DISPATCH_MAX_PARTS, U as DISPATCH_REQUEST_MAX_BYTES, V as DISPATCH_STRUCTURAL_RESERVE_BYTES, K as FileMention, W as FileMentionsToPartsOptions, X as INLINE_PARTS_MAX_BYTES, Y as MENTION_MAX_COUNT, Z as ProducerErrorEvent, _ as ProducerNoticeEvent, $ as ProducerPassthroughEvent, a0 as ProducerPassthroughEventType, a1 as ProducerReasoningEvent, a2 as ProducerTextEvent, a3 as ProducerToolCallEvent, a4 as ProducerToolResultEvent, a5 as ProducerUsageEvent, a6 as ProducerWireEvent, a7 as SandboxMentionPathCheck, a8 as assertPromptPartsWithinCap, a9 as base64WireLen, aa as buildMentionPromptBlock, ab as chatTurnRequestInit, ac as fileMentionsToParts, ad as formatBytes, ae as mediaTypeForMentionPath, af as mentionKindForPath, ag as parseChatTurnParts, ah as parseFileMentions, ai as promptPartsByteSize, aj as validateSandboxMentionPath } from '../parts-1sRYSPjF.js';
|
|
3
|
+
export { A as ALLOWED_ATTACHMENT_SNIFFED_MIMES, a as ATTACHMENT_ACCEPT, b as ATTACHMENT_MAX_COUNT, c as AttachmentTypeCheckResult, C as CreateSandboxFileIndexRouteOptions, F as FileIndexAuthorization, d as FileIndexCache, e as FileIndexReadyResponse, f as FileIndexResponse, g as FileIndexWarmingResponse, M as MAX_ATTACHMENT_TOTAL_BYTES, h as MAX_BINARY_ATTACHMENT_BYTES, i as MAX_TEXT_ATTACHMENT_BYTES, S as SandboxFileTreeSource, j as SandboxTreeFile, k as SandboxTreeResult, l as SniffResult, m as attachmentSizeErrorMessage, n as attachmentTotalSizeErrorMessage, o as checkAttachmentType, p as createSandboxFileIndexRoute, s as sanitizeAttachmentFileName, q as sniffBinary } from '../attachment-validation-D0csjCvz.js';
|
|
4
4
|
import { ChatTurnIdentity, ChatTurnProducer } from '@tangle-network/agent-runtime';
|
|
5
5
|
import { InteractionAnswerRoute, InteractionAnswerRouteOptions } from '../interactions/index.js';
|
|
6
6
|
import { PersistedChatMessageForTurn } from '../stream/index.js';
|
|
@@ -335,7 +335,8 @@ declare function createChatTurnRoutes<TContext = void>(options: CreateChatTurnRo
|
|
|
335
335
|
* the `ChatTurnProducer` shape agent-runtime's `handleChatTurn` consumes AND
|
|
336
336
|
* the client vocabulary `/web-react`'s `dispatchChatStreamLine` already parses
|
|
337
337
|
* (`text` / `reasoning` / `tool_call` / `tool_result` / `usage` /
|
|
338
|
-
* `interaction`). Legal and tax each hand-rolled
|
|
338
|
+
* `notice` / structured `error` / `interaction`). Legal and tax each hand-rolled
|
|
339
|
+
* this mapping differently;
|
|
339
340
|
* this is that middle, composed from `/stream`'s normalizers — no new loop
|
|
340
341
|
* logic, no SDK import (the event source is an injected `AsyncIterable`).
|
|
341
342
|
*
|
|
@@ -376,11 +377,13 @@ interface SandboxChatProducerOptions {
|
|
|
376
377
|
model?: string;
|
|
377
378
|
/** Which ask kinds the product renders a card for. Anything else is
|
|
378
379
|
* auto-declined (see `declineInteraction`) so the run never hangs in the
|
|
379
|
-
* broker waiting on a card no client will show. Default: question/plan.
|
|
380
|
+
* broker waiting on a card no client will show. Default: question/plan.
|
|
381
|
+
* Products with per-turn plan mode can close over it without another option:
|
|
382
|
+
* `(kind) => kind === 'question' || (kind === 'plan' && planEnabled)`. */
|
|
380
383
|
isRenderableInteraction?: (kind: string) => boolean;
|
|
381
384
|
/** Resolve a non-renderable ask (wire `respondToSessionInteraction` with the
|
|
382
|
-
* session's sidecar connection). Without it,
|
|
383
|
-
*
|
|
385
|
+
* session's sidecar connection). Without it, a failure notice is emitted and
|
|
386
|
+
* the run stays blocked until the broker times out. */
|
|
384
387
|
declineInteraction?: (id: string) => Promise<void>;
|
|
385
388
|
/** Opt-in eager promotion of harness-emitted `file` parts. Unset, a `file`
|
|
386
389
|
* part persists exactly as the harness sent it — a transient `url` (a
|
|
@@ -497,8 +500,8 @@ interface DetachedTurnOptions {
|
|
|
497
500
|
}
|
|
498
501
|
interface DetachedTurnResult {
|
|
499
502
|
/** `completed` — clean drain: persist + bill. `failed` — a terminal error
|
|
500
|
-
*
|
|
501
|
-
*
|
|
503
|
+
* event, including the producer's structured `sandbox.stream_failed` event
|
|
504
|
+
* when the raw sandbox stream throws: skip billing, render an error row. */
|
|
502
505
|
state: 'completed' | 'failed';
|
|
503
506
|
text: string;
|
|
504
507
|
/** The structured assistant body to persist (tool calls, file/plan/interaction
|