@ziggs-ai/api-client 0.36.4 → 0.37.1
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/agreementVerbs.d.ts +3 -11
- package/dist/capabilities/agreementVerbs.js +6 -108
- package/dist/capabilities/chat.d.ts +2 -0
- package/dist/capabilities/chat.js +6 -3
- package/dist/capabilities/discovery.js +6 -0
- package/dist/capabilities/index.d.ts +1 -1
- package/dist/capabilities/index.js +1 -1
- package/dist/capabilities/marketplace.js +2 -2
- package/dist/capabilities/mcpBriefs.js +0 -12
- package/dist/capabilities/proposeProviderId.d.ts +1 -1
- package/dist/capabilities/proposeProviderId.js +1 -1
- package/dist/http/operatorHeaders.d.ts +5 -0
- package/dist/http/operatorHeaders.js +13 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/shared/delegateCreds.d.ts +24 -0
- package/dist/shared/delegateCreds.js +44 -0
- package/dist/shared/runtimeLog.js +3 -4
- package/package.json +1 -1
|
@@ -3,20 +3,12 @@ export declare const agreementBuyCapability: CapabilityDefinition;
|
|
|
3
3
|
export declare const agreementBidCapability: CapabilityDefinition;
|
|
4
4
|
export declare const agreementBrokerCapability: CapabilityDefinition;
|
|
5
5
|
export declare const agreementRequestCapability: CapabilityDefinition;
|
|
6
|
-
export declare const agreementOfferCapability: CapabilityDefinition;
|
|
7
|
-
/**
|
|
8
|
-
* Pause and resume act on a listing that already exists and form nothing. A
|
|
9
|
-
* pause keeps the same row, id and sold hires; revoke is the verb that ends a
|
|
10
|
-
* listing for good.
|
|
11
|
-
*/
|
|
12
|
-
export declare const listingPauseCapability: CapabilityDefinition;
|
|
13
|
-
export declare const listingResumeCapability: CapabilityDefinition;
|
|
14
6
|
export declare const agreementHandoffCapability: CapabilityDefinition;
|
|
15
7
|
export declare const AGREEMENT_VERB_CAPABILITIES: CapabilityDefinition[];
|
|
16
8
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
9
|
+
* Pause and resume left the agent surface. A person or the deploy
|
|
10
|
+
* opens and closes a listing. The array stays so registration has one place
|
|
11
|
+
* to look and finds nothing.
|
|
20
12
|
*/
|
|
21
13
|
export declare const LISTING_DOOR_CAPABILITIES: CapabilityDefinition[];
|
|
22
14
|
/**
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { delegateAgreement, getAgreement, proposeBroadcast, proposeDirectTo, } from '../http/AgreementClient.js';
|
|
2
|
-
import { pauseOffer, publishOffer, resumeOffer } from '../http/MarketplaceClient.js';
|
|
3
2
|
import { fullCreds } from './types.js';
|
|
4
3
|
import { nextCall } from './nextCall.js';
|
|
5
4
|
/**
|
|
@@ -193,7 +192,7 @@ export const agreementBidCapability = {
|
|
|
193
192
|
names: { sdk: 'agreement_bid', mcp: 'ziggs_agreement_bid' },
|
|
194
193
|
title: 'You work, they pay (named counterparty)',
|
|
195
194
|
descriptions: {
|
|
196
|
-
sdk: 'Offer to do work for a named counterparty, who pays. You provide.
|
|
195
|
+
sdk: 'Offer to do work for a named counterparty, who pays. You provide. A standing listing for whoever claims it is published by a person or the deploy, not by this verb.',
|
|
197
196
|
},
|
|
198
197
|
annotation: 'destructive',
|
|
199
198
|
params: {
|
|
@@ -262,7 +261,7 @@ export const agreementRequestCapability = {
|
|
|
262
261
|
names: { sdk: 'agreement_request', mcp: 'ziggs_agreement_request' },
|
|
263
262
|
title: 'They work, you pay (open to anyone)',
|
|
264
263
|
descriptions: {
|
|
265
|
-
sdk: 'Post work you want done and will pay for, for whoever claims it. Whoever claims does the work.
|
|
264
|
+
sdk: 'Post work you want done and will pay for, for whoever claims it. Whoever claims does the work. A standing listing of work you would do is published by a person or the deploy.',
|
|
266
265
|
},
|
|
267
266
|
annotation: 'destructive',
|
|
268
267
|
params: {
|
|
@@ -286,103 +285,6 @@ export const agreementRequestCapability = {
|
|
|
286
285
|
},
|
|
287
286
|
sdkOptions: { isAgreementCreation: true },
|
|
288
287
|
};
|
|
289
|
-
/**
|
|
290
|
-
* No mandate param here, deliberately: a listing is formed inside no job. It is
|
|
291
|
-
* a standing invitation to the world that outlives whatever the agent happens
|
|
292
|
-
* to be doing today, and the publish path says so at its own end
|
|
293
|
-
* (`POST /marketplace/offers/publish`). Hanging one under a job would kill the
|
|
294
|
-
* listing when the job ended.
|
|
295
|
-
*
|
|
296
|
-
* No price default here on purpose: an unstated price is a free hire, and the
|
|
297
|
-
* publish path is the one place that says so. Stating a price publishes a paid
|
|
298
|
-
* listing.
|
|
299
|
-
*
|
|
300
|
-
* No replay key either, and that one has a cost worth knowing: each call
|
|
301
|
-
* publishes a fresh row rather than replaying, and the previous listing is
|
|
302
|
-
* retired as it goes, so an agent that republishes leaves dead rows behind it.
|
|
303
|
-
* One listing per agent still holds; the churn does not.
|
|
304
|
-
*/
|
|
305
|
-
/**
|
|
306
|
-
* Seats on a listing: how many customers may hold a live hire from it at once.
|
|
307
|
-
* A hire that ends gives its seat back, so this is a capacity, not a lifetime
|
|
308
|
-
* count. Only the listing verb takes it; a direct proposal has one customer.
|
|
309
|
-
*/
|
|
310
|
-
const MAX_CLAIMS_PARAM = {
|
|
311
|
-
type: 'number',
|
|
312
|
-
description: 'How many customers may hold a live hire from this listing at once. A hire that ends gives its seat back. While every seat is taken, new claims are refused as full until one frees. Omit for unlimited. Set it when your attention is limited: every customer who hires you can wake you.',
|
|
313
|
-
};
|
|
314
|
-
export const agreementOfferCapability = {
|
|
315
|
-
key: 'agreement_offer',
|
|
316
|
-
names: { sdk: 'agreement_offer', mcp: 'ziggs_agreement_offer' },
|
|
317
|
-
title: 'You work, they pay (open to anyone)',
|
|
318
|
-
descriptions: {
|
|
319
|
-
sdk: 'Publish work you will do, for whoever claims it and pays. You provide. This is your listing: it stands until revoked or exhausted. To offer one named counterparty instead, use agreement_bid.',
|
|
320
|
-
},
|
|
321
|
-
annotation: 'destructive',
|
|
322
|
-
params: { audience: AUDIENCE_PARAM, ...TERMS_PARAMS, maxClaims: MAX_CLAIMS_PARAM },
|
|
323
|
-
needsAgentId: true,
|
|
324
|
-
handler: async (args, env) => {
|
|
325
|
-
const terms = termsFrom(args);
|
|
326
|
-
const agreement = await publishOffer({
|
|
327
|
-
description: terms.description ?? '',
|
|
328
|
-
price: terms.price,
|
|
329
|
-
lifecycle: terms.lifecycle,
|
|
330
|
-
expiresAt: terms.expiresAt,
|
|
331
|
-
maxExecutions: terms.maxExecutions,
|
|
332
|
-
conversationAllowance: terms.conversationAllowance,
|
|
333
|
-
conversationAllowanceScope: terms.conversationAllowanceScope,
|
|
334
|
-
interactionMode: terms.interactionMode,
|
|
335
|
-
billing: terms.billing,
|
|
336
|
-
engagementKind: engagementKindFrom(args),
|
|
337
|
-
audience: args['audience'],
|
|
338
|
-
...(typeof args['maxClaims'] === 'number' ? { maxClaims: args['maxClaims'] } : {}),
|
|
339
|
-
}, fullCreds(env));
|
|
340
|
-
return { agreement, readPlan: publishedNext(env) };
|
|
341
|
-
},
|
|
342
|
-
sdkOptions: { isAgreementCreation: true },
|
|
343
|
-
};
|
|
344
|
-
/* ───────────────────────── the door on your own listing ──────────────────── */
|
|
345
|
-
/** The listing the pause and resume verbs act on. */
|
|
346
|
-
const LISTING_ID_PARAM = {
|
|
347
|
-
type: 'string',
|
|
348
|
-
required: true,
|
|
349
|
-
description: 'Your listing: the agreement id your offer was published under (what ziggs_agreement_offer answered with). On your own profile it is doors.listingAgreementId.',
|
|
350
|
-
};
|
|
351
|
-
/**
|
|
352
|
-
* Pause and resume act on a listing that already exists and form nothing. A
|
|
353
|
-
* pause keeps the same row, id and sold hires; revoke is the verb that ends a
|
|
354
|
-
* listing for good.
|
|
355
|
-
*/
|
|
356
|
-
export const listingPauseCapability = {
|
|
357
|
-
key: 'listing_pause',
|
|
358
|
-
names: { sdk: 'listing_pause', mcp: 'ziggs_listing_pause' },
|
|
359
|
-
title: 'Pause your listing',
|
|
360
|
-
descriptions: {
|
|
361
|
-
sdk: 'Stop taking new customers on a listing you publish, without deleting it. New claims on it are refused until you resume it with listing_resume. Same listing, same id; hires already sold keep running. To end a listing for good, use agreement_revoke.',
|
|
362
|
-
},
|
|
363
|
-
annotation: 'destructive',
|
|
364
|
-
params: { agreementId: LISTING_ID_PARAM },
|
|
365
|
-
needsAgentId: true,
|
|
366
|
-
handler: async (args, env) => {
|
|
367
|
-
const agreement = await pauseOffer(args['agreementId'], fullCreds(env));
|
|
368
|
-
return { status: 'paused', agreement };
|
|
369
|
-
},
|
|
370
|
-
};
|
|
371
|
-
export const listingResumeCapability = {
|
|
372
|
-
key: 'listing_resume',
|
|
373
|
-
names: { sdk: 'listing_resume', mcp: 'ziggs_listing_resume' },
|
|
374
|
-
title: 'Resume your listing',
|
|
375
|
-
descriptions: {
|
|
376
|
-
sdk: 'Reopen a listing you paused with listing_pause: same listing, same id, taking new customers again. A listing closed because every seat is taken, or because its agent stopped answering, reopens on its own and needs no resume.',
|
|
377
|
-
},
|
|
378
|
-
annotation: 'destructive',
|
|
379
|
-
params: { agreementId: LISTING_ID_PARAM },
|
|
380
|
-
needsAgentId: true,
|
|
381
|
-
handler: async (args, env) => {
|
|
382
|
-
const agreement = await resumeOffer(args['agreementId'], fullCreds(env));
|
|
383
|
-
return { status: 'resumed', agreement };
|
|
384
|
-
},
|
|
385
|
-
};
|
|
386
288
|
/* ──────────────────────────────── hand-off ───────────────────────────────── */
|
|
387
289
|
export const agreementHandoffCapability = {
|
|
388
290
|
key: 'agreement_handoff',
|
|
@@ -441,18 +343,14 @@ export const AGREEMENT_VERB_CAPABILITIES = [
|
|
|
441
343
|
agreementBidCapability,
|
|
442
344
|
agreementBrokerCapability,
|
|
443
345
|
agreementRequestCapability,
|
|
444
|
-
agreementOfferCapability,
|
|
445
346
|
agreementHandoffCapability,
|
|
446
347
|
];
|
|
447
348
|
/**
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
349
|
+
* Pause and resume left the agent surface. A person or the deploy
|
|
350
|
+
* opens and closes a listing. The array stays so registration has one place
|
|
351
|
+
* to look and finds nothing.
|
|
451
352
|
*/
|
|
452
|
-
export const LISTING_DOOR_CAPABILITIES = [
|
|
453
|
-
listingPauseCapability,
|
|
454
|
-
listingResumeCapability,
|
|
455
|
-
];
|
|
353
|
+
export const LISTING_DOOR_CAPABILITIES = [];
|
|
456
354
|
/**
|
|
457
355
|
* Subcontract sits next to the propose verbs, not inside them: the parent
|
|
458
356
|
* already exists, and the conversation is optional. The server uses the
|
|
@@ -5,6 +5,8 @@ export interface SendPresentation {
|
|
|
5
5
|
ok: true;
|
|
6
6
|
chatId: string;
|
|
7
7
|
messageId: string;
|
|
8
|
+
/** Keep the server's delivery guidance on every client surface. */
|
|
9
|
+
message?: string;
|
|
8
10
|
/** What the server did with this send, stated so it cannot be over-read. */
|
|
9
11
|
delivered: string;
|
|
10
12
|
/** Who it was addressed to, exactly as the server resolved it. */
|
|
@@ -24,6 +24,7 @@ export function presentSendResult(result, env) {
|
|
|
24
24
|
ok: true,
|
|
25
25
|
chatId: result.chatId,
|
|
26
26
|
messageId: result.messageId,
|
|
27
|
+
...(result.message ? { message: result.message } : {}),
|
|
27
28
|
...(workContext ? { workContext } : {}),
|
|
28
29
|
};
|
|
29
30
|
if (!delivery) {
|
|
@@ -38,9 +39,11 @@ export function presentSendResult(result, env) {
|
|
|
38
39
|
// What counted it, in the server's words: a stranger's free messages with a
|
|
39
40
|
// listed agent run out, and the person writing needs to know before they do.
|
|
40
41
|
const counted = result.coverage?.message ? ` ${result.coverage.message}` : '';
|
|
41
|
-
const routing = delivery.
|
|
42
|
-
?
|
|
43
|
-
:
|
|
42
|
+
const routing = delivery.broadcast
|
|
43
|
+
? "This human-only broadcast does not wake assistants or stand-ins. If you need a reply, send a new message in this same chat to the person's returned participant id (receiverId), with a fresh message id or idempotency key. Existing conversation permissions still apply."
|
|
44
|
+
: delivery.reachable
|
|
45
|
+
? `Assigned to ${delivery.assignee ?? 'nobody'}; reachable: ${delivery.reachable}${delivery.reason ? ` (${delivery.reason})` : ''}.${delivery.lastRead ? ` Last inbox read: ${delivery.lastRead}.` : ''}`
|
|
46
|
+
: 'Mailbox routing is unconfirmed; a person may be covered by an assistant.';
|
|
44
47
|
return {
|
|
45
48
|
...base,
|
|
46
49
|
delivered: `Message ${result.messageId} was accepted into chat ${result.chatId}, addressed to ${destination}. ${routing} Accepted is not read and does not confirm a wake or reply.${counted}`,
|
|
@@ -33,6 +33,8 @@ export const agentSearchCapability = {
|
|
|
33
33
|
}
|
|
34
34
|
const chatOpen = env.surface === 'mcp' ? 'ziggs_chat_open' : 'chat_open';
|
|
35
35
|
const linkList = env.surface === 'mcp' ? 'ziggs_link_list' : 'link_list';
|
|
36
|
+
const marketplace = env.surface === 'mcp' ? 'ziggs_marketplace_view' : 'marketplace_view';
|
|
37
|
+
const request = env.surface === 'mcp' ? 'ziggs_agreement_request' : 'agreement_request';
|
|
36
38
|
const people = result.people ?? [];
|
|
37
39
|
const messageThem = people.length
|
|
38
40
|
? {
|
|
@@ -53,6 +55,10 @@ export const agentSearchCapability = {
|
|
|
53
55
|
'your org: people by name (returned under people, to message as people)',
|
|
54
56
|
],
|
|
55
57
|
hint: 'Zero agents means no agent matched these terms; discovery itself is up. ' +
|
|
58
|
+
// An agent given work to farm out stopped here with it undone. The
|
|
59
|
+
// next rungs of the hiring ladder belong at the moment the search
|
|
60
|
+
// comes back empty, not in a skill loaded every session.
|
|
61
|
+
`To get work done, open listings and requests are in ${marketplace}; when nothing fits, post the work with ${request} so whoever can do it claims it. ` +
|
|
56
62
|
"People are not agents: a teammate is found by their name and comes back under people, never as their agents. " +
|
|
57
63
|
`To reach them, open a chat with that user id (${chatOpen} participantId). ` +
|
|
58
64
|
'Matching is lexical, so try shorter or different keywords. ' +
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { type CapabilitySurface, type CapabilityAnnotation, type CapabilityParam, type CapabilityEnv, type CapabilityDefinition, fullCreds, rethrowWithContext, } from './types.js';
|
|
2
2
|
export { type McpBrief, type McpDoor, hasMcpBrief, mcpBriefNames, mcpDescription, } from './mcpBriefs.js';
|
|
3
3
|
export { nextCall, nextCallsFromUntrustedContent, isStaleAdvertisedAction, peerPrincipalId, isPersonaFace, workContextFromEnv, type NextCall, type NextCallOutcome, type NextCallEffects, type NextCallHold, type NextCallOptions, type WorkContext, } from './nextCall.js';
|
|
4
|
-
export { AGREEMENT_VERB_CAPABILITIES, LISTING_DOOR_CAPABILITIES,
|
|
4
|
+
export { AGREEMENT_VERB_CAPABILITIES, LISTING_DOOR_CAPABILITIES, agreementBuyCapability, agreementBidCapability, agreementBrokerCapability, agreementRequestCapability, agreementHandoffCapability, agreementSubcontractCapability, } from './agreementVerbs.js';
|
|
5
5
|
export { PAYMENT_CAPABILITIES, paymentBalanceCapability } from './payments.js';
|
|
6
6
|
export { LINK_CAPABILITIES, listLinksCapability, proposeLinkCapability, linkIsReachOnly, } from './links.js';
|
|
7
7
|
export { INTRODUCTION_CAPABILITIES, mintIntroductionCapability, redeemIntroductionCapability, listIntroductionsCapability, revokeIntroductionCapability, } from './introductions.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { fullCreds, rethrowWithContext, } from './types.js';
|
|
2
2
|
export { hasMcpBrief, mcpBriefNames, mcpDescription, } from './mcpBriefs.js';
|
|
3
3
|
export { nextCall, nextCallsFromUntrustedContent, isStaleAdvertisedAction, peerPrincipalId, isPersonaFace, workContextFromEnv, } from './nextCall.js';
|
|
4
|
-
export { AGREEMENT_VERB_CAPABILITIES, LISTING_DOOR_CAPABILITIES,
|
|
4
|
+
export { AGREEMENT_VERB_CAPABILITIES, LISTING_DOOR_CAPABILITIES, agreementBuyCapability, agreementBidCapability, agreementBrokerCapability, agreementRequestCapability, agreementHandoffCapability, agreementSubcontractCapability, } from './agreementVerbs.js';
|
|
5
5
|
export { PAYMENT_CAPABILITIES, paymentBalanceCapability } from './payments.js';
|
|
6
6
|
export { LINK_CAPABILITIES, listLinksCapability, proposeLinkCapability, linkIsReachOnly, } from './links.js';
|
|
7
7
|
export { INTRODUCTION_CAPABILITIES, mintIntroductionCapability, redeemIntroductionCapability, listIntroductionsCapability, revokeIntroductionCapability, } from './introductions.js';
|
|
@@ -7,8 +7,8 @@ const VIEW_KINDS = ['all', 'requests', 'offers'];
|
|
|
7
7
|
function publishHint(env) {
|
|
8
8
|
const claim = env.surface === 'mcp' ? 'ziggs_agreement_claim' : 'agreement_claim';
|
|
9
9
|
const publish = env.surface === 'mcp'
|
|
10
|
-
? '
|
|
11
|
-
: '
|
|
10
|
+
? 'Post a request with ziggs_agreement_request (claimer works, you pay). A standing listing is published by a person or the deploy.'
|
|
11
|
+
: 'Post a request via agreement_propose with proposedTo "everyone"/"org" and no providerId. A standing listing is published by a person or the deploy.';
|
|
12
12
|
return (`Reuse an active agreement that already covers the work. Otherwise claim any row with ${claim} ` +
|
|
13
13
|
`(agreementId) — listings are take-it-or-leave-it, never counter one. ${publish}`);
|
|
14
14
|
}
|
|
@@ -62,10 +62,6 @@ const BRIEFS = {
|
|
|
62
62
|
does: 'Posts work you want done and will pay for: whoever claims it does the work.',
|
|
63
63
|
changes: 'publishes a request others can claim',
|
|
64
64
|
},
|
|
65
|
-
ziggs_agreement_offer: {
|
|
66
|
-
does: 'Publishes your listing: you provide, whoever claims it pays. Claimers take it as posted.',
|
|
67
|
-
changes: 'publishes it until revoked or sold out',
|
|
68
|
-
},
|
|
69
65
|
ziggs_agreement_buy: {
|
|
70
66
|
does: 'Proposes work to a named counterparty: they provide, you pay. Most published agents accept only claims of their listing.',
|
|
71
67
|
changes: 'sends a proposal they approve, reject or counter',
|
|
@@ -102,14 +98,6 @@ const BRIEFS = {
|
|
|
102
98
|
does: 'Ends an agreement you provide, for good, once its whole scope is delivered. A finished task closes with ziggs_task_set_result instead.',
|
|
103
99
|
changes: 'revokes every grant it conferred; it cannot be reopened',
|
|
104
100
|
},
|
|
105
|
-
ziggs_listing_pause: {
|
|
106
|
-
does: 'Stops new claims on a listing you publish; hires already sold keep running.',
|
|
107
|
-
changes: 'pauses it until ziggs_listing_resume',
|
|
108
|
-
},
|
|
109
|
-
ziggs_listing_resume: {
|
|
110
|
-
does: 'Reopens a listing you paused.',
|
|
111
|
-
changes: 'it takes new claims again',
|
|
112
|
-
},
|
|
113
101
|
// Rooms
|
|
114
102
|
ziggs_chat_list: {
|
|
115
103
|
does: 'Lists rooms you hold a grant on, with last message and unread count. fields adds members or rosterSummary.',
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* tools. Stated on the schema so a fresh agent does not burn a turn learning
|
|
4
4
|
* the rule from the validation error.
|
|
5
5
|
*/
|
|
6
|
-
export declare const AGREEMENT_PROPOSE_PROVIDER_ID_DESCRIPTION = "REQUIRED on a direct proposal: name who does the work \u2014 your own id (you are offering to work) or the proposedTo id (you are commissioning the recipient). Do not omit it when proposedTo is a person/agent id. Broadcast (proposedTo everyone/org): omit
|
|
6
|
+
export declare const AGREEMENT_PROPOSE_PROVIDER_ID_DESCRIPTION = "REQUIRED on a direct proposal: name who does the work \u2014 your own id (you are offering to work) or the proposedTo id (you are commissioning the recipient). Do not omit it when proposedTo is a person/agent id. Broadcast (proposedTo everyone/org): omit providerId to post a request (claimer works). A person or the deploy publishes a standing listing; this agent does not. Payer is always the non-providing side.";
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* tools. Stated on the schema so a fresh agent does not burn a turn learning
|
|
4
4
|
* the rule from the validation error.
|
|
5
5
|
*/
|
|
6
|
-
export const AGREEMENT_PROPOSE_PROVIDER_ID_DESCRIPTION = 'REQUIRED on a direct proposal: name who does the work — your own id (you are offering to work) or the proposedTo id (you are commissioning the recipient). Do not omit it when proposedTo is a person/agent id. Broadcast (proposedTo everyone/org): omit
|
|
6
|
+
export const AGREEMENT_PROPOSE_PROVIDER_ID_DESCRIPTION = 'REQUIRED on a direct proposal: name who does the work — your own id (you are offering to work) or the proposedTo id (you are commissioning the recipient). Do not omit it when proposedTo is a person/agent id. Broadcast (proposedTo everyone/org): omit providerId to post a request (claimer works). A person or the deploy publishes a standing listing; this agent does not. Payer is always the non-providing side.';
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
type AssistantHints = {
|
|
2
2
|
orgId?: string;
|
|
3
3
|
resource?: string;
|
|
4
|
+
clientSessionId?: string;
|
|
5
|
+
instanceId?: string;
|
|
6
|
+
workspaceIds?: string;
|
|
7
|
+
app?: string;
|
|
8
|
+
sessionName?: string;
|
|
4
9
|
};
|
|
5
10
|
/** Node-only, opt-in request context. Ordinary HTTP clients remain browser-safe. */
|
|
6
11
|
export declare function withAssistantRequest<T>(hints: AssistantHints, run: () => T): Promise<Awaited<T>>;
|
|
@@ -6,11 +6,22 @@ export async function withAssistantRequest(hints, run) {
|
|
|
6
6
|
assistantRequest = new AsyncLocalStorage();
|
|
7
7
|
return assistantRequest;
|
|
8
8
|
});
|
|
9
|
-
|
|
9
|
+
const context = await assistantContextLoading;
|
|
10
|
+
// A workspace router adds its per-operation target inside the caller's
|
|
11
|
+
// session. Preserve that session without sharing it between concurrent calls.
|
|
12
|
+
return await context.run({ ...context.getStore(), ...hints, orgId: hints.orgId, resource: hints.resource }, run);
|
|
10
13
|
}
|
|
11
14
|
export function assistantRequestHeaders() {
|
|
12
15
|
const hints = assistantRequest?.getStore();
|
|
13
|
-
return {
|
|
16
|
+
return {
|
|
17
|
+
...(hints?.orgId ? { 'X-Workspace-Id': hints.orgId } : {}),
|
|
18
|
+
...(hints?.resource ? { 'X-Ziggs-Resource': hints.resource } : {}),
|
|
19
|
+
...(hints?.clientSessionId ? { 'X-Ziggs-Session': hints.clientSessionId } : {}),
|
|
20
|
+
...(hints?.instanceId ? { 'X-Ziggs-Instance': hints.instanceId } : {}),
|
|
21
|
+
...(hints?.workspaceIds ? { 'X-Ziggs-Workspaces': hints.workspaceIds } : {}),
|
|
22
|
+
...(hints?.app ? { 'X-Ziggs-App': hints.app } : {}),
|
|
23
|
+
...(hints?.sessionName ? { 'X-Ziggs-Session-Name': hints.sessionName } : {}),
|
|
24
|
+
};
|
|
14
25
|
}
|
|
15
26
|
/**
|
|
16
27
|
* Auth headers for operator-key HTTP clients.
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,9 @@ export { getBackendUrl } from './utils/urlUtils.js';
|
|
|
7
7
|
export { configureApiClient, apiClientConfig } from './config.js';
|
|
8
8
|
export type { ApiClientConfig, ApiClientLogLevel } from './config.js';
|
|
9
9
|
export { runtimeLog, resetRuntimeLogLevelCache } from './shared/runtimeLog.js';
|
|
10
|
+
export type { RuntimeLogLevel } from './shared/runtimeLog.js';
|
|
11
|
+
export { resolveDelegateCreds, resolveDelegateHttpUrl, } from './shared/delegateCreds.js';
|
|
12
|
+
export type { DelegateEnv, ResolvedDelegateCreds, } from './shared/delegateCreds.js';
|
|
10
13
|
export { RateLimitedError, isRateLimited, parseRetryAfterMs, pollSurfaceError, } from './shared/rateLimit.js';
|
|
11
14
|
export { parseErrorMessage, parseErrorCode, throwApiError, } from './shared/apiError.js';
|
|
12
15
|
export { ApiError } from './types.js';
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { getBackendUrl } from './utils/urlUtils.js';
|
|
|
6
6
|
// the host injects the environment; this package never reads it.
|
|
7
7
|
export { configureApiClient, apiClientConfig } from './config.js';
|
|
8
8
|
export { runtimeLog, resetRuntimeLogLevelCache } from './shared/runtimeLog.js';
|
|
9
|
+
export { resolveDelegateCreds, resolveDelegateHttpUrl, } from './shared/delegateCreds.js';
|
|
9
10
|
// one ApiError shape; 429s carry the server's wait.
|
|
10
11
|
export { RateLimitedError, isRateLimited, parseRetryAfterMs, pollSurfaceError, } from './shared/rateLimit.js';
|
|
11
12
|
// One reader for the one error shape the API answers in — exported so nothing has
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The environment a delegate process was handed. Callers read the process;
|
|
3
|
+
* this module does not.
|
|
4
|
+
*/
|
|
5
|
+
export interface DelegateEnv {
|
|
6
|
+
ZIGGS_API_URL?: string;
|
|
7
|
+
HTTP_URL?: string;
|
|
8
|
+
ZIGGS_OPERATOR_KEY?: string;
|
|
9
|
+
ZIGGS_AGENT_ID?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ResolvedDelegateCreds {
|
|
12
|
+
/** `ZIGGS_API_URL` wins over `HTTP_URL`. Absent when neither is set. */
|
|
13
|
+
httpUrl?: string;
|
|
14
|
+
operatorKey: string;
|
|
15
|
+
/** Empty when the key is a directory connection (`connectionClientId`). */
|
|
16
|
+
agentId: string;
|
|
17
|
+
}
|
|
18
|
+
/** Which base URL this process was told to use. The specific name wins. */
|
|
19
|
+
export declare function resolveDelegateHttpUrl(env: DelegateEnv): string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* One reading of a delegate's key, agent, and base URL.
|
|
22
|
+
* An agent-scoped key supplies the agent id. A session JWT is refused.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveDelegateCreds(env: DelegateEnv): ResolvedDelegateCreds;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { decodeOperatorKeyClaims, isOperatorKeyExpired } from './operatorKey.js';
|
|
2
|
+
const MINT = 'An MCP client that supports OAuth signs in at https://mcp.ziggsai.com/mcp. ' +
|
|
3
|
+
'To run with a key, issue one in the Ziggs app (Agent-only access, or Agents > Access keys). ' +
|
|
4
|
+
'Docs: https://ziggsai.com/docs#connect-assistant';
|
|
5
|
+
/** Which base URL this process was told to use. The specific name wins. */
|
|
6
|
+
export function resolveDelegateHttpUrl(env) {
|
|
7
|
+
const specific = env.ZIGGS_API_URL?.trim();
|
|
8
|
+
if (specific)
|
|
9
|
+
return specific;
|
|
10
|
+
const generic = env.HTTP_URL?.trim();
|
|
11
|
+
return generic || undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* One reading of a delegate's key, agent, and base URL.
|
|
15
|
+
* An agent-scoped key supplies the agent id. A session JWT is refused.
|
|
16
|
+
*/
|
|
17
|
+
export function resolveDelegateCreds(env) {
|
|
18
|
+
const operatorKey = env.ZIGGS_OPERATOR_KEY?.trim() ?? '';
|
|
19
|
+
if (!operatorKey) {
|
|
20
|
+
throw new Error(`ZIGGS_OPERATOR_KEY is required. ${MINT}`);
|
|
21
|
+
}
|
|
22
|
+
const claims = decodeOperatorKeyClaims(operatorKey);
|
|
23
|
+
if (claims?.type && claims.type !== 'operator') {
|
|
24
|
+
throw new Error(`ZIGGS_OPERATOR_KEY must be an operator token (not a session JWT). ${MINT}`);
|
|
25
|
+
}
|
|
26
|
+
if (isOperatorKeyExpired(claims)) {
|
|
27
|
+
throw new Error(`operator key expired (keyId=${claims?.keyId ?? 'unknown'}). ${MINT}`);
|
|
28
|
+
}
|
|
29
|
+
const httpUrl = resolveDelegateHttpUrl(env);
|
|
30
|
+
if (claims?.connectionClientId) {
|
|
31
|
+
return { httpUrl, operatorKey, agentId: '' };
|
|
32
|
+
}
|
|
33
|
+
const bound = claims?.boundAgentId?.trim() || '';
|
|
34
|
+
const fromEnv = env.ZIGGS_AGENT_ID?.trim() || '';
|
|
35
|
+
if (bound && fromEnv && bound !== fromEnv) {
|
|
36
|
+
throw new Error(`ZIGGS_AGENT_ID (${fromEnv}) conflicts with agent-scoped key bound to "${bound}". ` +
|
|
37
|
+
'Remove ZIGGS_AGENT_ID or use a fleet impersonation key instead.');
|
|
38
|
+
}
|
|
39
|
+
const agentId = bound || fromEnv;
|
|
40
|
+
if (!agentId) {
|
|
41
|
+
throw new Error(`set ZIGGS_AGENT_ID, or mint an agent-scoped operator key (boundAgentId in token). ${MINT}`);
|
|
42
|
+
}
|
|
43
|
+
return { httpUrl, operatorKey, agentId };
|
|
44
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @see agent-sdk/src/shared/runtimeLog.ts
|
|
2
|
+
* Process-wide log level for every package that imports this. The host sets it
|
|
3
|
+
* with `configureApiClient({ logLevel })`; this package does not read the
|
|
4
|
+
* environment. The SDK re-exports these names.
|
|
6
5
|
*/
|
|
7
6
|
import { apiClientConfig, apiClientConfigVersion } from '../config.js';
|
|
8
7
|
const SEVERITY = {
|