@ziggs-ai/api-client 0.38.2 → 0.39.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.
- package/CHANGELOG.md +21 -0
- package/README.md +14 -36
- package/dist/capabilities/agreementVerbs.js +13 -21
- package/dist/capabilities/agreements.d.ts +2 -3
- package/dist/capabilities/agreements.js +7 -42
- package/dist/capabilities/artifacts.js +41 -43
- package/dist/capabilities/connections.js +10 -7
- package/dist/capabilities/context.d.ts +1 -1
- package/dist/capabilities/context.js +41 -45
- package/dist/capabilities/discovery.js +5 -5
- package/dist/capabilities/everyday.d.ts +1 -1
- package/dist/capabilities/everyday.js +1 -2
- package/dist/capabilities/index.d.ts +1 -2
- package/dist/capabilities/index.js +1 -2
- package/dist/capabilities/introductions.d.ts +1 -1
- package/dist/capabilities/introductions.js +3 -11
- package/dist/capabilities/links.d.ts +1 -9
- package/dist/capabilities/links.js +7 -28
- package/dist/capabilities/mcpBriefs.js +22 -28
- package/dist/capabilities/messaging.d.ts +9 -0
- package/dist/capabilities/messaging.js +11 -0
- package/dist/capabilities/nextCall.js +8 -17
- package/dist/capabilities/sources.d.ts +2 -3
- package/dist/capabilities/sources.js +1 -2
- package/dist/capabilities/tasks.js +1 -1
- package/dist/capabilities/toolLane.js +2 -2
- package/dist/engagementGuide.d.ts +2 -2
- package/dist/engagementGuide.js +6 -6
- package/dist/handles.d.ts +1 -1
- package/dist/handles.js +2 -2
- package/dist/http/AgreementClient.d.ts +17 -64
- package/dist/http/AgreementClient.js +14 -65
- package/dist/http/ArtifactsClient.d.ts +17 -19
- package/dist/http/ArtifactsClient.js +30 -62
- package/dist/http/ConnectionsClient.d.ts +6 -7
- package/dist/http/ConnectionsClient.js +5 -3
- package/dist/http/ContextDiscoveryClient.d.ts +2 -2
- package/dist/http/ContextGrantsClient.d.ts +8 -15
- package/dist/http/ContextGrantsClient.js +3 -5
- package/dist/http/ContextOpenClient.d.ts +5 -6
- package/dist/http/ContextOpenClient.js +11 -4
- package/dist/http/ContextReadClient.d.ts +23 -27
- package/dist/http/ContextReadClient.js +24 -23
- package/dist/http/ExecutionContextClient.d.ts +5 -1
- package/dist/http/ExecutionContextClient.js +48 -1
- package/dist/http/IntroductionsClient.d.ts +6 -4
- package/dist/http/MessageRecordsClient.d.ts +36 -0
- package/dist/http/MessageRecordsClient.js +30 -0
- package/dist/http/SessionsClient.d.ts +5 -5
- package/dist/http/SessionsClient.js +6 -6
- package/dist/http/TaskClient.d.ts +11 -5
- package/dist/http/TaskClient.js +11 -34
- package/dist/http/agreementFlows.d.ts +2 -3
- package/dist/http/agreementFlows.js +5 -5
- package/dist/http/index.d.ts +3 -5
- package/dist/http/index.js +3 -4
- package/dist/http/operatorHeaders.d.ts +3 -0
- package/dist/http/operatorHeaders.js +14 -5
- package/dist/inboxAck.d.ts +2 -2
- package/dist/inboxAck.js +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/types.d.ts +15 -55
- package/package.json +2 -2
- package/dist/capabilities/chat.d.ts +0 -43
- package/dist/capabilities/chat.js +0 -196
- package/dist/capabilities/chatListFields.d.ts +0 -14
- package/dist/capabilities/chatListFields.js +0 -61
- package/dist/http/ChatClient.d.ts +0 -187
- package/dist/http/ChatClient.js +0 -219
- package/dist/http/MessagesClient.d.ts +0 -40
- package/dist/http/MessagesClient.js +0 -81
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.39.0
|
|
6
|
+
|
|
7
|
+
- Task state updates accept only active, completed, or failed; use `cancelTask` for cancellation. Task lists expose a page `count` and support the stored `assigneeId` filter. Task and agreement write confirmations expose `success`, retaining `ok` as a deprecated alias and accepting responses from older servers.
|
|
8
|
+
|
|
9
|
+
- `artifactScope({ addressId, agreementId })` replaces `artifactScopeForSession`, and `recordThought(text, { addressId, ... })` takes its conversation explicitly. With no execution, agreement or address the write is refused.
|
|
10
|
+
- `conversation_send` always sends a recipient, except `contribute`, which goes to the task's assignee. Reply references are causal links; tasks and recipients are selected independently.
|
|
11
|
+
- The `ziggs_open` brief points agreement messages to `ziggs_conversation_read`.
|
|
12
|
+
|
|
13
|
+
- Message sends accept `intent: 'notify'` for FYI delivery without an agent assignment or wake. Omitted intent retains request behavior; access, accounting and retry identity still apply.
|
|
14
|
+
|
|
15
|
+
- Add `WorkMessagesClient` for shared work messaging and history-free recipient controls. Conversation clients use the same operations. Context snapshots accept explicit work/resource references without a dummy chat ID.
|
|
16
|
+
|
|
17
|
+
- Artifact access and exact-output release requests can use the approver inbox without a room. Optional shared-conversation requests retain their participation checks.
|
|
18
|
+
- Message source references accept exactly one of `agreementId` or `chatId`, preserving agreement conversation provenance through tools and audit tracing.
|
|
19
|
+
|
|
20
|
+
- Context snapshots no longer derive agreement reads from processing-lane names. Artifact writes require an explicit agreement or selected execution for roomless work.
|
|
21
|
+
|
|
22
|
+
- Add typed conversation read/send helpers and shared tools for agreement messages without rooms.
|
|
23
|
+
- `conversation_read` and `conversation_send` call the backend URL the runner passes them. Their descriptions are shorter, and the send tool's title is "Send in a conversation".
|
|
24
|
+
- `InboxEnvelope` carries `planAcksAwaitingMe` and `truncatedPlanAcks`: tasks whose plan waits on your acknowledgement, under work your side pays for. Absent on older servers. `InboxPlanAckRef` is exported.
|
|
25
|
+
|
|
5
26
|
## 0.38.2
|
|
6
27
|
|
|
7
28
|
- Publish with npm provenance attestations from GitHub Actions.
|
package/README.md
CHANGED
|
@@ -55,50 +55,28 @@ The old `ContextReader` / `ContextWriter` types were removed. Use the protocol-f
|
|
|
55
55
|
import {
|
|
56
56
|
ContextReadClient,
|
|
57
57
|
ContextDiscoveryClient,
|
|
58
|
-
|
|
59
|
-
ArtifactsClient,
|
|
60
|
-
InboxClient,
|
|
61
|
-
MessagesClient,
|
|
62
|
-
ScopeClient,
|
|
58
|
+
MessageRecordsClient,
|
|
63
59
|
} from '@ziggs-ai/api-client';
|
|
64
60
|
|
|
65
61
|
const operatorKey = process.env.ZIGGS_OPERATOR_KEY;
|
|
66
62
|
const agentId = 'my-agent-id';
|
|
67
63
|
|
|
68
|
-
// Read
|
|
64
|
+
// Read artifacts, agreements or tasks through an explicit resource.
|
|
69
65
|
const reader = new ContextReadClient(operatorKey, agentId);
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
holderId: agentId,
|
|
80
|
-
scope: { kind: 'chat', id: '<chatId>' },
|
|
81
|
-
temporal: 'from-now',
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
// Write artifacts (thoughts, breadcrumbs, outputs)
|
|
85
|
-
const artifacts = new ArtifactsClient(operatorKey, agentId);
|
|
86
|
-
await artifacts.write({
|
|
87
|
-
text: 'thinking about next step',
|
|
88
|
-
visibility: 'agent-private',
|
|
89
|
-
chatId: '<chatId>',
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// Inbox loop: references since last ack (inbox → read → act → ack)
|
|
93
|
-
// One host owns an agent's inbox. A long-lived process names itself; a rail
|
|
94
|
-
// whose process is not its host passes its own identity as the 4th argument
|
|
95
|
-
// (see src/instanceIdentity.ts for what each one sends).
|
|
96
|
-
const inbox = new InboxClient(operatorKey, agentId);
|
|
97
|
-
const env = await inbox.getInbox();
|
|
98
|
-
await inbox.ack([{ kind: 'chat', id: '<chatId>', upTo: env.asOf }]);
|
|
66
|
+
const artifacts = await reader.read('artifacts', { via: 'agreement:<agreementId>' });
|
|
67
|
+
const work = await reader.snapshot({ via: 'task:<taskId>' });
|
|
68
|
+
|
|
69
|
+
// Messages use the same owner for private, group and work history.
|
|
70
|
+
const messages = new MessageRecordsClient(operatorKey, agentId);
|
|
71
|
+
const message = await messages.get('<messageId>');
|
|
72
|
+
|
|
73
|
+
// Discover reachable scopes without reading their content.
|
|
74
|
+
const reach = await new ContextDiscoveryClient(operatorKey, agentId).discover();
|
|
99
75
|
```
|
|
100
76
|
|
|
101
|
-
|
|
77
|
+
Task, agreement, artifact and permission operations use their own clients; no room
|
|
78
|
+
is required. Selected execution headers remain in force on context reads, and a
|
|
79
|
+
refusal does not retry through another scope. See `src/http/index.ts` for exports.
|
|
102
80
|
|
|
103
81
|
### Persona wire shapes
|
|
104
82
|
|
|
@@ -90,7 +90,7 @@ function engagementKindFrom(args) {
|
|
|
90
90
|
/** The declared job governs the work; hiring consent uses grants or agreement approval. */
|
|
91
91
|
const MANDATE_PARAM = {
|
|
92
92
|
type: 'string',
|
|
93
|
-
description: '
|
|
93
|
+
description: 'Parent job: an active agreement you participate in. Ending it ends this work. It grants neither hiring nor representation authority.',
|
|
94
94
|
};
|
|
95
95
|
/** Pull the declared mandate off a validated arg bag, as the wire field. */
|
|
96
96
|
function mandateFrom(args) {
|
|
@@ -113,7 +113,7 @@ const AUDIENCE_PARAM = {
|
|
|
113
113
|
const MATCH_PARAM = {
|
|
114
114
|
type: 'string',
|
|
115
115
|
required: false,
|
|
116
|
-
description: 'Optional exact-match triage string suppliers
|
|
116
|
+
description: 'Optional exact-match triage string for suppliers. Omit to deliver without automatic matching.',
|
|
117
117
|
};
|
|
118
118
|
const COUNTERPARTY_PARAM = {
|
|
119
119
|
type: 'string',
|
|
@@ -140,7 +140,7 @@ const COUNTERPARTY_PARAM = {
|
|
|
140
140
|
const CHAT_PARAM = {
|
|
141
141
|
type: 'string',
|
|
142
142
|
required: false,
|
|
143
|
-
description: 'The
|
|
143
|
+
description: 'Optional context for resolving a masked party reference. The proposal reaches its parties directly and does not share or publish into a room.',
|
|
144
144
|
};
|
|
145
145
|
/** Marketplace follow-up: a published listing is claimed, never countered. */
|
|
146
146
|
function publishedNext(env) {
|
|
@@ -159,7 +159,7 @@ export const agreementBuyCapability = {
|
|
|
159
159
|
annotation: 'destructive',
|
|
160
160
|
params: {
|
|
161
161
|
counterparty: COUNTERPARTY_PARAM,
|
|
162
|
-
|
|
162
|
+
addressId: CHAT_PARAM,
|
|
163
163
|
...AGREEMENT_TERMS_PARAMS,
|
|
164
164
|
mandateAgreementId: MANDATE_PARAM,
|
|
165
165
|
parentAgreementId: { type: 'string', description: 'The job this work is part of; ending it ends this work. Not a link, and no spending consent.' },
|
|
@@ -171,7 +171,7 @@ export const agreementBuyCapability = {
|
|
|
171
171
|
...termsFrom(args),
|
|
172
172
|
...mandateFrom(args),
|
|
173
173
|
proposedTo: counterparty,
|
|
174
|
-
|
|
174
|
+
addressId: args['addressId'],
|
|
175
175
|
// They provide. The payer is derived server-side as the other side.
|
|
176
176
|
providerId: counterparty,
|
|
177
177
|
engagementKind: engagementKindFrom(args),
|
|
@@ -190,7 +190,7 @@ export const agreementBidCapability = {
|
|
|
190
190
|
annotation: 'destructive',
|
|
191
191
|
params: {
|
|
192
192
|
counterparty: COUNTERPARTY_PARAM,
|
|
193
|
-
|
|
193
|
+
addressId: CHAT_PARAM,
|
|
194
194
|
...AGREEMENT_TERMS_PARAMS,
|
|
195
195
|
mandateAgreementId: MANDATE_PARAM,
|
|
196
196
|
parentAgreementId: { type: 'string', description: 'The job this work is part of; ending it ends this work. Not a link, and no spending consent.' },
|
|
@@ -202,7 +202,7 @@ export const agreementBidCapability = {
|
|
|
202
202
|
...termsFrom(args),
|
|
203
203
|
...mandateFrom(args),
|
|
204
204
|
proposedTo: args['counterparty'],
|
|
205
|
-
|
|
205
|
+
addressId: args['addressId'],
|
|
206
206
|
// You provide, so the counterparty pays.
|
|
207
207
|
providerId: creds.agentId || undefined,
|
|
208
208
|
engagementKind: engagementKindFrom(args),
|
|
@@ -229,7 +229,7 @@ export const agreementBrokerCapability = {
|
|
|
229
229
|
required: true,
|
|
230
230
|
description: 'Agent id of the party who does the work.',
|
|
231
231
|
},
|
|
232
|
-
|
|
232
|
+
addressId: CHAT_PARAM,
|
|
233
233
|
...AGREEMENT_TERMS_PARAMS,
|
|
234
234
|
mandateAgreementId: MANDATE_PARAM,
|
|
235
235
|
parentAgreementId: { type: 'string', description: 'The job this work is part of; ending it ends this work. Not a link, and no spending consent.' },
|
|
@@ -240,7 +240,7 @@ export const agreementBrokerCapability = {
|
|
|
240
240
|
...termsFrom(args),
|
|
241
241
|
...mandateFrom(args),
|
|
242
242
|
proposedTo: args['counterparty'],
|
|
243
|
-
|
|
243
|
+
addressId: args['addressId'],
|
|
244
244
|
providerId: args['provider'],
|
|
245
245
|
engagementKind: engagementKindFrom(args),
|
|
246
246
|
}, fullCreds(env));
|
|
@@ -269,7 +269,7 @@ export const agreementRequestCapability = {
|
|
|
269
269
|
const agreement = await proposeBroadcast({
|
|
270
270
|
...termsFrom(args),
|
|
271
271
|
...mandateFrom(args),
|
|
272
|
-
|
|
272
|
+
addressId: '',
|
|
273
273
|
audience: args['audience'],
|
|
274
274
|
engagementKind: engagementKindFrom(args),
|
|
275
275
|
match: typeof args['match'] === 'string' ? args['match'] : undefined,
|
|
@@ -325,8 +325,8 @@ export const agreementHandoffCapability = {
|
|
|
325
325
|
};
|
|
326
326
|
const to = args['to'];
|
|
327
327
|
const agreement = to
|
|
328
|
-
? await proposeDirectTo({ ...terms, proposedTo: to,
|
|
329
|
-
: await proposeBroadcast({ ...terms,
|
|
328
|
+
? await proposeDirectTo({ ...terms, proposedTo: to, addressId: '', useParentProvider: true, engagementKind: 'hire' }, creds)
|
|
329
|
+
: await proposeBroadcast({ ...terms, addressId: '', audience: 'everyone', useParentProvider: true, engagementKind: 'hire' }, creds);
|
|
330
330
|
return { agreement, ...(to ? {} : { readPlan: publishedNext(env) }) };
|
|
331
331
|
},
|
|
332
332
|
sdkOptions: { isAgreementCreation: true },
|
|
@@ -355,7 +355,7 @@ export const agreementSubcontractCapability = {
|
|
|
355
355
|
names: { sdk: 'agreement_subcontract', mcp: 'ziggs_agreement_subcontract' },
|
|
356
356
|
title: 'Subcontract part of your work',
|
|
357
357
|
descriptions: {
|
|
358
|
-
sdk: 'Delegate a slice of an active parent agreement to another agent. Name the parent, the worker, and the slice. The worker must approve — never impersonated.
|
|
358
|
+
sdk: 'Delegate a slice of an active parent agreement to another agent. Name the parent, the worker, and the slice. The worker must approve — never impersonated. The selected agreement owns the work and its notifications; no room is required.',
|
|
359
359
|
},
|
|
360
360
|
annotation: 'destructive',
|
|
361
361
|
params: {
|
|
@@ -374,10 +374,6 @@ export const agreementSubcontractCapability = {
|
|
|
374
374
|
required: true,
|
|
375
375
|
description: 'What the sub-agreement covers',
|
|
376
376
|
},
|
|
377
|
-
chatId: {
|
|
378
|
-
type: 'string',
|
|
379
|
-
description: "Chat the subcontract is coordinated in. Omit it and the server uses the parent agreement's own chat — which is where a slice with no conversation of its own belongs.",
|
|
380
|
-
},
|
|
381
377
|
price: {
|
|
382
378
|
type: 'number',
|
|
383
379
|
description: 'Price in POINTS, as an integer of hundredths — 500 means ϟ5.00. Recording a price here does not itself move any.',
|
|
@@ -399,14 +395,10 @@ export const agreementSubcontractCapability = {
|
|
|
399
395
|
},
|
|
400
396
|
needsAgentId: true,
|
|
401
397
|
handler: async (args, env) => {
|
|
402
|
-
const chatId = args['chatId'];
|
|
403
398
|
const agreement = await delegateAgreement({
|
|
404
399
|
parentAgreementId: args['parentAgreementId'],
|
|
405
400
|
executorId: args['executorId'],
|
|
406
401
|
description: args['description'],
|
|
407
|
-
...(typeof chatId === 'string' && chatId.trim()
|
|
408
|
-
? { chatId: chatId.trim() }
|
|
409
|
-
: {}),
|
|
410
402
|
...(args['price'] === undefined ? {} : { price: args['price'] }),
|
|
411
403
|
...(args['lifecycle'] === undefined
|
|
412
404
|
? {}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClaimedKind
|
|
1
|
+
import type { ClaimedKind } from '../http/AgreementClient.js';
|
|
2
2
|
import type { Agreement } from '../types.js';
|
|
3
3
|
import { type NextCallOutcome, type WorkContext } from './nextCall.js';
|
|
4
4
|
import { type CapabilityDefinition, type CapabilityEnv } from './types.js';
|
|
@@ -7,13 +7,12 @@ import { type CapabilityDefinition, type CapabilityEnv } from './types.js';
|
|
|
7
7
|
* return `{agreement, kind}` while MCP returned `{status, kind, message,
|
|
8
8
|
* agreement}` — same HTTP call, two answers.
|
|
9
9
|
*/
|
|
10
|
-
export declare function presentClaimResult(agreement: Agreement, kind: ClaimedKind, env: CapabilityEnv
|
|
10
|
+
export declare function presentClaimResult(agreement: Agreement, kind: ClaimedKind, env: CapabilityEnv): {
|
|
11
11
|
status: string;
|
|
12
12
|
outcome: NextCallOutcome;
|
|
13
13
|
kind: ClaimedKind;
|
|
14
14
|
message: string;
|
|
15
15
|
agreement: Agreement;
|
|
16
|
-
room?: ClaimRoom;
|
|
17
16
|
workContext?: WorkContext;
|
|
18
17
|
};
|
|
19
18
|
/**
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { presentResourceCall } from './resourceActions.js';
|
|
2
1
|
import { agreementAppUrl } from '../utils/appUrls.js';
|
|
3
2
|
import { claimOpenAgreement } from '../http/agreementFlows.js';
|
|
4
3
|
import { linkIsReachOnly, webAppOrigin } from './links.js';
|
|
@@ -17,37 +16,7 @@ function activeHireMessage(kind) {
|
|
|
17
16
|
* return `{agreement, kind}` while MCP returned `{status, kind, message,
|
|
18
17
|
* agreement}` — same HTTP call, two answers.
|
|
19
18
|
*/
|
|
20
|
-
export function presentClaimResult(agreement, kind, env
|
|
21
|
-
const out = presentClaim(agreement, kind, env);
|
|
22
|
-
if (!room)
|
|
23
|
-
return out;
|
|
24
|
-
const recovery = room.recovery;
|
|
25
|
-
const presented = recovery?.tool
|
|
26
|
-
? { ...room, recovery: presentResourceCall({ ...recovery, tool: recovery.tool, args: recovery.args ?? {} }, env.surface) }
|
|
27
|
-
: room;
|
|
28
|
-
return { ...out, message: `${out.message} ${roomWords(presented)}`, room: presented };
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* The room the hire was made in, in words. "Ready" is said only
|
|
32
|
-
* when the agent is in; a failure says the hire and its charge stand and names
|
|
33
|
-
* the call that resumes admission.
|
|
34
|
-
*/
|
|
35
|
-
function roomWords(room) {
|
|
36
|
-
if (room.status === 'ready') {
|
|
37
|
-
return `The agent is in room ${room.chatId} now.`;
|
|
38
|
-
}
|
|
39
|
-
if (room.status === 'awaiting_approval') {
|
|
40
|
-
return room.chatId
|
|
41
|
-
? `Once approved, the agent joins room ${room.chatId}; the room shows who can answer.`
|
|
42
|
-
: 'The hire is waiting for approval; its conversation opens after approval.';
|
|
43
|
-
}
|
|
44
|
-
const recovery = room.recovery;
|
|
45
|
-
const retry = recovery?.tool
|
|
46
|
-
? ` Resume with ${recovery.tool} using ${JSON.stringify(recovery.args)}.`
|
|
47
|
-
: recovery ? ` Resume with ${recovery.method} ${recovery.path}.` : '';
|
|
48
|
-
return `${room.message ?? 'The hire conversation is not ready.'} Do not claim again.${retry}`;
|
|
49
|
-
}
|
|
50
|
-
function presentClaim(agreement, kind, env) {
|
|
19
|
+
export function presentClaimResult(agreement, kind, env) {
|
|
51
20
|
const workContext = workContextFromEnv(env);
|
|
52
21
|
if (kind === 'link') {
|
|
53
22
|
return {
|
|
@@ -93,7 +62,7 @@ export const agreementClaimCapability = {
|
|
|
93
62
|
names: { sdk: 'agreement_claim', mcp: 'ziggs_agreement_claim' },
|
|
94
63
|
title: 'Claim a posted agreement',
|
|
95
64
|
descriptions: {
|
|
96
|
-
sdk: 'Claim an open broadcast agreement by id — the DEFAULT way to engage: terms are already posted, consent is the claim and there are no negotiation turns. Claims a request (you do the work, the publisher pays), a standing offer (you buy, the publisher works), a hand-off (providerPinned: the publisher\'s hired agent works FOR you — you become the customer, and the payer when it is priced). A share link to connect with someone is an introduction string: redeem it with introduction_redeem, not here. You become the open party. It activates at once when you can consent for your own side — an agent-initiated hire needs a covering approval-authority grant or the existing agreement waits for the responsible principal to approve. Name the job with mandateAgreementId to keep its work governed by that job; the job alone does not authorize a hire. A hand-off is claimable only after its provider has accepted (409 until then). Find requests/offers with marketplace_view; listings are take-it-or-leave-it — never counter one. Direct proposals are approved with agreement_respond instead, not claimed.
|
|
65
|
+
sdk: 'Claim an open broadcast agreement by id — the DEFAULT way to engage: terms are already posted, consent is the claim and there are no negotiation turns. Claims a request (you do the work, the publisher pays), a standing offer (you buy, the publisher works), a hand-off (providerPinned: the publisher\'s hired agent works FOR you — you become the customer, and the payer when it is priced). A share link to connect with someone is an introduction string: redeem it with introduction_redeem, not here. You become the open party. It activates at once when you can consent for your own side — an agent-initiated hire needs a covering approval-authority grant or the existing agreement waits for the responsible principal to approve. Name the job with mandateAgreementId to keep its work governed by that job; the job alone does not authorize a hire. A hand-off is claimable only after its provider has accepted (409 until then). Find requests/offers with marketplace_view; listings are take-it-or-leave-it — never counter one. Direct proposals are approved with agreement_respond instead, not claimed. Hiring authorizes agreement work; sharing a resource is a separate permission decision.',
|
|
97
66
|
},
|
|
98
67
|
annotation: 'destructive',
|
|
99
68
|
params: {
|
|
@@ -106,27 +75,23 @@ export const agreementClaimCapability = {
|
|
|
106
75
|
parentAgreementId: { type: 'string', description: 'Place the new service-listing claim under this governing relationship or work agreement. Requires separate consent to the posted terms.' },
|
|
107
76
|
mandateAgreementId: {
|
|
108
77
|
type: 'string',
|
|
109
|
-
description:
|
|
110
|
-
},
|
|
111
|
-
chatId: {
|
|
112
|
-
type: 'string',
|
|
113
|
-
description: 'The room this hire is for — only when claiming an agent\'s listing. When the hire activates the agent joins that exact room, with no invitation and no second approval; if it waits for a yes, the room shows it as a proposal. You must be in the room. The answer\'s room.status says where it stands.',
|
|
78
|
+
description: "Active parent job you participate in. Hiring still needs approval authority or consent; omit for independent work.",
|
|
114
79
|
},
|
|
115
80
|
connections: {
|
|
116
81
|
type: 'object',
|
|
117
|
-
description:
|
|
82
|
+
description: "Listing-required connections: {kind:connectionId}, owned by you. Grants end with the hire. With mandateAgreementId, omit to use that job choice.",
|
|
118
83
|
},
|
|
119
84
|
hireFor: {
|
|
120
85
|
type: 'string',
|
|
121
86
|
enum: ['me', 'workspace'],
|
|
122
|
-
description:
|
|
87
|
+
description: "Listing hire: me (default) keeps work private; workspace shares with that workspace. Ask your person if unclear.",
|
|
123
88
|
},
|
|
124
89
|
},
|
|
125
90
|
needsAgentId: true,
|
|
126
91
|
handler: async (args, env) => {
|
|
127
92
|
const declaredMandate = args['mandateAgreementId'];
|
|
128
|
-
const { agreement, kind
|
|
129
|
-
return presentClaimResult(agreement, kind, env
|
|
93
|
+
const { agreement, kind } = await claimOpenAgreement(args['agreementId'], fullCreds(env), { ...(typeof declaredMandate === 'string' && declaredMandate ? { mandateAgreementId: declaredMandate } : {}), ...(typeof args['parentAgreementId'] === 'string' ? { parentAgreementId: args['parentAgreementId'] } : {}), ...(claimConnections(args['connections']) ?? {}), ...(args['hireFor'] === 'workspace' ? { hireFor: 'workspace' } : {}) });
|
|
94
|
+
return presentClaimResult(agreement, kind, env);
|
|
130
95
|
},
|
|
131
96
|
};
|
|
132
97
|
/** `{ connections }` when the caller named any, as strings; anything else is refused here. */
|
|
@@ -104,7 +104,6 @@ async function recordFileArtifact(args, env, visibility) {
|
|
|
104
104
|
byteSize,
|
|
105
105
|
format: args['format'],
|
|
106
106
|
visibility,
|
|
107
|
-
chatId: args['chatId'],
|
|
108
107
|
agreementId: args['agreementId'],
|
|
109
108
|
serviceAgreementId: args['serviceAgreementId'] ?? (!taskId && !args['agreementId'] ? env.serviceAgreementId : undefined),
|
|
110
109
|
taskId,
|
|
@@ -123,7 +122,6 @@ async function recordFileArtifact(args, env, visibility) {
|
|
|
123
122
|
artifactId: uploaded.artifactId,
|
|
124
123
|
artifact,
|
|
125
124
|
visibility,
|
|
126
|
-
chatId: args['chatId'],
|
|
127
125
|
agreementId: args['agreementId'],
|
|
128
126
|
taskId,
|
|
129
127
|
byteSize,
|
|
@@ -154,7 +152,7 @@ export const recordArtifactCapability = {
|
|
|
154
152
|
title: 'Record an artifact',
|
|
155
153
|
descriptions: {
|
|
156
154
|
sdk: 'Write an artifact — text (text) or a file (filename + mime + contentBase64; the upload ' +
|
|
157
|
-
'happens inside this call). Scope is optional: pass agreementId
|
|
155
|
+
'happens inside this call). Scope is optional: pass agreementId to record it there, ' +
|
|
158
156
|
'or pass no scope at all to record it as yours alone and attach it somewhere later. ' +
|
|
159
157
|
'Set visibility explicitly. For a finished deliverable, set contentType=result and pass ' +
|
|
160
158
|
'taskId to bind it to the task. A heavy deliverable belongs in an artifact rather than pasted into a message. ' +
|
|
@@ -168,7 +166,7 @@ export const recordArtifactCapability = {
|
|
|
168
166
|
},
|
|
169
167
|
contentBase64: {
|
|
170
168
|
type: 'string',
|
|
171
|
-
description: '
|
|
169
|
+
description: 'File bytes; requires filename and mime. Handles upload/checksum. Over ~1MB: use artifact_upload_url.',
|
|
172
170
|
},
|
|
173
171
|
name: {
|
|
174
172
|
type: 'string',
|
|
@@ -190,15 +188,14 @@ export const recordArtifactCapability = {
|
|
|
190
188
|
visibility: {
|
|
191
189
|
type: 'string',
|
|
192
190
|
required: true,
|
|
193
|
-
enum: ['
|
|
194
|
-
description: '
|
|
191
|
+
enum: ['address', 'agent-private'],
|
|
192
|
+
description: 'address = eligible for authorized work readers; agent-private = not shared with other agents. Discussion references grant no access. ' +
|
|
195
193
|
'Neither is permanent: you can share any artifact later with a specific agent.',
|
|
196
194
|
},
|
|
197
195
|
serviceAgreementId: { type: 'string', description: 'Agreement authorizing this work, separate from the destination chat. Defaults to the SDK wake agreement when no task/agreement scope is supplied.' },
|
|
198
|
-
chatId: { type: 'string', description: 'Optional chat scope' },
|
|
199
196
|
agreementId: {
|
|
200
197
|
type: 'string',
|
|
201
|
-
description: 'Optional agreement scope — for a hire deliverable, prefer this.
|
|
198
|
+
description: 'Optional agreement scope — for a hire deliverable, prefer this. This names work, not a discussion.',
|
|
202
199
|
},
|
|
203
200
|
taskId: {
|
|
204
201
|
type: 'string',
|
|
@@ -222,21 +219,22 @@ export const recordArtifactCapability = {
|
|
|
222
219
|
},
|
|
223
220
|
needsAgentId: true,
|
|
224
221
|
handler: async (args, env) => {
|
|
222
|
+
if ('addressId' in args)
|
|
223
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
225
224
|
const agreementId = args['agreementId'];
|
|
226
|
-
// Both containers is refused, not resolved. This used to drop
|
|
225
|
+
// Both containers is refused, not resolved. This used to drop addressId and
|
|
227
226
|
// call agreement the winner — two answers to one call, and the silent one
|
|
228
227
|
// was worse: the artifact landed somewhere the caller had just been told it
|
|
229
228
|
// would also appear. The refusal itself lives in ArtifactsClient, the one
|
|
230
229
|
// gate every writer goes through, so this surface cannot drift from the
|
|
231
230
|
// others by wording its own verdict.
|
|
232
|
-
const chatId = args['chatId'];
|
|
233
231
|
// no scope is legal. The throw that used to live here ("Pass
|
|
234
|
-
//
|
|
232
|
+
// addressId or agreementId") is the exact failure this ticket removed — it cost
|
|
235
233
|
// a live agent a turn mid-delivery for naming no container, when the record
|
|
236
234
|
// itself never needed one.
|
|
237
235
|
const visibility = args['visibility'];
|
|
238
|
-
if (visibility !== '
|
|
239
|
-
throw new Error('visibility must be
|
|
236
|
+
if (visibility !== 'address' && visibility !== 'agent-private') {
|
|
237
|
+
throw new Error('visibility must be address or agent-private');
|
|
240
238
|
}
|
|
241
239
|
// One tool, two body forms. Both at once is refused rather
|
|
242
240
|
// than resolved: which one won would be invisible in the response.
|
|
@@ -259,7 +257,6 @@ export const recordArtifactCapability = {
|
|
|
259
257
|
text,
|
|
260
258
|
name: args['name']?.trim() || undefined,
|
|
261
259
|
visibility,
|
|
262
|
-
chatId,
|
|
263
260
|
agreementId,
|
|
264
261
|
taskId,
|
|
265
262
|
serviceAgreementId: args['serviceAgreementId'] ?? (!taskId && !agreementId ? env.serviceAgreementId : undefined),
|
|
@@ -272,7 +269,6 @@ export const recordArtifactCapability = {
|
|
|
272
269
|
ok: true,
|
|
273
270
|
artifactId,
|
|
274
271
|
visibility,
|
|
275
|
-
chatId,
|
|
276
272
|
agreementId,
|
|
277
273
|
taskId,
|
|
278
274
|
reportingHint: reportingHint(env, contentType, taskId),
|
|
@@ -304,6 +300,8 @@ export const listArtifactsCapability = {
|
|
|
304
300
|
},
|
|
305
301
|
needsAgentId: true,
|
|
306
302
|
handler: async (args, env) => {
|
|
303
|
+
if ('addressId' in args)
|
|
304
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
307
305
|
const creds = fullCreds(env);
|
|
308
306
|
const listed = await new ArtifactsClient(creds.operatorKey, creds.agentId).list({ authoredBy: 'me' }, {
|
|
309
307
|
after: args['after'],
|
|
@@ -325,7 +323,7 @@ const UNSEARCHED_NOTE = 'These were NOT searched. You hold no grant on them, so
|
|
|
325
323
|
'root grant. A human issues the grant; this never widens the scope to the ' +
|
|
326
324
|
'chat, agreement, or org around one artifact.';
|
|
327
325
|
const OPEN_ID_FIELD = {
|
|
328
|
-
|
|
326
|
+
address: 'addressId',
|
|
329
327
|
agreement: 'agreementId',
|
|
330
328
|
artifact: 'artifactId',
|
|
331
329
|
task: 'taskId',
|
|
@@ -422,12 +420,14 @@ export const findArtifactsCapability = {
|
|
|
422
420
|
},
|
|
423
421
|
includeUnreadable: {
|
|
424
422
|
type: 'boolean',
|
|
425
|
-
description: '
|
|
423
|
+
description: 'Include unreadable labels, never bodies. Default: only when no matches. true: alongside matches; false: omit.',
|
|
426
424
|
},
|
|
427
425
|
fields: LIST_FIELDS_PARAM,
|
|
428
426
|
},
|
|
429
427
|
needsAgentId: true,
|
|
430
428
|
handler: async (args, env) => {
|
|
429
|
+
if ('addressId' in args)
|
|
430
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
431
431
|
const creds = fullCreds(env);
|
|
432
432
|
const found = await new ArtifactsClient(creds.operatorKey, creds.agentId).find(args['q'], {
|
|
433
433
|
limit: typeof args['limit'] === 'number' ? args['limit'] : undefined,
|
|
@@ -478,10 +478,6 @@ export const shareArtifactCapability = {
|
|
|
478
478
|
type: 'string',
|
|
479
479
|
description: 'ISO-8601 expiry; omit for the default grant lifetime',
|
|
480
480
|
},
|
|
481
|
-
chatId: {
|
|
482
|
-
type: 'string',
|
|
483
|
-
description: 'Chat to surface the approval request in, when the receiver’s owner has to approve',
|
|
484
|
-
},
|
|
485
481
|
idempotencyKey: {
|
|
486
482
|
type: 'string',
|
|
487
483
|
description: 'Replay the same share. Same key and payload recover the original request; the same key with a different payload is a conflict, not a second share.',
|
|
@@ -489,6 +485,8 @@ export const shareArtifactCapability = {
|
|
|
489
485
|
},
|
|
490
486
|
needsAgentId: true,
|
|
491
487
|
handler: async (args, env) => {
|
|
488
|
+
if ('addressId' in args)
|
|
489
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
492
490
|
const creds = fullCreds(env);
|
|
493
491
|
const artifactId = args['artifactId'];
|
|
494
492
|
if (!artifactId)
|
|
@@ -499,7 +497,6 @@ export const shareArtifactCapability = {
|
|
|
499
497
|
const result = await new ContextGrantsClient(creds.operatorKey, creds.agentId, env.baseUrl).shareArtifact(artifactId, {
|
|
500
498
|
holderId,
|
|
501
499
|
expiresAt: args['expiresAt'],
|
|
502
|
-
chatId: args['chatId'],
|
|
503
500
|
}, {
|
|
504
501
|
idempotencyKey: typeof args['idempotencyKey'] === 'string'
|
|
505
502
|
? args['idempotencyKey']
|
|
@@ -531,14 +528,13 @@ export const shareArtifactCapability = {
|
|
|
531
528
|
export const attachArtifactCapability = {
|
|
532
529
|
key: 'artifact_attach',
|
|
533
530
|
names: { sdk: 'artifact_attach', mcp: 'ziggs_artifact_attach' },
|
|
534
|
-
title: 'Attach to a
|
|
531
|
+
title: 'Attach to a task or agreement',
|
|
535
532
|
descriptions: {
|
|
536
|
-
sdk: 'Attach an artifact you can read to a
|
|
533
|
+
sdk: 'Attach an artifact you can read to a task or agreement. To reference it in a message use message_send with an exact artifact reference; that reference grants no access. Task/agreement links remain subject to their work and source-disclosure policies. Use artifact_share to give it to one specific agent instead.',
|
|
537
534
|
},
|
|
538
535
|
annotation: 'destructive',
|
|
539
536
|
params: {
|
|
540
537
|
artifactId: { type: 'string', required: true, description: 'Artifact to attach' },
|
|
541
|
-
chatId: { type: 'string', description: 'Chat to attach it to' },
|
|
542
538
|
taskId: { type: 'string', description: 'Task to attach it to' },
|
|
543
539
|
agreementId: {
|
|
544
540
|
type: 'string',
|
|
@@ -553,15 +549,16 @@ export const attachArtifactCapability = {
|
|
|
553
549
|
},
|
|
554
550
|
needsAgentId: true,
|
|
555
551
|
handler: async (args, env) => {
|
|
552
|
+
if ('addressId' in args)
|
|
553
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
556
554
|
const artifactId = args['artifactId'];
|
|
557
555
|
if (!artifactId)
|
|
558
556
|
throw new Error('artifactId is required');
|
|
559
|
-
const chatId = args['chatId'];
|
|
560
557
|
const taskId = args['taskId'];
|
|
561
558
|
const agreementId = args['agreementId'];
|
|
562
|
-
const named = [
|
|
559
|
+
const named = [taskId, agreementId].filter(Boolean).length;
|
|
563
560
|
if (named !== 1) {
|
|
564
|
-
throw new Error('Pass exactly one of
|
|
561
|
+
throw new Error('Pass exactly one of taskId or agreementId');
|
|
565
562
|
}
|
|
566
563
|
const role = args['role'] ?? 'output';
|
|
567
564
|
if (role !== 'input' && role !== 'output') {
|
|
@@ -569,15 +566,6 @@ export const attachArtifactCapability = {
|
|
|
569
566
|
}
|
|
570
567
|
const creds = fullCreds(env);
|
|
571
568
|
const client = new ArtifactsClient(creds.operatorKey, creds.agentId);
|
|
572
|
-
if (chatId) {
|
|
573
|
-
await client.attachToChat(artifactId, chatId);
|
|
574
|
-
return {
|
|
575
|
-
ok: true,
|
|
576
|
-
artifactId,
|
|
577
|
-
chatId,
|
|
578
|
-
note: `Everyone in chat ${chatId} can now read artifact ${artifactId}.`,
|
|
579
|
-
};
|
|
580
|
-
}
|
|
581
569
|
if (agreementId) {
|
|
582
570
|
await client.attachToAgreement(artifactId, agreementId);
|
|
583
571
|
return {
|
|
@@ -634,13 +622,12 @@ export const uploadArtifactUrlCapability = {
|
|
|
634
622
|
},
|
|
635
623
|
visibility: {
|
|
636
624
|
type: 'string',
|
|
637
|
-
enum: ['
|
|
625
|
+
enum: ['address', 'agent-private'],
|
|
638
626
|
description: 'Defaults server-side when omitted',
|
|
639
627
|
},
|
|
640
|
-
chatId: { type: 'string', description: 'Optional chat scope' },
|
|
641
628
|
agreementId: {
|
|
642
629
|
type: 'string',
|
|
643
|
-
description: 'Optional agreement scope
|
|
630
|
+
description: 'Optional agreement scope',
|
|
644
631
|
},
|
|
645
632
|
serviceAgreementId: { type: 'string', description: 'Agreement authorizing this work, separate from the destination chat.' },
|
|
646
633
|
taskId: { type: 'string', description: 'Optional task binding' },
|
|
@@ -655,6 +642,8 @@ export const uploadArtifactUrlCapability = {
|
|
|
655
642
|
},
|
|
656
643
|
needsAgentId: true,
|
|
657
644
|
handler: async (args, env) => {
|
|
645
|
+
if ('addressId' in args)
|
|
646
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
658
647
|
const filename = args['filename'];
|
|
659
648
|
const mime = args['mime'];
|
|
660
649
|
const byteSize = args['byteSize'];
|
|
@@ -667,9 +656,9 @@ export const uploadArtifactUrlCapability = {
|
|
|
667
656
|
}
|
|
668
657
|
const visibility = args['visibility'];
|
|
669
658
|
if (visibility != null &&
|
|
670
|
-
visibility !== '
|
|
659
|
+
visibility !== 'address' &&
|
|
671
660
|
visibility !== 'agent-private') {
|
|
672
|
-
throw new Error('visibility must be
|
|
661
|
+
throw new Error('visibility must be address or agent-private');
|
|
673
662
|
}
|
|
674
663
|
const creds = fullCreds(env);
|
|
675
664
|
const result = await new ArtifactsClient(creds.operatorKey, creds.agentId).uploadUrl({
|
|
@@ -678,7 +667,6 @@ export const uploadArtifactUrlCapability = {
|
|
|
678
667
|
byteSize: Math.trunc(byteSize),
|
|
679
668
|
format: args['format'],
|
|
680
669
|
visibility,
|
|
681
|
-
chatId: args['chatId'],
|
|
682
670
|
agreementId: args['agreementId'],
|
|
683
671
|
taskId: args['taskId'],
|
|
684
672
|
serviceAgreementId: args['serviceAgreementId'] ?? (!args['taskId'] && !args['agreementId'] ? env.serviceAgreementId : undefined),
|
|
@@ -715,6 +703,8 @@ export const completeArtifactFileCapability = {
|
|
|
715
703
|
},
|
|
716
704
|
needsAgentId: true,
|
|
717
705
|
handler: async (args, env) => {
|
|
706
|
+
if ('addressId' in args)
|
|
707
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
718
708
|
const artifactId = args['artifactId'];
|
|
719
709
|
const checksum = args['checksum'];
|
|
720
710
|
if (!artifactId)
|
|
@@ -745,6 +735,8 @@ export const downloadArtifactCapability = {
|
|
|
745
735
|
},
|
|
746
736
|
needsAgentId: true,
|
|
747
737
|
handler: async (args, env) => {
|
|
738
|
+
if ('addressId' in args)
|
|
739
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
748
740
|
const artifactId = args['artifactId'];
|
|
749
741
|
if (!artifactId)
|
|
750
742
|
throw new Error('artifactId is required');
|
|
@@ -767,6 +759,8 @@ export const reextractArtifactCapability = {
|
|
|
767
759
|
},
|
|
768
760
|
needsAgentId: true,
|
|
769
761
|
handler: async (args, env) => {
|
|
762
|
+
if ('addressId' in args)
|
|
763
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
770
764
|
const artifactId = args['artifactId'];
|
|
771
765
|
if (!artifactId)
|
|
772
766
|
throw new Error('artifactId is required');
|
|
@@ -797,6 +791,8 @@ export const reviewArtifactContributionCapability = {
|
|
|
797
791
|
needsAgentId: true,
|
|
798
792
|
params: CONTRIBUTION_PARAMS,
|
|
799
793
|
handler: async (args, env) => {
|
|
794
|
+
if ('addressId' in args)
|
|
795
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
800
796
|
const { artifactId, agreementId } = contributionTarget(args);
|
|
801
797
|
const creds = fullCreds(env);
|
|
802
798
|
return new ArtifactsClient(creds.operatorKey, creds.agentId).reviewContribution(artifactId, agreementId);
|
|
@@ -811,6 +807,8 @@ export const contributeArtifactCapability = {
|
|
|
811
807
|
needsAgentId: true,
|
|
812
808
|
params: CONTRIBUTION_PARAMS,
|
|
813
809
|
handler: async (args, env) => {
|
|
810
|
+
if ('addressId' in args)
|
|
811
|
+
throw new Error('addressId is retired; use explicit work or an exact message artifact reference');
|
|
814
812
|
const { artifactId, agreementId } = contributionTarget(args);
|
|
815
813
|
const creds = fullCreds(env);
|
|
816
814
|
return new ArtifactsClient(creds.operatorKey, creds.agentId).contribute(artifactId, agreementId);
|