@ziggs-ai/agent-sdk 0.15.0 → 0.17.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 (119) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +110 -88
  3. package/dist/{AgentHost.d.ts → Agent.d.ts} +66 -27
  4. package/dist/{AgentHost.js → Agent.js} +221 -119
  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} +145 -95
  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 +2 -2
  14. package/dist/{agent → brain}/claudeSdkProtocol.js +2 -2
  15. package/dist/{agent → brain}/claudeSdkTools.d.ts +2 -1
  16. package/dist/{agent → brain}/claudeSdkTools.js +9 -65
  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} +54 -40
  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}/agreements/AgreementService.d.ts +10 -1
  40. package/dist/{server → platform}/agreements/AgreementService.js +9 -1
  41. package/dist/{server → platform}/inboxLoop.d.ts +34 -1
  42. package/dist/{server → platform}/inboxLoop.js +122 -14
  43. package/dist/{server → platform}/polls/PollKind.d.ts +4 -7
  44. package/dist/{server → platform}/polls/PollKind.js +3 -6
  45. package/dist/{server → platform}/polls/PollRunner.d.ts +5 -6
  46. package/dist/{server → platform}/polls/PollRunner.js +24 -12
  47. package/dist/platform/polls/declaredPollRunner.d.ts +4 -0
  48. package/dist/platform/polls/declaredPollRunner.js +29 -0
  49. package/dist/{server → platform}/tools/index.d.ts +1 -0
  50. package/dist/{server → platform}/tools/index.js +1 -0
  51. package/dist/{server → platform}/tools/tier1/protocolRunner.js +33 -27
  52. package/dist/{server → platform}/tools/tier1/protocolTools.js +2 -7
  53. package/dist/{server → platform}/tools/tier2/mcpConnectionTools.js +6 -3
  54. package/dist/platform/tools/tier2/taskTools.d.ts +3 -0
  55. package/dist/platform/tools/tier2/taskTools.js +6 -0
  56. package/dist/runtime/bootstrapCtx.d.ts +1 -1
  57. package/dist/runtime/bootstrapCtx.js +1 -1
  58. package/dist/runtime/buildOutcome.d.ts +0 -8
  59. package/dist/runtime/buildOutcome.js +20 -6
  60. package/dist/runtime/kickoff.js +1 -1
  61. package/dist/runtime/runTurn.d.ts +1 -1
  62. package/dist/runtime/runTurn.js +18 -18
  63. package/dist/runtime/validateWorkflow.js +1 -1
  64. package/dist/runtime/wakeOutcome.d.ts +27 -0
  65. package/dist/runtime/wakeOutcome.js +43 -0
  66. package/dist/skills/parseSkill.d.ts +7 -2
  67. package/dist/skills/parseSkill.js +22 -5
  68. package/dist/skills/skillReadReference.d.ts +6 -0
  69. package/dist/skills/skillReadReference.js +27 -0
  70. package/dist/tools/needs.js +2 -2
  71. package/dist/tools/recordReport.d.ts +5 -0
  72. package/dist/tools/recordReport.js +5 -0
  73. package/dist/tools/toolCreds.d.ts +1 -1
  74. package/dist/tools/toolCreds.js +1 -1
  75. package/dist/types.d.ts +3 -3
  76. package/package.json +2 -2
  77. package/dist/server/createHealthServer.d.ts +0 -7
  78. package/dist/server/createHealthServer.js +0 -75
  79. package/dist/server/runLauncher.d.ts +0 -22
  80. package/dist/server/runLauncher.js +0 -160
  81. /package/dist/{agent → brain}/toolManagerToSdkMcp.d.ts +0 -0
  82. /package/dist/{server → platform}/EventQueue.js +0 -0
  83. /package/dist/{server → platform}/OutboxBuffer.d.ts +0 -0
  84. /package/dist/{server → platform}/OutboxBuffer.js +0 -0
  85. /package/dist/{server → platform}/SeenMessages.d.ts +0 -0
  86. /package/dist/{server → platform}/SeenMessages.js +0 -0
  87. /package/dist/{server → platform}/proactive/ProactiveTrigger.d.ts +0 -0
  88. /package/dist/{server → platform}/proactive/ProactiveTrigger.js +0 -0
  89. /package/dist/{server → platform}/requestMatch.d.ts +0 -0
  90. /package/dist/{server → platform}/requestMatch.js +0 -0
  91. /package/dist/{server → platform}/tasks/TaskService.d.ts +0 -0
  92. /package/dist/{server → platform}/tasks/TaskService.js +0 -0
  93. /package/dist/{server → platform}/tasks/index.d.ts +0 -0
  94. /package/dist/{server → platform}/tasks/index.js +0 -0
  95. /package/dist/{server → platform}/telemetryIngest.d.ts +0 -0
  96. /package/dist/{server → platform}/telemetryIngest.js +0 -0
  97. /package/dist/{server → platform}/tools/tier1/protocolRunner.d.ts +0 -0
  98. /package/dist/{server → platform}/tools/tier1/protocolTools.d.ts +0 -0
  99. /package/dist/{server → platform}/tools/tier2/artifactTools.d.ts +0 -0
  100. /package/dist/{server → platform}/tools/tier2/artifactTools.js +0 -0
  101. /package/dist/{server → platform}/tools/tier2/chatTools.d.ts +0 -0
  102. /package/dist/{server → platform}/tools/tier2/chatTools.js +0 -0
  103. /package/dist/{server → platform}/tools/tier2/connectionTools.d.ts +0 -0
  104. /package/dist/{server → platform}/tools/tier2/connectionTools.js +0 -0
  105. /package/dist/{server → platform}/tools/tier2/contextTools.d.ts +0 -0
  106. /package/dist/{server → platform}/tools/tier2/contextTools.js +0 -0
  107. /package/dist/{server → platform}/tools/tier2/discoveryTools.d.ts +0 -0
  108. /package/dist/{server → platform}/tools/tier2/discoveryTools.js +0 -0
  109. /package/dist/{server → platform}/tools/tier2/grantsTools.d.ts +0 -0
  110. /package/dist/{server → platform}/tools/tier2/grantsTools.js +0 -0
  111. /package/dist/{server → platform}/tools/tier2/introductionTools.d.ts +0 -0
  112. /package/dist/{server → platform}/tools/tier2/introductionTools.js +0 -0
  113. /package/dist/{server → platform}/tools/tier2/linkTools.d.ts +0 -0
  114. /package/dist/{server → platform}/tools/tier2/linkTools.js +0 -0
  115. /package/dist/{server → platform}/tools/tier2/marketplaceTools.d.ts +0 -0
  116. /package/dist/{server → platform}/tools/tier2/marketplaceTools.js +0 -0
  117. /package/dist/{server → platform}/tools/tier2/mcpConnectionTools.d.ts +0 -0
  118. /package/dist/{server → platform}/tools/tier2/paymentTools.d.ts +0 -0
  119. /package/dist/{server → platform}/tools/tier2/paymentTools.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
  */
