@ziggs-ai/agent-sdk 0.16.1 → 0.18.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.
Files changed (113) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +110 -88
  3. package/dist/{AgentHost.d.ts → Agent.d.ts} +50 -27
  4. package/dist/{AgentHost.js → Agent.js} +135 -129
  5. package/dist/adapters/AnthropicAdapter.d.ts +1 -1
  6. package/dist/adapters/AnthropicAdapter.js +1 -1
  7. package/dist/{agent/ClaudeSdkAgent.d.ts → brain/ClaudeBrain.d.ts} +23 -11
  8. package/dist/{agent/ClaudeSdkAgent.js → brain/ClaudeBrain.js} +99 -99
  9. package/dist/{agent/Agent.d.ts → brain/ZiggsBrain.d.ts} +23 -20
  10. package/dist/{agent/Agent.js → brain/ZiggsBrain.js} +12 -11
  11. package/dist/{agent → brain}/claudeCognition.d.ts +1 -1
  12. package/dist/{agent → brain}/claudeCognition.js +1 -1
  13. package/dist/{agent → brain}/claudeSdkProtocol.d.ts +1 -1
  14. package/dist/{agent → brain}/claudeSdkProtocol.js +1 -1
  15. package/dist/{agent → brain}/claudeSdkTools.d.ts +1 -1
  16. package/dist/{agent → brain}/claudeSdkTools.js +5 -14
  17. package/dist/{agent → brain}/hostedAgentConnection.d.ts +1 -1
  18. package/dist/{agent → brain}/hostedAgentConnection.js +3 -3
  19. package/dist/brain/index.d.ts +6 -6
  20. package/dist/brain/index.js +2 -2
  21. package/dist/brain/onBehalfAgreement.d.ts +51 -0
  22. package/dist/brain/onBehalfAgreement.js +99 -0
  23. package/dist/{agent → brain}/toolManagerToSdkMcp.js +10 -1
  24. package/dist/defineAgent.js +4 -4
  25. package/dist/formatters/HistoryFormatter.js +2 -1
  26. package/dist/index.d.ts +30 -31
  27. package/dist/index.js +24 -25
  28. package/dist/{adapters/McpAdapter.d.ts → mcp/createMcpAgent.d.ts} +16 -15
  29. package/dist/{adapters/McpAdapter.js → mcp/createMcpAgent.js} +82 -46
  30. package/dist/memory/MemoryStore.d.ts +18 -1
  31. package/dist/memory/MemoryStore.js +43 -0
  32. package/dist/{server → platform}/ConnectionPool.d.ts +9 -3
  33. package/dist/{server → platform}/ConnectionPool.js +16 -4
  34. package/dist/{server → platform}/EventQueue.d.ts +1 -1
  35. package/dist/{server → platform}/StateTimers.d.ts +1 -1
  36. package/dist/{server → platform}/StateTimers.js +1 -1
  37. package/dist/{server → platform}/ZiggsEffectHandler.d.ts +4 -4
  38. package/dist/{server → platform}/ZiggsEffectHandler.js +2 -2
  39. package/dist/{server → platform}/inboxLoop.d.ts +34 -1
  40. package/dist/{server → platform}/inboxLoop.js +122 -14
  41. package/dist/{server → platform}/polls/PollKind.d.ts +4 -7
  42. package/dist/{server → platform}/polls/PollKind.js +3 -6
  43. package/dist/{server → platform}/polls/PollRunner.d.ts +5 -6
  44. package/dist/{server → platform}/polls/PollRunner.js +24 -12
  45. package/dist/platform/polls/declaredPollRunner.d.ts +4 -0
  46. package/dist/platform/polls/declaredPollRunner.js +29 -0
  47. package/dist/{server → platform}/tools/tier2/mcpConnectionTools.js +32 -18
  48. package/dist/runtime/bootstrapCtx.d.ts +1 -1
  49. package/dist/runtime/bootstrapCtx.js +1 -1
  50. package/dist/runtime/buildOutcome.js +1 -1
  51. package/dist/runtime/runTurn.d.ts +1 -1
  52. package/dist/runtime/runTurn.js +18 -18
  53. package/dist/runtime/validateWorkflow.js +1 -1
  54. package/dist/skills/parseSkill.d.ts +7 -2
  55. package/dist/skills/parseSkill.js +22 -5
  56. package/dist/skills/skillReadReference.d.ts +6 -0
  57. package/dist/skills/skillReadReference.js +27 -0
  58. package/dist/tools/needs.js +2 -2
  59. package/dist/tools/toolCreds.d.ts +1 -1
  60. package/dist/tools/toolCreds.js +1 -1
  61. package/dist/types.d.ts +3 -3
  62. package/package.json +2 -2
  63. package/dist/server/createHealthServer.d.ts +0 -7
  64. package/dist/server/createHealthServer.js +0 -75
  65. package/dist/server/runLauncher.d.ts +0 -22
  66. package/dist/server/runLauncher.js +0 -160
  67. /package/dist/{agent → brain}/toolManagerToSdkMcp.d.ts +0 -0
  68. /package/dist/{server → platform}/EventQueue.js +0 -0
  69. /package/dist/{server → platform}/OutboxBuffer.d.ts +0 -0
  70. /package/dist/{server → platform}/OutboxBuffer.js +0 -0
  71. /package/dist/{server → platform}/SeenMessages.d.ts +0 -0
  72. /package/dist/{server → platform}/SeenMessages.js +0 -0
  73. /package/dist/{server → platform}/agreements/AgreementService.d.ts +0 -0
  74. /package/dist/{server → platform}/agreements/AgreementService.js +0 -0
  75. /package/dist/{server → platform}/proactive/ProactiveTrigger.d.ts +0 -0
  76. /package/dist/{server → platform}/proactive/ProactiveTrigger.js +0 -0
  77. /package/dist/{server → platform}/requestMatch.d.ts +0 -0
  78. /package/dist/{server → platform}/requestMatch.js +0 -0
  79. /package/dist/{server → platform}/tasks/TaskService.d.ts +0 -0
  80. /package/dist/{server → platform}/tasks/TaskService.js +0 -0
  81. /package/dist/{server → platform}/tasks/index.d.ts +0 -0
  82. /package/dist/{server → platform}/tasks/index.js +0 -0
  83. /package/dist/{server → platform}/telemetryIngest.d.ts +0 -0
  84. /package/dist/{server → platform}/telemetryIngest.js +0 -0
  85. /package/dist/{server → platform}/tools/index.d.ts +0 -0
  86. /package/dist/{server → platform}/tools/index.js +0 -0
  87. /package/dist/{server → platform}/tools/tier1/protocolRunner.d.ts +0 -0
  88. /package/dist/{server → platform}/tools/tier1/protocolRunner.js +0 -0
  89. /package/dist/{server → platform}/tools/tier1/protocolTools.d.ts +0 -0
  90. /package/dist/{server → platform}/tools/tier1/protocolTools.js +0 -0
  91. /package/dist/{server → platform}/tools/tier2/artifactTools.d.ts +0 -0
  92. /package/dist/{server → platform}/tools/tier2/artifactTools.js +0 -0
  93. /package/dist/{server → platform}/tools/tier2/chatTools.d.ts +0 -0
  94. /package/dist/{server → platform}/tools/tier2/chatTools.js +0 -0
  95. /package/dist/{server → platform}/tools/tier2/connectionTools.d.ts +0 -0
  96. /package/dist/{server → platform}/tools/tier2/connectionTools.js +0 -0
  97. /package/dist/{server → platform}/tools/tier2/contextTools.d.ts +0 -0
  98. /package/dist/{server → platform}/tools/tier2/contextTools.js +0 -0
  99. /package/dist/{server → platform}/tools/tier2/discoveryTools.d.ts +0 -0
  100. /package/dist/{server → platform}/tools/tier2/discoveryTools.js +0 -0
  101. /package/dist/{server → platform}/tools/tier2/grantsTools.d.ts +0 -0
  102. /package/dist/{server → platform}/tools/tier2/grantsTools.js +0 -0
  103. /package/dist/{server → platform}/tools/tier2/introductionTools.d.ts +0 -0
  104. /package/dist/{server → platform}/tools/tier2/introductionTools.js +0 -0
  105. /package/dist/{server → platform}/tools/tier2/linkTools.d.ts +0 -0
  106. /package/dist/{server → platform}/tools/tier2/linkTools.js +0 -0
  107. /package/dist/{server → platform}/tools/tier2/marketplaceTools.d.ts +0 -0
  108. /package/dist/{server → platform}/tools/tier2/marketplaceTools.js +0 -0
  109. /package/dist/{server → platform}/tools/tier2/mcpConnectionTools.d.ts +0 -0
  110. /package/dist/{server → platform}/tools/tier2/paymentTools.d.ts +0 -0
  111. /package/dist/{server → platform}/tools/tier2/paymentTools.js +0 -0
  112. /package/dist/{server → platform}/tools/tier2/taskTools.d.ts +0 -0
  113. /package/dist/{server → platform}/tools/tier2/taskTools.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased — agent vocabulary and lifecycle (breaking)
