@tangle-network/agent-app 0.1.0 → 0.1.2

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.
Files changed (3) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +116 -31
  3. package/package.json +24 -10
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tangle Network
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,59 +1,144 @@
1
1
  # @tangle-network/agent-app
2
2
 
3
- Shared **application-shell framework** for Tangle agent products (insurance, tax, legal, creative, gtm, agent-builder). The substrate packages (`@tangle-network/{sandbox, agent-runtime, agent-eval, agent-integrations, agent-knowledge, tcloud}`) are the *engine*; this package is the *shell* — the opinionated, reusable application layer those products currently fork-duplicate.
3
+ [![npm](https://img.shields.io/npm/v/@tangle-network/agent-app.svg)](https://www.npmjs.com/package/@tangle-network/agent-app)
4
+ [![npm provenance](https://img.shields.io/badge/npm-provenance-blue.svg)](https://www.npmjs.com/package/@tangle-network/agent-app#provenance)
5
+ [![license](https://img.shields.io/npm/l/@tangle-network/agent-app.svg)](./LICENSE)
4
6
 
5
- The goal: a product should `pnpm add @tangle-network/agent-app`, supply its domain seams (schema, prompt, taxonomy, persistence), and get the whole shell instead of copy-forking another agent app and inheriting its bugs (the way insurance forked legal and inherited legal's IRS/FinCEN filing scripts).
7
+ The application-shell layer for building agent products on the Tangle stack.
6
8
 
7
- Everything here is **domain-seamed**: the generic mechanism lives in the package; each product supplies callbacks/config for the domain-specific bits. The package imports no product code.
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.
8
10
 
9
- ## Modules
11
+ ## Highlights
12
+
13
+ - **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.
14
+ - **Bounded tool loop** — `runAppToolLoop` / `streamAppToolLoop`: stream a turn → collect tool calls → dispatch → fold results back → re-run, capped. Substrate-free behind a `streamTurn` seam, so it drives a sandboxed agent, a Worker, or an in-browser copilot unchanged.
15
+ - **Sandbox-optional** — the same tools, billing, eval, and loop work without a container. A `fetch`-only adapter maps any OpenAI-compatible stream (Tangle Router, tcloud) into the loop. See [`examples/browser-copilot.md`](./examples/browser-copilot.md).
16
+ - **Composes the engine, never forks it** — `/eval` re-exports `@tangle-network/agent-eval`'s verifier; `/integrations` wraps the hub; `/tangle` and `/billing` take the tcloud client as a structural contract. Engines are **peer dependencies** — you pin the version, nothing is bundled.
17
+ - **ESM, typed, zero runtime deps** in the substrate-free modules (`/runtime`, `/web`, `/crypto`, `/redact`, `/stream`). Ships with `.d.ts` and npm [provenance](https://www.npmjs.com/package/@tangle-network/agent-app#provenance).
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pnpm add @tangle-network/agent-app
23
+ ```
10
24
 
11
- | Subpath | Status | What it is |
25
+ The engine packages you actually use are **peer dependencies** — install the ones your modules touch:
26
+
27
+ ```bash
28
+ # /eval composes the eval engine; /integrations composes the hub client
29
+ pnpm add @tangle-network/agent-eval @tangle-network/agent-integrations
30
+ ```
31
+
32
+ | Peer | Required by | Range |
12
33
  |---|---|---|
13
- | `@tangle-network/agent-app/tools` | **shipped + tested** | The structured agent→app tool side channel — `submit_proposal` (approval-gated), `schedule_followup`, `render_ui`, `add_citation`. OpenAI tool defs, MCP-server builder, HTTP route handler, agent-runtime executor, capability auth. Replaces brittle fenced `:::` blocks with validated tool calls. Seam: `AppToolHandlers` + `AppToolTaxonomy`. |
14
- | `@tangle-network/agent-app/delegation` | **shipped + tested** | The agent-runtime "driven loop" MCP (`delegate_research` / `delegate_code` / `delegation_status` …) for multi-step work that runs to completion in its own agent-driver sandbox. Optional; opt in by spreading into the profile `mcp` map. |
15
- | `@tangle-network/agent-app/tangle` | ✅ **shipped + tested** | Tangle login (SSO) + the developer self-service **app-registration → broker-token** flow: `buildConsentUrl` (one-time user consent) + `createBrokerTokenProvider` (caches/auto-refreshes the `sk-tan-broker-` token per durable grant, shares in-flight mints). Structural (depends on the minter contract; pass the concrete `TangleAppsClient` from `@tangle-network/agent-integrations`). |
16
- | `@tangle-network/agent-app/runtime` | ✅ **shipped + tested** | `runAppToolLoop` — the bounded multi-turn tool loop every app's chat runtime hand-rolls: stream a turn → collect tool calls → dispatch → fold results back → re-run, capped. Substrate-free via a `streamTurn` seam (wrap any backend / `runAgentTaskStream`) + an `executeToolCall` seam (route to integration + app-tool executors). |
17
- | `@tangle-network/agent-app/eval` | ✅ **shipped + tested** | The inline completion gate: `producedFromToolEvents` (bridge `/tools` produced events), `verifyCompletion` (per-requirement `satisfiedBy` gate), `tokenRecallChecker` (deterministic content check), `weightedScore`. For full campaigns/traces/LLM-judge use `@tangle-network/agent-eval`; this composes with it. |
34
+ | `@tangle-network/agent-eval` | `/eval` | `>=0.50.0` |
35
+ | `@tangle-network/agent-integrations` | `/integrations`, `/tangle` | `>=0.32.0` |
18
36
 
19
- = built, typechecked, unit-tested, builds. All five modules done 39 tests.
37
+ The substrate-free modules (`/runtime`, `/tools`, `/web`, `/crypto`, `/redact`, `/stream`, `/billing`) need no peers.
20
38
 
21
- ## `/tools` usage (the shipped module)
39
+ ## Quick start
22
40
 
23
- A product supplies its taxonomy + handlers (its real DB/vault ops), then wires the three surfaces:
41
+ A product supplies its **taxonomy** (which proposal types exist, which are approval-gated) and its **handlers** (the real DB/vault writes), then wires the tool side channel to whichever surface it runs on.
24
42
 
25
43
  ```ts
26
44
  import {
27
- buildAppToolOpenAITools, createAppToolRuntimeExecutor, handleAppToolRequest,
28
- buildAppToolMcpServer, type AppToolHandlers, type AppToolTaxonomy,
45
+ buildAppToolOpenAITools,
46
+ createAppToolRuntimeExecutor,
47
+ type AppToolHandlers,
48
+ type AppToolTaxonomy,
29
49
  } from '@tangle-network/agent-app/tools'
50
+ import { runAppToolLoop } from '@tangle-network/agent-app/runtime'
51
+
52
+ // 1. Declare the domain (the package bakes in no proposal types or rules).
53
+ const taxonomy: AppToolTaxonomy = {
54
+ proposalTypes: ['recommend', 'contact', 'other'],
55
+ regulatedTypes: ['recommend', 'contact'], // these require a certified approver
56
+ }
57
+
58
+ // 2. Provide the side effects — your store, your validation.
59
+ const handlers: AppToolHandlers = {
60
+ submitProposal,
61
+ scheduleFollowup,
62
+ renderUi,
63
+ addCitation,
64
+ }
65
+
66
+ // 3. Advertise the tools to the model and route their execution.
67
+ const tools = buildAppToolOpenAITools(taxonomy)
68
+ const executeToolCall = createAppToolRuntimeExecutor({
69
+ handlers,
70
+ taxonomy,
71
+ ctx: { userId, workspaceId, threadId },
72
+ })
73
+
74
+ // 4. Run a bounded, tool-driven turn loop over any backend.
75
+ const result = await runAppToolLoop({
76
+ systemPrompt,
77
+ userMessage,
78
+ streamTurn, // wrap your model / runAgentTaskStream
79
+ executeToolCall,
80
+ isExecutableTool: (name) => tools.some((t) => t.function.name === name),
81
+ })
82
+
83
+ console.log(result.finalText, result.toolResults)
84
+ ```
30
85
 
31
- const taxonomy: AppToolTaxonomy = { proposalTypes: [...], regulatedTypes: [...] }
32
- const handlers: AppToolHandlers = { submitProposal, scheduleFollowup, renderUi, addCitation } // your DB ops
33
-
34
- // 1. Sandbox MCP path — one route file per tool:
35
- export const action = ({ request }) =>
36
- handleAppToolRequest(request, { tool: 'submit_proposal', handlers, taxonomy, verifyToken })
86
+ `streamTurn` is the one seam that varies by backend. For an in-browser or edge copilot talking to an OpenAI-compatible endpoint, you don't write it by hand:
37
87
 
38
- // 2. Per-turn MCP servers (spread into the agent profile's mcp map):
39
- const mcp = { submit_proposal: buildAppToolMcpServer({ tool: 'submit_proposal', baseUrl, token, ctx, description }) /* … */ }
88
+ ```ts
89
+ import { createOpenAICompatStreamTurn, resolveTangleModelConfig } from '@tangle-network/agent-app/runtime'
40
90
 
41
- // 3. agent-runtime chat path (eval / non-sandbox) advertise tools + execute:
42
- runChatThroughRuntime({ /* */ backend: makeBackend({ tools: buildAppToolOpenAITools(taxonomy) }),
43
- appToolExecutor: createAppToolRuntimeExecutor({ handlers, taxonomy, ctx, onProduced }) })
91
+ const cfg = resolveTangleModelConfig() // reads provider/model/key/baseUrl from env, or pass literals
92
+ const streamTurn = createOpenAICompatStreamTurn({ ...cfg, tools })
44
93
  ```
45
94
 
46
- `insurance-agent` is the reference consumer; its `src/lib/.server/tools/*` is being refactored to delegate here.
95
+ The full three-transport walkthrough (Tangle Router, tcloud, Vercel AI SDK) is in [`examples/browser-copilot.md`](./examples/browser-copilot.md).
96
+
97
+ ## How it's organised
98
+
99
+ One rule decides where anything lives:
100
+
101
+ > Does the capability make sense **without** a specific app's tool side channel, approval queue, or chat route?
102
+ > **Yes** → it belongs in an engine package (contribute it down).
103
+ > **No** → it's app-shell, and it belongs here.
104
+
105
+ 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.
106
+
107
+ ## Modules
108
+
109
+ Each is an independent entry point — import only what you use.
110
+
111
+ | Subpath | What it gives you |
112
+ |---|---|
113
+ | [`/tools`](src/tools) | The structured agent→app side channel: `buildAppToolOpenAITools`, `createAppToolRuntimeExecutor`, `handleAppToolRequest` (HTTP), `buildAppToolMcpServer` / `buildHttpMcpServer` (MCP), `createCapabilityToken` + `authenticateToolRequest` (capability auth), `ToolInputError`. |
114
+ | [`/runtime`](src/runtime) | `runAppToolLoop` / `streamAppToolLoop` (bounded tool loop), `resolveTangleModelConfig` (Tangle Router / Anthropic BYOK), and `toLoopEvents` / `createOpenAICompatStreamTurn` (OpenAI-compat stream → loop events, with fragmented tool-call args reassembled). |
115
+ | [`/integrations`](src/integrations) | Integration-hub client: `HubExecClient`, `resolveIntegrationAction`, `invokeIntegrationHub`. Composes `@tangle-network/agent-integrations`. |
116
+ | [`/eval`](src/eval) | `producedFromToolEvents` (bridge tool events into the eval verifier) and `createTokenRecallChecker` (deterministic content check). Re-exports `@tangle-network/agent-eval`'s `verifyCompletion`, `extractProducedState`, `weightedComposite`, `createLlmCorrectnessChecker`. |
117
+ | [`/tangle`](src/tangle) | App-registration consent URL (`buildConsentUrl`) and a cached, auto-refreshing broker-token provider (`createBrokerTokenProvider`). Structural over the tcloud client. |
118
+ | [`/billing`](src/billing) | `createWorkspaceKeyManager` — mint / rotate / roll over / report usage on per-workspace, budget-capped model keys. Seams for provisioner, store, and crypto. |
119
+ | [`/delegation`](src/delegation) | `buildDelegationMcpServer` — the agent-runtime driven-loop MCP (`delegate_research`, `delegate_code`, `delegation_status`) for multi-step work that runs to completion in its own sandbox. Opt-in. |
120
+ | [`/crypto`](src/crypto) | AES-GCM field encryption: `encryptAesGcm`, `decryptAesGcm`, `createFieldCrypto`. Key supplied by the caller. |
121
+ | [`/web`](src/web) | Request-boundary utilities: `parseJsonObjectBody`, `requireString`, `extractRequestContext`, `checkRateLimit`, `addSecurityHeaders`. |
122
+ | [`/stream`](src/stream) | SSE normalization and turn identity: `normalizeToolEvent`, `resolveChatTurn`, `encodeEvent`, message-part merging. |
123
+ | [`/redact`](src/redact) | `redactForIngestion` — PII redaction before content leaves the boundary. |
47
124
 
48
- ## Why this exists
125
+ The root entry (`@tangle-network/agent-app`) re-exports every module, but importing the subpath keeps your bundle to what you use.
49
126
 
50
- Each agent app re-implements the same plumbing (chat pipeline, approval queue, the structured side channel, vault, auth/RBAC, eval scaffold). That fork-duplication is why a single change — e.g. migrating the human-in-the-loop gate from fenced `:::proposal` blocks to validated tool calls — has to be redone in five apps. Lifting the shell here makes it a one-place change, propagated by a version bump.
127
+ ## Compatibility
51
128
 
52
- ## Develop
129
+ - **ESM only.** Ships `import` + `types` conditions per subpath.
130
+ - **Runtimes:** Node ≥ 20, Cloudflare Workers / edge, and the browser (the substrate-free modules use only Web-standard APIs — `fetch`, Web Crypto, `TextEncoder`).
131
+ - **TypeScript:** strict; full `.d.ts` for every entry point.
132
+
133
+ ## Contributing
53
134
 
54
135
  ```bash
55
136
  pnpm install
56
137
  pnpm typecheck && pnpm test && pnpm build
57
138
  ```
58
139
 
59
- Build: tsup (ESM + d.ts). Tests: vitest. No upward deps on any product.
140
+ Build is [tsup](https://tsup.egoist.dev) (ESM + `.d.ts`), tests are [vitest](https://vitest.dev). A change keeps the suite green and follows the layering rule above — anything engine-general is contributed down to the substrate, not duplicated here. See [AGENTS.md](./AGENTS.md) for the full contributor contract.
141
+
142
+ ## License
143
+
144
+ [MIT](./LICENSE)
package/package.json CHANGED
@@ -1,7 +1,20 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-app",
3
- "version": "0.1.0",
4
- "description": "Shared application-shell framework for Tangle agent products: the structured agent→app tool side channel (proposals, follow-ups, generated UI, citations), domain-seamed so each product supplies its own persistence and types.",
3
+ "version": "0.1.2",
4
+ "packageManager": "pnpm@10.33.4",
5
+ "description": "Application-shell framework for Tangle agent products: a bounded tool loop, the structured agent→app tool side channel, integration-hub client, per-workspace billing, and crypto — composed over the Tangle agent substrate through typed seams.",
6
+ "keywords": [
7
+ "tangle",
8
+ "ai-agent",
9
+ "agent-framework",
10
+ "llm",
11
+ "tool-calling",
12
+ "mcp",
13
+ "openai",
14
+ "approval-workflow",
15
+ "cloudflare-workers",
16
+ "eval"
17
+ ],
5
18
  "homepage": "https://github.com/tangle-network/agent-app#readme",
6
19
  "repository": {
7
20
  "type": "git",
@@ -79,6 +92,14 @@
79
92
  "default": "./dist/redact/index.js"
80
93
  }
81
94
  },
95
+ "scripts": {
96
+ "build": "tsup",
97
+ "dev": "tsup --watch",
98
+ "prepare": "tsup",
99
+ "test": "vitest run",
100
+ "test:watch": "vitest",
101
+ "typecheck": "tsc --noEmit"
102
+ },
82
103
  "devDependencies": {
83
104
  "@types/node": "^25.6.0",
84
105
  "tsup": "^8.0.0",
@@ -90,12 +111,5 @@
90
111
  "peerDependencies": {
91
112
  "@tangle-network/agent-integrations": ">=0.32.0",
92
113
  "@tangle-network/agent-eval": ">=0.50.0"
93
- },
94
- "scripts": {
95
- "build": "tsup",
96
- "dev": "tsup --watch",
97
- "test": "vitest run",
98
- "test:watch": "vitest",
99
- "typecheck": "tsc --noEmit"
100
114
  }
101
- }
115
+ }