@ziggs-ai/api-client 0.28.0 → 0.29.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/dist/capabilities/chat.js +7 -1
- package/dist/capabilities/context.js +14 -6
- package/dist/capabilities/index.d.ts +1 -0
- package/dist/capabilities/index.js +1 -0
- package/dist/capabilities/nextCall.d.ts +4 -2
- package/dist/capabilities/resourceActions.d.ts +3 -0
- package/dist/capabilities/resourceActions.js +9 -0
- package/dist/http/AgreementClient.d.ts +2 -2
- package/dist/http/AgreementClient.js +8 -3
- package/dist/http/ChatClient.d.ts +4 -0
- package/dist/http/ChatClient.js +2 -0
- package/dist/http/ContextOpenClient.d.ts +19 -8
- package/dist/http/ContextReadClient.d.ts +2 -0
- package/dist/http/index.d.ts +1 -1
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
|
@@ -66,6 +66,7 @@ export const openConversationCapability = {
|
|
|
66
66
|
participantIds: { type: 'array', items: { type: 'string' }, description: '1–20 known ids. Without chatId: people, for a separate group. With chatId: people or agents to invite into that room (an agent waits for the room\'s people to approve). Use instead of participantId. Each invitation is authorized separately.' },
|
|
67
67
|
chatId: { type: 'string', description: 'Existing room to invite participantIds into. Never creates another room. Omit creation options and agreementId.' },
|
|
68
68
|
idempotencyKey: { type: 'string', description: 'Required for group creation: a unique key for this conversation, reused unchanged on retries. A different participant set needs a new key.' },
|
|
69
|
+
name: { type: 'string', description: 'Name for a new group, 1–80 characters. Pair rooms and team channels take no name. A retry of the same idempotencyKey keeps the first name. Rename later is PATCH /chats/:chatId by someone who can admit people.' },
|
|
69
70
|
createIfMissing: { type: 'boolean', description: 'Set false to reuse only an existing room for this acting agent and participant. A missing room is refused without creating a replacement.' },
|
|
70
71
|
newChat: {
|
|
71
72
|
type: 'boolean',
|
|
@@ -99,7 +100,10 @@ export const openConversationCapability = {
|
|
|
99
100
|
else if (args.chatId || args.idempotencyKey) {
|
|
100
101
|
throw new Error('chatId and idempotencyKey require participantIds');
|
|
101
102
|
}
|
|
102
|
-
|
|
103
|
+
if (typeof args.name === 'string' && args.name.trim() && !Array.isArray(args.participantIds)) {
|
|
104
|
+
throw new Error('A name is for a new group. Pair rooms take no name; the person is the name.');
|
|
105
|
+
}
|
|
106
|
+
const { chatId, reused, invited, name } = await openConversation({
|
|
103
107
|
...(typeof args.participantId === 'string' ? { participantId: args.participantId } : {}),
|
|
104
108
|
...(Array.isArray(args.participantIds) ? { participantIds: args.participantIds } : {}),
|
|
105
109
|
...(typeof args.chatId === 'string' ? { chatId: args.chatId } : {}),
|
|
@@ -107,6 +111,7 @@ export const openConversationCapability = {
|
|
|
107
111
|
...(args.newChat === true ? { newChat: true } : {}),
|
|
108
112
|
...(typeof args.createIfMissing === 'boolean' ? { createIfMissing: args.createIfMissing } : {}),
|
|
109
113
|
...(typeof args.agreementId === 'string' && args.agreementId ? { agreementId: args.agreementId } : {}),
|
|
114
|
+
...(typeof args.name === 'string' && args.name.trim() ? { name: args.name.trim() } : {}),
|
|
110
115
|
}, fullCreds(env));
|
|
111
116
|
const lister = env.surface === 'mcp' ? 'ziggs_grant_list' : 'grant_list';
|
|
112
117
|
const grantNote = `Use ${lister} with scopeKind ["chat"] to inspect your room grants. Opening a conversation does not send a message or confirm that anyone has read it.`;
|
|
@@ -126,6 +131,7 @@ export const openConversationCapability = {
|
|
|
126
131
|
chatId,
|
|
127
132
|
actingAgentId: fullCreds(env).agentId,
|
|
128
133
|
...(typeof reused === 'boolean' ? { reused } : {}),
|
|
134
|
+
...(name ? { name } : {}),
|
|
129
135
|
...(invited ? { invited } : {}),
|
|
130
136
|
note: `${outcomeNote} ${grantNote}`,
|
|
131
137
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { presentResourceActions } from './resourceActions.js';
|
|
1
2
|
import { ContextReadClient, CONTEXT_READ_TYPES, CONTEXT_READ_VIA, parseVia, viaHint, } from '../http/ContextReadClient.js';
|
|
2
3
|
import { ContextOpenClient } from '../http/ContextOpenClient.js';
|
|
3
4
|
import { ContextGrantsClient, } from '../http/ContextGrantsClient.js';
|
|
@@ -306,9 +307,16 @@ function presentOpenResult(result, env) {
|
|
|
306
307
|
});
|
|
307
308
|
return {
|
|
308
309
|
...result,
|
|
309
|
-
actions: result.
|
|
310
|
+
actions: result.actions
|
|
311
|
+
? [...presentResourceActions(result.actions, env.surface),
|
|
312
|
+
...resumeActions.map(a => ({ ...a, action: 'resume', state: 'not_evaluated' }))]
|
|
313
|
+
: result.access.continuation?.request
|
|
314
|
+
? [requestAccessAction(result.access.continuation.request, env)]
|
|
315
|
+
: result.ref.kind === 'artifact' && result.outcome === 'unreadable'
|
|
316
|
+
? [requestAccessAction({ scopeKind: 'artifact', scopeId: result.ref.id, permission: 'read', durationHours: 24 }, env)]
|
|
317
|
+
: resumeActions,
|
|
310
318
|
actingAgentId: fullCreds(env).agentId,
|
|
311
|
-
...(result.ref.kind === 'artifact' && result.outcome !== 'ok' ? {
|
|
319
|
+
...(!result.actions && result.ref.kind === 'artifact' && result.outcome !== 'ok' ? {
|
|
312
320
|
requestAccessHint: `If a source you already read supplied this artifact reference and its human owner, ${requestTool} scopeKind=artifact can ask that owner for temporary read access without a prior grant. It needs a conversation with the owner; ${chatTool} can open or reuse one, subject to authorization. Discover the request tool's schema before calling it. This response does not confirm existence or ownership. A request grants no access until the human owner approves.`,
|
|
313
321
|
} : {}),
|
|
314
322
|
};
|
|
@@ -318,8 +326,8 @@ export const openCapability = {
|
|
|
318
326
|
names: { sdk: 'open', mcp: 'ziggs_open' },
|
|
319
327
|
title: 'Open a returned resource',
|
|
320
328
|
descriptions: {
|
|
321
|
-
sdk: '
|
|
322
|
-
mcp: '
|
|
329
|
+
sdk: 'Read a returned resource: pass exactly one of artifactId, chatId, taskId, agreementId. The backend resolves access and returns scoped actions with required inputs and recovery calls. Opening executes none of those actions. Extraction pending/failed is not an empty document.',
|
|
330
|
+
mcp: 'Read a returned artifact, chat, task, or agreement: pass exactly one corresponding id. No preliminary grant lookup. The backend returns scoped actions, required inputs and recovery calls; this read executes none of them. Hidden and unknown look the same. Extraction pending/failed is not an empty document.',
|
|
323
331
|
},
|
|
324
332
|
annotation: 'read-only',
|
|
325
333
|
params: {
|
|
@@ -341,8 +349,8 @@ export const accessExplainCapability = {
|
|
|
341
349
|
names: { sdk: 'access_explain', mcp: 'ziggs_access_explain' },
|
|
342
350
|
title: 'Explain access to a resource',
|
|
343
351
|
descriptions: {
|
|
344
|
-
sdk: 'Read-only access explanation for an ordinary returned id. Same one-of artifactId/chatId/taskId/agreementId as open.
|
|
345
|
-
mcp: 'Read-only access explanation for an ordinary returned id (exactly one of artifactId, chatId, taskId, agreementId). No grant id. Rechecks authorization.
|
|
352
|
+
sdk: 'Read-only access explanation for an ordinary returned id. Same one-of artifactId/chatId/taskId/agreementId as open. Returns scoped action states, required inputs and recovery calls. Does not return content and does not request or approve anything.',
|
|
353
|
+
mcp: 'Read-only access explanation for an ordinary returned id (exactly one of artifactId, chatId, taskId, agreementId). No grant id. Rechecks authorization. Returns scoped actions and recovery calls; this call never executes them. Hidden and unknown reveal no labels, owners, excerpts, or counts.',
|
|
346
354
|
},
|
|
347
355
|
annotation: 'read-only',
|
|
348
356
|
params: OPEN_ID_PARAMS,
|
|
@@ -18,3 +18,4 @@ export { ARTIFACT_CAPABILITIES, recordArtifactCapability, listArtifactsCapabilit
|
|
|
18
18
|
export { CHAT_CAPABILITIES, openConversationCapability, presentSendResult, type SendPresentation, } from './chat.js';
|
|
19
19
|
export { EVERYDAY_MCP_TOOLS, EVERYDAY_DESTRUCTIVE_MCP, EVERYDAY_NO_SDK_TWIN, EVERYDAY_SDK_TOOLS, } from './everyday.js';
|
|
20
20
|
export { annotationForSdkTool } from './toolLane.js';
|
|
21
|
+
export { presentResourceActions } from './resourceActions.js';
|
|
@@ -18,3 +18,4 @@ export { ARTIFACT_CAPABILITIES, recordArtifactCapability, listArtifactsCapabilit
|
|
|
18
18
|
export { CHAT_CAPABILITIES, openConversationCapability, presentSendResult, } from './chat.js';
|
|
19
19
|
export { EVERYDAY_MCP_TOOLS, EVERYDAY_DESTRUCTIVE_MCP, EVERYDAY_NO_SDK_TWIN, EVERYDAY_SDK_TOOLS, } from './everyday.js';
|
|
20
20
|
export { annotationForSdkTool } from './toolLane.js';
|
|
21
|
+
export { presentResourceActions } from './resourceActions.js';
|
|
@@ -4,7 +4,9 @@ import type { CapabilityDefinition, CapabilityEnv } from './types.js';
|
|
|
4
4
|
* One next step: the tool the calling surface registers, any args already
|
|
5
5
|
* known, and why.
|
|
6
6
|
*
|
|
7
|
-
* Ready means
|
|
7
|
+
* Ready means the call has complete arguments and no declared hold; it is
|
|
8
|
+
* not an authorization decision. The server checks permission on execution.
|
|
9
|
+
* Incomplete means a required
|
|
8
10
|
* argument is missing or an address field is not an address — the suggestion
|
|
9
11
|
* still names the tool, and `missing` says what has to be filled first.
|
|
10
12
|
*
|
|
@@ -19,7 +21,7 @@ export interface NextCall {
|
|
|
19
21
|
args?: Record<string, unknown>;
|
|
20
22
|
/** One clause: what running this achieves, or what is still missing. */
|
|
21
23
|
why: string;
|
|
22
|
-
/**
|
|
24
|
+
/** Arguments are complete and no hold is declared; does not prove authority. */
|
|
23
25
|
ready: boolean;
|
|
24
26
|
/** Required argument names that are absent or not an address. */
|
|
25
27
|
missing?: readonly string[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Bind canonical tool names without changing the backend's decision or scope. */
|
|
2
|
+
export function presentResourceActions(actions, surface) {
|
|
3
|
+
const toolName = (name) => surface === 'mcp' && !name.startsWith('ziggs_') ? `ziggs_${name}` : name;
|
|
4
|
+
const call = (value) => ({ ...value, tool: toolName(value.tool) });
|
|
5
|
+
return actions.map(action => ({ ...action,
|
|
6
|
+
...(action.tool ? { tool: toolName(action.tool) } : {}),
|
|
7
|
+
...(action.recovery ? { recovery: call(action.recovery) } : {}),
|
|
8
|
+
}));
|
|
9
|
+
}
|
|
@@ -190,8 +190,8 @@ export declare function resolveMyPendingApprovalPartyId(agreement: Agreement, op
|
|
|
190
190
|
* Record this party's approval decision on an agreement
|
|
191
191
|
* (`PUT /agreements/:agreementId/approvals/:partyId`).
|
|
192
192
|
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
193
|
+
* Use the partyId from the server's approvalAction. Agents need covering
|
|
194
|
+
* approval authority even for their own slot; the server rechecks it on PUT.
|
|
195
195
|
* Canonical for hire, service, link, and request proposals.
|
|
196
196
|
*/
|
|
197
197
|
export declare function approveAgreementAsParty(agreementId: string, partyId: string, status: 'approved' | 'rejected', creds: Creds): Promise<Agreement>;
|
|
@@ -53,6 +53,7 @@ export function linkSummary(a) {
|
|
|
53
53
|
// chat with. Dropping it here is what that looked like: the server sent the
|
|
54
54
|
// peer and the allow-list ate it before any caller saw it.
|
|
55
55
|
...(a.peer ? { peer: a.peer } : {}),
|
|
56
|
+
...(a.approvalAction ? { approvalAction: a.approvalAction } : {}),
|
|
56
57
|
...(a.description ? { description: a.description } : {}),
|
|
57
58
|
// Seat bookkeeping on an open invite — link state, not commerce.
|
|
58
59
|
...(a.linkInvite ? { linkInvite: a.linkInvite } : {}),
|
|
@@ -222,7 +223,11 @@ export async function respondToAgreement(agreementId, action, creds, opts = {})
|
|
|
222
223
|
if (!agreement) {
|
|
223
224
|
throw new Error(`Agreement ${agreementId} not found`);
|
|
224
225
|
}
|
|
225
|
-
const
|
|
226
|
+
const approval = agreement.approvalAction;
|
|
227
|
+
if (approval && (approval.state !== 'available' || !approval.partyId)) {
|
|
228
|
+
throw new Error(`${approval.explanation}${opts.appUrl ? ` Review: ${opts.appUrl}` : ''}`);
|
|
229
|
+
}
|
|
230
|
+
const partyId = approval?.partyId ?? resolveMyPendingApprovalPartyId(agreement, {
|
|
226
231
|
ownerUserId: opts.ownerUserId,
|
|
227
232
|
agentId: creds.agentId,
|
|
228
233
|
});
|
|
@@ -288,8 +293,8 @@ export function resolveMyPendingApprovalPartyId(agreement, opts) {
|
|
|
288
293
|
* Record this party's approval decision on an agreement
|
|
289
294
|
* (`PUT /agreements/:agreementId/approvals/:partyId`).
|
|
290
295
|
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
296
|
+
* Use the partyId from the server's approvalAction. Agents need covering
|
|
297
|
+
* approval authority even for their own slot; the server rechecks it on PUT.
|
|
293
298
|
* Canonical for hire, service, link, and request proposals.
|
|
294
299
|
*/
|
|
295
300
|
export async function approveAgreementAsParty(agreementId, partyId, status, creds) {
|
|
@@ -26,6 +26,8 @@ export interface OpenConversationInput {
|
|
|
26
26
|
participantIds?: string[];
|
|
27
27
|
chatId?: string;
|
|
28
28
|
idempotencyKey?: string;
|
|
29
|
+
/** Name for a new group. Pair rooms take no name. */
|
|
30
|
+
name?: string;
|
|
29
31
|
newChat?: boolean;
|
|
30
32
|
agreementId?: string;
|
|
31
33
|
createIfMissing?: boolean;
|
|
@@ -38,6 +40,7 @@ export declare function openConversation(participant: string | OpenConversationI
|
|
|
38
40
|
chatId: string;
|
|
39
41
|
reused?: boolean;
|
|
40
42
|
invited?: ChatOpenInvite[];
|
|
43
|
+
name?: string;
|
|
41
44
|
}>;
|
|
42
45
|
export interface SendChatMessageInput {
|
|
43
46
|
/**
|
|
@@ -158,6 +161,7 @@ export declare class ChatClient {
|
|
|
158
161
|
chatId: string;
|
|
159
162
|
reused?: boolean;
|
|
160
163
|
invited?: ChatOpenInvite[];
|
|
164
|
+
name?: string;
|
|
161
165
|
}>;
|
|
162
166
|
addMember(input: AddChatMemberInput): Promise<AddChatMemberResult>;
|
|
163
167
|
sendMessage(input: SendChatMessageInput): Promise<SendChatMessageResult>;
|
package/dist/http/ChatClient.js
CHANGED
|
@@ -38,12 +38,14 @@ export async function openConversation(participant, creds, { newChat = false, ag
|
|
|
38
38
|
// the room — defaulting to false would report a reused conversation as fresh,
|
|
39
39
|
// which is worse than saying nothing.
|
|
40
40
|
const reused = data['reused'];
|
|
41
|
+
const name = data['name'];
|
|
41
42
|
const invited = Array.isArray(data['invited'])
|
|
42
43
|
? data['invited']
|
|
43
44
|
: undefined;
|
|
44
45
|
return {
|
|
45
46
|
chatId: data['chatId'],
|
|
46
47
|
...(typeof reused === 'boolean' ? { reused } : {}),
|
|
48
|
+
...(typeof name === 'string' && name ? { name } : {}),
|
|
47
49
|
...(invited ? { invited } : {}),
|
|
48
50
|
};
|
|
49
51
|
}
|
|
@@ -14,16 +14,25 @@ export interface ContextOpenBody {
|
|
|
14
14
|
after?: string;
|
|
15
15
|
limit?: number;
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
/** Backend-evaluated action, scoped to a resource. Never a permission token. */
|
|
18
|
+
export interface ResourceActionCall {
|
|
19
|
+
tool: string;
|
|
20
|
+
args: Record<string, unknown>;
|
|
21
|
+
required?: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface ResourceAction extends Partial<ResourceActionCall> {
|
|
24
|
+
action: string;
|
|
25
|
+
state: 'available' | 'needs_decision' | 'unavailable' | 'not_evaluated';
|
|
26
|
+
reasonCode?: string;
|
|
27
|
+
reason?: unknown;
|
|
28
|
+
scope?: {
|
|
29
|
+
kind: string;
|
|
30
|
+
id: string;
|
|
31
|
+
agreementId?: string;
|
|
32
|
+
};
|
|
33
|
+
recovery?: ResourceActionCall;
|
|
24
34
|
}
|
|
25
35
|
export interface ContextOpenAccess {
|
|
26
|
-
abilities: ContextOpenAbilities;
|
|
27
36
|
summary: string;
|
|
28
37
|
document?: {
|
|
29
38
|
empty: boolean;
|
|
@@ -42,6 +51,8 @@ export interface ContextOpenAccess {
|
|
|
42
51
|
};
|
|
43
52
|
}
|
|
44
53
|
export interface ContextOpenResult {
|
|
54
|
+
/** Optional for servers predating resource action projections. */
|
|
55
|
+
actions?: ResourceAction[];
|
|
45
56
|
outcome: ContextOpenOutcome;
|
|
46
57
|
ref: ContextOpenRef;
|
|
47
58
|
access: ContextOpenAccess;
|
|
@@ -57,6 +57,8 @@ export interface ContextSnapshotParticipant {
|
|
|
57
57
|
[key: string]: unknown;
|
|
58
58
|
}
|
|
59
59
|
export interface ContextSnapshotResult {
|
|
60
|
+
/** Server-resolved orientation; writes recheck authority. */
|
|
61
|
+
workBrief?: Record<string, unknown>;
|
|
60
62
|
work?: Record<string, unknown>;
|
|
61
63
|
history: unknown[];
|
|
62
64
|
agreements: unknown[];
|
package/dist/http/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type { ArtifactVisibility, ListArtifactsOptions, ListArtifactsQuery, List
|
|
|
10
10
|
export { ContextReadClient, CONTEXT_READ_TYPES, CONTEXT_READ_VIA, VIA_KINDS, parseVia, viaHint, } from './ContextReadClient.js';
|
|
11
11
|
export type { ContextReadType, ContextReadQuery, ContextReadEnvelope, ContextSnapshotResult, ContextSnapshotParticipant, ViaKind, } from './ContextReadClient.js';
|
|
12
12
|
export { ContextOpenClient, CONTEXT_OPEN_KINDS } from './ContextOpenClient.js';
|
|
13
|
-
export type { ContextOpenKind, ContextOpenOutcome, ContextOpenRef, ContextOpenBody,
|
|
13
|
+
export type { ContextOpenKind, ContextOpenOutcome, ContextOpenRef, ContextOpenBody, ResourceAction, ResourceActionCall, ContextOpenAccess, ContextOpenResult, ContextExplainResult, } from './ContextOpenClient.js';
|
|
14
14
|
export { ContextDiscoveryClient } from './ContextDiscoveryClient.js';
|
|
15
15
|
export type { DiscoverableItem } from './ContextDiscoveryClient.js';
|
|
16
16
|
export { IntroductionsClient } from './IntroductionsClient.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -176,6 +176,11 @@ export interface AgreementApprovalEntry {
|
|
|
176
176
|
heldReason?: string | null;
|
|
177
177
|
}
|
|
178
178
|
export interface Agreement {
|
|
179
|
+
approvalAction?: {
|
|
180
|
+
state: 'available' | 'needs_decision' | 'unavailable';
|
|
181
|
+
partyId?: string;
|
|
182
|
+
explanation: string;
|
|
183
|
+
};
|
|
179
184
|
agreementId: string;
|
|
180
185
|
parentAgreementId?: string | null;
|
|
181
186
|
rootAgreementId?: string | null;
|