@ziggs-ai/api-client 0.26.0 → 0.27.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.
|
@@ -304,7 +304,7 @@ export const listArtifactsCapability = {
|
|
|
304
304
|
mcp: 'List business artifacts YOU authored, across every scope and none; tool-operation and thought traces are excluded. Use this to find something you ' +
|
|
305
305
|
'recorded free-standing (no chat/agreement/task), which the scope reads cannot return. ' +
|
|
306
306
|
'To read an artifact someone shared WITH you, use ziggs_context_read with via=artifact:<id>; ' +
|
|
307
|
-
'to see what has been shared with you, use ziggs_grant_list with scopeKind
|
|
307
|
+
'to see what has been shared with you, use ziggs_grant_list with scopeKind ["artifact"].',
|
|
308
308
|
},
|
|
309
309
|
annotation: 'read-only',
|
|
310
310
|
params: {
|
|
@@ -51,8 +51,8 @@ export const openConversationCapability = {
|
|
|
51
51
|
names: { sdk: 'chat_open', mcp: 'ziggs_chat_open' },
|
|
52
52
|
title: 'Start or reuse a conversation',
|
|
53
53
|
descriptions: {
|
|
54
|
-
sdk: 'Open a conversation or explicitly invite people to a room. participantId opens/reuses the acting agent’s pair conversation with one person or agent; newChat opens a separate subject. participantIds creates a separate group with the acting caller and those people; include a stable idempotencyKey for retries. chatId plus participantIds invites people into that exact room, requiring room access and admission authority. Every person needs a valid contact basis: shared organization membership, a link, or an applicable agreement. Each participant keeps their own agent and work relationships; opening a group selects no service agreement. Group creation never expands an existing private DM. Invited teammates read from admission onward.
|
|
55
|
-
mcp: 'Open a conversation or explicitly invite people to a room. participantId opens/reuses the acting agent’s pair conversation with one person or agent; newChat opens a separate subject. participantIds creates a separate group with the acting caller and those people; include a stable idempotencyKey for retries. chatId plus participantIds invites people into that exact room, requiring room access and admission authority. Every person needs a valid contact basis: shared organization membership, a link, or an applicable agreement. Each participant keeps their own agent and work relationships; opening a group selects no service agreement. Group creation never expands an existing private DM. Invited teammates read from admission onward.
|
|
54
|
+
sdk: 'Open a conversation or explicitly invite people to a room. participantId opens/reuses the acting agent’s pair conversation with one person or agent; newChat opens a separate subject. participantIds creates a separate group with the acting caller and those people; include a stable idempotencyKey for retries. chatId plus participantIds invites people into that exact room, requiring room access and admission authority. Every person needs a valid contact basis: shared organization membership, a link, or an applicable agreement. Each participant keeps their own agent and work relationships; opening a group selects no service agreement. Group creation never expands an existing private DM. Invited teammates read from admission onward. A new group is opened with people. With chatId, participantIds may also name agents: each joins through the same admission as the web app, so it must be reachable (your own, one of your company, published, or already engaged), and an agent you invite waits until the people in the room approve it in the app; the result lists each id as added, already-here or pending. Your own missing seat is asked for with access_request. Reach another person through their user id, not an unpublished agent of theirs. If you cannot reach someone your person knows, ask your person to introduce you in a room. Opening does not send a message; chat_send must name its intended receiverId to guarantee a target. To list accessible rooms, use grant_list with scopeKind ["chat"].',
|
|
55
|
+
mcp: 'Open a conversation or explicitly invite people to a room. participantId opens/reuses the acting agent’s pair conversation with one person or agent; newChat opens a separate subject. participantIds creates a separate group with the acting caller and those people; include a stable idempotencyKey for retries. chatId plus participantIds invites people into that exact room, requiring room access and admission authority. Every person needs a valid contact basis: shared organization membership, a link, or an applicable agreement. Each participant keeps their own agent and work relationships; opening a group selects no service agreement. Group creation never expands an existing private DM. Invited teammates read from admission onward. A new group is opened with people. With chatId, participantIds may also name agents: each joins through the same admission as the web app, so it must be reachable (your own, one of your company, published, or already engaged), and an agent you invite waits until the people in the room approve it in the app; the result lists each id as added, already-here or pending. Your own missing seat is asked for with ziggs_access_request. Reach another person through their user id, not an unpublished agent of theirs. For missing access to a known room, use ziggs_access_request; opening another room does not recover its history. Opening does not send a message; ziggs_chat_send must name its intended receiverId to guarantee a target.',
|
|
56
56
|
},
|
|
57
57
|
annotation: 'write',
|
|
58
58
|
params: {
|
|
@@ -60,7 +60,7 @@ export const openConversationCapability = {
|
|
|
60
60
|
type: 'string',
|
|
61
61
|
description: 'Known user or agent id from search, a directory, a chat, or an agreement. For a teammate or a linked person, their user id, not an agent of theirs. No existing chat is required; do not guess ids.',
|
|
62
62
|
},
|
|
63
|
-
participantIds: { type: 'array', items: { type: 'string' }, description: '1–20 known
|
|
63
|
+
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.' },
|
|
64
64
|
chatId: { type: 'string', description: 'Existing room to invite participantIds into. Never creates another room. Omit creation options and agreementId.' },
|
|
65
65
|
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.' },
|
|
66
66
|
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.' },
|
|
@@ -87,7 +87,7 @@ export const openConversationCapability = {
|
|
|
87
87
|
if (args.participantId !== undefined || !Array.isArray(args.participantIds) ||
|
|
88
88
|
args.participantIds.length < 1 || args.participantIds.length > 20 ||
|
|
89
89
|
args.participantIds.some(id => typeof id !== 'string' || !id.trim())) {
|
|
90
|
-
throw new Error('Use participantIds containing 1–20
|
|
90
|
+
throw new Error('Use participantIds containing 1–20 ids, without participantId');
|
|
91
91
|
}
|
|
92
92
|
if (!args.chatId && (typeof args.idempotencyKey !== 'string' || !args.idempotencyKey.trim())) {
|
|
93
93
|
throw new Error('Group creation requires an idempotencyKey; reuse it when retrying');
|
|
@@ -96,7 +96,7 @@ export const openConversationCapability = {
|
|
|
96
96
|
else if (args.chatId || args.idempotencyKey) {
|
|
97
97
|
throw new Error('chatId and idempotencyKey require participantIds');
|
|
98
98
|
}
|
|
99
|
-
const { chatId, reused } = await openConversation({
|
|
99
|
+
const { chatId, reused, invited } = await openConversation({
|
|
100
100
|
...(typeof args.participantId === 'string' ? { participantId: args.participantId } : {}),
|
|
101
101
|
...(Array.isArray(args.participantIds) ? { participantIds: args.participantIds } : {}),
|
|
102
102
|
...(typeof args.chatId === 'string' ? { chatId: args.chatId } : {}),
|
|
@@ -106,14 +106,14 @@ export const openConversationCapability = {
|
|
|
106
106
|
...(typeof args.agreementId === 'string' && args.agreementId ? { agreementId: args.agreementId } : {}),
|
|
107
107
|
}, fullCreds(env));
|
|
108
108
|
const lister = env.surface === 'mcp' ? 'ziggs_grant_list' : 'grant_list';
|
|
109
|
-
const grantNote = `Use ${lister} scopeKind
|
|
109
|
+
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.`;
|
|
110
110
|
// word the note from the outcome instead of covering both cases.
|
|
111
111
|
// "Open (or reused)" told the agent the distinction existed and then
|
|
112
112
|
// withheld it — worse than silence, because the agent cannot even tell
|
|
113
113
|
// there is something to look up. A backend too old to report it keeps the
|
|
114
114
|
// old both-cases wording, and `reused` is simply absent from the result.
|
|
115
115
|
const outcomeNote = args.chatId
|
|
116
|
-
?
|
|
116
|
+
? inviteNote(invited)
|
|
117
117
|
: reused === true
|
|
118
118
|
? 'Reused the conversation you already had with the named participants, so it may already hold history — read it before you speak.'
|
|
119
119
|
: reused === false
|
|
@@ -123,8 +123,25 @@ export const openConversationCapability = {
|
|
|
123
123
|
chatId,
|
|
124
124
|
actingAgentId: fullCreds(env).agentId,
|
|
125
125
|
...(typeof reused === 'boolean' ? { reused } : {}),
|
|
126
|
+
...(invited ? { invited } : {}),
|
|
126
127
|
note: `${outcomeNote} ${grantNote}`,
|
|
127
128
|
};
|
|
128
129
|
},
|
|
129
130
|
};
|
|
131
|
+
/** Say what happened to each invited id, so the agent reports it truthfully. */
|
|
132
|
+
function inviteNote(invited) {
|
|
133
|
+
if (!invited?.length) {
|
|
134
|
+
return 'The named people can participate in this room. Their history access remains bounded by their grants.';
|
|
135
|
+
}
|
|
136
|
+
const ids = (status) => invited.filter((row) => row.status === status).map((row) => row.id);
|
|
137
|
+
const parts = [];
|
|
138
|
+
if (ids('added').length)
|
|
139
|
+
parts.push(`Added: ${ids('added').join(', ')}.`);
|
|
140
|
+
if (ids('already-here').length)
|
|
141
|
+
parts.push(`Already in the room: ${ids('already-here').join(', ')}.`);
|
|
142
|
+
if (ids('pending').length) {
|
|
143
|
+
parts.push(`Waiting for the people in the room to approve: ${ids('pending').join(', ')}. They see it in the app; the agent cannot read or write here until then, and asking again does not make a second request.`);
|
|
144
|
+
}
|
|
145
|
+
return `${parts.join(' ')} Invited people read from now on.`;
|
|
146
|
+
}
|
|
130
147
|
export const CHAT_CAPABILITIES = [openConversationCapability];
|
|
@@ -19,7 +19,7 @@ export const connectionProxyCapability = {
|
|
|
19
19
|
sdk: "Use a named-connector stored connection (e.g. the owner's GitHub/Jira) without ever seeing the credential. " +
|
|
20
20
|
"Calls the backend connections proxy with a grant the owner issued to this agent. " +
|
|
21
21
|
'Not for remote MCP servers (provider "mcp") — those use mcp_tool_call / mcp_tools_list; proxy refuses them with "Unknown provider: mcp". ' +
|
|
22
|
-
"Don't know connectionId/grantId yet? Use grant_list (scopeKind
|
|
22
|
+
"Don't know connectionId/grantId yet? Use grant_list (scopeKind [\"connection\"]) or connection_list_grants first.",
|
|
23
23
|
mcp: "Use a named-connector stored connection (e.g. the owner's GitHub/Jira — NOT an agent-to-agent Link, see ziggs_link_list) without ever seeing the credential. " +
|
|
24
24
|
"Calls the backend connections proxy with a grant the owner issued to this agent. " +
|
|
25
25
|
'Not for remote MCP servers (provider "mcp") — those use ziggs_mcp_tool_call / ziggs_mcp_tools_list; proxy refuses them with "Unknown provider: mcp". ' +
|
|
@@ -128,7 +128,7 @@ export const requestConnectionCapability = {
|
|
|
128
128
|
? "A connection-consent card is now in the chat awaiting your principal. Tell the human now (pull-only MCP has no push) — they approve it right in the chat. " +
|
|
129
129
|
"Once approved, the connection + grant appear in ziggs_connection_list for ziggs_mcp_tools_list / ziggs_mcp_tool_call."
|
|
130
130
|
: "A connection-consent card is now in the chat awaiting your principal — they approve it right there. " +
|
|
131
|
-
"Once approved, the connection + grant appear in grant_list (scopeKind
|
|
131
|
+
"Once approved, the connection + grant appear in grant_list (scopeKind [\"connection\"]) / connection_list_grants for mcp_tools_list / mcp_tool_call.",
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
catch (e) {
|
|
@@ -64,7 +64,7 @@ export const contextReadCapability = {
|
|
|
64
64
|
title: 'Read context you hold',
|
|
65
65
|
descriptions: {
|
|
66
66
|
sdk: `Read the contents of a scope you already hold a grant for: ${CONTEXT_READ_TYPES.join(' | ')}. Each type reads through its own entries — ${VIA_BY_TYPE}. Use grant_list first to see which scopes your grants cover, then read through any of them. ${ARTIFACT_VIA_NOTE}. Cursored; all access is grant-fenced server-side.`,
|
|
67
|
-
mcp: `Read the contents of a scope you already hold: ${CONTEXT_READ_TYPES.join(' | ')} (the type param). Each type accepts its own via entries — ${VIA_BY_TYPE} — and any other pairing is refused. ${ARTIFACT_VIA_NOTE} (e.g. an artifact someone shared with you; ziggs_grant_list scopeKind
|
|
67
|
+
mcp: `Read the contents of a scope you already hold: ${CONTEXT_READ_TYPES.join(' | ')} (the type param). Each type accepts its own via entries — ${VIA_BY_TYPE} — and any other pairing is refused. ${ARTIFACT_VIA_NOTE} (e.g. an artifact someone shared with you; ziggs_grant_list with scopeKind ["artifact"] shows those). Forward-delta with after+direction=forward; cursor pagination; contextGrantId pins a grant. The response carries a \`readPlan\` with the next page and/or forward-delta call pre-filled (after=this page's latestSequence), so you can keep reading without rebuilding args. This is the single read path for all four types — to discover which scopes exist, use the listers: ziggs_chat_list, ziggs_task_list, ziggs_agreement_list, ziggs_grant_list, ziggs_link_list.`,
|
|
68
68
|
},
|
|
69
69
|
annotation: 'read-only',
|
|
70
70
|
params: {
|
|
@@ -13,6 +13,14 @@ import { type Creds } from '../types.js';
|
|
|
13
13
|
* with without a second call.
|
|
14
14
|
*/
|
|
15
15
|
export type ChatSummary = ChatReadDto;
|
|
16
|
+
/** What happened to one id when chat_open invited into an existing room. */
|
|
17
|
+
export interface ChatOpenInvite {
|
|
18
|
+
id: string;
|
|
19
|
+
kind: 'person' | 'agent';
|
|
20
|
+
/** pending: an agent's joining waits for the people in the room to approve it. */
|
|
21
|
+
status: 'added' | 'already-here' | 'pending';
|
|
22
|
+
admissionId?: string;
|
|
23
|
+
}
|
|
16
24
|
export interface OpenConversationInput {
|
|
17
25
|
participantId?: string;
|
|
18
26
|
participantIds?: string[];
|
|
@@ -29,6 +37,7 @@ export declare function openConversation(participant: string | OpenConversationI
|
|
|
29
37
|
}): Promise<{
|
|
30
38
|
chatId: string;
|
|
31
39
|
reused?: boolean;
|
|
40
|
+
invited?: ChatOpenInvite[];
|
|
32
41
|
}>;
|
|
33
42
|
export interface SendChatMessageInput {
|
|
34
43
|
/**
|
|
@@ -135,6 +144,7 @@ export declare class ChatClient {
|
|
|
135
144
|
}): Promise<{
|
|
136
145
|
chatId: string;
|
|
137
146
|
reused?: boolean;
|
|
147
|
+
invited?: ChatOpenInvite[];
|
|
138
148
|
}>;
|
|
139
149
|
addMember(input: AddChatMemberInput): Promise<AddChatMemberResult>;
|
|
140
150
|
sendMessage(input: SendChatMessageInput): Promise<SendChatMessageResult>;
|
package/dist/http/ChatClient.js
CHANGED
|
@@ -38,9 +38,13 @@ 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 invited = Array.isArray(data['invited'])
|
|
42
|
+
? data['invited']
|
|
43
|
+
: undefined;
|
|
41
44
|
return {
|
|
42
45
|
chatId: data['chatId'],
|
|
43
46
|
...(typeof reused === 'boolean' ? { reused } : {}),
|
|
47
|
+
...(invited ? { invited } : {}),
|
|
44
48
|
};
|
|
45
49
|
}
|
|
46
50
|
/**
|