@@ -55,6 +56,11 @@ export declare function laneSessionIdForTask(task: {
55
56
  originChatId?: string | null;
56
57
  agreementId?: string | null;
57
58
  }): string;
59
+ /** Pull the cost-record keys off a wake event or session id. */
60
+ export declare function workScopeFromWake(event: unknown, sessionId?: string): {
61
+ agreementId?: string;
62
+ taskId?: string;
63
+ };
58
64
  interface LlmAdapter {
59
65
  chatMessages(messages: unknown[], tools?: unknown[], options?: Record<string, unknown>): Promise<unknown>;
60
66
  }
@@ -65,7 +71,11 @@ interface AgentServices {
65
71
  } | LlmAdapter;
66
72
  [key: string]: unknown;
67
73
  }
68
- 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[];
69
79
  openaiKey?: string;
70
80
  anthropicKey?: string;
71
81
  model?: string;
@@ -123,10 +133,12 @@ export interface AgentHostOptions {
123
133
  * Agent-private long-term memory. Operator-provided. Default: a fresh
124
134
  * `InMemoryStore` (non-durable; lost on process restart). For durability,
125
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.
126
138
  */
127
139
  memory?: MemoryStore;
128
140
  /**
129
- * FSM session persistence. Operator-provided. When set, AgentHost loads
141
+ * FSM session persistence. Operator-provided. When set, Agent loads
130
142
  * prior state before each tick (cold-start recovery) and saves after every
131
143
  * successful tick. Omit to keep state in-process only (default behaviour).
132
144
  */
@@ -148,11 +160,14 @@ export interface AgentHostOptions {
148
160
  sessionId: string;
149
161
  model: string;
150
162
  cognition: string;
151
- metrics: import('./agent/Agent.js').TickOutput['metrics'];
163
+ metrics: import('./brain/ZiggsBrain.js').TickOutput['metrics'];
164
+ /** Present when the wake carried an agreement/task. */
165
+ agreementId?: string;
166
+ taskId?: string;
152
167
  }) => void;
153
168
  /**
154
169
  * Called with everything a wake consists of, immediately before the brain
155
- * 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
156
171
  * later against edited agent source — the difference between iterating on a
157
172
  * prompt in seconds and standing a whole world back up to see one turn.
158
173
  *
@@ -164,8 +179,8 @@ export interface AgentHostOptions {
164
179
  /** Production monitoring ingest. Default on; set false to disable. */
165
180
  telemetryIngest?: boolean;
166
181
  /**
167
- * Pull inbox on every WS connect/reconnect. Default true.
168
- * 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.
169
184
  */
170
185
  inboxCatchUp?: boolean;
171
186
  }
