@ziggs-ai/api-client 0.32.0 → 0.33.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/context.js +15 -7
- package/dist/http/ArtifactsClient.d.ts +4 -7
- package/dist/http/ArtifactsClient.js +2 -2
- package/dist/http/ContextGrantsClient.d.ts +2 -1
- package/dist/http/ContextGrantsClient.js +1 -1
- package/dist/http/ContextOpenClient.d.ts +2 -0
- package/dist/http/InboxClient.d.ts +3 -1
- package/dist/http/InboxClient.js +1 -0
- package/dist/http/grants.d.ts +2 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/types.d.ts +2 -1
- package/package.json +2 -2
|
@@ -293,6 +293,10 @@ function openBodyFromArgs(args) {
|
|
|
293
293
|
return body;
|
|
294
294
|
}
|
|
295
295
|
function presentOpenResult(result, env) {
|
|
296
|
+
// Resource-routed OAuth calls let the backend select the assistant. Their
|
|
297
|
+
// local credentials have no agent id, so only the response can name it.
|
|
298
|
+
const actingAgentId = result.actingAgentId !== undefined
|
|
299
|
+
? result.actingAgentId : fullCreds(env).agentId || undefined;
|
|
296
300
|
// Expose a request-only next action, never execute it as part of a read.
|
|
297
301
|
const requestTool = env.surface === 'mcp' ? 'ziggs_access_request' : 'access_request';
|
|
298
302
|
const chatTool = env.surface === 'mcp' ? 'ziggs_chat_open' : 'chat_open';
|
|
@@ -302,7 +306,7 @@ function presentOpenResult(result, env) {
|
|
|
302
306
|
return [];
|
|
303
307
|
const row = item;
|
|
304
308
|
const ask = row.grantRequest;
|
|
305
|
-
if (row.status !== 'active' || !isContextAccessRequest(ask) || ask.holderId !==
|
|
309
|
+
if (row.status !== 'active' || !isContextAccessRequest(ask) || !actingAgentId || ask.holderId !== actingAgentId || !ask.scope?.id || !['artifact', 'chat', 'agreement', 'task'].includes(ask.scope.kind ?? ''))
|
|
306
310
|
return [];
|
|
307
311
|
return [{ kind: 'resume', tool: env.surface === 'mcp' ? 'ziggs_open' : 'open', args: { [`${ask.scope.kind}Id`]: ask.scope.id }, effect: 'read_only', note: 'Approval recorded. Open the original scope; the server rechecks expiry and revocation.' }];
|
|
308
312
|
});
|
|
@@ -316,7 +320,7 @@ function presentOpenResult(result, env) {
|
|
|
316
320
|
: result.ref.kind === 'artifact' && result.outcome === 'unreadable'
|
|
317
321
|
? [requestAccessAction({ scopeKind: 'artifact', scopeId: result.ref.id, permission: 'read', durationHours: 24 }, env)]
|
|
318
322
|
: resumeActions,
|
|
319
|
-
actingAgentId:
|
|
323
|
+
...(actingAgentId !== undefined ? { actingAgentId } : {}),
|
|
320
324
|
...(!result.actions && result.ref.kind === 'artifact' && result.outcome !== 'ok' ? {
|
|
321
325
|
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.`,
|
|
322
326
|
} : {}),
|
|
@@ -409,15 +413,15 @@ export const accessRequestCapability = {
|
|
|
409
413
|
title: 'Request access for yourself',
|
|
410
414
|
annotation: 'write', needsAgentId: true,
|
|
411
415
|
descriptions: {
|
|
412
|
-
sdk: 'Request optional bounded access to one artifact, chat, agreement context or task. Creates only a pending approval; never grants access or approves. Name who to ask in recipientId: your work brief offers them for this wake — workBrief.actingFor.customer.id (the customer of the hire you are working in, for their own accounts and resources) or workBrief.actingFor.operator.id (your operator, for tools you bring). Anyone else is refused, and the refusal lists who you can ask. Artifact requests also need chatId, the conversation they approve in. Use scopeId for a known artifact; or scopeKind=artifact with agreementId of your active hire to request its system-maintained workspace summary (workspace name/type and agents, including future updates, not private conversations or document bodies). Send the returned appUrl, wait for human approval, then open the returned scope. Hiring alone grants no source access. Revocation and expiry are checked by the system.',
|
|
413
|
-
mcp: 'Request access for this agent, never approve or grant it. Use scopeId for an artifact, chat, agreement or task; scopeKind=artifact with agreementId of your active hire resolves its system-maintained workspace summary artifact. Name who to ask in recipientId; a pick the server cannot use here is refused, and the refusal lists who you can ask. Artifact requests also require chatId. Explain the scope and lifetime; summary access includes future updates only to that artifact. Surface appUrl and wait for human approval; then open the returned scope. Pending grants no access.',
|
|
416
|
+
sdk: 'Request optional bounded access to one artifact, chat, agreement context or task. Creates only a pending approval; never grants access or approves. Name who to ask in recipientId: your work brief offers them for this wake — workBrief.actingFor.customer.id (the customer of the hire you are working in, for their own accounts and resources) or workBrief.actingFor.operator.id (your operator, for tools you bring). Anyone else is refused, and the refusal lists who you can ask. Artifact requests also need chatId, the conversation they approve in. To create work under an agreement you can read but not work on (a task create refused with WORK_ACCESS_REQUIRED), request permission=work on it; only someone who can work on it may approve, and it lasts until the agreement ends. Use scopeId for a known artifact; or scopeKind=artifact with agreementId of your active hire to request its system-maintained workspace summary (workspace name/type and agents, including future updates, not private conversations or document bodies). Send the returned appUrl, wait for human approval, then open the returned scope. Hiring alone grants no source access. Revocation and expiry are checked by the system.',
|
|
417
|
+
mcp: 'Request access for this agent, never approve or grant it. Use scopeId for an artifact, chat, agreement or task; scopeKind=artifact with agreementId of your active hire resolves its system-maintained workspace summary artifact. Name who to ask in recipientId; a pick the server cannot use here is refused, and the refusal lists who you can ask. Artifact requests also require chatId. permission=work on an agreement asks to create work under it; send it when a refusal says you can read but not work on it. Explain the scope and lifetime; summary access includes future updates only to that artifact. Surface appUrl and wait for human approval; then open the returned scope. Pending grants no access.',
|
|
414
418
|
},
|
|
415
419
|
params: {
|
|
416
420
|
scopeKind: { type: 'string', required: true, enum: ['artifact', 'chat', 'agreement', 'task'] },
|
|
417
421
|
scopeId: { type: 'string', description: 'Original resource id. Omit when using a hire agreementId to request its workspace summary.' },
|
|
418
422
|
agreementId: { type: 'string', description: 'Artifact scope only: current hire id, used instead of scopeId to request the system-maintained workspace summary.' },
|
|
419
423
|
reason: { type: 'string', required: true, description: 'Why access is needed and who will receive the reply or summary' },
|
|
420
|
-
permission: { type: 'string', enum: ['read', 'reply'], description: 'read by default; reply is read and reply and is only valid for a chat' },
|
|
424
|
+
permission: { type: 'string', enum: ['read', 'reply', 'work'], description: 'read by default; reply is read and reply and is only valid for a chat; work lets you create work under an agreement you can read but not work on, and lasts until it ends' },
|
|
421
425
|
temporal: { type: 'string', enum: ['from-now', 'from-start'], description: 'Chat history requested; default from-now. Earlier messages need from-start. Other resources use from-start.' },
|
|
422
426
|
durationHours: { type: 'number', description: 'Integer 1–168 hours after approval; default 24' },
|
|
423
427
|
chatId: { type: 'string', description: 'Artifact or workspace requests only: existing conversation with the owner' },
|
|
@@ -437,8 +441,10 @@ export const accessRequestCapability = {
|
|
|
437
441
|
if (Boolean(agreementId) === Boolean(scopeId) || (agreementId && scopeKind !== 'artifact'))
|
|
438
442
|
throw new Error('Provide scopeId, or agreementId for its workspace summary artifact');
|
|
439
443
|
const permission = args.permission ?? 'read';
|
|
440
|
-
if (!['read', 'reply'].includes(String(permission)) || (permission === 'reply' && scopeKind !== 'chat'))
|
|
444
|
+
if (!['read', 'reply', 'work'].includes(String(permission)) || (permission === 'reply' && scopeKind !== 'chat'))
|
|
441
445
|
throw new Error('Only chat access may request reply permission');
|
|
446
|
+
if (permission === 'work' && scopeKind !== 'agreement')
|
|
447
|
+
throw new Error('Only agreement access may request work permission');
|
|
442
448
|
if (args.temporal !== undefined && (!['from-now', 'from-start'].includes(String(args.temporal)) || (scopeKind !== 'chat' && args.temporal === 'from-now')))
|
|
443
449
|
throw new Error('Only chats support from-now access');
|
|
444
450
|
const durationHours = args.durationHours ?? 24;
|
|
@@ -451,8 +457,10 @@ export const accessRequestCapability = {
|
|
|
451
457
|
durationHours, chatId: args.chatId,
|
|
452
458
|
recipientId: typeof args.recipientId === 'string' ? args.recipientId.trim() : undefined,
|
|
453
459
|
}, { idempotencyKey: args.idempotencyKey, laneId: creds.laneId });
|
|
460
|
+
const actingAgentId = result.actingAgentId ?? (creds.agentId || undefined);
|
|
454
461
|
return {
|
|
455
|
-
...result, outcome: 'pending', state: 'requested',
|
|
462
|
+
...result, outcome: 'pending', state: 'requested',
|
|
463
|
+
...(actingAgentId ? { actingAgentId } : {}),
|
|
456
464
|
scope: result.scope ?? { kind: scopeKind, id: scopeId },
|
|
457
465
|
appUrl: `${(env.webUrl ?? 'https://ziggsai.com').replace(/\/$/, '')}/app/agreements/${encodeURIComponent(result.agreementId)}`,
|
|
458
466
|
resumeAfterApproval: { tool: env.surface === 'mcp' ? 'ziggs_open' : 'open', args: result.scope ? { [`${result.scope.kind}Id`]: result.scope.id } : { [`${scopeKind}Id`]: scopeId } },
|
|
@@ -90,14 +90,10 @@ export interface WriteArtifactInput {
|
|
|
90
90
|
* When the deliverable lives outside Ziggs: both provider and http(s) URL.
|
|
91
91
|
* The `text` is the in-Ziggs summary. Ziggs does not fetch the URL.
|
|
92
92
|
*/
|
|
93
|
-
externalRef?:
|
|
94
|
-
provider: string;
|
|
95
|
-
url: string;
|
|
96
|
-
};
|
|
93
|
+
externalRef?: ArtifactExternalRef;
|
|
97
94
|
}
|
|
98
|
-
/** Every file format the server stores
|
|
99
|
-
export
|
|
100
|
-
export type ArtifactFileFormat = (typeof ARTIFACT_FILE_FORMATS)[number];
|
|
95
|
+
/** Every file format the server stores — the contracts list, re-exported under the names callers already use. */
|
|
96
|
+
export { ARTIFACT_FILE_FORMATS, type ArtifactExternalRef, type ArtifactFileFormat } from '@ziggs-ai/contracts';
|
|
101
97
|
export interface ArtifactUploadUrlInput {
|
|
102
98
|
/** Short list name. Defaults to filename on the server when omitted. */
|
|
103
99
|
name?: string;
|
|
@@ -137,6 +133,7 @@ export type ArtifactFileView = Record<string, unknown> & {
|
|
|
137
133
|
extractionError?: string | null;
|
|
138
134
|
filename?: string | null;
|
|
139
135
|
};
|
|
136
|
+
import type { ArtifactExternalRef, ArtifactFileFormat } from '@ziggs-ai/contracts';
|
|
140
137
|
export { AGREEMENT_LANE_PREFIX } from '@ziggs-ai/contracts';
|
|
141
138
|
export declare function artifactScopeForSession(sessionId: string): {
|
|
142
139
|
chatId: string;
|
|
@@ -13,8 +13,8 @@ export const ARTIFACT_INLINE_TEXT_OVER_LIMIT_HINT = `text exceeds ${ARTIFACT_INL
|
|
|
13
13
|
'For larger content use ziggs_artifact_upload_url (file rail), or split into ' +
|
|
14
14
|
'an index artifact plus part artifacts and list the part ids in the index. ' +
|
|
15
15
|
'The server does not auto-split.';
|
|
16
|
-
/** Every file format the server stores
|
|
17
|
-
export
|
|
16
|
+
/** Every file format the server stores — the contracts list, re-exported under the names callers already use. */
|
|
17
|
+
export { ARTIFACT_FILE_FORMATS } from '@ziggs-ai/contracts';
|
|
18
18
|
function resolveUploadBytes(input) {
|
|
19
19
|
if (input.content != null) {
|
|
20
20
|
return Buffer.isBuffer(input.content)
|
|
@@ -102,7 +102,7 @@ export declare class ContextGrantsClient {
|
|
|
102
102
|
scopeId?: string;
|
|
103
103
|
agreementId?: string;
|
|
104
104
|
reason: string;
|
|
105
|
-
permission?: 'read' | 'reply';
|
|
105
|
+
permission?: 'read' | 'reply' | 'work';
|
|
106
106
|
temporal?: 'from-now' | 'from-start';
|
|
107
107
|
durationHours?: number;
|
|
108
108
|
chatId?: string;
|
|
@@ -116,6 +116,7 @@ export declare class ContextGrantsClient {
|
|
|
116
116
|
status: 'pending_approval';
|
|
117
117
|
agreementId: string;
|
|
118
118
|
accessGranted: false;
|
|
119
|
+
actingAgentId?: string;
|
|
119
120
|
scope?: {
|
|
120
121
|
kind: string;
|
|
121
122
|
id: string;
|
|
@@ -80,7 +80,7 @@ export class ContextGrantsClient {
|
|
|
80
80
|
if (result.status !== 'pending_approval' || !result.agreementId || result.accessGranted !== false) {
|
|
81
81
|
throw new Error('Expected a pending access request with accessGranted=false');
|
|
82
82
|
}
|
|
83
|
-
return { status: 'pending_approval', agreementId: result.agreementId, accessGranted: false, ...(result.scope ? { scope: result.scope } : {}), ...sentToOf(result) };
|
|
83
|
+
return { status: 'pending_approval', agreementId: result.agreementId, accessGranted: false, ...(typeof result.actingAgentId === 'string' && result.actingAgentId ? { actingAgentId: result.actingAgentId } : {}), ...(result.scope ? { scope: result.scope } : {}), ...sentToOf(result) };
|
|
84
84
|
}
|
|
85
85
|
async requestArtifactAccess(artifactId, input, opts) {
|
|
86
86
|
const res = await fetch(`${this.baseUrl}/context/artifacts/${encodeURIComponent(artifactId)}/access-requests`, {
|
|
@@ -51,6 +51,8 @@ export interface ContextOpenAccess {
|
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
export interface ContextOpenResult {
|
|
54
|
+
/** Server-resolved caller; absent on older servers, null for human callers. */
|
|
55
|
+
actingAgentId?: string | null;
|
|
54
56
|
/** Optional for servers predating resource action projections. */
|
|
55
57
|
actions?: ResourceAction[];
|
|
56
58
|
outcome: ContextOpenOutcome;
|
|
@@ -20,7 +20,9 @@ export declare class InboxClient {
|
|
|
20
20
|
constructor(operatorKey: string, agentId?: string, baseUrl?: string, instanceId?: string);
|
|
21
21
|
private headers;
|
|
22
22
|
private inboxUrl;
|
|
23
|
-
getInbox(opts?: InboxReadOptions
|
|
23
|
+
getInbox(opts?: InboxReadOptions & {
|
|
24
|
+
signal?: AbortSignal;
|
|
25
|
+
}): Promise<InboxEnvelope>;
|
|
24
26
|
/**
|
|
25
27
|
* Wait for assigned mail without taking the host lease.
|
|
26
28
|
* Still sends X-Ziggs-Instance; the server ignores it on this route.
|
package/dist/http/InboxClient.js
CHANGED
|
@@ -50,6 +50,7 @@ export class InboxClient {
|
|
|
50
50
|
async getInbox(opts = {}) {
|
|
51
51
|
const res = await fetch(this.inboxUrl('/inbox', opts), {
|
|
52
52
|
headers: this.headers(),
|
|
53
|
+
...(opts.signal ? { signal: opts.signal } : {}),
|
|
53
54
|
});
|
|
54
55
|
const body = await res.text().catch(() => '');
|
|
55
56
|
if (!res.ok) {
|
package/dist/http/grants.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export type GrantHolderKind = 'user' | 'org' | 'agent';
|
|
|
22
22
|
* both: `read` sees the scope, `write` takes part in it, `admit` brings others
|
|
23
23
|
* in as well.
|
|
24
24
|
*/
|
|
25
|
-
export type GrantAccessKind
|
|
25
|
+
export type { GrantAccessKind };
|
|
26
26
|
/**
|
|
27
27
|
* The kind of principal-authored consent object a grant rests on. Every grant
|
|
28
28
|
* is minted by one of these, or delegated from a parent grant that was.
|
|
@@ -62,6 +62,7 @@ export type { GrantScopeView, GrantCaveatView };
|
|
|
62
62
|
* client believed a different subset of the row.
|
|
63
63
|
*/
|
|
64
64
|
import type { GrantView, GrantScopeView, GrantCaveatView } from '@ziggs-ai/contracts';
|
|
65
|
+
import type { GrantAccessKind } from '@ziggs-ai/contracts';
|
|
65
66
|
export type { GrantView };
|
|
66
67
|
/** Value of the first caveat of `type` on a grant, or undefined. */
|
|
67
68
|
export declare function grantCaveat(grant: GrantView, type: string): unknown | undefined;
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export type { DecisionOutcome, DecisionWords, DecisionWordsInput, } from './deci
|
|
|
17
17
|
export { planInboxAck, planPartialInboxAck, inboxAckAllowed, inboxAckHandledIds, } from './inboxAck.js';
|
|
18
18
|
export type { InboxAckDecision, InboxAckStep, InboxAckEnvelope, PlanInboxAckOptions, } from './inboxAck.js';
|
|
19
19
|
export { agreementLaneId, agreementIdFromLane, isAgreementLaneId, isAgreementId } from '@ziggs-ai/contracts';
|
|
20
|
+
/** The one way to show points (hundredths → ϟ5.00), shared with the web and the phone. */
|
|
21
|
+
export { POINTS_GLYPH, formatPoints, formatPointsPrice } from '@ziggs-ai/contracts';
|
|
20
22
|
export * from './shared/operatorKey.js';
|
|
21
23
|
export { INBOX_HOST_CLAIMANT_HEADER, INSTANCE_IDENTITY_MAX_LENGTH, cliHostIdentity, hostIdentity, instanceIdentity, mcpConnectionIdentity, } from './instanceIdentity.js';
|
|
22
24
|
export * from './utils/appUrls.js';
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,8 @@ export { ApiError } from './types.js';
|
|
|
18
18
|
export { decisionWords, speakableActor } from './decisionWords.js';
|
|
19
19
|
export { planInboxAck, planPartialInboxAck, inboxAckAllowed, inboxAckHandledIds, } from './inboxAck.js';
|
|
20
20
|
export { agreementLaneId, agreementIdFromLane, isAgreementLaneId, isAgreementId } from '@ziggs-ai/contracts';
|
|
21
|
+
/** The one way to show points (hundredths → ϟ5.00), shared with the web and the phone. */
|
|
22
|
+
export { POINTS_GLYPH, formatPoints, formatPointsPrice } from '@ziggs-ai/contracts';
|
|
21
23
|
export * from './shared/operatorKey.js';
|
|
22
24
|
export { INBOX_HOST_CLAIMANT_HEADER, INSTANCE_IDENTITY_MAX_LENGTH, cliHostIdentity, hostIdentity, instanceIdentity, mcpConnectionIdentity, } from './instanceIdentity.js';
|
|
23
25
|
export * from './utils/appUrls.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgreementPartySide, AgreementParties, PrincipalPresentation, InboxDeliveryRef } from '@ziggs-ai/contracts';
|
|
2
2
|
import type { InboxRequestChannel } from '@ziggs-ai/contracts';
|
|
3
|
+
import type { InboxPartyKind } from '@ziggs-ai/contracts';
|
|
3
4
|
/**
|
|
4
5
|
* One failure shape for every HTTP client path.
|
|
5
6
|
*
|
|
@@ -368,7 +369,7 @@ export type MessageHandler = (text: string, metadata: MessageMetadata) => Promis
|
|
|
368
369
|
*/
|
|
369
370
|
export type InboxDeliveryKind = 'message' | 'artifact' | 'task-state' | 'agreement' | 'request';
|
|
370
371
|
/** The two mailbox owners. Agents own no mailbox — they read through grants. */
|
|
371
|
-
export type InboxPartyKind
|
|
372
|
+
export type { InboxPartyKind };
|
|
372
373
|
/** One mailbox this reader's merged view includes. */
|
|
373
374
|
export interface InboxSourceRef {
|
|
374
375
|
partyId: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ziggs-ai/api-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "HTTP and WebSocket client for the Ziggs backend API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"test:watch": "node --import tsx/esm --test --watch test/*.test.ts"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@ziggs-ai/contracts": "^0.
|
|
30
|
+
"@ziggs-ai/contracts": "^0.21.0",
|
|
31
31
|
"socket.io-client": "^4.7.0"
|
|
32
32
|
},
|
|
33
33
|
"keywords": [
|