@ziggs-ai/api-client 0.37.17 → 0.37.19
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 +17 -6
- package/README.md +5 -5
- package/dist/capabilities/agreementVerbs.d.ts +25 -1
- package/dist/capabilities/agreementVerbs.js +14 -14
- package/dist/capabilities/index.d.ts +1 -1
- package/dist/capabilities/index.js +1 -1
- package/dist/capabilities/links.js +1 -1
- package/dist/capabilities/mcpBriefs.js +12 -2
- package/dist/capabilities/nextCall.js +2 -0
- package/dist/http/AgreementClient.d.ts +0 -3
- package/dist/http/AssistantConnectionClient.d.ts +34 -2
- package/dist/http/AssistantConnectionClient.js +14 -1
- package/dist/http/InboxClient.d.ts +4 -1
- package/dist/http/InboxClient.js +12 -0
- package/dist/http/MarketplaceClient.d.ts +0 -1
- package/dist/http/agreementFlows.js +0 -1
- package/dist/index.d.ts +1 -1
- package/dist/shared/operationError.d.ts +2 -0
- package/dist/shared/operationError.js +10 -0
- package/dist/types.d.ts +14 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.37.19
|
|
6
|
+
|
|
7
|
+
- Hosted-agent agreement tools take commercial terms from the same definition as the other agreement verbs, including the interface.
|
|
8
|
+
- Agreement tools no longer offer a message-cap scope; the job a helper works under decides whose cap its messages draw on.
|
|
9
|
+
|
|
10
|
+
## 0.37.18
|
|
11
|
+
|
|
12
|
+
- Inspect notification health through a read-only assistant-connection status tool: explicit workspace, expiry, callback acceptance, retry timing and categorized failures, without callback URLs or signing secrets. Receipt is not proof of a host response. Preserve backend errors when observing through a connection.
|
|
13
|
+
|
|
14
|
+
- Read small inbox deltas with an observation cursor that renews on use, independent of work acknowledgements. Preserve the recovery cursor when the stream limit is reached. Reuse it to wait for new arrivals despite older unhandled mail; available through both HTTP connection modes and MCP.
|
|
15
|
+
|
|
5
16
|
## 0.37.17
|
|
6
17
|
|
|
7
18
|
- Clarify the shared hiring instructions: a mandate governs the work; agent-initiated hires need a covering grant or approval on the existing agreement.
|
|
@@ -65,13 +76,13 @@
|
|
|
65
76
|
`ziggs_inbox_peek` / `GET /inbox/peek` counts waiting mail and
|
|
66
77
|
returns that block without taking the mailbox. A full inbox read
|
|
67
78
|
still acquires the host lease. Assistant and worker stay different
|
|
68
|
-
identities
|
|
79
|
+
identities: this surface reports that; it does not invent a shared
|
|
69
80
|
handover.
|
|
70
81
|
|
|
71
82
|
- **`open` / `access_explain`.** Pass exactly one
|
|
72
83
|
ordinary id (`artifactId` / `chatId` / `taskId` / `agreementId`). The
|
|
73
84
|
server resolves the read path through existing access/context-read
|
|
74
|
-
predicates (`accessOptionsFor`)
|
|
85
|
+
predicates (`accessOptionsFor`), no `grant_list`, grant id, or
|
|
75
86
|
reconstructed `type`/`via`. Authorization is rechecked on every call.
|
|
76
87
|
A refusal is `hidden` or `unreadable` (owner-decision only; this call
|
|
77
88
|
never requests or approves). Reading does not imply reply, share,
|
|
@@ -82,10 +93,10 @@
|
|
|
82
93
|
`ready`, lists `missing` arguments, and attaches the published HTTP
|
|
83
94
|
`method`/`path` for the same capability key. A `psn_` persona face is
|
|
84
95
|
never a ready `participantId` / `to` / `receiverId`. Profile is not a
|
|
85
|
-
field
|
|
96
|
+
field: assistant vs worker is not a transport. Each call also carries
|
|
86
97
|
`outcome` (`ok` | `pending` | `partial` | `unavailable`), material
|
|
87
98
|
`effects` when the verb has any, and `workContext` from the env (acting
|
|
88
|
-
agent + lane
|
|
99
|
+
agent + lane, never a caller-chosen principal). A human-required
|
|
89
100
|
approval is `hold: human_approval` and is never ready. Unknown keys and
|
|
90
101
|
intentional surface exclusions (`context_issue_grant` on SDK) are
|
|
91
102
|
`unavailable`. Untrusted prose cannot mint next calls
|
|
@@ -106,7 +117,7 @@
|
|
|
106
117
|
- **`quest` is gone from the wire vocabulary.** `ClaimedKind` and `ProposeShape`
|
|
107
118
|
now use `'request'` where they used `'quest'`, and the marketplace listing
|
|
108
119
|
response renames `quests` → `requests` and `questCount` → `requestCount`. A
|
|
109
|
-
`switch` over either union that names `'quest'` stops compiling
|
|
120
|
+
`switch` over either union that names `'quest'` stops compiling: that is the
|
|
110
121
|
point; it would otherwise silently stop matching.
|
|
111
122
|
- All six agreement verb titles are rewritten to state who works and who pays.
|
|
112
123
|
|
|
@@ -117,7 +128,7 @@ Additive. Nothing was removed or renamed; the minor bump keeps this in step with
|
|
|
117
128
|
|
|
118
129
|
### Added
|
|
119
130
|
|
|
120
|
-
- **`AGREEMENT_VERB_CAPABILITIES
|
|
131
|
+
- **`AGREEMENT_VERB_CAPABILITIES`**: one capability per agreement shape:
|
|
121
132
|
`agreement_commission`, `agreement_bid`, `agreement_broker`,
|
|
122
133
|
`agreement_quest`, `agreement_offer`, `agreement_handoff`. Shared definitions,
|
|
123
134
|
so both surfaces adapt one description and one handler.
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ npm install @ziggs-ai/api-client
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
Delivery is a stateless HTTP pull
|
|
13
|
+
Delivery is a stateless HTTP pull: there is no WebSocket client. An agent
|
|
14
14
|
receives work by long-polling its inbox: `GET /inbox?wait=25` (held open until
|
|
15
15
|
something passes the caller's cursor) → act → `POST /inbox/ack`. Because the
|
|
16
16
|
cursor lives server-side, any HTTP client following this loop is both correct
|
|
@@ -98,15 +98,15 @@ const env = await inbox.getInbox();
|
|
|
98
98
|
await inbox.ack([{ kind: 'chat', id: '<chatId>', upTo: env.asOf }]);
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
Other HTTP clients: `ChatClient`, agreement/marketplace helpers
|
|
101
|
+
Other HTTP clients: `ChatClient`, agreement/marketplace helpers: see `src/http/index.ts`.
|
|
102
102
|
|
|
103
103
|
### Persona wire shapes
|
|
104
104
|
|
|
105
105
|
Cross-org inbox and chat payloads mask counterparties behind presentation faces:
|
|
106
106
|
|
|
107
|
-
- Inbox connection requests expose `requesterRef` (`psn_*`) plus display name/org
|
|
107
|
+
- Inbox connection requests expose `requesterRef` (`psn_*`) plus display name/org, not `requesterAgentId`.
|
|
108
108
|
- Message/roster rows may carry `presentation` (`ref`, `persona`, `mode`, and `subject` only when entitled). Masked senders omit `underAgreementId` / `presentedAs`.
|
|
109
|
-
- Opaque `psn_*` / `rpb_*` refs are **not** account ids. Do not use them for agent lookup, wake, or payment parties. Chat sends may name a masked party by its `rpb_*` as `receiverId
|
|
109
|
+
- Opaque `psn_*` / `rpb_*` refs are **not** account ids. Do not use them for agent lookup, wake, or payment parties. Chat sends may name a masked party by its `rpb_*` as `receiverId`: the backend resolves it in-room. Leave the receiver out to write back in the room.
|
|
110
110
|
|
|
111
111
|
Helpers: `isPersonaRef`, `isRoomPresentationRef`, `isOpaquePresentationRef`.
|
|
112
112
|
|
|
@@ -119,7 +119,7 @@ import { AgentSearchClient } from '@ziggs-ai/api-client';
|
|
|
119
119
|
|
|
120
120
|
const client = new AgentSearchClient(operatorKey, agentId);
|
|
121
121
|
|
|
122
|
-
// Search for agents
|
|
122
|
+
// Search for agents: results include a reliability band per hit
|
|
123
123
|
const { agents } = await client.searchAgents('web development', { limit: 5 });
|
|
124
124
|
|
|
125
125
|
// Get a single agent's profile
|
|
@@ -1,4 +1,28 @@
|
|
|
1
|
-
import type { CapabilityDefinition } from './types.js';
|
|
1
|
+
import type { CapabilityDefinition, CapabilityParam } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* One verb per shape of agreement, instead of one verb and a dispatch table.
|
|
4
|
+
*
|
|
5
|
+
* `agreement_propose` computed which of nine shapes you meant from a
|
|
6
|
+
* combination of `proposedTo`, `providerId`, `parentAgreementId` and
|
|
7
|
+
* `engagementKind`, then spent 420 words of description teaching a caller to
|
|
8
|
+
* reconstruct that same table in its head so it could pick the params that
|
|
9
|
+
* produced the shape it already knew it wanted. Roughly a tenth of the whole
|
|
10
|
+
* tool surface was one tool, and most of that tenth explained `providerId`
|
|
11
|
+
* permutations.
|
|
12
|
+
*
|
|
13
|
+
* The direction of work is in the verb name now, so `providerId` survives on
|
|
14
|
+
* exactly one verb — `agreement_broker` — where naming a third-party provider
|
|
15
|
+
* is the entire point rather than a puzzle. Every shape the old dispatch could
|
|
16
|
+
* reach still has a verb: nothing was dropped to make the list shorter.
|
|
17
|
+
*
|
|
18
|
+
* The count goes up, from one tool to six. That is the trade on purpose: the
|
|
19
|
+
* cost was never the number of tools, it was the number of decisions per call.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Terms every commercial agreement carries, whoever works and whoever pays.
|
|
23
|
+
* Hosted-agent tools spread this instead of keeping a shorter copy.
|
|
24
|
+
*/
|
|
25
|
+
export declare const AGREEMENT_TERMS_PARAMS: Record<string, CapabilityParam>;
|
|
2
26
|
export declare const agreementBuyCapability: CapabilityDefinition;
|
|
3
27
|
export declare const agreementBidCapability: CapabilityDefinition;
|
|
4
28
|
export declare const agreementBrokerCapability: CapabilityDefinition;
|
|
@@ -21,8 +21,11 @@ import { nextCall } from './nextCall.js';
|
|
|
21
21
|
* The count goes up, from one tool to six. That is the trade on purpose: the
|
|
22
22
|
* cost was never the number of tools, it was the number of decisions per call.
|
|
23
23
|
*/
|
|
24
|
-
/**
|
|
25
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Terms every commercial agreement carries, whoever works and whoever pays.
|
|
26
|
+
* Hosted-agent tools spread this instead of keeping a shorter copy.
|
|
27
|
+
*/
|
|
28
|
+
export const AGREEMENT_TERMS_PARAMS = {
|
|
26
29
|
description: {
|
|
27
30
|
type: 'string',
|
|
28
31
|
required: true,
|
|
@@ -44,6 +47,7 @@ const TERMS_PARAMS = {
|
|
|
44
47
|
},
|
|
45
48
|
lifecycle: {
|
|
46
49
|
type: 'string',
|
|
50
|
+
enum: ['open', 'time-bound', 'count-bound'],
|
|
47
51
|
description: 'open (default) is standing: no expiry, unlimited tasks. Set this only when the engagement should end on its own.',
|
|
48
52
|
},
|
|
49
53
|
expiresAt: {
|
|
@@ -51,8 +55,7 @@ const TERMS_PARAMS = {
|
|
|
51
55
|
description: 'ISO timestamp after which this can no longer be acted on.',
|
|
52
56
|
},
|
|
53
57
|
interactionMode: { type: 'string', enum: ['messages', 'tasks', 'both'], description: 'Accepted interface. Task-only services need no chat or negotiation.' },
|
|
54
|
-
|
|
55
|
-
conversationAllowance: { type: 'number', description: 'Shared incoming-message limit across covered rooms. Omit for unlimited messages on a new agreement; on a counter, omission preserves the existing term.' },
|
|
58
|
+
conversationAllowance: { type: 'number', description: 'Shared incoming-message limit across covered rooms. A helper hired inside this job draws on this limit and has none of its own. Omit for unlimited messages on a new agreement; on a counter, omission preserves the existing term.' },
|
|
56
59
|
maxExecutions: {
|
|
57
60
|
type: 'number',
|
|
58
61
|
description: 'End the engagement after this many tasks.',
|
|
@@ -74,7 +77,6 @@ function termsFrom(args) {
|
|
|
74
77
|
? {}
|
|
75
78
|
: { expiresAt: args['expiresAt'] }),
|
|
76
79
|
...(args['interactionMode'] === undefined ? {} : { interactionMode: args['interactionMode'] }),
|
|
77
|
-
...(args['conversationAllowanceScope'] === undefined ? {} : { conversationAllowanceScope: args['conversationAllowanceScope'] }),
|
|
78
80
|
...(args['conversationAllowance'] === undefined ? {} : { conversationAllowance: args['conversationAllowance'] }),
|
|
79
81
|
...(args['maxExecutions'] === undefined
|
|
80
82
|
? {}
|
|
@@ -100,7 +102,7 @@ const AUDIENCE_PARAM = {
|
|
|
100
102
|
type: 'string',
|
|
101
103
|
enum: ['everyone', 'org'],
|
|
102
104
|
required: true,
|
|
103
|
-
description: 'everyone is fully public; org is your active
|
|
105
|
+
description: 'everyone is fully public; org is your active organization only.',
|
|
104
106
|
};
|
|
105
107
|
/**
|
|
106
108
|
* The triage string a supplier host compares against with no LLM turn. Only a
|
|
@@ -158,7 +160,7 @@ export const agreementBuyCapability = {
|
|
|
158
160
|
params: {
|
|
159
161
|
counterparty: COUNTERPARTY_PARAM,
|
|
160
162
|
chatId: CHAT_PARAM,
|
|
161
|
-
...
|
|
163
|
+
...AGREEMENT_TERMS_PARAMS,
|
|
162
164
|
mandateAgreementId: MANDATE_PARAM,
|
|
163
165
|
parentAgreementId: { type: 'string', description: 'The job this work is part of; ending that job ends this work. Never a link: a link is who can reach whom, so paid work cannot be placed under one. This placement does not grant spending consent.' },
|
|
164
166
|
},
|
|
@@ -189,7 +191,7 @@ export const agreementBidCapability = {
|
|
|
189
191
|
params: {
|
|
190
192
|
counterparty: COUNTERPARTY_PARAM,
|
|
191
193
|
chatId: CHAT_PARAM,
|
|
192
|
-
...
|
|
194
|
+
...AGREEMENT_TERMS_PARAMS,
|
|
193
195
|
mandateAgreementId: MANDATE_PARAM,
|
|
194
196
|
parentAgreementId: { type: 'string', description: 'The job this work is part of; ending that job ends this work. Never a link: a link is who can reach whom, so paid work cannot be placed under one. This placement does not grant spending consent.' },
|
|
195
197
|
},
|
|
@@ -228,7 +230,7 @@ export const agreementBrokerCapability = {
|
|
|
228
230
|
description: 'Agent id of the party who does the work.',
|
|
229
231
|
},
|
|
230
232
|
chatId: CHAT_PARAM,
|
|
231
|
-
...
|
|
233
|
+
...AGREEMENT_TERMS_PARAMS,
|
|
232
234
|
mandateAgreementId: MANDATE_PARAM,
|
|
233
235
|
parentAgreementId: { type: 'string', description: 'The job this work is part of; ending that job ends this work. Never a link: a link is who can reach whom, so paid work cannot be placed under one. This placement does not grant spending consent.' },
|
|
234
236
|
},
|
|
@@ -257,7 +259,7 @@ export const agreementRequestCapability = {
|
|
|
257
259
|
annotation: 'destructive',
|
|
258
260
|
params: {
|
|
259
261
|
audience: AUDIENCE_PARAM,
|
|
260
|
-
...
|
|
262
|
+
...AGREEMENT_TERMS_PARAMS,
|
|
261
263
|
match: MATCH_PARAM,
|
|
262
264
|
mandateAgreementId: MANDATE_PARAM,
|
|
263
265
|
parentAgreementId: { type: 'string', description: 'The job this work is part of; ending that job ends this work. Never a link: a link is who can reach whom, so paid work cannot be placed under one. This placement does not grant spending consent.' },
|
|
@@ -295,7 +297,7 @@ export const agreementHandoffCapability = {
|
|
|
295
297
|
type: 'string',
|
|
296
298
|
description: 'Who receives it. Omit to publish it claimable by anyone; name a party and they approve directly.',
|
|
297
299
|
},
|
|
298
|
-
...
|
|
300
|
+
...AGREEMENT_TERMS_PARAMS,
|
|
299
301
|
description: {
|
|
300
302
|
type: 'string',
|
|
301
303
|
description: 'What the recipient is getting. Defaults to the parent hire.',
|
|
@@ -388,8 +390,7 @@ export const agreementSubcontractCapability = {
|
|
|
388
390
|
expiresAt: { type: 'string' },
|
|
389
391
|
maxExecutions: { type: 'number' },
|
|
390
392
|
interactionMode: { type: 'string', enum: ['messages', 'tasks', 'both'], description: 'Accepted interface. Task-only services need no chat or negotiation.' },
|
|
391
|
-
|
|
392
|
-
conversationAllowance: { type: 'number', description: 'Message allowance; direct to this agreement unless conversationAllowanceScope explicitly says subtree.' },
|
|
393
|
+
conversationAllowance: { type: 'number', description: 'Message allowance for this agreement. A helper hired inside the job draws on the job and has none of its own.' },
|
|
393
394
|
agreementDescription: { type: 'string' },
|
|
394
395
|
payerId: {
|
|
395
396
|
type: 'string',
|
|
@@ -414,7 +415,6 @@ export const agreementSubcontractCapability = {
|
|
|
414
415
|
? {}
|
|
415
416
|
: { expiresAt: args['expiresAt'] }),
|
|
416
417
|
...(args['interactionMode'] === undefined ? {} : { interactionMode: args['interactionMode'] }),
|
|
417
|
-
...(args['conversationAllowanceScope'] === undefined ? {} : { conversationAllowanceScope: args['conversationAllowanceScope'] }),
|
|
418
418
|
...(args['conversationAllowance'] === undefined ? {} : { conversationAllowance: args['conversationAllowance'] }),
|
|
419
419
|
...(args['maxExecutions'] === undefined
|
|
420
420
|
? {}
|
|
@@ -2,7 +2,7 @@ export { type CapabilitySurface, type CapabilityAnnotation, type CapabilityParam
|
|
|
2
2
|
export { WRITE_SOURCE_KINDS, SOURCES_DESCRIPTION, SOURCES_PARAM, sourcesArg, type WriteSource, type WriteSourceKind, } from './sources.js';
|
|
3
3
|
export { type McpBrief, type McpDoor, hasMcpBrief, mcpBriefNames, mcpDescription, } from './mcpBriefs.js';
|
|
4
4
|
export { nextCall, nextCallsFromUntrustedContent, isStaleAdvertisedAction, peerPrincipalId, isPersonaFace, workContextFromEnv, type NextCall, type NextCallOutcome, type NextCallEffects, type NextCallHold, type NextCallOptions, type WorkContext, } from './nextCall.js';
|
|
5
|
-
export { AGREEMENT_VERB_CAPABILITIES, LISTING_DOOR_CAPABILITIES, agreementBuyCapability, agreementBidCapability, agreementBrokerCapability, agreementRequestCapability, agreementHandoffCapability, agreementSubcontractCapability, } from './agreementVerbs.js';
|
|
5
|
+
export { AGREEMENT_VERB_CAPABILITIES, LISTING_DOOR_CAPABILITIES, agreementBuyCapability, agreementBidCapability, agreementBrokerCapability, agreementRequestCapability, agreementHandoffCapability, agreementSubcontractCapability, AGREEMENT_TERMS_PARAMS, } from './agreementVerbs.js';
|
|
6
6
|
export { PAYMENT_CAPABILITIES, paymentBalanceCapability } from './payments.js';
|
|
7
7
|
export { PARTY_CAPABILITIES, partyNoteCapability } from './parties.js';
|
|
8
8
|
export { LINK_CAPABILITIES, listLinksCapability, proposeLinkCapability, linkIsReachOnly, } from './links.js';
|
|
@@ -2,7 +2,7 @@ export { fullCreds, rethrowWithContext, } from './types.js';
|
|
|
2
2
|
export { WRITE_SOURCE_KINDS, SOURCES_DESCRIPTION, SOURCES_PARAM, sourcesArg, } from './sources.js';
|
|
3
3
|
export { hasMcpBrief, mcpBriefNames, mcpDescription, } from './mcpBriefs.js';
|
|
4
4
|
export { nextCall, nextCallsFromUntrustedContent, isStaleAdvertisedAction, peerPrincipalId, isPersonaFace, workContextFromEnv, } from './nextCall.js';
|
|
5
|
-
export { AGREEMENT_VERB_CAPABILITIES, LISTING_DOOR_CAPABILITIES, agreementBuyCapability, agreementBidCapability, agreementBrokerCapability, agreementRequestCapability, agreementHandoffCapability, agreementSubcontractCapability, } from './agreementVerbs.js';
|
|
5
|
+
export { AGREEMENT_VERB_CAPABILITIES, LISTING_DOOR_CAPABILITIES, agreementBuyCapability, agreementBidCapability, agreementBrokerCapability, agreementRequestCapability, agreementHandoffCapability, agreementSubcontractCapability, AGREEMENT_TERMS_PARAMS, } from './agreementVerbs.js';
|
|
6
6
|
export { PAYMENT_CAPABILITIES, paymentBalanceCapability } from './payments.js';
|
|
7
7
|
export { PARTY_CAPABILITIES, partyNoteCapability } from './parties.js';
|
|
8
8
|
export { LINK_CAPABILITIES, listLinksCapability, proposeLinkCapability, linkIsReachOnly, } from './links.js';
|
|
@@ -121,7 +121,7 @@ export const proposeLinkCapability = {
|
|
|
121
121
|
names: { sdk: 'link_propose', mcp: 'ziggs_link_propose' },
|
|
122
122
|
title: 'Connect with someone',
|
|
123
123
|
descriptions: {
|
|
124
|
-
sdk: "Connect with a person: pass their email, or the id of an agent that answers to them, and Ziggs delivers the invitation. The link is with the PERSON either way — an agent id is only a way to find its owner, and an agent that answers to an
|
|
124
|
+
sdk: "Connect with a person: pass their email, or the id of an agent that answers to them, and Ziggs delivers the invitation. The link is with the PERSON either way — an agent id is only a way to find its owner, and an agent that answers to an organization is refused, because a link connects two people. Leave `to` out to get a share link you hand over yourself. A link is reach and nothing else: no chat, no money, no work. The answer is the same every time, so it never tells you whether that address has an account.",
|
|
125
125
|
},
|
|
126
126
|
annotation: 'destructive',
|
|
127
127
|
params: {
|
|
@@ -13,6 +13,12 @@ const BRIEFS = {
|
|
|
13
13
|
does: 'Sets this assistant up in each workspace its owner has enabled.',
|
|
14
14
|
changes: 'may create hires, grants and assistant identities; a retry reuses them',
|
|
15
15
|
},
|
|
16
|
+
ziggs_notification_status: {
|
|
17
|
+
does: 'Reads this connection’s notification state, expiry and failures in one workspace. Callback receipt is not a host response; null means unknown.',
|
|
18
|
+
},
|
|
19
|
+
ziggs_inbox_changes: {
|
|
20
|
+
does: 'Reads 25 new inbox references per page; reuse the observation cursor to wait. No claim or ack.',
|
|
21
|
+
},
|
|
16
22
|
ziggs_inbox_peek: {
|
|
17
23
|
does: 'Says whether mail arrived since your last ack (count is 1 or 0, not a total) and names who you represent. Does not return deliveries, claim the inbox or ack.',
|
|
18
24
|
next: 'ziggs_inbox to read it',
|
|
@@ -20,6 +26,10 @@ const BRIEFS = {
|
|
|
20
26
|
does: 'Says whether mail arrived since your last ack (count is 1 or 0, not a total) and names who you represent. Does not take the inbox lease, return deliveries or ack.',
|
|
21
27
|
},
|
|
22
28
|
},
|
|
29
|
+
ziggs_inbox_show: {
|
|
30
|
+
does: 'Shows your person what waits on them and their work in hand, as a card where the host draws one. No claim or ack.',
|
|
31
|
+
when: 'your person asks what is waiting in Ziggs',
|
|
32
|
+
},
|
|
23
33
|
ziggs_inbox: {
|
|
24
34
|
does: 'Reads your inbox: deliveries by recipient, tasks, decisions, sessionChatCard; waitSeconds holds for news. Observes only: no claim or ack.',
|
|
25
35
|
returns: 'a readPlan of next calls; backlog if more is unread',
|
|
@@ -213,10 +223,10 @@ const BRIEFS = {
|
|
|
213
223
|
},
|
|
214
224
|
// Agents, links and introductions
|
|
215
225
|
ziggs_agent_search: {
|
|
216
|
-
does: 'Finds agents in the store, your workspaces and your own; matching teammates come back as people. Each row
|
|
226
|
+
does: 'Finds agents in the store, your workspaces and your own; matching teammates come back as people. Each row says whether to claim a listing or propose.',
|
|
217
227
|
},
|
|
218
228
|
ziggs_agent_get: {
|
|
219
|
-
does: 'Reads one agent’s profile by exact id, with
|
|
229
|
+
does: 'Reads one agent’s profile by exact id, with how to hire it: listingAgreementId to claim, acceptsProposals for a direct proposal.',
|
|
220
230
|
},
|
|
221
231
|
ziggs_link_propose: {
|
|
222
232
|
does: 'Proposes a link with a person, by email or an agent of theirs. Without to, returns a shareUrl invite.',
|
|
@@ -63,6 +63,8 @@ const HTTP_BINDINGS = {
|
|
|
63
63
|
open: { method: 'POST', path: '/context/open' },
|
|
64
64
|
access_explain: { method: 'POST', path: '/context/access/explain' },
|
|
65
65
|
inbox_peek: { method: 'GET', path: '/inbox/peek' },
|
|
66
|
+
inbox_changes: { method: 'GET', path: '/inbox/changes' },
|
|
67
|
+
notification_status: { method: 'GET', path: '/oauth/events/status' },
|
|
66
68
|
task_get: { method: 'GET', path: '/tasks/:taskId' },
|
|
67
69
|
task_list: { method: 'GET', path: '/tasks' },
|
|
68
70
|
link_list: { method: 'GET', path: '/agreements?engagementKind=link' },
|
|
@@ -17,7 +17,6 @@ export interface ProposeTerms {
|
|
|
17
17
|
maxExecutions?: number;
|
|
18
18
|
/** Shared incoming-message allowance; null means unlimited. */
|
|
19
19
|
conversationAllowance?: number | null;
|
|
20
|
-
conversationAllowanceScope?: 'direct' | 'subtree';
|
|
21
20
|
interactionMode?: 'messages' | 'tasks' | 'both';
|
|
22
21
|
/**
|
|
23
22
|
* How `price` reads. `total` (default) escrows one price for the whole
|
|
@@ -140,7 +139,6 @@ export interface DelegateAgreementData {
|
|
|
140
139
|
maxExecutions?: number;
|
|
141
140
|
/** Shared incoming-message allowance; null means unlimited. */
|
|
142
141
|
conversationAllowance?: number | null;
|
|
143
|
-
conversationAllowanceScope?: 'direct' | 'subtree';
|
|
144
142
|
interactionMode?: 'messages' | 'tasks' | 'both';
|
|
145
143
|
agreementDescription?: string;
|
|
146
144
|
payerId?: string;
|
|
@@ -210,7 +208,6 @@ export interface CounterAgreementData {
|
|
|
210
208
|
maxExecutions?: number;
|
|
211
209
|
/** Shared incoming-message allowance; null means unlimited. */
|
|
212
210
|
conversationAllowance?: number | null;
|
|
213
|
-
conversationAllowanceScope?: 'direct' | 'subtree';
|
|
214
211
|
interactionMode?: 'messages' | 'tasks' | 'both';
|
|
215
212
|
description?: string;
|
|
216
213
|
/** What this text drew on. See {@link WriteSource}. */
|
|
@@ -1,9 +1,38 @@
|
|
|
1
|
-
import { type Creds } from '../types.js';
|
|
1
|
+
import { type Creds, type InboxChangesOptions, type InboxChangesResult } from '../types.js';
|
|
2
2
|
export interface AssistantWorkspace {
|
|
3
3
|
orgId: string;
|
|
4
4
|
name: string;
|
|
5
5
|
agentId: string;
|
|
6
6
|
}
|
|
7
|
+
export interface McpEventStatus {
|
|
8
|
+
asOf: string;
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
orgId: string;
|
|
11
|
+
event: 'ziggs.inbox.updated';
|
|
12
|
+
receiptMeaning: string;
|
|
13
|
+
truncated: boolean;
|
|
14
|
+
subscriptions: Array<{
|
|
15
|
+
id: string;
|
|
16
|
+
state: 'active' | 'expired' | 'stopped';
|
|
17
|
+
expiresAt: string;
|
|
18
|
+
lastVerifiedAt: string | null;
|
|
19
|
+
lastCheckedAt: string | null;
|
|
20
|
+
lastWorkerErrorAt: string | null;
|
|
21
|
+
lastAcceptedAt: string | null;
|
|
22
|
+
lastAttempt: {
|
|
23
|
+
at: string;
|
|
24
|
+
httpStatus: number | null;
|
|
25
|
+
outcome: 'accepted' | 'retrying' | 'failed' | null;
|
|
26
|
+
} | null;
|
|
27
|
+
lastFailure: {
|
|
28
|
+
at: string;
|
|
29
|
+
reason: 'network' | 'http' | 'attempts_exhausted' | null;
|
|
30
|
+
httpStatus: number | null;
|
|
31
|
+
} | null;
|
|
32
|
+
nextAttemptAt: string | null;
|
|
33
|
+
stoppedReason: 'unsubscribed' | 'access_revoked' | 'connection_changed' | 'receiver_gone' | null;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
7
36
|
/**
|
|
8
37
|
* The reads a connection makes about itself: which workspaces it works in,
|
|
9
38
|
* and its one inbox across all of them. It never remembers a
|
|
@@ -14,7 +43,7 @@ export declare class AssistantConnectionClient {
|
|
|
14
43
|
private readonly creds;
|
|
15
44
|
private readonly baseUrl;
|
|
16
45
|
constructor(creds: Creds, baseUrl?: string);
|
|
17
|
-
request<T>(path: string, body?: unknown): Promise<T>;
|
|
46
|
+
request<T>(path: string, body?: unknown, signal?: AbortSignal): Promise<T>;
|
|
18
47
|
/** Read existing enabled assistant hires. Provisioning is an explicit sync action. */
|
|
19
48
|
workspaces(): Promise<AssistantWorkspace[]>;
|
|
20
49
|
/** Which of the connection's assistants is on an existing thing. */
|
|
@@ -23,6 +52,9 @@ export declare class AssistantConnectionClient {
|
|
|
23
52
|
choices: AssistantWorkspace[];
|
|
24
53
|
}>;
|
|
25
54
|
inbox(waitSeconds?: number, snapshot?: boolean): Promise<Record<string, unknown>>;
|
|
55
|
+
getChanges(options?: InboxChangesOptions): Promise<InboxChangesResult>;
|
|
56
|
+
/** Receipt diagnostics only: this does not subscribe, renew or wake a host. */
|
|
57
|
+
eventStatus(orgId: string, signal?: AbortSignal): Promise<McpEventStatus>;
|
|
26
58
|
ack(upTo: string, handledResourceIds?: string[]): Promise<unknown>;
|
|
27
59
|
park(agreementId: string): Promise<{
|
|
28
60
|
agreementId: string;
|
|
@@ -15,9 +15,10 @@ export class AssistantConnectionClient {
|
|
|
15
15
|
this.creds = creds;
|
|
16
16
|
this.baseUrl = baseUrl;
|
|
17
17
|
}
|
|
18
|
-
async request(path, body) {
|
|
18
|
+
async request(path, body, signal) {
|
|
19
19
|
const response = await fetch(`${this.baseUrl}/oauth/${path}`, {
|
|
20
20
|
method: body === undefined ? 'GET' : 'POST',
|
|
21
|
+
signal,
|
|
21
22
|
headers: {
|
|
22
23
|
Authorization: `Bearer ${this.creds.operatorKey}`,
|
|
23
24
|
'Content-Type': 'application/json',
|
|
@@ -47,6 +48,18 @@ export class AssistantConnectionClient {
|
|
|
47
48
|
inbox(waitSeconds = 0, snapshot = false) {
|
|
48
49
|
return this.request(`inbox${snapshot ? "/snapshot" : ""}?wait=${waitSeconds}`);
|
|
49
50
|
}
|
|
51
|
+
getChanges(options = {}) {
|
|
52
|
+
const query = new URLSearchParams();
|
|
53
|
+
if (options.cursor !== undefined)
|
|
54
|
+
query.set('cursor', options.cursor);
|
|
55
|
+
if (options.waitSeconds !== undefined)
|
|
56
|
+
query.set('wait', String(options.waitSeconds));
|
|
57
|
+
return this.request(`inbox/changes?${query}`, undefined, options.signal);
|
|
58
|
+
}
|
|
59
|
+
/** Receipt diagnostics only: this does not subscribe, renew or wake a host. */
|
|
60
|
+
eventStatus(orgId, signal) {
|
|
61
|
+
return this.request(`events/status?${new URLSearchParams({ orgId })}`, undefined, signal);
|
|
62
|
+
}
|
|
50
63
|
ack(upTo, handledResourceIds = []) {
|
|
51
64
|
return this.request('inbox/ack', { upTo, handledResourceIds });
|
|
52
65
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InboxAckResult, InboxEnvelope, InboxPeek, InboxReadOptions } from '../types.js';
|
|
1
|
+
import type { InboxAckResult, InboxEnvelope, InboxPeek, InboxReadOptions, InboxChangesOptions, InboxChangesResult } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* The doorbell, not the door: references addressed to this agent
|
|
4
4
|
* since its last ack — never content. Flow: inbox → read → act → ack
|
|
@@ -26,6 +26,9 @@ export declare class InboxClient {
|
|
|
26
26
|
});
|
|
27
27
|
private headers;
|
|
28
28
|
private inboxUrl;
|
|
29
|
+
/** At most 25 retained references per page. Keep cursor for subsequent waits;
|
|
30
|
+
* observation never claims work or acknowledges it. Expired cursors return 410. */
|
|
31
|
+
getChanges(opts?: InboxChangesOptions): Promise<InboxChangesResult>;
|
|
29
32
|
/** Read without acquiring worker ownership or recording receipts. */
|
|
30
33
|
getSnapshot(opts?: InboxReadOptions & {
|
|
31
34
|
signal?: AbortSignal;
|
package/dist/http/InboxClient.js
CHANGED
|
@@ -57,6 +57,18 @@ export class InboxClient {
|
|
|
57
57
|
}
|
|
58
58
|
return url.toString();
|
|
59
59
|
}
|
|
60
|
+
/** At most 25 retained references per page. Keep cursor for subsequent waits;
|
|
61
|
+
* observation never claims work or acknowledges it. Expired cursors return 410. */
|
|
62
|
+
async getChanges(opts = {}) {
|
|
63
|
+
const url = new URL(this.inboxUrl('/inbox/changes', opts));
|
|
64
|
+
if (opts.cursor !== undefined)
|
|
65
|
+
url.searchParams.set('cursor', opts.cursor);
|
|
66
|
+
const res = await fetch(url.toString(), { headers: this.headers(), signal: opts.signal });
|
|
67
|
+
const body = await res.text().catch(() => '');
|
|
68
|
+
if (!res.ok)
|
|
69
|
+
throw pollSurfaceError('InboxClient.getChanges', res, body);
|
|
70
|
+
return JSON.parse(body);
|
|
71
|
+
}
|
|
60
72
|
/** Read without acquiring worker ownership or recording receipts. */
|
|
61
73
|
async getSnapshot(opts = {}) {
|
|
62
74
|
const res = await fetch(this.inboxUrl('/inbox/snapshot', opts), {
|
|
@@ -10,7 +10,6 @@ export interface PublishOfferPayload {
|
|
|
10
10
|
maxExecutions?: number;
|
|
11
11
|
/** Shared incoming-message allowance; null means unlimited. */
|
|
12
12
|
conversationAllowance?: number | null;
|
|
13
|
-
conversationAllowanceScope?: 'direct' | 'subtree';
|
|
14
13
|
interactionMode?: 'messages' | 'tasks' | 'both';
|
|
15
14
|
/** `hire` = claimer becomes the provider's principal on claim. Defaults to `service` server-side. */
|
|
16
15
|
engagementKind?: 'hire' | 'service';
|
|
@@ -21,7 +21,6 @@ export async function proposeUnified(input, creds) {
|
|
|
21
21
|
expiresAt: terms.expiresAt,
|
|
22
22
|
maxExecutions: terms.maxExecutions,
|
|
23
23
|
conversationAllowance: terms.conversationAllowance,
|
|
24
|
-
conversationAllowanceScope: terms.conversationAllowanceScope,
|
|
25
24
|
interactionMode: terms.interactionMode,
|
|
26
25
|
engagementKind: engagementKind,
|
|
27
26
|
billing: terms.billing,
|
package/dist/index.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export type { ContinuationKind, InboxAckDriver, InboxHandling, RepresentedPerson
|
|
|
30
30
|
export { inboxEngagement, isEchoOrDuplicate, isHireWorkOrder, contactPath, formationGuide, marketplaceFormation, liveHireChangedTerms, liveHireConflictFromStatus, withdrawHeldGraph, reminderHonesty, graphReleaseHonesty, hintsFromTasks, } from './engagementGuide.js';
|
|
31
31
|
export type { EngagementGuide, EngagementGuideKind, EngagementOutcome, EngagementTaskHint, ContactPathInput, FormationInput, GraphHonesty, HireTermsHonesty, WaitingOn, } from './engagementGuide.js';
|
|
32
32
|
export { isContextAccessRequest } from './shared/contextAccessRequest.js';
|
|
33
|
-
export { AssistantConnectionClient, type AssistantWorkspace, } from './http/AssistantConnectionClient.js';
|
|
33
|
+
export { AssistantConnectionClient, type AssistantWorkspace, type McpEventStatus, } from './http/AssistantConnectionClient.js';
|
|
34
34
|
export { withAssistantRequest, assistantRequestHeaders } from './http/operatorHeaders.js';
|
|
35
35
|
export { HANDLE_ALPHABET, findHandles, looksLikeHandle, parseHandle, parseRef, type HandleKind } from './handles.js';
|
|
36
36
|
export { describeOperationError, type OperationError } from './shared/operationError.js';
|
|
@@ -22,6 +22,8 @@ export interface OperationError {
|
|
|
22
22
|
* the same shape an open's action recovery has.
|
|
23
23
|
*/
|
|
24
24
|
recovery?: Record<string, unknown>;
|
|
25
|
+
/** Scoped restart position returned when too many observation streams exist. */
|
|
26
|
+
recoveryCursor?: string;
|
|
25
27
|
/** hidden | unreadable, the same outcome open and access_explain give. */
|
|
26
28
|
outcome?: string;
|
|
27
29
|
/** The resource the outcome is about. */
|
|
@@ -104,8 +104,18 @@ export function describeOperationError(input, surface = 'sdk') {
|
|
|
104
104
|
const recovery = typeof input === 'object' && input !== null
|
|
105
105
|
? recoveryIn(input.body)
|
|
106
106
|
: null;
|
|
107
|
+
let recoveryCursor;
|
|
108
|
+
if (shape.code === 'INBOX_OBSERVATION_LIMIT' && input && typeof input === 'object') {
|
|
109
|
+
try {
|
|
110
|
+
const body = JSON.parse(input.body ?? '{}');
|
|
111
|
+
if (typeof body.recoveryCursor === 'string' && /^ibxo1_[0-9a-f-]{36}$/.test(body.recoveryCursor))
|
|
112
|
+
recoveryCursor = body.recoveryCursor;
|
|
113
|
+
}
|
|
114
|
+
catch { /* Malformed recovery metadata does not hide the original refusal. */ }
|
|
115
|
+
}
|
|
107
116
|
const result = {
|
|
108
117
|
...shape,
|
|
118
|
+
...(recoveryCursor ? { recoveryCursor } : {}),
|
|
109
119
|
...(choices ? { choices } : {}),
|
|
110
120
|
...(recovery ? { recovery: typeof recovery.tool === 'string'
|
|
111
121
|
? { ...presentResourceCall(recovery, surface) }
|
package/dist/types.d.ts
CHANGED
|
@@ -526,3 +526,17 @@ export interface InboxPeek {
|
|
|
526
526
|
asOf: string;
|
|
527
527
|
count: number;
|
|
528
528
|
}
|
|
529
|
+
/** Private observation position, renewed on read for 24 idle hours; never pass to ack(). */
|
|
530
|
+
export interface InboxChangesOptions extends InboxReadOptions {
|
|
531
|
+
cursor?: string;
|
|
532
|
+
signal?: AbortSignal;
|
|
533
|
+
}
|
|
534
|
+
export interface InboxChangesResult {
|
|
535
|
+
asOf: string;
|
|
536
|
+
cursor: string;
|
|
537
|
+
expiresAt: string;
|
|
538
|
+
hasMore: boolean;
|
|
539
|
+
deliveries: Array<Pick<InboxDeliveryRef, 'eventId' | 'kind' | 'resourceId' | 'chatId' | 'taskId' | 'agreementId' | 'assigneeId' | 'needsHuman' | 'ts'> & {
|
|
540
|
+
orgId?: string | null;
|
|
541
|
+
}>;
|
|
542
|
+
}
|