@@ -204,17 +219,16 @@ export interface WakeRecord {
204
219
  */
205
220
  export declare function warnOnShadowedPlatformTools(platformTools: ToolDefinition[], ownTools: ToolDefinition[], agentId: string | undefined): void;
206
221
  /**
207
- * AgentHost — the Server. Owns a pure {@link Agent}, an {@link EffectHandler},
208
- * a transport (Ziggs WebSocket), and the lane router (per-session FIFO queue
209
- * + in-memory session state).
210
- *
211
- * 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.
212
226
  */
213
- export declare class AgentHost {
214
- options: Required<Pick<AgentHostOptions, 'agentId' | 'operatorKey' | 'openaiKey'>> & AgentHostOptions;
227
+ export declare class Agent {
228
+ options: Required<Pick<AgentOptions, 'agentId' | 'operatorKey' | 'openaiKey'>> & AgentOptions;
215
229
  toolManager: ToolManager;
216
230
  llm?: OpenAIAdapter | LlmAdapter;
217
- agent: Agent | ClaudeSdkAgent;
231
+ brain: ZiggsBrain | ClaudeBrain;
218
232
  private eff;
219
233
  private eventQueue;
220
234
  private sessions;
@@ -224,12 +238,15 @@ export declare class AgentHost {
224
238
  private sessionStore;
225
239
  private taskService;
226
240
  private agreementService;
241
+ private telemetryClient?;
227
242
  private messageSender;
228
243
  private seenMessages;
229
244
  private stateTimers;
230
245
  /** The per-agent inbox long-poll loop — this agent's sole wake source. */
231
246
  private inboxLoop;
232
247
  private inboxLoopEnabled;
248
+ private started;
249
+ private pollRunner;
233
250
  /** Short-lived grant-provider cache for the declared-needs gate. */
234
251
  /**
235
252
  * Lanes where an unmet-need refusal has already been allowed its one turn to
@@ -240,7 +257,7 @@ export declare class AgentHost {
240
257
  /** Tasks left active by the asking turn, failed right after it (per lane). */
241
258
  private unmetTasksPendingAsk;
242
259
  private grantProviderCache;
243
- constructor(options?: AgentHostOptions);
260
+ constructor(options?: AgentOptions);
244
261
  private _validate;
245
262
  private _setup;
246
263
  /**
@@ -275,6 +292,14 @@ export declare class AgentHost {
275
292
  * Failing open is deliberate. If the lookup errors we run the turn — a missed
276
293
  * suppression costs tokens, while a wrongly suppressed turn drops work.
277
294
  */
295
+ private recordWakeOutcome;
296
+ private memoryForWake;
297
+ /**
298
+ * A chat-lane session that still carries a cancelled hire from a previous
299
+ * engagement will agreement_get that dead row and stop. Drop it so this
300
+ * wake keys on the live room / hire.
301
+ */
302
+ private dropStaleCancelledAgreementSession;
278
303
  private laneAgreementIsTerminal;
279
304
  /**
280
305
  * the trailing turn on work that is already reported.
@@ -335,12 +360,12 @@ export declare class AgentHost {
335
360
  private canAskForAccess;
336
361
  private _processEvent;
337
362
  /**
338
- * 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.
339
364
  *
340
365
  * The dev loop for a prompt: record a wake off a live run, edit the agent, and
341
366
  * see what it does differently in seconds instead of standing a world back up
342
367
  * for one turn. The brain, tools and effect handler are the real ones, so the
343
- * 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
344
369
  * is why it belongs against a disposable world and not a shared one.
345
370
  *
346
371
  * Deliberately NOT routed through `_processEvent`: everything that method does
@@ -354,11 +379,10 @@ export declare class AgentHost {
354
379
  private _resolveOwnAgentId;
355
380
  connectAsync(_timeout?: number): Promise<this>;
356
381
  /**
357
- * plain string compare against {@link AgentHostOptions.requestMatchTags}
382
+ * plain string compare against {@link AgentOptions.requestMatchTags}
358
383
  * and `specialization`. No match → return (caller acks). Match → normal wake.
359
384
  */
360
385
  private triageRequestDelivery;
361
- private _bootstrapAssignedActiveTasks;
362
386
  /** replay task-assigned for an existing active task (demo recovery). */
363
387
  wakeTaskAssignment(taskId: string): Promise<void>;
364
388
  disconnect(): void;
@@ -370,11 +394,26 @@ export declare class AgentHost {
370
394
  drain(timeoutMs?: number): Promise<WaitForIdleResult>;
371
395
  registerTool(tool: ToolDefinition): string;
372
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
+ };
373
412
  }
374
413
  /**
375
- * createAgent(config) → AgentHost
414
+ * createAgent(config) → Agent
376
415
  * createAgentPool([cfg, ...]) → ConnectionPool (lazy fleet, async-loaded)
377
416
  */
378
- export declare function createAgent(options?: AgentHostOptions | AgentConfig): AgentHost;
379
- export declare function createAgentPool(configs: AgentHostOptions[] | AgentConfig[]): Promise<unknown>;
380
- 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;