network-ai 5.12.7 → 5.13.1

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 (77) hide show
  1. package/INTEGRATION_GUIDE.md +2 -2
  2. package/README.md +67 -11
  3. package/SKILL.md +9 -6
  4. package/dist/adapters/anthropic-messages-adapter.d.ts +141 -0
  5. package/dist/adapters/anthropic-messages-adapter.d.ts.map +1 -0
  6. package/dist/adapters/anthropic-messages-adapter.js +218 -0
  7. package/dist/adapters/anthropic-messages-adapter.js.map +1 -0
  8. package/dist/adapters/index.d.ts +2 -0
  9. package/dist/adapters/index.d.ts.map +1 -1
  10. package/dist/adapters/index.js +6 -1
  11. package/dist/adapters/index.js.map +1 -1
  12. package/dist/esm/adapters/anthropic-messages-adapter.js +218 -0
  13. package/dist/esm/adapters/anthropic-messages-adapter.js.map +1 -0
  14. package/dist/esm/adapters/index.js +6 -1
  15. package/dist/esm/adapters/index.js.map +1 -1
  16. package/dist/esm/index.js +30 -1
  17. package/dist/esm/index.js.map +1 -1
  18. package/dist/esm/lib/effort-policy.js +107 -0
  19. package/dist/esm/lib/effort-policy.js.map +1 -0
  20. package/dist/esm/lib/fan-out.js +47 -14
  21. package/dist/esm/lib/fan-out.js.map +1 -1
  22. package/dist/esm/lib/goal-decomposer.js +79 -10
  23. package/dist/esm/lib/goal-decomposer.js.map +1 -1
  24. package/dist/esm/lib/model-budget.js +167 -0
  25. package/dist/esm/lib/model-budget.js.map +1 -0
  26. package/dist/esm/lib/model-gateway.js +243 -0
  27. package/dist/esm/lib/model-gateway.js.map +1 -0
  28. package/dist/esm/lib/owasp-compliance.js +167 -0
  29. package/dist/esm/lib/owasp-compliance.js.map +1 -0
  30. package/dist/esm/lib/retry-budget.js +75 -0
  31. package/dist/esm/lib/retry-budget.js.map +1 -0
  32. package/dist/esm/lib/telemetry-provider.js +109 -1
  33. package/dist/esm/lib/telemetry-provider.js.map +1 -1
  34. package/dist/esm/lib/thinking-blocks.js +106 -0
  35. package/dist/esm/lib/thinking-blocks.js.map +1 -0
  36. package/dist/index.d.ts +16 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +30 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/lib/effort-policy.d.ts +88 -0
  41. package/dist/lib/effort-policy.d.ts.map +1 -0
  42. package/dist/lib/effort-policy.js +107 -0
  43. package/dist/lib/effort-policy.js.map +1 -0
  44. package/dist/lib/fan-out.d.ts +17 -0
  45. package/dist/lib/fan-out.d.ts.map +1 -1
  46. package/dist/lib/fan-out.js +47 -14
  47. package/dist/lib/fan-out.js.map +1 -1
  48. package/dist/lib/goal-decomposer.d.ts +18 -0
  49. package/dist/lib/goal-decomposer.d.ts.map +1 -1
  50. package/dist/lib/goal-decomposer.js +79 -10
  51. package/dist/lib/goal-decomposer.js.map +1 -1
  52. package/dist/lib/model-budget.d.ts +144 -0
  53. package/dist/lib/model-budget.d.ts.map +1 -0
  54. package/dist/lib/model-budget.js +167 -0
  55. package/dist/lib/model-budget.js.map +1 -0
  56. package/dist/lib/model-gateway.d.ts +252 -0
  57. package/dist/lib/model-gateway.d.ts.map +1 -0
  58. package/dist/lib/model-gateway.js +243 -0
  59. package/dist/lib/model-gateway.js.map +1 -0
  60. package/dist/lib/owasp-compliance.d.ts +57 -0
  61. package/dist/lib/owasp-compliance.d.ts.map +1 -0
  62. package/dist/lib/owasp-compliance.js +167 -0
  63. package/dist/lib/owasp-compliance.js.map +1 -0
  64. package/dist/lib/retry-budget.d.ts +51 -0
  65. package/dist/lib/retry-budget.d.ts.map +1 -0
  66. package/dist/lib/retry-budget.js +75 -0
  67. package/dist/lib/retry-budget.js.map +1 -0
  68. package/dist/lib/telemetry-provider.d.ts +72 -0
  69. package/dist/lib/telemetry-provider.d.ts.map +1 -1
  70. package/dist/lib/telemetry-provider.js +109 -1
  71. package/dist/lib/telemetry-provider.js.map +1 -1
  72. package/dist/lib/thinking-blocks.d.ts +77 -0
  73. package/dist/lib/thinking-blocks.d.ts.map +1 -0
  74. package/dist/lib/thinking-blocks.js +106 -0
  75. package/dist/lib/thinking-blocks.js.map +1 -0
  76. package/package.json +3 -3
  77. package/socket.json +8 -0
@@ -496,7 +496,7 @@ Run these before declaring the integration production-ready:
496
496
  - [ ] `npx ts-node test-phase4.ts` — 147 behavioral tests pass
497
497
  - [ ] `npx ts-node test-qa.ts` — 67 QA orchestrator tests pass
498
498
  - [ ] `npx ts-node test-phase7.ts` — 94 Phase 7 tests pass (hooks, flow control, composer, semantic search)
499
- - [ ] `npm run test:all` — all 3,269 tests pass across 33 suites
499
+ - [ ] `npm run test:all` — all 3,373 tests pass across 37 suites
500
500
  - [ ] `npm run demo -- --08` runs to completion in < 10 seconds
501
501
 
502
502
  ### Race Condition Safety
@@ -564,4 +564,4 @@ Run these before declaring the integration production-ready:
564
564
 
565
565
  ---
566
566
 
