@tangle-network/agent-runtime 0.21.0 → 0.22.0

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 CHANGED
@@ -362,6 +362,94 @@ const researcherDelegate: ResearcherDelegate = async (args, ctx) => {
362
362
  createMcpServer({ researcherDelegate })
363
363
  ```
364
364
 
365
+ ## OpenAI-compat backend — tools + fail-loud errors
366
+
367
+ `createOpenAICompatibleBackend` forwards an OpenAI Chat Completions
368
+ `tools[]` array on every request when configured. Streamed tool calls
369
+ (both OpenAI delta shape and the Anthropic `tool_use` shape proxied by
370
+ the router) are assembled across SSE chunks and emitted as a single
371
+ `tool_call` RuntimeStreamEvent per call. The backend does NOT execute
372
+ tools — surfacing the call is the contract; dispatch is the caller's
373
+ problem.
374
+
375
+ ```ts
376
+ import {
377
+ createOpenAICompatibleBackend,
378
+ runAgentTaskStream,
379
+ type OpenAIChatTool,
380
+ } from '@tangle-network/agent-runtime'
381
+
382
+ const delegateResearch: OpenAIChatTool = {
383
+ type: 'function',
384
+ function: {
385
+ name: 'delegate_research',
386
+ description: 'Spin up a researcher loop and return a taskId.',
387
+ parameters: {
388
+ type: 'object',
389
+ properties: { question: { type: 'string' } },
390
+ required: ['question'],
391
+ },
392
+ },
393
+ }
394
+
395
+ const backend = createOpenAICompatibleBackend({
396
+ apiKey: process.env.TANGLE_API_KEY!,
397
+ baseUrl: 'https://router.tangle.tools/v1',
398
+ model: 'claude-sonnet-4-6',
399
+ tools: [delegateResearch /* + delegate_code, delegate_feedback, etc. */],
400
+ toolChoice: 'auto', // or 'none' | 'required' | { type: 'function', function: { name } }
401
+ })
402
+
403
+ for await (const event of runAgentTaskStream({ task, backend, input })) {
404
+ if (event.type === 'tool_call') {
405
+ // Dispatch through your MCP / sandbox runtime. `args` is JSON-parsed
406
+ // when the model produced a valid object, raw string otherwise.
407
+ const result = await dispatch(event.toolName, event.args)
408
+ // Feed `result` back on a follow-up turn via `input.messages`.
409
+ }
410
+ }
411
+ ```
412
+
413
+ Callers integrating with `agent-runtime/mcp` typically project the MCP
414
+ server's `tools/list` response into this shape once at config time and
415
+ pass the array as `tools`. The runtime intentionally does NOT depend on
416
+ `@modelcontextprotocol/sdk` — keeping the backend transport thin lets
417
+ domain repos own MCP plumbing.
418
+
419
+ ### Transport errors fail loud
420
+
421
+ Non-success HTTP responses (4xx/5xx after retry exhaustion) and
422
+ connection failures throw `BackendTransportError` from inside the
423
+ `stream()` generator. `runAgentTaskStream` catches the throw and emits:
424
+
425
+ - `backend_error` event with `error: { kind: 'transport', message, status, body }`
426
+ - terminal `final` event with `status: 'failed'` carrying the same `error` detail
427
+
428
+ Consumers building a `RunRecord` MUST map `final.error` onto
429
+ `RunRecord.error`. Treating an empty `finalText` as "agent produced
430
+ nothing" hides credit exhaustion (HTTP 402), auth failure (401),
431
+ model-not-found (404), and upstream outages (5xx).
432
+
433
+ ```ts
434
+ for await (const event of runAgentTaskStream({ task, backend, input })) {
435
+ run.observe(event)
436
+ if (event.type === 'final') {
437
+ run.complete({
438
+ status: event.status === 'completed' ? 'completed' : 'failed',
439
+ resultSummary: event.text ?? '',
440
+ error: event.error
441
+ ? `${event.error.kind} ${event.error.status ?? ''}: ${event.error.message}`
442
+ : undefined,
443
+ })
444
+ }
445
+ }
446
+ ```
447
+
448
+ The body is captured truncated to 2 KiB. By default the sanitized
449
+ telemetry envelope surfaces `error.kind` + `error.status` but redacts
450
+ `error.body` (it can echo user-visible text from a provider's error
451
+ page). Opt in with `RuntimeTelemetryOptions.includeControlPayloads`.
452
+
365
453
  ## Error taxonomy
366
454
 
367
455
  | Error | When |
@@ -369,7 +457,7 @@ createMcpServer({ researcherDelegate })
369
457
  | `ValidationError` | Caller passed invalid arguments |
370
458
  | `ConfigError` | Required env / config missing |
371
459
  | `NotFoundError` | A named resource does not exist |
372
- | `BackendTransportError` | Backend HTTP / IPC call returned non-success |
460
+ | `BackendTransportError` | Backend HTTP / IPC call returned non-success — carries `status` + truncated `body` |
373
461
  | `SessionMismatchError` | Resume requested against a different backend |
374
462
  | `RuntimeRunStateError` | `RuntimeRunHandle` lifecycle methods called out of order |
375
463
 
@@ -421,6 +509,10 @@ Runnable in [`examples/`](./examples/). Every example imports from
421
509
  - [`model-resolution/`](./examples/model-resolution/) — router catalog + fail-closed admission
422
510
  - [`agent-into-reviewer/`](./examples/agent-into-reviewer/) — pipe one runtime's stream into a reviewer agent
423
511
  - [`chat-handler/`](./examples/chat-handler/) — `handleChatTurn` (the centerpiece production pattern)
512
+ - [`coder-loop/`](./examples/coder-loop/) — `coderProfile` + `runLoop` + `FanoutVote` (driven-loop kernel)
513
+ - [`researcher-loop/`](./examples/researcher-loop/) — `researcherProfile` + `runLoop` + `FanoutVote` (peer dep: `@tangle-network/agent-knowledge`)
514
+ - [`mcp-delegation/`](./examples/mcp-delegation/) — mount `agent-runtime-mcp` in a product `AgentProfile` + stdio `tools/list` smoke
515
+ - [`fleet-delegation/`](./examples/fleet-delegation/) — `TANGLE_FLEET_ID` env flip + `createFleetWorkspaceExecutor` topology
424
516
 
425
517
  ## Tests
426
518
 
package/dist/agent.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _tangle_network_agent_eval from '@tangle-network/agent-eval';
2
2
  import { FindingSubject, TraceAnalystKindSpec, AnalystFinding } from '@tangle-network/agent-eval';
3
- import { R as RuntimeStreamEvent } from './types-DvJIha6w.js';
3
+ import { R as RuntimeStreamEvent } from './types-BFgFD_sl.js';
4
4
  import { I as ImprovementAdapter, K as KnowledgeAdapter, a as RunAnalystLoopResult } from './types-D_MXrmJP.js';
5
5
 
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ValidationError
3
- } from "./chunk-RZAOYKCO.js";
3
+ } from "./chunk-XZYF3YJN.js";
4
4
 
5
5
  // src/loops/drivers/refine.ts
6
6
  function createRefineDriver(options = {}) {
@@ -405,4 +405,4 @@ export {
405
405
  refineWinnerIndex,
406
406
  runLoop
407
407
  };
408
- //# sourceMappingURL=chunk-EDVCVFQB.js.map
408
+ //# sourceMappingURL=chunk-724Y4KHY.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createFanoutVoteDriver
3
- } from "./chunk-XLWPTPRP.js";
3
+ } from "./chunk-URDSRUPQ.js";
4
4
 
5
5
  // src/profiles/coder.ts
6
6
  var DEFAULT_MAX_DIFF_LINES = 400;
@@ -245,4 +245,4 @@ export {
245
245
  multiHarnessCoderFanout,
246
246
  createCoderValidator
247
247
  };
248
- //# sourceMappingURL=chunk-Z5LKAYAS.js.map
248
+ //# sourceMappingURL=chunk-CBQVID7G.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  runLoop
3
- } from "./chunk-EDVCVFQB.js";
3
+ } from "./chunk-724Y4KHY.js";
4
4
  import {
5
5
  coderProfile,
6
6
  multiHarnessCoderFanout
7
- } from "./chunk-Z5LKAYAS.js";
7
+ } from "./chunk-CBQVID7G.js";
8
8
  import {
9
9
  NotFoundError
10
- } from "./chunk-RZAOYKCO.js";
10
+ } from "./chunk-XZYF3YJN.js";
11
11
 
12
12
  // src/mcp/executor.ts
13
13
  function createSiblingSandboxExecutor(options) {
@@ -1048,7 +1048,7 @@ import { createInterface } from "readline";
1048
1048
  import { Readable, Writable } from "stream";
1049
1049
  var PROTOCOL_VERSION = "2024-11-05";
1050
1050
  var DEFAULT_SERVER_NAME = "agent-runtime-mcp";
1051
- var DEFAULT_SERVER_VERSION = "0.21.0";
1051
+ var DEFAULT_SERVER_VERSION = "0.22.0";
1052
1052
  function createMcpServer(options = {}) {
1053
1053
  const queue = options.queue ?? new DelegationTaskQueue();
1054
1054
  const feedbackStore = options.feedbackStore ?? new InMemoryFeedbackStore();
@@ -1268,4 +1268,4 @@ export {
1268
1268
  createMcpServer,
1269
1269
  createInProcessTransport
1270
1270
  };
1271
- //# sourceMappingURL=chunk-4XA4TWKW.js.map
1271
+ //# sourceMappingURL=chunk-FTWTA6YE.js.map