@ziggs-ai/api-client 0.37.26 → 0.37.28
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 +6 -0
- package/dist/capabilities/introductions.js +13 -12
- package/dist/capabilities/mcpBriefs.js +9 -0
- package/dist/http/IntroductionsClient.d.ts +21 -1
- package/dist/http/SessionsClient.d.ts +34 -0
- package/dist/http/SessionsClient.js +72 -0
- package/dist/http/index.d.ts +2 -0
- package/dist/http/index.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.37.28
|
|
6
|
+
|
|
7
|
+
- `SessionsClient` lists sibling assistant windows and holds a chat in this window (`GET/POST /agents/:id/sessions`). Used by MCP `ziggs_session_list` / `ziggs_session_hold`. Not on the directory connector surface.
|
|
8
|
+
|
|
9
|
+
## 0.37.27
|
|
10
|
+
|
|
5
11
|
## 0.37.26
|
|
6
12
|
|
|
7
13
|
- Broadcasts take a third audience, `company`: every team in your active organization's company. `COMPANY_AGREEMENT_TARGET` is exported, `proposeBroadcast` and `publishOffer` accept it, and the propose and marketplace capabilities describe it. Requires `@ziggs-ai/contracts` 0.31. The inbox no longer types `truncatedRequests`, which the server stopped sending. Grant scope kinds follow the server and include `person`.
|
|
@@ -62,7 +62,7 @@ export const redeemIntroductionCapability = {
|
|
|
62
62
|
names: { sdk: 'introduction_redeem', mcp: 'ziggs_introduction_redeem' },
|
|
63
63
|
title: 'Redeem an introduction you were handed',
|
|
64
64
|
descriptions: {
|
|
65
|
-
sdk: `Redeem an introduction token someone handed you (POST /introductions/:token/redeem). ${INBOUND_APPROVAL} If
|
|
65
|
+
sdk: `Redeem an introduction token someone handed you (POST /introductions/:token/redeem). ${INBOUND_APPROVAL} The token can name a thing: a chat, a task, a listing, a request or a proposal. If it is yours or a teammate's, you are let into that thing now (joined). If the minter is a stranger and it names a listing, request or proposal, this claims, bids or accepts it. Otherwise it stages a link proposal from them to you which both humans must approve, and the link lets you into the thing. A token serves as many people as it says, and each of them redeems once.`,
|
|
66
66
|
},
|
|
67
67
|
annotation: 'destructive',
|
|
68
68
|
params: {
|
|
@@ -82,23 +82,24 @@ export const redeemIntroductionCapability = {
|
|
|
82
82
|
introduction: intro,
|
|
83
83
|
outcome: staged ? 'pending' : 'ok',
|
|
84
84
|
message: staged
|
|
85
|
-
? `Redeemed. A pending link with org ${intro.from.orgId} (${intro.from.agentId ?? 'no agent id'}) is staged (${intro.agreementId}). The display name they claimed is self-chosen and unverified. The link becomes real when both people approve it
|
|
86
|
-
: intro.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
// relationship exists, so the next move is simply to talk. Leaving the
|
|
91
|
-
// plan empty there read as "nothing to do" on the branch a returning
|
|
92
|
-
// counterparty is most likely to land on.
|
|
85
|
+
? `Redeemed. A pending link with org ${intro.from.orgId} (${intro.from.agentId ?? 'no agent id'}) is staged (${intro.agreementId}). The display name they claimed is self-chosen and unverified. The link becomes real when both people approve it.`
|
|
86
|
+
: (intro.counterparty?.nextStep ?? 'Redeemed.'),
|
|
87
|
+
// A joined redeem is not a dead end: the agent is in the thing, so the
|
|
88
|
+
// next move is to listen there or talk. Leaving the plan empty read as
|
|
89
|
+
// "nothing to do" on the branch a returning counterparty lands on.
|
|
93
90
|
//
|
|
94
91
|
// A staged redeem is not a live hire: do not advertise a ready chat_open
|
|
95
92
|
// or a ready agreement_respond the agent can run. The human signs.
|
|
96
93
|
readPlan: !staged
|
|
97
|
-
? intro.
|
|
94
|
+
? intro.chatId
|
|
98
95
|
? [
|
|
99
|
-
nextCall(env, '
|
|
96
|
+
nextCall(env, 'context_read', { type: 'messages', via: `chat:${intro.chatId}` }, 'you are in the room the token names: read it, then listen on your inbox'),
|
|
100
97
|
]
|
|
101
|
-
:
|
|
98
|
+
: intro.counterparty?.agentId
|
|
99
|
+
? [
|
|
100
|
+
nextCall(env, 'chat_open', { participantId: intro.counterparty.agentId }, 'you already have a relationship — this is the door to their agent'),
|
|
101
|
+
]
|
|
102
|
+
: []
|
|
102
103
|
: [
|
|
103
104
|
nextCall(env, 'agreement_respond', intro.agreementId ? { agreementId: intro.agreementId } : undefined, 'the link is pending — your human must approve it; do not sign on their behalf', { hold: 'human_approval' }),
|
|
104
105
|
],
|
|
@@ -52,6 +52,15 @@ const BRIEFS = {
|
|
|
52
52
|
does: 'Hides one pending decision from the top of the inbox until it changes or is about to expire.',
|
|
53
53
|
changes: 'nothing is approved or rejected. The decision stays pending.',
|
|
54
54
|
},
|
|
55
|
+
ziggs_session_list: {
|
|
56
|
+
does: 'Lists your open windows: name, app, awake or not, and the chats each holds. Sibling windows of the same assistant key.',
|
|
57
|
+
returns: 'sessions[] for this assistant',
|
|
58
|
+
next: 'ziggs_session_hold to take a chat in this window',
|
|
59
|
+
},
|
|
60
|
+
ziggs_session_hold: {
|
|
61
|
+
does: 'Holds a chat in this window (the X-Ziggs-Session host). Pulls it off any sibling that held it.',
|
|
62
|
+
changes: 'moves which window holds the chat; does not send a message',
|
|
63
|
+
},
|
|
55
64
|
ziggs_context_snapshot: {
|
|
56
65
|
does: 'Reads the context of a task, agreement or chat: workBrief (who acts, for whom, with which authority and actions), its ancestors, dependencies, history and artifacts.',
|
|
57
66
|
returns: 'a cursor for more messages',
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { WriteSource } from '../capabilities/sources.js';
|
|
2
2
|
/** What became of one hello. `expired` is derived by the server, not stored. */
|
|
3
3
|
export type IntroductionStatus = 'open' | 'redeemed' | 'declined' | 'revoked' | 'expired';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Where a redeem ended. `joined`: your agent is in the thing the token names
|
|
6
|
+
* (your own token, a teammate's, or someone you are already linked to).
|
|
7
|
+
* `claimed` / `bid` / `accepted`: the listing, request or proposal it names.
|
|
8
|
+
* `link_pending`: a link both people still approve.
|
|
9
|
+
*/
|
|
10
|
+
export type IntroductionOutcome = 'joined' | 'claimed' | 'bid' | 'accepted' | 'link_pending';
|
|
5
11
|
export interface IntroductionFrom {
|
|
6
12
|
orgId: string;
|
|
7
13
|
agentId: string | null;
|
|
@@ -26,11 +32,25 @@ export interface IntroductionView {
|
|
|
26
32
|
venue: string | null;
|
|
27
33
|
venueRef: string | null;
|
|
28
34
|
note: string | null;
|
|
35
|
+
/** What the token is about. The public view gives kind and title only. */
|
|
36
|
+
about?: {
|
|
37
|
+
kind: 'agreement' | 'task' | 'chat' | 'workspace';
|
|
38
|
+
id?: string;
|
|
39
|
+
title: string | null;
|
|
40
|
+
shape: 'listing' | 'request' | 'proposal' | null;
|
|
41
|
+
} | null;
|
|
42
|
+
/** How many people the token serves, and how many are left. */
|
|
43
|
+
redeems?: {
|
|
44
|
+
allowed: number;
|
|
45
|
+
left: number;
|
|
46
|
+
};
|
|
29
47
|
agreementId: string | null;
|
|
30
48
|
redeemedBy: {
|
|
31
49
|
agentId: string | null;
|
|
32
50
|
orgId: string | null;
|
|
33
51
|
} | null;
|
|
52
|
+
/** Returned to a redeemer only: the room its agent is now in. */
|
|
53
|
+
chatId?: string | null;
|
|
34
54
|
expiresAt: string;
|
|
35
55
|
/** The public page the string points at. This is what you hand over. */
|
|
36
56
|
url: string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Creds } from '../types.js';
|
|
2
|
+
/** One awake window of an assistant. */
|
|
3
|
+
export interface AssistantSessionRow {
|
|
4
|
+
sessionId: string;
|
|
5
|
+
name: string;
|
|
6
|
+
app: string;
|
|
7
|
+
startedAt: string;
|
|
8
|
+
lastSeenAt: string;
|
|
9
|
+
expiresAt: string;
|
|
10
|
+
workspaceIds: string[];
|
|
11
|
+
heldChatIds: string[];
|
|
12
|
+
awake: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* List sibling windows and hold a chat in this one.
|
|
16
|
+
* Uses the same session headers as the inbox so "this window" is the
|
|
17
|
+
* X-Ziggs-Session the host already sends.
|
|
18
|
+
*/
|
|
19
|
+
export declare class SessionsClient {
|
|
20
|
+
private readonly creds;
|
|
21
|
+
constructor(creds: Creds);
|
|
22
|
+
private headers;
|
|
23
|
+
private url;
|
|
24
|
+
list(): Promise<AssistantSessionRow[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Hold `chatId` in this window (omit sessionId; server resolves from
|
|
27
|
+
* X-Ziggs-Session), move it to `sessionId`, or pass null to release.
|
|
28
|
+
*/
|
|
29
|
+
hold(chatId: string, sessionId?: string | null): Promise<{
|
|
30
|
+
success: true;
|
|
31
|
+
chatId: string;
|
|
32
|
+
sessionId: string | null;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
2
|
+
import { pollSurfaceError } from '../shared/rateLimit.js';
|
|
3
|
+
import { buildCredsHeaders } from './operatorHeaders.js';
|
|
4
|
+
/**
|
|
5
|
+
* List sibling windows and hold a chat in this one.
|
|
6
|
+
* Uses the same session headers as the inbox so "this window" is the
|
|
7
|
+
* X-Ziggs-Session the host already sends.
|
|
8
|
+
*/
|
|
9
|
+
export class SessionsClient {
|
|
10
|
+
creds;
|
|
11
|
+
constructor(creds) {
|
|
12
|
+
this.creds = creds;
|
|
13
|
+
if (!creds.operatorKey)
|
|
14
|
+
throw new Error('SessionsClient: operatorKey is required');
|
|
15
|
+
if (!creds.agentId)
|
|
16
|
+
throw new Error('SessionsClient: agentId is required');
|
|
17
|
+
}
|
|
18
|
+
headers() {
|
|
19
|
+
const headers = buildCredsHeaders({
|
|
20
|
+
operatorKey: this.creds.operatorKey,
|
|
21
|
+
agentId: this.creds.agentId,
|
|
22
|
+
laneId: this.creds.laneId,
|
|
23
|
+
});
|
|
24
|
+
if (this.creds.clientSessionId)
|
|
25
|
+
headers['X-Ziggs-Session'] = this.creds.clientSessionId;
|
|
26
|
+
if (this.creds.workspaceIds)
|
|
27
|
+
headers['X-Ziggs-Workspaces'] = this.creds.workspaceIds;
|
|
28
|
+
if (this.creds.app)
|
|
29
|
+
headers['X-Ziggs-App'] = this.creds.app;
|
|
30
|
+
if (this.creds.sessionName)
|
|
31
|
+
headers['X-Ziggs-Session-Name'] = this.creds.sessionName;
|
|
32
|
+
if (this.creds.instanceId)
|
|
33
|
+
headers['X-Ziggs-Instance'] = this.creds.instanceId;
|
|
34
|
+
return headers;
|
|
35
|
+
}
|
|
36
|
+
url(path) {
|
|
37
|
+
return `${getBackendUrl()}/agents/${encodeURIComponent(this.creds.agentId)}${path}`;
|
|
38
|
+
}
|
|
39
|
+
async list() {
|
|
40
|
+
const res = await fetch(this.url('/sessions'), {
|
|
41
|
+
method: 'GET',
|
|
42
|
+
headers: this.headers(),
|
|
43
|
+
});
|
|
44
|
+
const body = await res.json().catch(() => ({}));
|
|
45
|
+
if (!res.ok)
|
|
46
|
+
throw pollSurfaceError('SessionsClient.list', res, body);
|
|
47
|
+
const rows = body.sessions;
|
|
48
|
+
return Array.isArray(rows) ? rows : [];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Hold `chatId` in this window (omit sessionId; server resolves from
|
|
52
|
+
* X-Ziggs-Session), move it to `sessionId`, or pass null to release.
|
|
53
|
+
*/
|
|
54
|
+
async hold(chatId, sessionId) {
|
|
55
|
+
if (!chatId?.trim())
|
|
56
|
+
throw new Error('SessionsClient.hold: chatId is required');
|
|
57
|
+
const body = {
|
|
58
|
+
chatId: chatId.trim(),
|
|
59
|
+
};
|
|
60
|
+
if (sessionId !== undefined)
|
|
61
|
+
body.sessionId = sessionId;
|
|
62
|
+
const res = await fetch(this.url('/sessions/hold'), {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
headers: this.headers(),
|
|
65
|
+
body: JSON.stringify(body),
|
|
66
|
+
});
|
|
67
|
+
const parsed = await res.json().catch(() => ({}));
|
|
68
|
+
if (!res.ok)
|
|
69
|
+
throw pollSurfaceError('SessionsClient.hold', res, parsed);
|
|
70
|
+
return parsed;
|
|
71
|
+
}
|
|
72
|
+
}
|
package/dist/http/index.d.ts
CHANGED
|
@@ -31,6 +31,8 @@ export type { MyOrg, OrgResolution } from './OrgsClient.js';
|
|
|
31
31
|
export { AgentSearchClient } from './AgentSearchClient.js';
|
|
32
32
|
export { TelemetryClient } from './TelemetryClient.js';
|
|
33
33
|
export { InboxClient } from './InboxClient.js';
|
|
34
|
+
export { SessionsClient } from './SessionsClient.js';
|
|
35
|
+
export type { AssistantSessionRow } from './SessionsClient.js';
|
|
34
36
|
export { planInboxAck, planPartialInboxAck, inboxAckAllowed, inboxAckHandledIds, } from '../inboxAck.js';
|
|
35
37
|
export type { InboxAckDecision, InboxAckStep, InboxAckEnvelope, PlanInboxAckOptions, } from '../inboxAck.js';
|
|
36
38
|
export { WAKE_LANE_HEADER, WAKE_AGREEMENT_HEADER, laneHeader, laneUnderAgreement, buildOperatorHeaders, buildCredsHeaders, } from './operatorHeaders.js';
|
package/dist/http/index.js
CHANGED
|
@@ -21,6 +21,7 @@ export { fetchMyOrgs, resolveOrgSelector, fetchDelegateAccess, fetchHostedAgentA
|
|
|
21
21
|
export { AgentSearchClient } from './AgentSearchClient.js';
|
|
22
22
|
export { TelemetryClient } from './TelemetryClient.js';
|
|
23
23
|
export { InboxClient } from './InboxClient.js';
|
|
24
|
+
export { SessionsClient } from './SessionsClient.js';
|
|
24
25
|
export { planInboxAck, planPartialInboxAck, inboxAckAllowed, inboxAckHandledIds, } from '../inboxAck.js';
|
|
25
26
|
// The lane header, built in one place — see operatorHeaders.ts. Exported
|
|
26
27
|
// because the MCP transports in agent-sdk and ziggs-mcp send it too, and a
|