4
+
5
+ - `Agent` names the body returned by `createAgent`; decision engines are `ZiggsBrain` and `ClaudeBrain`. See the README migration table.
6
+ - Platform integration moves to `src/platform`, brains to `src/brain`, and external MCP tool composition to `src/mcp`.
7
+ - Process startup and health serving move to the private operator package.
8
+ - Every Agent validates, starts and stops its declared polls, including direct, MCP, lab and evaluation construction.
9
+ - `createMcpAgent` returns `agent`; the selected decision engine is `agent.brain`.
10
+ - Selecting `claudeBrain()` uses the five-minute Claude wake timeout.
11
+
12
+
3
13
  ## Unreleased
4
14
 
5
15
  ### Breaking
package/README.md CHANGED
@@ -1,131 +1,153 @@
1
1
  # @ziggs-ai/agent-sdk
2
2
 
3
- **What it is:** A small JavaScript framework for building **autonomous agents** that run on the **Ziggs** platform. You describe behavior as a **workflow** (states, prompts, actions, transitions), wire **tools**, and the SDK handles **LLM calls**, **context**, **tasks**, and **delivery** from Ziggs (HTTP inbox long-poll).
3
+ An agent has a **brain** that decides and a **body** with an identity, inbox,
4
+ wallet, memory and contracts. The SDK runs that body in your process.
4
5
 
