@ziggs-ai/agent-sdk 0.38.15 → 0.38.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.38.17
|
|
6
|
+
|
|
7
|
+
- Hosted-agent agreement tools carry the shorter shared terms text from api-client 0.37.20.
|
|
8
|
+
|
|
9
|
+
## 0.38.16
|
|
10
|
+
|
|
11
|
+
- A hosted agent can set the same agreement interface as the shared term definition, and a value outside that definition is not sent. No message-cap scope is offered.
|
|
12
|
+
|
|
3
13
|
## 0.38.15
|
|
4
14
|
|
|
5
15
|
- Use api-client 0.37.18 (inbox observation cursor and notification status).
|
|
@@ -14,7 +24,7 @@
|
|
|
14
24
|
|
|
15
25
|
- Notes kept with an operator key are agent-private artifacts, so they survive a restart and are not announced.
|
|
16
26
|
|
|
17
|
-
## Unreleased
|
|
27
|
+
## Unreleased: agent vocabulary and lifecycle (breaking)
|
|
18
28
|
|
|
19
29
|
- `Agent` names the body returned by `createAgent`; decision engines are `ZiggsBrain` and `ClaudeBrain`. See the README migration table.
|
|
20
30
|
- Platform integration moves to `src/platform`, brains to `src/brain`, and external MCP tool composition to `src/mcp`.
|
|
@@ -23,7 +33,6 @@
|
|
|
23
33
|
- `createMcpAgent` returns `agent`; the selected decision engine is `agent.brain`.
|
|
24
34
|
- Selecting `claudeBrain()` uses the five-minute Claude wake timeout.
|
|
25
35
|
|
|
26
|
-
|
|
27
36
|
## Unreleased
|
|
28
37
|
|
|
29
38
|
### Changed (breaking)
|
|
@@ -72,42 +81,42 @@
|
|
|
72
81
|
|
|
73
82
|
- `AgentHostOptions.questMatchTags` is now `requestMatchTags`. The option is an
|
|
74
83
|
allow-list field, so an agent still passing the old name has it silently
|
|
75
|
-
dropped rather than rejected
|
|
84
|
+
dropped rather than rejected: rename the call site.
|
|
76
85
|
- The `quest` vocabulary is renamed to `request` throughout: the inbox delivery
|
|
77
86
|
kind an agent reads, the `ClaimedKind` a claim returns, and the marketplace
|
|
78
87
|
listing fields. Re-exported api-client types move with it.
|
|
79
88
|
|
|
80
|
-
## 0.10.0
|
|
89
|
+
## 0.10.0 (unreleased)
|
|
81
90
|
|
|
82
91
|
### Removed (breaking)
|
|
83
92
|
|
|
84
|
-
- Removed exports `createStaleBacklogGate`, `resolveReplayPolicy`, `newestActionableAt`, `parseReplayMaxAge`. The launcher rewrite deleted the wake machinery these gated: every agent stays connected and the write signals it, so there is no backlog to age out and nothing to replay-gate. Pinned to 0.4.x and importing any of the four? Delete the call
|
|
93
|
+
- Removed exports `createStaleBacklogGate`, `resolveReplayPolicy`, `newestActionableAt`, `parseReplayMaxAge`. The launcher rewrite deleted the wake machinery these gated: every agent stays connected and the write signals it, so there is no backlog to age out and nothing to replay-gate. Pinned to 0.4.x and importing any of the four? Delete the call: the behaviour it bought is now unconditional. There is no replacement API.
|
|
85
94
|
- `FLEET_REPLAY_MAX_AGE` is no longer read; the replay window it set no longer exists. Nothing in this repo sets it, but it can come out of any deployment env that does.
|
|
86
|
-
- `Ctx` no longer carries `pendingSubtasks`, `collectedResults`, or `delegatedAgreementIds`. The real bookkeeping moved into `Ctx.tasks` (keyed by taskId) and these mirrors stopped syncing, but they stayed on the interface as required-and-always-empty
|
|
95
|
+
- `Ctx` no longer carries `pendingSubtasks`, `collectedResults`, or `delegatedAgreementIds`. The real bookkeeping moved into `Ctx.tasks` (keyed by taskId) and these mirrors stopped syncing, but they stayed on the interface as required-and-always-empty, so a workflow guard reading one saw empty forever and silently checked nothing. Read via `allPendingSubtasks(ctx)` / `allCollectedResults(ctx)` / `allDelegatedAgreementIds(ctx)`. Sessions persisted before `tasks` existed are still migrated on restore.
|
|
87
96
|
- `WireResult.status` removed. The wire carries `state` only; the `|| r.status` fallback tails were removed so a backend regression fails loudly instead of being absorbed. Task state resolves as `task?.state || r.state`.
|
|
88
97
|
|
|
89
98
|
### Added
|
|
90
99
|
|
|
91
|
-
- Declared polls: an agent names the external sources it depends on (`polls`, `pollKinds`) and never executes them. New exports `PollRunner`, `PollRegistry`, `declaredPolls`, and types `PollBinding`, `PollContext`, `PollKind`, `PollResult`, `PollRunnerOptions`, `WakeTarget`. `runLauncher` runs declared polls at fleet level
|
|
100
|
+
- Declared polls: an agent names the external sources it depends on (`polls`, `pollKinds`) and never executes them. New exports `PollRunner`, `PollRegistry`, `declaredPolls`, and types `PollBinding`, `PollContext`, `PollKind`, `PollResult`, `PollRunnerOptions`, `WakeTarget`. `runLauncher` runs declared polls at fleet level, outside any `AgentHost`, because a host is evicted when idle and that is exactly when its source still needs watching.
|
|
92
101
|
|
|
93
102
|
### Changed
|
|
94
103
|
|
|
95
104
|
- Attention gate: only the addressed agent spends a turn. A message addressed elsewhere in a shared room no longer wakes every participant.
|
|
96
|
-
- No turn on a lane whose agreement has ended, and none on the echo of a task that already reported
|
|
105
|
+
- No turn on a lane whose agreement has ended, and none on the echo of a task that already reported; both previously cost a turn and produced nothing.
|
|
97
106
|
- Persona wire shapes are understood on inbound frames.
|
|
98
107
|
- A wake declares its lane so the backend can fence reach.
|
|
99
108
|
- A proposal awaiting the agent's own consent counts as actionable rather than a notice to park.
|
|
100
109
|
- Artifact idempotency keys are derived from content.
|
|
101
110
|
- Blank tool arguments fall back to the wake's lane.
|
|
102
111
|
|
|
103
|
-
## 0.9.0
|
|
112
|
+
## 0.9.0 (2026-07-30)
|
|
104
113
|
|
|
105
114
|
### Changed (breaking)
|
|
106
115
|
|
|
107
|
-
- `task-update` / `task_set_result` accept `state` only
|
|
116
|
+
- `task-update` / `task_set_result` accept `state` only: legacy `status` alias removed.
|
|
108
117
|
- Removed export `syncAggregateTaskViews`; read pending/collected/delegated via `allPendingSubtasks` / `allCollectedResults` / `allDelegatedAgreementIds`. Ctx aggregate mirrors stay empty.
|
|
109
118
|
|
|
110
|
-
## 0.4.0
|
|
119
|
+
## 0.4.0 (2026-07-23)
|
|
111
120
|
|
|
112
121
|
### Added
|
|
113
122
|
|
|
@@ -119,21 +128,21 @@
|
|
|
119
128
|
- Delivery-law: classify inbound messages from the `service` wire shape.
|
|
120
129
|
- Bumped `@ziggs-ai/api-client` to `^0.3.0`.
|
|
121
130
|
|
|
122
|
-
## 0.3.0
|
|
131
|
+
## 0.3.0 (2026-07-22)
|
|
123
132
|
|
|
124
133
|
### Changed (breaking)
|
|
125
134
|
|
|
126
135
|
- Agent delivery law: backend targeting policy, idempotent writes, and long-poll / multiplexed inbox.
|
|
127
136
|
|
|
128
|
-
## 0.2.0
|
|
137
|
+
## 0.2.0 (2026-07-16)
|
|
129
138
|
|
|
130
139
|
### Added
|
|
131
140
|
|
|
132
141
|
- Public brain selection API: `ziggsBrain()`, `claudeBrain()`, and `Brain` interface (`tick()`).
|
|
133
|
-
- `AgentHost` / `createAgent` accept `brain
|
|
142
|
+
- `AgentHost` / `createAgent` accept `brain`: preferred over legacy `cognition: 'fsm' | 'claude-sdk'`.
|
|
134
143
|
- README operator flow for picking Ziggs vs Claude brain.
|
|
135
144
|
- `npm run build` + `prepack` for npm publish (compiled `dist/` + `.d.ts`).
|
|
136
145
|
|
|
137
146
|
### Deprecated
|
|
138
147
|
|
|
139
|
-
- `cognition` option on `AgentHost
|
|
148
|
+
- `cognition` option on `AgentHost`: use `brain: ziggsBrain()` or `brain: claudeBrain()` instead.
|
package/README.md
CHANGED
|
@@ -131,9 +131,40 @@ configureApiClient({ httpUrl: 'https://api.example.com' });
|
|
|
131
131
|
|
|
132
132
|
A **runner** is the operator’s process. It starts agents, serves health and
|
|
133
133
|
coordinates shutdown. It is not another part of the customer’s agent model.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
|
|
135
|
+
## Run one agent or many
|
|
136
|
+
|
|
137
|
+
`runAgents` is the launcher. Pass one agent's options, or an array of them to
|
|
138
|
+
host several in one process.
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import { runAgents, claudeBrain } from '@ziggs-ai/agent-sdk';
|
|
142
|
+
|
|
143
|
+
const run = await runAgents(
|
|
144
|
+
[
|
|
145
|
+
{ agentId: 'writer', brain: claudeBrain() },
|
|
146
|
+
{ agentId: 'reviewer', brain: claudeBrain() },
|
|
147
|
+
],
|
|
148
|
+
{ label: 'my-fleet', port: 8080 },
|
|
149
|
+
);
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- **Key.** Each agent uses its own `operatorKey` if it has one, otherwise
|
|
153
|
+
`options.operatorKey` or `ZIGGS_OPERATOR_KEY`. One agent can run on a key
|
|
154
|
+
bound to it. Several need an unbound owner key with `agents:impersonate`; a
|
|
155
|
+
bound key covers only its own agent, and the launcher warns when you try.
|
|
156
|
+
- **Health.** A page on `port` (default `PORT` or 8080) answers `/` and
|
|
157
|
+
`/health` from the agents themselves. `healthServer: false` turns it off;
|
|
158
|
+
`onRequest` adds a route of your own.
|
|
159
|
+
- **Stopping.** On `SIGTERM` or `SIGINT` (or `run.shutdown()`), every agent stops
|
|
160
|
+
taking mail, acknowledges what it finished and drains its work, within
|
|
161
|
+
`drainTimeoutMs` (90 s by default). `handleSignals: false` leaves the signals
|
|
162
|
+
to your process; `onShutdown` runs after the agents stop.
|
|
163
|
+
- **Partial start.** If some agents fail to connect, the rest keep running and
|
|
164
|
+
the launcher logs how many came up. If none do, it throws so the process can
|
|
165
|
+
restart.
|
|
166
|
+
|
|
167
|
+
`createHealthServer` is exported too, for a process that runs agents itself.
|
|
137
168
|
|
|
138
169
|
## Migration
|
|
139
170
|
|
|
@@ -154,4 +185,4 @@ names. No backend identity or stored data migration is required.
|
|
|
154
185
|
## Requirements
|
|
155
186
|
|
|
156
187
|
Node.js 18 or later, an authorized Ziggs operator key and the provider key for
|
|
157
|
-
your selected brain/model.
|
|
188
|
+
your selected brain/model. Apache-2.0; see [LICENSE](../LICENSE).
|
|
@@ -45,6 +45,11 @@ function normalizePlanInPlace(payload) {
|
|
|
45
45
|
? 'before_execution'
|
|
46
46
|
: 'with_proposal';
|
|
47
47
|
}
|
|
48
|
+
function oneOf(value, allowed) {
|
|
49
|
+
return typeof value === 'string' && allowed.includes(value)
|
|
50
|
+
? value
|
|
51
|
+
: undefined;
|
|
52
|
+
}
|
|
48
53
|
/** The `sources` a protocol call carried, when it carried a list. */
|
|
49
54
|
function sourcesOf(payload) {
|
|
50
55
|
return Array.isArray(payload.sources)
|
|
@@ -92,6 +97,7 @@ cachedAgreements) {
|
|
|
92
97
|
if (!payload.agreementId)
|
|
93
98
|
return null;
|
|
94
99
|
// The price is the one the model stated; the SDK adds none.
|
|
100
|
+
const interactionMode = oneOf(payload['interactionMode'], ['messages', 'tasks', 'both']);
|
|
95
101
|
return agreementService.counter(payload.agreementId, {
|
|
96
102
|
price: payload.price,
|
|
97
103
|
agreementDescription: payload.agreementDescription,
|
|
@@ -100,6 +106,10 @@ cachedAgreements) {
|
|
|
100
106
|
maxExecutions: payload.maxExecutions,
|
|
101
107
|
description: payload.description,
|
|
102
108
|
...sourcesOf(payload),
|
|
109
|
+
...(interactionMode ? { interactionMode } : {}),
|
|
110
|
+
...(payload.conversationAllowance !== undefined
|
|
111
|
+
? { conversationAllowance: payload.conversationAllowance }
|
|
112
|
+
: {}),
|
|
103
113
|
});
|
|
104
114
|
case 'agreement-check-proposal':
|
|
105
115
|
if (!payload.agreementId)
|
|
@@ -282,6 +292,7 @@ async function proposeAgreement(services, payload, chatId, writeKeys = null) {
|
|
|
282
292
|
const billing = payload['billing'] === 'per_task' || payload['billing'] === 'total'
|
|
283
293
|
? payload['billing']
|
|
284
294
|
: undefined;
|
|
295
|
+
const interactionMode = oneOf(payload['interactionMode'], ['messages', 'tasks', 'both']);
|
|
285
296
|
const { agreement, shape } = await services.agreementService.proposeUnified({
|
|
286
297
|
proposedTo: payload.proposedTo,
|
|
287
298
|
chatId: chatId ?? undefined,
|
|
@@ -292,6 +303,7 @@ async function proposeAgreement(services, payload, chatId, writeKeys = null) {
|
|
|
292
303
|
expiresAt: typeof payload.expiresAt === 'string' ? payload.expiresAt : undefined,
|
|
293
304
|
maxExecutions: typeof payload.maxExecutions === 'number' ? payload.maxExecutions : undefined,
|
|
294
305
|
billing,
|
|
306
|
+
...(interactionMode ? { interactionMode } : {}),
|
|
295
307
|
...(payload.conversationAllowance !== undefined ? { conversationAllowance: payload.conversationAllowance } : {}),
|
|
296
308
|
agreementDescription: payload.agreementDescription,
|
|
297
309
|
...sourcesOf(payload),
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import { defineTool } from '../../../tools/defineTool.js';
|
|
2
2
|
import { requireProtocolOperation } from '../../../tasks/protocolRegistry.js';
|
|
3
3
|
import { dispatchProtocolOp } from './protocolRunner.js';
|
|
4
|
-
import { AGREEMENT_PROPOSE_PROVIDER_ID_DESCRIPTION, agreementClaimCapability, agreementSubcontractCapability, SOURCES_PARAM, } from '@ziggs-ai/api-client';
|
|
5
|
-
/** keep these enums in lockstep with MCP ziggs_agreement_* / ziggs_task_create. */
|
|
6
|
-
const LIFECYCLE_ENUM = ['open', 'time-bound', 'count-bound'];
|
|
4
|
+
import { AGREEMENT_PROPOSE_PROVIDER_ID_DESCRIPTION, AGREEMENT_TERMS_PARAMS, agreementClaimCapability, agreementSubcontractCapability, SOURCES_PARAM, } from '@ziggs-ai/api-client';
|
|
7
5
|
const PLAN_REVIEW_TIMING_ENUM = ['with_proposal', 'before_execution'];
|
|
8
|
-
const lifecycleParam = {
|
|
9
|
-
type: 'string',
|
|
10
|
-
enum: [...LIFECYCLE_ENUM],
|
|
11
|
-
description: "Usually inferred: expiresAt → 'time-bound', maxExecutions → 'count-bound', neither → 'open' (standing).",
|
|
12
|
-
};
|
|
13
6
|
const planReviewTimingParam = {
|
|
14
7
|
type: 'string',
|
|
15
8
|
enum: [...PLAN_REVIEW_TIMING_ENUM],
|
|
@@ -60,7 +53,18 @@ function handlerFor(toolName) {
|
|
|
60
53
|
return result;
|
|
61
54
|
};
|
|
62
55
|
}
|
|
63
|
-
export const agreementProposeTool = defineTool('agreement_propose', {
|
|
56
|
+
export const agreementProposeTool = defineTool('agreement_propose', {
|
|
57
|
+
...AGREEMENT_TERMS_PARAMS,
|
|
58
|
+
proposedTo: { type: 'string', required: true },
|
|
59
|
+
engagementKind: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
enum: ['hire', 'service'],
|
|
62
|
+
description: 'Contract type. Defaults to service. For a bilateral trust link, use link_propose.',
|
|
63
|
+
},
|
|
64
|
+
parentAgreementId: 'string',
|
|
65
|
+
providerId: { type: 'string', description: AGREEMENT_PROPOSE_PROVIDER_ID_DESCRIPTION },
|
|
66
|
+
agreementDescription: 'string',
|
|
67
|
+
}, handlerFor('agreement_propose'), { description: 'Propose an agreement — direct, broadcast, or link; there are no separate publish tools. Engagement precedence (posted-first): 1) REUSE an active agreement on matching terms, 2) CLAIM the counterparty\'s listing (marketplace_view → agreement_claim; never counter a listing), 3) POST a request broadcast here when nothing listed fits, 4) direct-propose ONLY for bespoke terms, renegotiation, or commissioning a named counterparty with no listing — most published agents are claim-only and refuse direct proposals with a pointer at their listing. Direction is stated, never guessed: providerId = your own id ("I work, you pay") or providerId = proposedTo ("you work, I pay") on direct proposals. Broadcast with proposedTo="everyone" (fully public) or "org" (your org only) and no providerId posts a REQUEST any agent may claim. A person or the deploy publishes a standing listing; this agent does not. For a bilateral trust link, use link_propose: it takes an email or an agent id, or neither for a share link. engagementKind defaults to service. Agreements are STANDING by default (no expiry, unlimited tasks under one agreement); set expiresAt or maxExecutions only when the engagement should end on its own.', isAgreementCreation: true });
|
|
64
68
|
export const agreementSubcontractTool = defineTool('agreement_subcontract', agreementSubcontractCapability.params, handlerFor('agreement_subcontract'), { description: agreementSubcontractCapability.descriptions.sdk, isAgreementCreation: true });
|
|
65
69
|
export const agreementRespondTool = defineTool('agreement_respond', { agreementId: { type: 'string', required: true }, action: { type: 'string', required: true, enum: ['approve', 'reject'] } }, handlerFor('agreement_respond'), { description: 'Approve or reject a pending DIRECT agreement proposal addressed to you. Open broadcasts (requests, standing offers, link invites) have no personal approval slot — claim those with agreement_claim instead, or ignore them to pass. ONE exception: a hand-off that pins YOU as provider carries your pending approval even as an open broadcast — approving consents to serving whoever claims it (the row stays open for claims); rejecting cancels the hand-off. Ignoring it leaves the hand-off unclaimable, so always respond.' });
|
|
66
70
|
export const agreementClaimTool = defineTool('agreement_claim', agreementClaimCapability.params, handlerFor('agreement_claim'), { description: agreementClaimCapability.descriptions.sdk });
|
|
@@ -75,7 +79,18 @@ export const taskSetResultTool = defineTool('task_set_result', {
|
|
|
75
79
|
},
|
|
76
80
|
sources: SOURCES_PARAM,
|
|
77
81
|
}, handlerFor('task_set_result'), { description: 'Transition a task to its terminal state, completed or failed, and record the result. To cancel a task use task_cancel. Set the result here as an object ({ summary, status, links }): a task the parties opted into is closed by this call, whatever else you also sent them. Pass state (not status). This closes the task and not the engagement: a standing hire stays active for the next task, ending one is agreement_fulfill. The reply reports what actually happened — what was stored, who the completion was queued for (queued, not read), what per-task metering did — so report those and no more; a completed task is not by itself a paid one.' });
|
|
78
|
-
export const agreementCounterTool = defineTool('agreement_counter', {
|
|
82
|
+
export const agreementCounterTool = defineTool('agreement_counter', {
|
|
83
|
+
agreementId: { type: 'string', required: true },
|
|
84
|
+
price: AGREEMENT_TERMS_PARAMS.price,
|
|
85
|
+
agreementDescription: 'string',
|
|
86
|
+
expiresAt: AGREEMENT_TERMS_PARAMS.expiresAt,
|
|
87
|
+
lifecycle: AGREEMENT_TERMS_PARAMS.lifecycle,
|
|
88
|
+
maxExecutions: AGREEMENT_TERMS_PARAMS.maxExecutions,
|
|
89
|
+
interactionMode: AGREEMENT_TERMS_PARAMS.interactionMode,
|
|
90
|
+
conversationAllowance: AGREEMENT_TERMS_PARAMS.conversationAllowance,
|
|
91
|
+
description: 'string',
|
|
92
|
+
sources: AGREEMENT_TERMS_PARAMS.sources,
|
|
93
|
+
}, handlerFor('agreement_counter'), { description: 'Counter a pending proposal with revised terms instead of approving or rejecting. Check status first with agreement_get.' });
|
|
79
94
|
export const agreementGetTool = defineTool('agreement_get', { agreementId: { type: 'string', required: true } }, handlerFor('agreement_get'), { description: 'Read the current proposal status for an agreement (pending, approved, rejected, countered, expired).' });
|
|
80
95
|
export const agreementRevokeTool = defineTool('agreement_revoke', { agreementId: { type: 'string', required: true } }, handlerFor('agreement_revoke'), { description: 'Revoke a pending proposal you created so it can no longer be approved. Use when the user has clearly moved on to a different request before responding to the previous proposal card.' });
|
|
81
96
|
export const agreementFulfillTool = defineTool('agreement_fulfill', { agreementId: { type: 'string', required: true } }, handlerFor('agreement_fulfill'), { description: 'END an agreement you provide — permanently. Fulfilling terminates the whole relationship, not one deliverable: every grant it conferred is revoked and it cannot be reopened. Linked chats remain independent rooms governed by their own grants. Finished WORK is reported via task_set_result (the task closes; the agreement stays standing for the next task). Only fulfill when the engagement\'s full scope is delivered and nothing more is expected — never a standing hire that just finished a task.' });
|
|
@@ -49,7 +49,10 @@ export async function withAgreementContext(event, read) {
|
|
|
49
49
|
relationship: agreement.engagementKind === 'link',
|
|
50
50
|
interactionMode: terms.interactionMode ?? 'both',
|
|
51
51
|
parentAgreementId: agreement.parentAgreementId ?? null,
|
|
52
|
-
allowanceScope:
|
|
52
|
+
allowanceScope: (money.paymentStatus === 'included' || money.paymentStatus === 'allocated') &&
|
|
53
|
+
agreement.parentAgreementId
|
|
54
|
+
? 'job'
|
|
55
|
+
: 'own',
|
|
53
56
|
scope: terms.description,
|
|
54
57
|
lifecycle: terms.lifecycle,
|
|
55
58
|
expiresAt: terms.expiresAt ?? null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ziggs-ai/agent-sdk",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.17",
|
|
4
4
|
"description": "Agent framework SDK for building autonomous agents on the Ziggs platform",
|
|
5
5
|
"homepage": "https://ziggsai.com/docs",
|
|
6
6
|
"bugs": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@anthropic-ai/claude-agent-sdk": "^0.3.284",
|
|
31
31
|
"@anthropic-ai/sdk": "^0.110.0",
|
|
32
32
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
33
|
-
"@ziggs-ai/api-client": "0.37.
|
|
33
|
+
"@ziggs-ai/api-client": "0.37.20",
|
|
34
34
|
"@ziggs-ai/contracts": "^0.23.3",
|
|
35
35
|
"ajv": "^8.17.1",
|
|
36
36
|
"dotenv": "^17.2.3",
|