567
- *Network-AI v5.12.4 · MIT License · https://github.com/Jovancoding/Network-AI*
567
+ *Network-AI v5.13.0 · MIT License · https://github.com/Jovancoding/Network-AI*
package/README.md CHANGED
@@ -5,9 +5,9 @@
5
5
  [![Website](https://img.shields.io/badge/website-network--ai.org-4b9df2?style=flat&logo=web&logoColor=white)](https://network-ai.org/)
6
6
  [![CI](https://github.com/Jovancoding/Network-AI/actions/workflows/ci.yml/badge.svg)](https://github.com/Jovancoding/Network-AI/actions/workflows/ci.yml)
7
7
  [![CodeQL](https://github.com/Jovancoding/Network-AI/actions/workflows/codeql.yml/badge.svg)](https://github.com/Jovancoding/Network-AI/actions/workflows/codeql.yml)
8
- [![Release](https://img.shields.io/badge/release-v5.12.7-blue.svg)](https://github.com/Jovancoding/Network-AI/releases)
8
+ [![Release](https://img.shields.io/badge/release-v5.13.1-blue.svg)](https://github.com/Jovancoding/Network-AI/releases)
9
9
  [![npm](https://img.shields.io/npm/dw/network-ai.svg?label=npm%20downloads)](https://www.npmjs.com/package/network-ai)
10
- [![Tests](https://img.shields.io/badge/tests-3269%20passing-brightgreen.svg)](#testing)
10
+ [![Tests](https://img.shields.io/badge/tests-3373%20passing-brightgreen.svg)](#testing)
11
11
  [![Adapters](https://img.shields.io/badge/frameworks-29%20supported-blueviolet.svg)](#adapter-system)
12
12
  [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE)
13
13
  [![Socket](https://socket.dev/api/badge/npm/package/network-ai)](https://socket.dev/npm/package/network-ai/overview)
@@ -34,6 +34,7 @@ Network-AI is a TypeScript/Node.js multi-agent orchestrator that adds coordinati
34
34
  - **29 adapters** — LangChain (+ streaming), AutoGen, CrewAI, OpenAI Assistants, LlamaIndex, Semantic Kernel, Haystack, DSPy, Agno, MCP, Custom (+ streaming), OpenClaw, A2A, Codex, MiniMax, NemoClaw, APS, Copilot, LangGraph, Anthropic Computer Use, OpenAI Agents SDK, Vertex AI, Pydantic AI, Browser Agent, Hermes (NousResearch Hermes / any OpenAI-compatible endpoint), Orchestrator (hierarchical multi-orchestrator), and RLM (Recursive Language Model / any RLM-compatible HTTP endpoint) — no glue code, no lock-in
35
35
  - **Persistent project memory (Layer 3)** — `context_manager.py` injects decisions, goals, stack, milestones, and banned patterns into every system prompt so agents always have full project context
36
36
  - **v5.0 modules** — Agent VCR (record/replay), comparison runner, coverage reporter, goal DSL, approval inbox, job queue, gRPC/HTTP transport, playground REPL, adapter test harness, and more
37
+ - **Model-interaction lifecycle governance (v5.13)** — `GovernedModelGateway` absorbs the model refusal → fallback → billing chain (cross-model fallback, fallback-credit repricing, effort governance, thinking-block handoff) behind one governed, budgeted, audited call
37
38
 
38
39
  > **The silent failure mode in multi-agent systems:** parallel agents writing to the same key
39
40
  > use last-write-wins by default — one agent's result silently overwrites another's mid-flight.
@@ -51,6 +52,58 @@ Network-AI is a TypeScript/Node.js multi-agent orchestrator that adds coordinati
51
52
 
52
53
  ---
53
54
 
55
+ ## 🛡️ Model-Interaction Lifecycle Governance
56
+
57
+ Most governance tools stop at the agent boundary — they police which tools an agent may call *before* it acts. Network-AI also governs the layer underneath: **how an agent talks to the model.** When a frontier model declines a request with a classifier refusal, Network-AI absorbs the refusal → fallback → billing chain and presents one governed, budgeted, audited call.
58
+
59
+ - **`GovernedModelGateway`** — detect `stop_reason:"refusal"`, audit which classifier fired, route to a fallback model, and redeem the fallback-credit token so the retry is repriced as a cache read.
60
+ - **`ModelBudget`** — per-model USD accounting with fallback-credit repricing; never sums tokens across models.
61
+ - **`RefusalTelemetry`** — a refusal is an HTTP 200, invisible to error-rate monitoring; emitted as a discrete non-error signal with an `unservedRefusalCount` gap to alert on.
62
+ - **`EffortPolicy`** — turn the `effort` cost dial into a policy object: cap sub-agents at `low`, require justification for `xhigh`/`max`.
63
+ - **`ThinkingBlockManager`** — keep thinking blocks unchanged on the same model; strip them on a cross-model fallback; guard prompts against `reasoning_extraction` refusals.
64
+ - **Per-sub-agent fallback** — `FanOutFanIn` steps and `TeamRunner` tasks each carry their own fallback agent and per-request retry budget (`RetryBudget`), because a turn can refuse independently across an agent and its sub-agents.
65
+
66
+ ```typescript
67
+ import { AnthropicMessagesAdapter, ModelBudget, RefusalTelemetry } from 'network-ai';
68
+
69
+ const adapter = new AnthropicMessagesAdapter();
70
+ await adapter.initialize({});
71
+ adapter.registerModelAgent('analyst', {
72
+ client, // bring your own Anthropic client
73
+ model: 'claude-fable-5',
74
+ fallbackModels: ['claude-opus-4-8'], // classifier refusals fall through here
75
+ budget: new ModelBudget({
76
+ ceilingUsd: 5,
77
+ pricing: {
78
+ 'claude-fable-5': { inputPerMTok: 10, outputPerMTok: 50 },
79
+ 'claude-opus-4-8': { inputPerMTok: 5, outputPerMTok: 25 },
80
+ },
81
+ }),
82
+ telemetry: new RefusalTelemetry(),
83
+ });
84
+ const result = await adapter.executeAgent('analyst', { action: 'Summarize Q3 results', params: {} }, { agentId: 'cli' });
85
+ // result.data: { servedModel, servedByFallback, refused, refusalCategories, attempts, totalCostUsd }
86
+ ```
87
+
88
+ ### OWASP Agentic AI Top 10 (2026) — engine coverage
89
+
90
+ Verify programmatically with `verifyOwaspCoverage()` (exported from `network-ai`):
91
+
92
+ | Risk | Status | Primary control |
93
+ |---|---|---|
94
+ | ASI-01 Agent Goal Hijack | ✅ Covered | AuthGuardian gating + JourneyFSM control plane |
95
+ | ASI-02 Tool Misuse & Exploitation | ✅ Covered | AgentRuntime SandboxPolicy + ApprovalGate |
96
+ | ASI-03 Identity & Privilege Abuse | ✅ Covered | HMAC / Ed25519 signed tokens + trust scoring |
97
+ | ASI-04 Supply Chain Risks | ✅ Covered | 1 runtime dep + socket / clawhub / codeql gates |
98
+ | ASI-05 Unsafe Code Execution | ✅ Covered | ShellExecutor `shell:false` argv + path guards |
99
+ | ASI-06 Memory & Context Poisoning | ✅ Covered | LockedBlackboard + injection detection |
100
+ | ASI-07 Insecure Inter-Agent Comms | 🟡 Partial | FS-mutex + signed handoffs (local-trust boundary) |
101
+ | ASI-08 Cascading Failures | ✅ Covered | CircuitBreaker + budgets + RetryBudget |
102
+ | ASI-09 Human-Agent Trust Exploitation | ✅ Covered | ApprovalGate + tamper-evident audit trail |
103
+ | ASI-10 Rogue Agents | ✅ Covered | ComplianceMonitor + circuit-breaker kill switch |
104
+
105
+ ---
106
+
54
107
  ## ⚡ Try in 60 Seconds
55
108
 
56
109
  ```bash
@@ -489,7 +542,7 @@ npm run test:phase9 # Agent runtime, console, strategy agent
489
542
  npm run test:phase12 # Context Throttler, Partition Planner, Coverage Gate, Route Classifier
490
543
  ```
491
544
 
492
- **3,269 passing assertions across 33 test suites** (`npm run test:all`):
545
+ **3,373 passing assertions across 37 test suites** (`npm run test:all`):
493
546
 
494
547
  | Suite | Assertions | Covers |
495
548
  |---|---|---|
@@ -525,6 +578,9 @@ npm run test:phase12 # Context Throttler, Partition Planner, Coverage Gate,
525
578
  | `test-transport.ts` | 117 | Basis transport tier: `TransportAgent` state machine, `LandscapeAgent` health tracking, `AgentPool` drain/pause, fleet coordination, canary, rollback |
526
579
  | `test-claim-verifier.ts` | 50 | ClaimVerifier: receipt generation/tamper/expiry, corroborated/unsupported/undisclosed, trust decay/reset/DoS protection |
527
580
  | `test-phase13.ts` | 58 | ESM dual-build config, McpStreamableServer dispatch + resources + prompts, PhasePipeline checkpoint/resume/clear, SemanticMemory save/load/autoSave/clearPersisted |
581
+ | `test-phase14.ts` | 52 | Model lifecycle governance: `GovernedModelGateway` refusal→fallback, `ModelBudget` credit repricing, `RefusalTelemetry`, Anthropic Messages adapter |
582
+ | `test-phase15.ts` | 31 | Orchestration resilience: `RetryBudget`, per-sub-agent fallback in `FanOutFanIn` + `TeamRunner`, `EffortPolicy` |
583
+ | `test-phase16.ts` | 21 | `ThinkingBlockManager` lifecycle + reasoning-extraction guard, OWASP Agentic Top 10 coverage matrix |
528
584
  | `test.ts` | 39 | Core orchestrator smoke tests |
529
585
 
530
586
  ---
@@ -534,18 +590,18 @@ npm run test:phase12 # Context Throttler, Partition Planner, Coverage Gate,
534
590
  | Doc | Contents |
535
591
  |---|---|
536
592
  | [QUICKSTART.md](QUICKSTART.md) | Installation, first run, CLI reference, PowerShell guide, Python scripts CLI |
537
- | [ARCHITECTURE.md](ARCHITECTURE.md) | Race condition problem, FSM design, handoff protocol, module inventory, project structure |
593
+ | [ARCHITECTURE.md](ARCHITECTURE.md) | Race condition problem, FSM design, handoff protocol, model-interaction lifecycle governance, module inventory, project structure |
538
594
  | [BENCHMARKS.md](BENCHMARKS.md) | Provider performance, rate limits, local GPU, `max_completion_tokens` guide |
539
- | [SECURITY.md](SECURITY.md) | Security module, permission system, trust levels, audit trail, disclosure SLA, ClawHub scan findings |
595
+ | [SECURITY.md](SECURITY.md) | Security module, permission system, trust levels, audit trail, OWASP Agentic Top 10 coverage, disclosure SLA, ClawHub scan findings |
540
596
  | [THREAT_MODEL.md](THREAT_MODEL.md) | Adversary profiles, trust boundaries, explicit non-goals, security controls summary |
541
597
  | [DATA_LOCATIONS.md](DATA_LOCATIONS.md) | Every file Network-AI creates — path, purpose, data classification, operator responsibilities |
542
598
  | [SUPPLY_CHAIN.md](SUPPLY_CHAIN.md) | Runtime dependencies, what runs at install, network surface, SLSA/npm provenance verification |
543
599
  | [ENTERPRISE.md](ENTERPRISE.md) | Evaluation checklist, stability policy, security summary, integration entry points |
544
- | [AUDIT_LOG_SCHEMA.md](AUDIT_LOG_SCHEMA.md) | Audit log field reference, all event types, scoring formula |
600
+ | [AUDIT_LOG_SCHEMA.md](AUDIT_LOG_SCHEMA.md) | Audit log field reference, all event types (including `model.refusal` / `model.attempt`), scoring formula |
545
601
  | [ADOPTERS.md](ADOPTERS.md) | Known adopters — open a PR to add yourself |
546
- | [INTEGRATION_GUIDE.md](INTEGRATION_GUIDE.md) | End-to-end integration walkthrough with v5.0 modules |
547
- | [SKILL.md](SKILL.md) | OpenClaw/ClawHub Python skill — setup, orchestrator protocol, security scan findings |
548
- | [references/adapter-system.md](references/adapter-system.md) | Adapter architecture, all 29 adapters, writing custom adapters |
602
+ | [INTEGRATION_GUIDE.md](INTEGRATION_GUIDE.md) | End-to-end integration walkthrough with v5.13 modules |
603
+ | [SKILL.md](SKILL.md) | OpenClaw/ClawHub Python skill — setup, orchestrator protocol, OWASP engine coverage, security scan findings |
604
+ | [references/adapter-system.md](references/adapter-system.md) | Adapter architecture, all 29 adapters (incl. `AnthropicMessagesAdapter`), writing custom adapters |
549
605
  | [references/auth-guardian.md](references/auth-guardian.md) | Permission scoring, resource types, `scoreRequest()`, IAuthValidator interface |
550
606
  | [references/trust-levels.md](references/trust-levels.md) | Trust level configuration, APS delegation-chain mapping |
551
607
 
@@ -563,7 +619,7 @@ Three integration files are included in the repo root:
563
619
  |---|---|
564
620
  | [`claude-tools.json`](claude-tools.json) | Claude API tool use & OpenAI Codex — drop into the `tools` array |
565
621
  | [`openapi.yaml`](openapi.yaml) | Custom GPT Actions — import directly in the GPT editor |
566
- | [`claude-project-prompt.md`](claude-project-prompt.md) | Claude Projects — paste into Custom Instructions |
622
+ | [`claude-project-prompt.md`](claude-project-prompt.md) | Claude Projects — paste into Custom Instructions (includes lifecycle governance context) |
567
623
 
568
624
  **Claude API / Codex:**
569
625
  ```js
@@ -600,7 +656,7 @@ MIT License — [LICENSE](LICENSE) &nbsp;·&nbsp; [CHANGELOG](CHANGELOG.md) &nbs
600
656
  <details>
601
657
  <summary>Keywords</summary>
602
658
 
603
- multi-agent · agent orchestration · AI agents · agentic AI · agentic workflow · TypeScript · Node.js · LangGraph · CrewAI · AutoGen · MCP · model-context-protocol · LlamaIndex · Semantic Kernel · OpenAI Assistants · Haystack · DSPy · Agno · OpenClaw · ClawHub · shared state · blackboard pattern · atomic commits · guardrails · token budgets · permission gating · audit trail · agent coordination · agent handoffs · governance · cost-awareness
659
+ multi-agent · agent orchestration · AI agents · agentic AI · agentic workflow · TypeScript · Node.js · LangGraph · CrewAI · AutoGen · MCP · model-context-protocol · LlamaIndex · Semantic Kernel · OpenAI Assistants · Haystack · DSPy · Agno · OpenClaw · ClawHub · shared state · blackboard pattern · atomic commits · guardrails · token budgets · permission gating · audit trail · agent coordination · agent handoffs · governance · cost-awareness · refusal handling · fallback routing · model lifecycle · OWASP agentic AI · effort policy · thinking blocks
604
660
 
605
661
  </details>
606
662
 
package/SKILL.md CHANGED
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: network-ai
3
- description: "Local Python orchestration skill: multi-agent workflows via shared blackboard file, permission gating, token budget scripts, and persistent project context. All bundled Python scripts run locally with zero network calls. The full npm package (npm install network-ai) additionally ships a TypeScript library, CLI, and an optional operator-started MCP SSE server that binds a TCP port."
3
+ description: "Local Python orchestration skill: multi-agent workflows via shared blackboard file, permission gating, token budget scripts, and persistent project context. The bundled Python scripts make no network calls and have zero third-party dependencies. The parent repository also contains a TypeScript engine (not included in this skill bundle)."
4
4
  metadata:
5
5
  openclaw:
6
6
  emoji: "\U0001F41D"
7
7
  homepage: https://network-ai.org
8
8
  capabilities:
9
- filesystem: "read/write — project root `swarm-blackboard.md` (blackboard state), `data/pending_changes/<id>.json` (WAL entries), `data/audit_log.jsonl`, `data/active_grants.json`, `data/.signing_key`, `data/project-context.json`, `data/task_tracking.json`, `data/agent_health.json`, `data/budget_tracking.json`. All paths are local; nothing is transmitted over the network. When NETWORK_AI_ENV is set, data paths are rooted at `data/<env>/` instead of `data/`. The `--path` argument in blackboard.py is validated against the project root at runtime — paths outside the project directory are rejected (CWE-22)."
9
+ filesystem: "read/write — project root `swarm-blackboard.md` (blackboard state), `data/pending_changes/<id>.json` (WAL entries), `data/audit_log.jsonl`, `data/active_grants.json`, `data/.signing_key`, `data/project-context.json`, `data/task_tracking.json`, `data/agent_health.json`, `data/budget_tracking.json`. All paths are local; no data leaves the local filesystem. When NETWORK_AI_ENV is set, data paths are rooted at `data/<env>/` instead of `data/`. The `--path` argument in blackboard.py is validated against the project root at runtime — paths outside the project directory are rejected (CWE-22)."
10
10
  env_vars: "read — NETWORK_AI_ENV (environment routing), NETWORK_AI_MCP_SECRET (MCP bearer auth), NETWORK_AI_MINIMAL (minimal-mode flag). No env vars are written."
11
11
  shell_exec: "optional — AgentRuntime (lib/agent-runtime.ts) with SandboxPolicy and ApprovalGate; disabled by default. Never auto-enabled by this skill. auto_approve must NOT be set in production (see auto_approve_warning below)."
12
12
  tcp_port: "optional — MCP SSE server (bin/mcp-server.ts) binds 127.0.0.1 only when explicitly started by the operator. Requires a non-empty bearer-token secret. Never auto-started by this skill or any bundled Python script."
@@ -35,7 +35,7 @@ metadata:
35
35
  path: data/
36
36
  scope: local-only
37
37
  files: ["audit_log.jsonl", "active_grants.json", ".signing_key", "project-context.json", "task_tracking.json", "agent_health.json", "budget_tracking.json", "pending_changes/<id>.json"]
38
- description: "All persistent state is local-only. No files are transmitted over the network."
38
+ description: "All persistent state is local-only. No data leaves the local filesystem."
39
39
  blackboard_file:
40
40
  path: swarm-blackboard.md
41
41
  scope: local-only
@@ -535,7 +535,7 @@ Sequential processing - output of one feeds into next.
535
535
 
536
536
  **Every sensitive action MUST be logged to `data/audit_log.jsonl`** to maintain compliance and enable forensic analysis.
537
537
 
538
- > **Privacy note:** Audit log entries contain agent-provided free-text fields (justifications, descriptions). These are stored locally in `data/audit_log.jsonl` and never transmitted over the network by this skill. However, **do not put PII, passwords, or API keys in justification strings** — they persist on disk. Consider periodic log rotation and restricting OS file permissions on the `data/` directory.
538
+ > **Privacy note:** Audit log entries contain agent-provided free-text fields (justifications, descriptions). These are stored locally in `data/audit_log.jsonl` and kept on this machine only by this skill — no audit data leaves the local filesystem. However, **do not put PII, passwords, or API keys in justification strings** — they persist on disk. Consider periodic log rotation and restricting OS file permissions on the `data/` directory.
539
539
 
540
540
  ### What Gets Logged Automatically
541
541
 
@@ -732,6 +732,8 @@ python {baseDir}/scripts/swarm_guard.py supervisor-review --task-id "task_001"
732
732
 
733
733
  The following findings are drawn from the **MAESTRO Agent Security Threat** framework (OWASP LLM / ASVS mapping). They are addressed by existing architectural controls in Network-AI — not open vulnerabilities.
734
734
 
735
+ > **Engine-level OWASP Agentic AI Top 10 (2026):** the TypeScript orchestration engine maps all 10 OWASP Agentic risk categories (ASI-01 … ASI-10) to deterministic controls, verifiable programmatically via `verifyOwaspCoverage()` (`lib/owasp-compliance.ts`, exported from `network-ai`). See the coverage table in the README. The MAESTRO/AST findings below scope the bundled Python skill scripts.
736
+
735
737
  ### AST03 — Over-Privileged Skills · Severity: High
736
738
 
737
739
  > *Skills are granted broader permissions than their stated function requires, creating excessive blast radius if prompt-injected.*
@@ -751,7 +753,7 @@ The following findings are drawn from the **MAESTRO Agent Security Threat** fram
751
753
 
752
754
  | Control | How Network-AI addresses it |
753
755
  |---|---|
754
- | **Zero network calls (Python scripts)** | All bundled Python scripts use Python stdlib only, spawn no subprocesses, and make no network calls — declared in `metadata.openclaw.network_calls` and `bundle_scope`. The optional MCP SSE server (`bin/mcp-server.ts`) binds a TCP port only when explicitly started by the operator and requires a non-empty bearer-token secret. |
756
+ | **Zero network calls (Python scripts)** | All bundled Python scripts use Python stdlib only, spawn no subprocesses, and make no network calls — declared in `metadata.openclaw.network_calls` and `bundle_scope`. The optional TypeScript MCP server (`bin/mcp-server.ts`) is not part of the ClawHub bundle; it must be explicitly started by the operator via `npx network-ai-server` and requires a non-empty bearer-token secret. |
755
757
  | **AgentRuntime sandbox** | `ShellExecutor` enforces per-command timeout and output-size limits; `SandboxPolicy` allowlist/blocklist prevents unapproved shell commands from running at all |
756
758
  | **ClaimVerifier (Tier 1 agent honesty)** | `AgentRuntime` issues HMAC-signed outcome-bound receipts (`ExecutionReceipt`) on every `exec()` and `writeFile()`; `ClaimVerifier` (`lib/claim-verifier.ts`) reconciles agent-declared manifests against the audit log — `UNSUPPORTED_CLAIM` and `UNDISCLOSED_ACTION` violations surface through `ComplianceMonitor`; repeated fabrication decays `AuthGuardian` trust and forces `ApprovalGate` supervision |
757
759
  | **Source protection** | `SandboxPolicy.sourceProtection` constrains `FileAccessor.read/write/list` to `data/<env>/` only; any attempt to read outside that boundary throws `SourceProtectionError` — the agent receives `{success: false}`, no path details leak |
@@ -765,7 +767,7 @@ The following findings are drawn from the **MAESTRO Agent Security Threat** fram
765
767
 
766
768
  | Control | How Network-AI addresses it |
767
769
  |---|---|
768
- | **Exact version pinning** | npm `package.json` uses exact `"version": "5.12.4"` — no semver range specifiers; `clawhub install network-ai` pins to a specific published version |
770
+ | **Exact version pinning** | npm `package.json` uses exact `"version": "5.13.1"` — no semver range specifiers; `clawhub install network-ai` pins to a specific published version |
769
771
  | **Zero transitive dependency drift** | All bundled Python scripts use Python stdlib only — `pip install` is never required; there are no third-party packages to drift, be compromised upstream, or introduce CVEs |
770
772
  | **Signed, tagged releases** | Every release is committed with a signed Git tag (`v5.7.x`); commit hash is verifiable against CHANGELOG.md; GitHub releases link tag → diff → changelog entry |
771
773
  | **Supply chain monitoring** | npm package continuously scored by Socket.dev (score A); any new dependency or permission change triggers an alert |
@@ -791,6 +793,7 @@ This skill is scanned on every publish. The following Notes are flagged by desig
791
793
  | **SkillSpector** Context-Inappropriate Capability (MCP control surface breadth) | ~~Medium~~ Resolved | Same root cause — `comment.txt` enumerated the HTTP MCP server's 22 privileged tools (blackboard write, token ops, agent_spawn, fsm_transition, audit_query), which the scanner read as a broad remote-control surface inside a local skill. | Fixed in v5.12.7 — `comment.txt` excluded from the bundle (see row above) and enforced by the `clawhub:check` guard. The HTTP MCP server itself remains opt-in: it requires a non-empty bearer secret before `listen()` binds (fail-closed), runs only via `NETWORK_AI_MCP_SECRET=<secret> npx network-ai-server`, binds `127.0.0.1` by default, and is documented in `SUPPLY_CHAIN.md §5a`. |
792
794
  | **SkillSpector** Context-Inappropriate Capability (`_load_signing_key()` token minting) | Medium, 92% | `scripts/check_permission.py` mints, HMAC-signs, persists, and lists grant tokens — a de facto local authorization artifact that downstream components may be tempted to treat as real credentials. | Token advisory-only warnings appear in source, SKILL.md, and SECURITY.md. Every grant response includes the advisory notice. Tokens are labeled `grant_{uuid4().hex}`; the HMAC signature only proves local origin, not external identity. Platform-level authentication is required before any destructive action (PAYMENTS, DATABASE, FILE_EXPORT). See ASI03 rows above. |
793
795
  | **SkillSpector** Intent-Code Divergence (`FILE_EXPORT` missing from `HIGH_RISK_RESOURCES`) | ~~Low~~ Resolved | Comment stated `FILE_EXPORT` requires `--confirm-high-risk` but `HIGH_RISK_RESOURCES` only contained `PAYMENTS` and `DATABASE`; file export requests could receive advisory grants without the extra acknowledgment | Fixed in v5.11.0 — `FILE_EXPORT` added to `HIGH_RISK_RESOURCES` in `check_permission.py`; now requires `--confirm-high-risk` consistent with the documented policy |
796
+ | **SkillSpector** YARA `agent_skill_mcp_tool_poisoning_metadata` (MCP/tool metadata poisoning indicators) | ~~High~~ Resolved | SKILL.md frontmatter `description:` retained an older phrasing that referenced the optional TypeScript network server alongside "zero network calls" — a combination the YARA rule flags. A privacy-note sentence also used wording adjacent to file/data references that the exfiltration sub-rule flagged. | Fixed in v5.13.1 — frontmatter `description:` confirmed clean (server reference removed; TypeScript engine noted as parent repository only). Privacy note reworded to remove the flagged phrase. VirusTotal 64/64 clean throughout. |
794
797
  | **SkillSpector** Description-Behavior Mismatch (`ensure_data_dir()` ignoring env scope) | ~~Medium~~ Resolved | `ensure_data_dir()` always created the fixed top-level `data/` directory instead of the active env-specific path, breaking environment isolation when `NETWORK_AI_ENV` is set | Fixed in v5.11.0 — `ensure_data_dir()` now delegates to `_resolve_data_dir()` so audit log and grant files are always written to the correct env-scoped directory |
795
798
 
796
799
  ## References
@@ -0,0 +1,141 @@
1
+ /**
2
+ * AnthropicMessagesAdapter — governed Anthropic Messages binding.
3
+ *
4
+ * The concrete provider binding for {@link ../lib/model-gateway!GovernedModelGateway}.
5
+ * It maps the Anthropic Messages API (refusals, `output_config.effort`,
6
+ * fallback-credit redemption) to the gateway's normalized shapes, then exposes
7
+ * one governed `executeAgent` that absorbs the refusal → fallback → billing
8
+ * chain behind the standard adapter interface.
9
+ *
10
+ * Dependency-free (BYOC): you inject an `AnthropicMessagesClient`; the adapter
11
+ * never imports the Anthropic SDK. Build and test it against Claude Opus 4.8,
12
+ * which is also Claude Fable 5's fallback target.
13
+ *
14
+ * @module AnthropicMessagesAdapter
15
+ * @version 1.0.0
16
+ */
17
+ import type { AgentPayload, AgentContext, AgentResult, AdapterCapabilities } from '../types/agent-adapter';
18
+ import { BaseAdapter } from './base-adapter';
19
+ import { type ModelCaller, type ModelResponse, type EffortLevel, type BudgetSink, type AuditSink, type RefusalTelemetrySink, type ThinkingSink, type EffortSink } from '../lib/model-gateway';
20
+ /** Raw Anthropic Messages response (the subset this adapter reads). */
21
+ export interface AnthropicRawResponse {
22
+ id?: string;
23
+ model: string;
24
+ content: Array<{
25
+ type: string;
26
+ text?: string;
27
+ thinking?: string;
28
+ signature?: string;
29
+ [k: string]: unknown;
30
+ }>;
31
+ stop_reason: string | null;
32
+ stop_details?: {
33
+ type?: string;
34
+ category?: string | null;
35
+ explanation?: string;
36
+ fallback_credit_token?: string | null;
37
+ fallback_has_prefill_claim?: boolean | null;
38
+ recommended_model?: string | null;
39
+ } | null;
40
+ usage?: {
41
+ input_tokens?: number;
42
+ output_tokens?: number;
43
+ cache_read_input_tokens?: number;
44
+ cache_creation_input_tokens?: number;
45
+ };
46
+ }
47
+ /** Bring-your-own Anthropic Messages client (e.g. `client.beta.messages`). */
48
+ export interface AnthropicMessagesApiClient {
49
+ create(params: {
50
+ model: string;
51
+ max_tokens: number;
52
+ system?: string;
53
+ messages: Array<{
54
+ role: string;
55
+ content: unknown;
56
+ }>;
57
+ tools?: Array<Record<string, unknown>>;
58
+ output_config?: {
59
+ effort?: string;
60
+ };
61
+ fallback_credit_token?: string;
62
+ betas?: string[];
63
+ }): Promise<AnthropicRawResponse>;
64
+ }
65
+ /** Per-agent configuration for {@link AnthropicMessagesAdapter.registerModelAgent}. */
66
+ export interface AnthropicMessagesAgentConfig {
67
+ /** The injected Anthropic Messages client. */
68
+ client: AnthropicMessagesApiClient;
69
+ /** Primary model (default: `claude-fable-5`). */
70
+ model?: string;
71
+ /** Ordered fallback models (default: `['claude-opus-4-8']`). */
72
+ fallbackModels?: string[];
73
+ /** System prompt. */
74
+ systemPrompt?: string;
75
+ /** Max tokens per call (default: 1024). */
76
+ maxTokens?: number;
77
+ /** Default effort level. */
78
+ effort?: EffortLevel;
79
+ /** Cross-model budget. */
80
+ budget?: BudgetSink;
81
+ /** Audit destination. */
82
+ audit?: AuditSink;
83
+ /** Refusal/fallback telemetry. */
84
+ telemetry?: RefusalTelemetrySink;
85
+ /** Thinking-block lifecycle manager. */
86
+ thinking?: ThinkingSink;
87
+ /** Effort governance policy. */
88
+ effortPolicy?: EffortSink;
89
+ }
90
+ /**
91
+ * Map a raw Anthropic response to the gateway's normalized {@link ModelResponse}.
92
+ *
93
+ * @param raw The native response.
94
+ * @param requestedModel The model that was requested (fallback when `raw.model` is absent).
95
+ */
96
+ export declare function normalizeAnthropicResponse(raw: AnthropicRawResponse, requestedModel: string): ModelResponse;
97
+ /**
98
+ * Build a normalized {@link ModelCaller} from an Anthropic Messages client.
99
+ *
100
+ * Uses **client-side** fallback (the gateway drives the chain), so it never
101
+ * sets the server-side `fallbacks` parameter. When a fallback-credit token is
102
+ * present it is forwarded with the `fallback-credit-2026-06-01` beta header so
103
+ * the retry is repriced as a cache read.
104
+ *
105
+ * @param client The injected Anthropic Messages client.
106
+ * @returns A `ModelCaller` the gateway can drive.
107
+ */
108
+ export declare function createAnthropicCaller(client: AnthropicMessagesApiClient): ModelCaller;
109
+ /**
110
+ * Governed Anthropic Messages adapter.
111
+ *
112
+ * Each registered agent runs through its own {@link GovernedModelGateway}, so a
113
+ * single `executeAgent` call transparently handles refusals, cross-model
114
+ * fallback, fallback-credit billing, and thinking-block handoff.
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * const adapter = new AnthropicMessagesAdapter();
119
+ * await adapter.initialize({});
120
+ * adapter.registerModelAgent('analyst', {
121
+ * client, // your Anthropic client
122
+ * model: 'claude-fable-5',
123
+ * fallbackModels: ['claude-opus-4-8'],
124
+ * budget, audit, telemetry,
125
+ * });
126
+ * const result = await adapter.executeAgent('analyst', { action: 'Summarize…', params: {} }, ctx);
127
+ * ```
128
+ */
129
+ export declare class AnthropicMessagesAdapter extends BaseAdapter {
130
+ readonly name = "anthropic-messages";
131
+ readonly version = "1.0.0";
132
+ private agents;
133
+ get capabilities(): AdapterCapabilities;
134
+ /**
135
+ * Register a model-backed agent. Builds a {@link GovernedModelGateway} wired
136
+ * with the supplied budget/audit/telemetry/thinking/effort collaborators.
137
+ */
138
+ registerModelAgent(agentId: string, config: AnthropicMessagesAgentConfig): void;
139
+ executeAgent(agentId: string, payload: AgentPayload, _context: AgentContext): Promise<AgentResult>;
140
+ }
141
+ //# sourceMappingURL=anthropic-messages-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-messages-adapter.d.ts","sourceRoot":"","sources":["../../adapters/anthropic-messages-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ /**
3
+ * AnthropicMessagesAdapter — governed Anthropic Messages binding.
4
+ *
5
+ * The concrete provider binding for {@link ../lib/model-gateway!GovernedModelGateway}.
6
+ * It maps the Anthropic Messages API (refusals, `output_config.effort`,
7
+ * fallback-credit redemption) to the gateway's normalized shapes, then exposes
8
+ * one governed `executeAgent` that absorbs the refusal → fallback → billing
9
+ * chain behind the standard adapter interface.
10
+ *
11
+ * Dependency-free (BYOC): you inject an `AnthropicMessagesClient`; the adapter
12
+ * never imports the Anthropic SDK. Build and test it against Claude Opus 4.8,
13
+ * which is also Claude Fable 5's fallback target.
14
+ *
15
+ * @module AnthropicMessagesAdapter
16
+ * @version 1.0.0
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.AnthropicMessagesAdapter = void 0;
20
+ exports.normalizeAnthropicResponse = normalizeAnthropicResponse;
21
+ exports.createAnthropicCaller = createAnthropicCaller;
22
+ const base_adapter_1 = require("./base-adapter");
23
+ const thinking_blocks_1 = require("../lib/thinking-blocks");
24
+ const model_gateway_1 = require("../lib/model-gateway");
25
+ // ---------------------------------------------------------------------------
26
+ // Beta header for fallback-credit redemption
27
+ // ---------------------------------------------------------------------------
28
+ const FALLBACK_CREDIT_BETA = 'fallback-credit-2026-06-01';
29
+ /**
30
+ * Map a raw Anthropic response to the gateway's normalized {@link ModelResponse}.
31
+ *
32
+ * @param raw The native response.
33
+ * @param requestedModel The model that was requested (fallback when `raw.model` is absent).
34
+ */
35
+ function normalizeAnthropicResponse(raw, requestedModel) {
36
+ const content = (raw.content ?? []).map((b) => ({ ...b }));
37
+ const isRefusal = raw.stop_reason === 'refusal';
38
+ const usage = raw.usage ?? {};
39
+ const response = {
40
+ id: raw.id,
41
+ model: raw.model || requestedModel,
42
+ content,
43
+ stopReason: raw.stop_reason,
44
+ usage: {
45
+ inputTokens: usage.input_tokens ?? 0,
46
+ outputTokens: usage.output_tokens ?? 0,
47
+ cacheReadInputTokens: usage.cache_read_input_tokens ?? 0,
48
+ cacheCreationInputTokens: usage.cache_creation_input_tokens ?? 0,
49
+ },
50
+ };
51
+ if (isRefusal) {
52
+ const d = raw.stop_details ?? {};
53
+ response.refusal = {
54
+ category: (d.category ?? null),
55
+ explanation: d.explanation,
56
+ fallbackCreditToken: d.fallback_credit_token ?? null,
57
+ fallbackHasPrefillClaim: d.fallback_has_prefill_claim ?? null,
58
+ recommendedModel: d.recommended_model ?? null,
59
+ };
60
+ }
61
+ else {
62
+ response.refusal = null;
63
+ }
64
+ return response;
65
+ }
66
+ /**
67
+ * Build a normalized {@link ModelCaller} from an Anthropic Messages client.
68
+ *
69
+ * Uses **client-side** fallback (the gateway drives the chain), so it never
70
+ * sets the server-side `fallbacks` parameter. When a fallback-credit token is
71
+ * present it is forwarded with the `fallback-credit-2026-06-01` beta header so
72
+ * the retry is repriced as a cache read.
73
+ *
74
+ * @param client The injected Anthropic Messages client.
75
+ * @returns A `ModelCaller` the gateway can drive.
76
+ */
77
+ function createAnthropicCaller(client) {
78
+ return async (req) => {
79
+ const params = {
80
+ model: req.model,
81
+ max_tokens: req.maxTokens ?? 1024,
82
+ messages: req.messages.map((m) => ({ role: m.role, content: m.content })),
83
+ };
84
+ if (req.system)
85
+ params.system = req.system;
86
+ if (req.tools)
87
+ params.tools = req.tools;
88
+ if (req.effort)
89
+ params.output_config = { effort: req.effort };
90
+ if (req.fallbackCreditToken) {
91
+ params.fallback_credit_token = req.fallbackCreditToken;
92
+ params.betas = [FALLBACK_CREDIT_BETA];
93
+ }
94
+ const raw = await client.create(params);
95
+ return normalizeAnthropicResponse(raw, req.model);
96
+ };
97
+ }
98
+ // ---------------------------------------------------------------------------
99
+ // Adapter
100
+ // ---------------------------------------------------------------------------
101
+ /**
102
+ * Governed Anthropic Messages adapter.
103
+ *
104
+ * Each registered agent runs through its own {@link GovernedModelGateway}, so a
105
+ * single `executeAgent` call transparently handles refusals, cross-model
106
+ * fallback, fallback-credit billing, and thinking-block handoff.
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * const adapter = new AnthropicMessagesAdapter();
111
+ * await adapter.initialize({});
112
+ * adapter.registerModelAgent('analyst', {
113
+ * client, // your Anthropic client
114
+ * model: 'claude-fable-5',
115
+ * fallbackModels: ['claude-opus-4-8'],
116
+ * budget, audit, telemetry,
117
+ * });
118
+ * const result = await adapter.executeAgent('analyst', { action: 'Summarize…', params: {} }, ctx);
119
+ * ```
120
+ */
121
+ class AnthropicMessagesAdapter extends base_adapter_1.BaseAdapter {
122
+ name = 'anthropic-messages';
123
+ version = '1.0.0';
124
+ agents = new Map();
125
+ get capabilities() {
126
+ return {
127
+ streaming: false,
128
+ parallel: true,
129
+ bidirectional: false,
130
+ discovery: true,
131
+ authentication: false,
132
+ statefulSessions: false,
133
+ };
134
+ }
135
+ /**
136
+ * Register a model-backed agent. Builds a {@link GovernedModelGateway} wired
137
+ * with the supplied budget/audit/telemetry/thinking/effort collaborators.
138
+ */
139
+ registerModelAgent(agentId, config) {
140
+ if (!agentId || typeof agentId !== 'string') {
141
+ throw new TypeError('AnthropicMessagesAdapter.registerModelAgent: agentId must be a non-empty string');
142
+ }
143
+ if (!config || typeof config.client?.create !== 'function') {
144
+ throw new TypeError('AnthropicMessagesAdapter.registerModelAgent: config.client.create must be a function');
145
+ }
146
+ const primaryModel = config.model ?? 'claude-fable-5';
147
+ const gateway = new model_gateway_1.GovernedModelGateway({
148
+ caller: createAnthropicCaller(config.client),
149
+ primaryModel,
150
+ fallbackModels: config.fallbackModels ?? ['claude-opus-4-8'],
151
+ defaultEffort: config.effort,
152
+ budget: config.budget,
153
+ audit: config.audit,
154
+ telemetry: config.telemetry,
155
+ thinking: config.thinking ?? new thinking_blocks_1.ThinkingBlockManager(),
156
+ effort: config.effortPolicy,
157
+ });
158
+ this.agents.set(agentId, { gateway, config });
159
+ this.registerLocalAgent({
160
+ id: agentId,
161
+ name: agentId,
162
+ status: 'available',
163
+ capabilities: ['text', 'governed-fallback'],
164
+ metadata: { adapter: this.name, model: primaryModel },
165
+ });
166
+ }
167
+ async executeAgent(agentId, payload, _context) {
168
+ this.ensureReady();
169
+ const entry = this.agents.get(agentId);
170
+ if (!entry) {
171
+ return this.errorResult('MODEL_AGENT_NOT_FOUND', `No agent registered as '${agentId}'`, false);
172
+ }
173
+ const instruction = payload.handoff?.instruction ?? payload.params?.['instruction'] ?? payload.action;
174
+ const start = Date.now();
175
+ try {
176
+ const result = await entry.gateway.send({
177
+ messages: [{ role: 'user', content: instruction }],
178
+ system: entry.config.systemPrompt,
179
+ maxTokens: entry.config.maxTokens,
180
+ effort: entry.config.effort,
181
+ agentId,
182
+ });
183
+ const durationMs = Date.now() - start;
184
+ const text = result.response.content
185
+ .filter((b) => b.type === 'text')
186
+ .map((b) => b.text ?? '')
187
+ .join('\n');
188
+ const data = {
189
+ response: text,
190
+ servedModel: result.servedModel,
191
+ servedByFallback: result.servedByFallback,
192
+ refused: result.refused,
193
+ refusalCategories: result.refusalCategories,
194
+ attempts: result.attempts,
195
+ totalCostUsd: result.totalCostUsd,
196
+ };
197
+ if (result.refused) {
198
+ const category = result.refusalCategories[result.refusalCategories.length - 1] ?? null;
199
+ return {
200
+ success: false,
201
+ data,
202
+ error: {
203
+ code: 'MODEL_REFUSED',
204
+ message: `All models declined the request${category ? ` (category: ${category})` : ''}`,
205
+ recoverable: false,
206
+ },
207
+ metadata: { adapter: this.name, executionTimeMs: durationMs },
208
+ };
209
+ }
210
+ return this.successResult(data, durationMs);
211
+ }
212
+ catch (error) {
213
+ return this.errorResult('MODEL_EXECUTION_ERROR', error instanceof Error ? error.message : String(error), true, error);
214
+ }
215
+ }
216
+ }
217
+ exports.AnthropicMessagesAdapter = AnthropicMessagesAdapter;
218
+ //# sourceMappingURL=anthropic-messages-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-messages-adapter.js","sourceRoot":"","sources":["../../adapters/anthropic-messages-adapter.ts"],"names":[],"mappings":"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"}
@@ -66,6 +66,8 @@ export { LangGraphAdapter } from './langgraph-adapter';
66
66
  export type { LangGraphRunnable, LangGraphStreamable, LangGraphAgentConfig } from './langgraph-adapter';
67
67
  export { AnthropicComputerUseAdapter } from './anthropic-computer-use-adapter';
68
68
  export type { ComputerAction, ComputerToolCall, ComputerToolResult, ComputerActionHandler, AnthropicMessagesClient, ComputerUseAgentConfig, } from './anthropic-computer-use-adapter';
69
+ export { AnthropicMessagesAdapter, createAnthropicCaller, normalizeAnthropicResponse } from './anthropic-messages-adapter';
70
+ export type { AnthropicMessagesApiClient, AnthropicRawResponse, AnthropicMessagesAgentConfig } from './anthropic-messages-adapter';
69
71
  export { OpenAIAgentsAdapter } from './openai-agents-adapter';
70
72
  export type { OAIAgentTool, OAIAgentRunResult, OAIAgentRunner, OAIAgentsConfig, } from './openai-agents-adapter';
71
73
  export { VertexAIAdapter } from './vertex-ai-adapter';