5
- It is **not** a generic chat wrapper: the core idea is a **lightweight state machine** (`AgentMachine`) that walks your definition, runs **`runTurn`** for "thinking" steps (prompt + structured actions), and updates **context** from events and `transitions` so routing stays explicit and predictable.
6
+ `Agent` is one identity on Ziggs. It reads its inbox outbound over HTTP, routes
7
+ wakes into a brain and performs the brain’s effects through platform services.
8
+ It opens no listening socket. The brain is available as `agent.brain`.
6
9
 
7
- ---
10
+ ## Two ways to run an agent
8
11
 
9
- ## Mental model
12
+ | Rail | Where the body runs | Who supplies the brain and wake |
13
+ | --- | --- | --- |
14
+ | **Ziggs SDK** | In your process, through `@ziggs-ai/agent-sdk` | Your code picks a brain; the Agent runs inbox delivery and declared polls. |
15
+ | **Ziggs MCP** | On the Ziggs platform, exposed through MCP | Your existing MCP application supplies the brain and schedules inbox checks. |
10
16
 
11
- | Piece | Role |
12
- |--------|------|
13
- | **`defineAgent` / workflow** | Declarative agent: `initial`, `states`, optional `id`, `description`, `specialization`, merged `tools` / `services`. |
14
- | **`AgentMachine`** | Interprets the workflow: parked states wait for events; thinking states run `runTurn`; `transitions` picks the next state from context. |
15
- | **`runTurn`** | Builds prompts, calls the LLM (with tools), parses the model output, and returns effects for the machine. |
16
- | **`AgentHost`** | Batteries-included process: OpenAI adapter, tool manager, task service, context clients, **inbox long-poll** to Ziggs, and an **`Agent`** that dispatches incoming messages into the machine. |
17
- | **`Agent`** | Orchestrates message handling, machine lifecycle, and integration with platform APIs (without the host's delivery loop if you construct it yourself). |
17
+ [Ziggs MCP](../ziggs-mcp/README.md) has its own package and remote endpoint.
18
+ A brain running in an existing application does not need to embed this SDK.
19
+ Connecting MCP tools does not itself schedule an autonomous wake: the application
20
+ must arrange an inbox check, such as a scheduled task, and process and acknowledge
21
+ what it reads.
18
22
 
19
- There is **no** separate compile step: the workflow object is used **directly** by the runtime.
23
+ `createMcpAgent` serves a different purpose: it builds an SDK Agent with tools
24
+ from an external MCP server. That agent still runs here, with either built-in
25
+ brain. It returns `{ agent, closeMcp, toolNames }`.
20
26
 
21
- ---
22
-
23
- ## Workflow DSL (states)
24
-
25
- States are plain objects on `workflow.states`. Every state uses one unified concept:
26
-
27
- - **`transitions`** — an array of `{ to, when }` rules evaluated in order. The first rule whose `when(ctx)` returns true (or has no `when`) determines the next state. Supports a plain string shorthand: `'stateName'` is equivalent to `{ to: 'stateName' }`.
28
-
29
- Two kinds of state:
30
-
31
- - **Parked / waiting:** Has only `transitions`. The machine stops here and waits for the next event. When an event arrives it is classified into context flags (`approval`, `rejection`, `subtaskResult`, etc.) and `transitions` is evaluated to route forward.
27
+ ## Pick a brain
32
28
 
33
- - **Thinking:** Has `prompt`, `actions`, and `transitions`. The machine runs an LLM turn via `runTurn`, applies the result into context flags (`messageSent`, `toolResults`, `taskCompleted`, etc.), then evaluates `transitions` to route forward.
29
+ | Implementation | Selection | Decision loop |
30
+ | --- | --- | --- |
31
+ | `ZiggsBrain` | `ziggsBrain({ model?, openaiKey?, anthropicKey? })` | Your workflow controls states, actions and transitions. |
32
+ | `ClaudeBrain` | `claudeBrain({ anthropicKey?, model?, maxTurns?, specialization? })` | The Claude Agent SDK drives the tool loop. |
34
33
 
35
- Both kinds use the same `transitions` array and the same context shape — the only difference is what filled the context before evaluation.
34
+ Both implement `Brain`: a `kind` and `tick(TickInput): Promise<TickOutput>`.
35
+ Both use the same agent identity, platform tools, memory and contracts.
36
36
 
37
- Context flags available in transitions:
37
+ ```ts
38
+ import { createAgent, claudeBrain } from '@ziggs-ai/agent-sdk';
38
39
 
39
- | Set by incoming events (parked states) | Set by LLM turn results (thinking states) |
40
- |---------------------------------------|------------------------------------------|
41
- | `approval`, `rejection` | `messageSent`, `activeWait` |
42
- | `taskAssignment`, `subtaskResult` | `proposal`, `delegatedTask` |
43
- | `subtaskFailed`, `incomingMessage` | `taskCompleted`, `taskFailed` |
44
- | | `toolResults`, `lastError`, `respondedProposal` |
40
+ const agent = createAgent({
41
+ agentId: 'my-agent',
42
+ description: 'Drafts project briefs',
43
+ operatorKey: process.env.ZIGGS_OPERATOR_KEY,
44
+ brain: claudeBrain({ anthropicKey: process.env.ANTHROPIC_API_KEY }),
45
+ });
45
46
 
46
- The `wait` action is built-in: `defineAgent` automatically injects it into every thinking state that doesn't define one, and appends a `{ to: initial, when: ctx => ctx.activeWait }` transition if none exists.
47
+ await agent.connectAsync();
47
48
 
48
- ---
49
+ // When your process shuts down:
50
+ // agent.disconnect();
51
+ // await agent.drain();
52
+ ```
49
53
 
50
- ## Pick a brain
54
+ The identity must already exist on Ziggs and the operator key must authorize it.
55
+ `connectAsync()` starts outbound delivery; network failures retry inside the
56
+ inbox loop. It is safe to call again while connected. `disconnect()` stops new
57
+ polling and clears state timers; `drain()` waits for queued and active wakes.
51
58
 
52
- The **host** (`AgentHost` / `createAgent`) is the product — identity, delivery, tasks, agreements, tools. The **brain** is only *how the agent decides* on each wake.
59
+ The Claude brain’s default wake timeout is five minutes; the Ziggs brain’s is
60
+ two minutes. `tickTimeoutMs` overrides either. Legacy `cognition: 'fsm' |
61
+ 'claude-sdk'` remains supported; prefer `brain` for new code.
53
62
 
54
- | Brain | Factory | When to use |
55
- |--------|---------|-------------|
56
- | **Ziggs** (workflow / FSM) | `ziggsBrain({ model?, openaiKey?, anthropicKey? })` | Author a workflow; deterministic, controllable routing via `runTurn`. |
57
- | **Claude** (Agent SDK) | `claudeBrain({ anthropicKey, model?, maxTurns?, specialization? })` | Hand the loop to Claude `query()`; fewer knobs, more autonomy. |
63
+ ## Workflows
58
64
 
59
- Both brains share the same host, tools, and Ziggs protocol. Pick control vs autonomy.
65
+ `defineAgent` validates a workflow and supplies agreement kickoff defaults.
66
+ The resulting definition passes directly to `createAgent`; there is no compile
67
+ step. States explicitly declare `kind: 'parked'`, `'thinking'` or `'mechanical'`.
68
+ Transitions run in order, taking the first matching `when(ctx)` rule.
60
69
 
61
70
  ```ts
62
- import { createAgent, defineAgent, ziggsBrain, claudeBrain } from '@ziggs-ai/agent-sdk';
63
-
64
- // Ziggs brain — workflow required (states + initial or explicit workflow)
65
- const ziggsHost = createAgent({
66
- ...defineAgent({ agentId: 'my-agent', description: '…', initial: 'idle', states: { … } }),
71
+ import { createAgent, defineAgent, ziggsBrain } from '@ziggs-ai/agent-sdk';
72
+
73
+ const agent = createAgent({
74
+ ...defineAgent({
75
+ agentId: 'workflow-agent',
76
+ description: 'Waits for workflow events',
77
+ initial: 'idle',
78
+ states: { idle: { kind: 'parked', transitions: [] } },
79
+ }),
67
80
  operatorKey: process.env.ZIGGS_OPERATOR_KEY,
68
- brain: ziggsBrain({ openaiKey: process.env.OPENAI_API_KEY }),
81
+ brain: ziggsBrain({ anthropicKey: process.env.ANTHROPIC_API_KEY }),
69
82
  });
83
+ ```
70
84
 
71
- // Claude brain — no workflow needed (host synthesizes a parked state)
72
- const claudeHost = createAgent({
73
- agentId: 'claude-agent',
74
- description: 'A hired Claude specialist',
75
- operatorKey: process.env.ZIGGS_OPERATOR_KEY,
76
- brain: claudeBrain({ anthropicKey: process.env.ANTHROPIC_API_KEY }),
77
- });
85
+ `AgentMachine` interprets workflows; `runTurn` executes thinking states.
86
+ `thinkingDefaults({ initial })` provides explicit waiting defaults for authors
87
+ who want them.
78
88
 
79
- await claudeHost.connectAsync();
80
- ```
89
+ ## External wake sources
81
90
 
82
- Legacy `cognition: 'fsm' | 'claude-sdk'` still works but is deprecated — prefer `brain`.
91
+ Declare `polls: [{ kind, chatId, ...sourceOptions }]` and their implementations in
92
+ `pollKinds`. Each implementation supplies an `id`, optional `intervalMs` and
93
+ `poll(binding, { agentId, operatorKey })`, returning `{ actionable, hint? }`.
83
94
 
84
- The public **`Brain`** interface is `tick(TickInput): Promise<TickOutput>`. Built-in implementations: `Agent` (Ziggs) and `ClaudeSdkAgent` (Claude).
95
+ The Agent validates these declarations at construction, starts them on
96
+ `connectAsync()` and stops them on `disconnect()`. This applies to direct
97
+ construction, `createAgent`, `createAgentPool`, MCP tool agents, labs and evals.
98
+ Unknown kinds and missing chat IDs throw before startup. Pool startup rejects
99
+ if any registered agent fails to start. A source read completing
100
+ after disconnect cannot wake the agent. Each binding waits for its wake to finish
101
+ before polling again, with backoff and a wake budget.
85
102
 
86
- ---
103
+ Poll coordination is local to a process. Starting the same identity in two
104
+ processes also starts its external sources twice; inbox leases do not coordinate
105
+ those source reads.
87
106
 
88
- ## How you usually run an agent
107
+ ## Platform services and tools
89
108
 
90
- 1. **`defineAgent({ ... })`** → options object including `workflow`.
91
- 2. Pass **`openaiKey`**, **`operatorKey`** (Ziggs operator token), **`agentId`**, etc., and **`createAgent(config)`** (returns an **`AgentHost`**).
92
- 3. **`connect()`** to go live; the SDK long-polls the HTTP inbox and routes deliveries into **`handleMessage`**.
109
+ `src/brain/` contains decision engines; `src/platform/` contains outbound Ziggs
110
+ integration, inbox delivery, polls and effect handlers. `src/mcp/` composes
111
+ external MCP tools into SDK agents.
93
112
 
94
- Worked examples and the full build path: https://ziggsai.com/docs
113
+ Protocol tools are managed through `taskTools` (default `'all'`). Optional
114
+ capability bundles include `DISCOVERY_TOOLS`, `CONTEXT_TOOLS`, `CONNECTION_TOOLS`,
115
+ `MCP_CONNECTION_TOOLS`, `PAYMENT_TOOLS` and `ARTIFACT_TOOLS`.
116
+ Use `defineTool` for your own tools. Declared `needs` provide their access tools
117
+ and enforce missing grants at task start.
95
118
 
96
- Point the shared HTTP client at a non-default backend (self-hosted / local) before constructing hosts — no direct `@ziggs-ai/api-client` dependency needed:
119
+ Configure an alternate backend before constructing an agent:
97
120
 
98
121
  ```ts
99
- import { configureApiClient, createAgent } from '@ziggs-ai/agent-sdk';
100
-
122
+ import { configureApiClient } from '@ziggs-ai/agent-sdk';
101
123
  configureApiClient({ httpUrl: 'https://api.example.com' });
102
124
  ```
103
125
 
104
- ---
105
-
106
- ## Main exports (entry: `src/index.js`)
126
+ ## Process operations
107
127
 
108
- - **`AgentHost`**, **`createAgent`**, **`createAgentPool`**, **`defineAgent`**
109
- - **Brains:** `ziggsBrain`, `claudeBrain`, type `Brain`
110
- - **`Agent`**, **`AgentMachine`**, **`runTurn`**
111
- - **Prompt / tools:** `PromptBuilder`, `ToolManager`, `defineTool`
112
- - **Tools come in two tiers — single home: `server/tools/`:**
113
- - **Tier 1 — protocol grammar (`server/tools/tier1/`, `PROTOCOL_TOOLS`).** The verbs every agent speaks to participate in the agreement/task system: `agreementProposeTool`, `agreementSubcontractTool`, `agreementRespondTool`, `agreementCounterProposalTool`, `taskSpawnTool`, `taskUpdateTool`, `taskUpdatePlanStepTool`. **Framework-managed**: attached via the `taskTools` config (default `'all'`), dispatched to in-process services — *not* passed in the user `tools:` array. Publishing open work is part of this grammar: `agreement_propose({ proposedTo: "everyone" })` (there is no separate publish tool).
114
- - **Tier 2 — capability bundles (`server/tools/tier2/`, opt-in, HTTP-backed).** Discrete capability domains an agent chooses to have. **Off by default**; an agent gains a capability by spreading the bundle into its `tools:` array. Each tool reads `operatorKey`/`agentId` from tool context and wraps a backend HTTP client. Bundles: `DISCOVERY_TOOLS` (`agentSearchTool`, `agentGetTool`), `MARKETPLACE_TOOLS` (`marketplaceViewTool` — read-only), `PAYMENT_TOOLS` (`paymentBalanceTool`, `paymentTransferTool`, …).
115
- - **Adapters / utils:** `OpenAIAdapter`, JSON helpers, formatters
116
- - **Re-exported** from `@ziggs-ai/api-client`: `configureApiClient`, type `ApiClientConfig`, `ContextReadClient`, `ContextDiscoveryClient`, `ContextGrantsClient`, `ArtifactsClient`, `MessagesClient`, `ScopeClient`, `AgentSearchClient`, `getBackendUrl`, etc. (There is no `ContextReader` / `ContextWriter` — use the clients above from `@ziggs-ai/api-client` directly. Delivery is HTTP inbox long-poll; read/ack via `InboxClient` from `@ziggs-ai/api-client`.)
128
+ A **runner** is the operator’s process. It starts agents, serves health and
129
+ coordinates shutdown. It is not another part of the customer’s agent model.
130
+ The repository’s private `@ziggs-ai/agent-runner` workspace owns `runAgents` and
131
+ `createHealthServer`; these are not SDK exports. An operator deploys the runner
132
+ and supplies a supervisor such as ECS to restart the process when it exits.
117
133
 
118
- Package export: `"."` → `dist/index.js` (see `package.json`; `npm run build` before publish or monorepo tests).
134
+ ## Migration
119
135
 
120
- ---
136
+ This is a breaking pre-beta rename; update imports before publishing this release.
121
137
 
122
- ## Requirements
138
+ | Previous API | Current API |
139
+ | --- | --- |
140
+ | `AgentHost`, `AgentHostOptions` | `Agent`, `AgentOptions` |
141
+ | Workflow `Agent`, `AgentOptions` | `ZiggsBrain`, `ZiggsBrainOptions` |
142
+ | `ClaudeSdkAgent`, `ClaudeSdkAgentOptions` | `ClaudeBrain`, `ClaudeBrainOptions` |
143
+ | `host.agent` | `agent.brain` |
144
+ | `createMcpAgent(...).host` | `createMcpAgent(...).agent` |
145
+ | SDK `runLauncher`, `createHealthServer` | Operator package `runAgents`, `createHealthServer` |
123
146
 
124
- - **Node** ≥ 18
125
- - Env: **`OPENAI_API_KEY`** for the Ziggs brain; **`ANTHROPIC_API_KEY`** for the Claude brain; Ziggs **`ZIGGS_OPERATOR_KEY`** (operator token, scope `agents:impersonate`) for platform features.
147
+ `createAgent`, `ziggsBrain`, `claudeBrain` and agent IDs on the wire retain their
148
+ names. No backend identity or stored data migration is required.
126
149
 
127
- ---
128
-
129
- ## License
150
+ ## Requirements
130
151
 
131
- MIT (see package metadata).
152
+ Node.js 18 or later, an authorized Ziggs operator key and the provider key for
153
+ your selected brain/model. MIT license; see package metadata.
@@ -1,15 +1,16 @@
1
+ import type { PollBinding, PollKind } from './platform/polls/PollKind.js';
1
2
  import type { AgentConfig, Ctx, Workflow } from './types.js';
2
- import { Agent, type TickOutput } from './agent/Agent.js';
3
- import { ClaudeSdkAgent, type CognitionKind } from './agent/ClaudeSdkAgent.js';
3
+ import { ZiggsBrain, type TickOutput } from './brain/ZiggsBrain.js';
4
+ import { ClaudeBrain, type CognitionKind } from './brain/ClaudeBrain.js';
4
5
  import { type BrainSelection } from './brain/index.js';
5
6
  export type { CognitionKind };
6
- import { type WaitForIdleResult } from './server/EventQueue.js';
7
+ import { type WaitForIdleResult } from './platform/EventQueue.js';
7
8
  import { type NormalizedEvent } from './ingress/normalizeIncoming.js';
8
9
  import { type MemoryStore } from './memory/MemoryStore.js';
9
10
  /**
10
11
  * Operator-provided FSM session persistence.
11
12
  *
12
- * AgentHost calls load() before each tick when a lane has no in-memory state
13
+ * Agent calls load() before each tick when a lane has no in-memory state
13
14
  * (e.g. after a container restart) and save() after every successful tick.
14
15
  * A null return from load() means "no prior state — start fresh."
15
16
  */
@@ -70,7 +71,11 @@ interface AgentServices {
70
71
  } | LlmAdapter;
71
72
  [key: string]: unknown;
72
73
  }
73
- export interface AgentHostOptions {
74
+ export interface AgentOptions {
75
+ /** External wake sources, started by connectAsync and stopped by disconnect. */
76
+ polls?: PollBinding[];
77
+ /** Implementations for this agent’s declared poll kinds. */
78
+ pollKinds?: PollKind[];
74
79
  openaiKey?: string;
75
80
  anthropicKey?: string;
76
81
  model?: string;
@@ -128,10 +133,12 @@ export interface AgentHostOptions {
128
133
  * Agent-private long-term memory. Operator-provided. Default: a fresh
129
134
  * `InMemoryStore` (non-durable; lost on process restart). For durability,
130
135
  * pass `new FileMemoryStore(path)` or your own implementation.
136
+ * Each wake is given a hire-scoped view of this store; agent key shapes
137
+ * do not change.
131
138
  */
132
139
  memory?: MemoryStore;
133
140
  /**
134
- * FSM session persistence. Operator-provided. When set, AgentHost loads
141
+ * FSM session persistence. Operator-provided. When set, Agent loads
135
142
  * prior state before each tick (cold-start recovery) and saves after every
136
143
  * successful tick. Omit to keep state in-process only (default behaviour).
137
144
  */
@@ -153,14 +160,14 @@ export interface AgentHostOptions {
153
160
  sessionId: string;
154
161
  model: string;
155
162
  cognition: string;
156
- metrics: import('./agent/Agent.js').TickOutput['metrics'];
163
+ metrics: import('./brain/ZiggsBrain.js').TickOutput['metrics'];
157
164
  /** Present when the wake carried an agreement/task. */
158
165
  agreementId?: string;
159
166
  taskId?: string;
160
167
  }) => void;
161
168
  /**
162
169
  * Called with everything a wake consists of, immediately before the brain
163
- * runs. Pair it with {@link AgentHost.replayWake} to re-run that exact wake
170
+ * runs. Pair it with {@link Agent.replayWake} to re-run that exact wake
164
171
  * later against edited agent source — the difference between iterating on a
165
172
  * prompt in seconds and standing a whole world back up to see one turn.
166
173
  *
@@ -172,8 +179,8 @@ export interface AgentHostOptions {
172
179
  /** Production monitoring ingest. Default on; set false to disable. */
173
180
  telemetryIngest?: boolean;
174
181
  /**
175
- * Pull inbox on every WS connect/reconnect. Default true.
176
- * Recovers messages lost when backend in-memory pending queues are dropped.
182
+ * Run the outbound inbox loop on connectAsync. Default true.
183
+ * Disable for offline tests or callers that deliver wakes themselves.
177
184
  */
178
185
  inboxCatchUp?: boolean;
179
186
  }
@@ -212,17 +219,16 @@ export interface WakeRecord {
212
219
  */
213
220
  export declare function warnOnShadowedPlatformTools(platformTools: ToolDefinition[], ownTools: ToolDefinition[], agentId: string | undefined): void;
214
221
  /**
215
- * AgentHost — the Server. Owns a pure {@link Agent}, an {@link EffectHandler},
216
- * a transport (Ziggs WebSocket), and the lane router (per-session FIFO queue
217
- * + in-memory session state).
218
- *
219
- * transport (WS) → handleMessage → agent.tick(.. , eff) → ..
222
+ * One agent identity and its body: inbox, tools, contracts, memory and lanes.
223
+ * The brain decides on each wake; platform services perform its effects.
224
+ * connectAsync starts outbound inbox reads and declared external polls.
225
+ * An Agent never opens a listening socket.
220
226
  */
221
- export declare class AgentHost {
222
- options: Required<Pick<AgentHostOptions, 'agentId' | 'operatorKey' | 'openaiKey'>> & AgentHostOptions;
227
+ export declare class Agent {
228
+ options: Required<Pick<AgentOptions, 'agentId' | 'operatorKey' | 'openaiKey'>> & AgentOptions;
223
229
  toolManager: ToolManager;
224
230
  llm?: OpenAIAdapter | LlmAdapter;
225
- agent: Agent | ClaudeSdkAgent;
231
+ brain: ZiggsBrain | ClaudeBrain;
226
232
  private eff;
227
233
  private eventQueue;
228
234
  private sessions;
@@ -239,6 +245,8 @@ export declare class AgentHost {
239
245
  /** The per-agent inbox long-poll loop — this agent's sole wake source. */
240
246
  private inboxLoop;
241
247
  private inboxLoopEnabled;
248
+ private started;
249
+ private pollRunner;
242
250
  /** Short-lived grant-provider cache for the declared-needs gate. */
243
251
  /**
244
252
  * Lanes where an unmet-need refusal has already been allowed its one turn to
@@ -249,7 +257,7 @@ export declare class AgentHost {
249
257
  /** Tasks left active by the asking turn, failed right after it (per lane). */
250
258
  private unmetTasksPendingAsk;
251
259
  private grantProviderCache;
252
- constructor(options?: AgentHostOptions);
260
+ constructor(options?: AgentOptions);
253
261
  private _validate;
254
262
  private _setup;
255
263
  /**
@@ -285,6 +293,7 @@ export declare class AgentHost {
285
293
  * suppression costs tokens, while a wrongly suppressed turn drops work.
286
294
  */
287
295
  private recordWakeOutcome;
296
+ private memoryForWake;
288
297
  /**
289
298
  * A chat-lane session that still carries a cancelled hire from a previous
290
299
  * engagement will agreement_get that dead row and stop. Drop it so this
@@ -351,12 +360,12 @@ export declare class AgentHost {
351
360
  private canAskForAccess;
352
361
  private _processEvent;
353
362
  /**
354
- * Re-run one recorded wake against THIS host's agent, and nothing else.
363
+ * Re-run one recorded wake against THIS agent, and nothing else.
355
364
  *
356
365
  * The dev loop for a prompt: record a wake off a live run, edit the agent, and
357
366
  * see what it does differently in seconds instead of standing a world back up
358
367
  * for one turn. The brain, tools and effect handler are the real ones, so the
359
- * turn is real — its tool calls hit the backend this host is pointed at, which
368
+ * turn is real — its tool calls hit the backend this agent is pointed at, which
360
369
  * is why it belongs against a disposable world and not a shared one.
361
370
  *
362
371
  * Deliberately NOT routed through `_processEvent`: everything that method does
@@ -370,11 +379,10 @@ export declare class AgentHost {
370
379
  private _resolveOwnAgentId;
371
380
  connectAsync(_timeout?: number): Promise<this>;
372
381
  /**
373
- * plain string compare against {@link AgentHostOptions.requestMatchTags}
382
+ * plain string compare against {@link AgentOptions.requestMatchTags}
374
383
  * and `specialization`. No match → return (caller acks). Match → normal wake.
375
384
  */
376
385
  private triageRequestDelivery;
377
- private _bootstrapAssignedActiveTasks;
378
386
  /** replay task-assigned for an existing active task (demo recovery). */
379
387
  wakeTaskAssignment(taskId: string): Promise<void>;
380
388
  disconnect(): void;
@@ -386,11 +394,26 @@ export declare class AgentHost {
386
394
  drain(timeoutMs?: number): Promise<WaitForIdleResult>;
387
395
  registerTool(tool: ToolDefinition): string;
388
396
  isConnected(): boolean;
397
+ /**
398
+ * Whether this agent is still reading its inbox, and when it last did. One
399
+ * signal, three readers: the store's online badge, an operator's health
400
+ * check, and monitoring. `lastPassAt` is the read itself; `lastAttemptAt`
401
+ * says the loop still turns when the server is the thing that is down.
402
+ * A `pollingInbox: false` agent (inboxCatchUp disabled, lab and eval paths)
403
+ * has nothing to be stale about and reports no timestamps.
404
+ */
405
+ inboxLiveness(): {
406
+ agentId: string;
407
+ connected: boolean;
408
+ pollingInbox: boolean;
409
+ lastPassAt: number | null;
410
+ lastAttemptAt: number | null;
411
+ };
389
412
  }
390
413
  /**
391
- * createAgent(config) → AgentHost
414
+ * createAgent(config) → Agent
392
415
  * createAgentPool([cfg, ...]) → ConnectionPool (lazy fleet, async-loaded)
393
416
  */
394
- export declare function createAgent(options?: AgentHostOptions | AgentConfig): AgentHost;
395
- export declare function createAgentPool(configs: AgentHostOptions[] | AgentConfig[]): Promise<unknown>;
396
- export default AgentHost;
417
+ export declare function createAgent(options?: AgentOptions | AgentConfig): Agent;
418
+ export declare function createAgentPool(configs: AgentOptions[] | AgentConfig[]): Promise<unknown>;
419
+ export default Agent;