@ziggs-ai/api-client 0.38.0 → 0.39.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/CHANGELOG.md +34 -0
- package/README.md +14 -36
- package/dist/capabilities/agreementVerbs.js +13 -21
- package/dist/capabilities/agreements.d.ts +2 -3
- package/dist/capabilities/agreements.js +8 -43
- package/dist/capabilities/artifacts.d.ts +6 -0
- package/dist/capabilities/artifacts.js +84 -43
- package/dist/capabilities/connections.js +10 -7
- package/dist/capabilities/context.d.ts +1 -1
- package/dist/capabilities/context.js +52 -45
- package/dist/capabilities/discovery.js +5 -5
- package/dist/capabilities/everyday.d.ts +1 -1
- package/dist/capabilities/everyday.js +1 -2
- package/dist/capabilities/index.d.ts +3 -4
- package/dist/capabilities/index.js +3 -4
- package/dist/capabilities/introductions.d.ts +1 -0
- package/dist/capabilities/introductions.js +64 -17
- package/dist/capabilities/links.d.ts +1 -9
- package/dist/capabilities/links.js +40 -39
- package/dist/capabilities/mcpBriefs.js +41 -34
- package/dist/capabilities/messaging.d.ts +9 -0
- package/dist/capabilities/messaging.js +11 -0
- package/dist/capabilities/nextCall.js +8 -17
- package/dist/capabilities/sources.d.ts +2 -3
- package/dist/capabilities/sources.js +1 -2
- package/dist/capabilities/tasks.d.ts +1 -0
- package/dist/capabilities/tasks.js +43 -2
- package/dist/capabilities/toolLane.js +2 -2
- package/dist/engagementGuide.d.ts +2 -2
- package/dist/engagementGuide.js +6 -6
- package/dist/handles.d.ts +1 -1
- package/dist/handles.js +2 -2
- package/dist/http/AgreementClient.d.ts +25 -63
- package/dist/http/AgreementClient.js +14 -65
- package/dist/http/ArtifactsClient.d.ts +31 -19
- package/dist/http/ArtifactsClient.js +43 -62
- package/dist/http/ConnectionsClient.d.ts +6 -7
- package/dist/http/ConnectionsClient.js +5 -3
- package/dist/http/ContextDiscoveryClient.d.ts +2 -2
- package/dist/http/ContextGrantsClient.d.ts +9 -15
- package/dist/http/ContextGrantsClient.js +3 -5
- package/dist/http/ContextOpenClient.d.ts +5 -6
- package/dist/http/ContextOpenClient.js +11 -4
- package/dist/http/ContextReadClient.d.ts +23 -27
- package/dist/http/ContextReadClient.js +24 -23
- package/dist/http/ExecutionContextClient.d.ts +5 -1
- package/dist/http/ExecutionContextClient.js +48 -1
- package/dist/http/IntroductionsClient.d.ts +33 -4
- package/dist/http/IntroductionsClient.js +6 -2
- package/dist/http/MessageRecordsClient.d.ts +36 -0
- package/dist/http/MessageRecordsClient.js +30 -0
- package/dist/http/SessionsClient.d.ts +5 -5
- package/dist/http/SessionsClient.js +6 -6
- package/dist/http/TaskClient.d.ts +35 -6
- package/dist/http/TaskClient.js +38 -36
- package/dist/http/agreementFlows.d.ts +2 -3
- package/dist/http/agreementFlows.js +5 -5
- package/dist/http/index.d.ts +3 -5
- package/dist/http/index.js +3 -4
- package/dist/http/operatorHeaders.d.ts +3 -0
- package/dist/http/operatorHeaders.js +14 -5
- package/dist/inboxAck.d.ts +2 -2
- package/dist/inboxAck.js +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/types.d.ts +25 -55
- package/package.json +2 -2
- package/dist/capabilities/chat.d.ts +0 -43
- package/dist/capabilities/chat.js +0 -196
- package/dist/capabilities/chatListFields.d.ts +0 -14
- package/dist/capabilities/chatListFields.js +0 -61
- package/dist/http/ChatClient.d.ts +0 -187
- package/dist/http/ChatClient.js +0 -219
- package/dist/http/MessagesClient.d.ts +0 -40
- package/dist/http/MessagesClient.js +0 -81
package/dist/http/ChatClient.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { decodeOperatorKeyClaims } from '../shared/operatorKey.js';
|
|
2
|
-
import { runtimeLog } from '../shared/runtimeLog.js';
|
|
3
|
-
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
4
|
-
import { throwApiError } from '../shared/apiError.js';
|
|
5
|
-
import { buildCredsHeaders } from './operatorHeaders.js';
|
|
6
|
-
// Auth, agent and the wake's lane, from the one helper — see operatorHeaders.
|
|
7
|
-
const buildHeaders = buildCredsHeaders;
|
|
8
|
-
function assertCreds(creds, op) {
|
|
9
|
-
if (!creds?.operatorKey)
|
|
10
|
-
throw new Error(`operatorKey is required for ${op}`);
|
|
11
|
-
if (!creds?.agentId && !decodeOperatorKeyClaims(creds.operatorKey)?.connectionClientId)
|
|
12
|
-
throw new Error(`agentId is required for ${op}`);
|
|
13
|
-
}
|
|
14
|
-
export async function openConversation(participant, creds, { newChat = false, agreementId, createIfMissing } = {}) {
|
|
15
|
-
const input = typeof participant === 'string'
|
|
16
|
-
? { participantId: participant, ...(newChat ? { newChat } : {}), ...(agreementId ? { agreementId } : {}), ...(createIfMissing !== undefined ? { createIfMissing } : {}) }
|
|
17
|
-
: participant;
|
|
18
|
-
const resumeHire = !!input?.chatId && !!input.agreementId;
|
|
19
|
-
if (resumeHire && (input.participantId || input.participantIds || input.newChat !== undefined || input.name !== undefined || input.idempotencyKey !== undefined || input.createIfMissing !== undefined)) {
|
|
20
|
-
throw new Error('To resume hire admission, pass only chatId and agreementId');
|
|
21
|
-
}
|
|
22
|
-
if (!input || (!resumeHire && !input.participantId && !input.participantIds?.length)) {
|
|
23
|
-
throw new Error('participantId is required, or use participantIds to invite people');
|
|
24
|
-
}
|
|
25
|
-
assertCreds(creds, 'open conversation');
|
|
26
|
-
const route = resumeHire
|
|
27
|
-
? `/chats/${encodeURIComponent(input.chatId)}/hires/${encodeURIComponent(input.agreementId)}/admission`
|
|
28
|
-
: '/chats';
|
|
29
|
-
const res = await fetch(`${getBackendUrl()}${route}`, {
|
|
30
|
-
method: 'POST',
|
|
31
|
-
headers: buildHeaders(creds),
|
|
32
|
-
// Only sent when asked for: an older backend ignores the field, so a
|
|
33
|
-
// caller that never wants a separate room behaves identically either way.
|
|
34
|
-
body: JSON.stringify(resumeHire ? {} : input),
|
|
35
|
-
});
|
|
36
|
-
if (!res.ok) {
|
|
37
|
-
const body = await res.text().catch(() => '');
|
|
38
|
-
throwApiError(res, body, `openConversation failed: ${res.status} ${res.statusText}`);
|
|
39
|
-
}
|
|
40
|
-
const data = await res.json().catch(() => null);
|
|
41
|
-
if (!data?.['chatId'] || typeof data['chatId'] !== 'string') {
|
|
42
|
-
throw new Error('Invalid response: expected { chatId } from POST /chats');
|
|
43
|
-
}
|
|
44
|
-
// left UNDEFINED rather than defaulted when the backend does not
|
|
45
|
-
// send it. A backend from before this field cannot be assumed to have created
|
|
46
|
-
// the room — defaulting to false would report a reused conversation as fresh,
|
|
47
|
-
// which is worse than saying nothing.
|
|
48
|
-
if (resumeHire && (data.chatId !== input.chatId || data.agreementId !== input.agreementId || !['ready', 'admission_failed'].includes(String(data.status)))) {
|
|
49
|
-
throw new Error('Invalid hire-admission response: expected the selected chat, hire and admission status');
|
|
50
|
-
}
|
|
51
|
-
const reused = data['reused'];
|
|
52
|
-
const name = data['name'];
|
|
53
|
-
const invited = Array.isArray(data['invited'])
|
|
54
|
-
? data['invited']
|
|
55
|
-
: undefined;
|
|
56
|
-
return {
|
|
57
|
-
chatId: data['chatId'],
|
|
58
|
-
...(resumeHire ? {
|
|
59
|
-
agreementId: input.agreementId,
|
|
60
|
-
status: data.status,
|
|
61
|
-
...(typeof data.reason === 'string' ? { reason: data.reason } : {}),
|
|
62
|
-
} : {}),
|
|
63
|
-
...(typeof reused === 'boolean' ? { reused } : {}),
|
|
64
|
-
...(typeof name === 'string' && name ? { name } : {}),
|
|
65
|
-
...(invited ? { invited } : {}),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function coverageFrom(value) {
|
|
69
|
-
if (!value || typeof value !== 'object')
|
|
70
|
-
return null;
|
|
71
|
-
const row = value;
|
|
72
|
-
return typeof row['agreementId'] === 'string' &&
|
|
73
|
-
typeof row['message'] === 'string' &&
|
|
74
|
-
typeof row['messagesUsed'] === 'number' &&
|
|
75
|
-
(row['messageLimit'] === null || typeof row['messageLimit'] === 'number')
|
|
76
|
-
? {
|
|
77
|
-
agreementId: row['agreementId'],
|
|
78
|
-
messagesUsed: row['messagesUsed'],
|
|
79
|
-
messageLimit: row['messageLimit'],
|
|
80
|
-
message: row['message'],
|
|
81
|
-
}
|
|
82
|
-
: null;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* POST /chats/:chatId/members — add user/agent; agent-invite may return pending admission.
|
|
86
|
-
*/
|
|
87
|
-
export async function addChatMember(input, creds) {
|
|
88
|
-
assertCreds(creds, 'add chat member');
|
|
89
|
-
const res = await fetch(`${getBackendUrl()}/chats/${encodeURIComponent(input.chatId)}/members`, {
|
|
90
|
-
method: 'POST',
|
|
91
|
-
headers: buildHeaders(creds),
|
|
92
|
-
body: JSON.stringify({
|
|
93
|
-
chatId: input.chatId,
|
|
94
|
-
memberId: input.memberId,
|
|
95
|
-
memberType: input.memberType,
|
|
96
|
-
temporal: input.temporal,
|
|
97
|
-
}),
|
|
98
|
-
});
|
|
99
|
-
const body = await res.text().catch(() => '');
|
|
100
|
-
if (!res.ok) {
|
|
101
|
-
throwApiError(res, body, `addChatMember failed: ${res.status} ${res.statusText}`);
|
|
102
|
-
}
|
|
103
|
-
const data = JSON.parse(body);
|
|
104
|
-
if (data['status'] === 'pending' && data['pendingAdmission']) {
|
|
105
|
-
return {
|
|
106
|
-
status: 'pending',
|
|
107
|
-
pendingAdmission: data['pendingAdmission'],
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
if (data['status'] === 'approved') {
|
|
111
|
-
return { status: 'approved', chat: data['chat'] };
|
|
112
|
-
}
|
|
113
|
-
return { chat: data['chat'] };
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* POST /chats/:chatId/messages, or POST /chats/messages when `to` names
|
|
117
|
-
* an existing participant and `chatId` is omitted.
|
|
118
|
-
*/
|
|
119
|
-
export async function sendChatMessage(input, creds) {
|
|
120
|
-
assertCreds(creds, 'send chat message');
|
|
121
|
-
const chatId = typeof input.chatId === 'string' ? input.chatId.trim() : '';
|
|
122
|
-
const to = typeof input.to === 'string' ? input.to.trim() : '';
|
|
123
|
-
if (!chatId && !to) {
|
|
124
|
-
throw new Error('chatId or to is required for send chat message');
|
|
125
|
-
}
|
|
126
|
-
const entryType = input.entryType ?? 'message';
|
|
127
|
-
const contentType = input.contentType ?? 'text';
|
|
128
|
-
const personSend = !chatId && Boolean(to);
|
|
129
|
-
const url = personSend
|
|
130
|
-
? `${getBackendUrl()}/chats/messages`
|
|
131
|
-
: `${getBackendUrl()}/chats/${encodeURIComponent(chatId)}/messages`;
|
|
132
|
-
const res = await fetch(url, {
|
|
133
|
-
method: 'POST',
|
|
134
|
-
headers: buildHeaders(creds),
|
|
135
|
-
body: JSON.stringify({
|
|
136
|
-
...(personSend ? { to } : { chatId }),
|
|
137
|
-
messageId: input.messageId,
|
|
138
|
-
text: input.text,
|
|
139
|
-
entryType,
|
|
140
|
-
contentType,
|
|
141
|
-
// Canonical wire shape is `{ id, type? }`; bare strings are still
|
|
142
|
-
// accepted by the backend after edge normalize, but first-party
|
|
143
|
-
// clients send the object.
|
|
144
|
-
receiver: input.receiverId ? { id: input.receiverId } : undefined,
|
|
145
|
-
underAgreementId: input.underAgreementId,
|
|
146
|
-
conversationAgreementId: input.conversationAgreementId,
|
|
147
|
-
taskId: input.taskId,
|
|
148
|
-
...(input.sources ? { sources: input.sources } : {}),
|
|
149
|
-
}),
|
|
150
|
-
});
|
|
151
|
-
if (!res.ok) {
|
|
152
|
-
const body = await res.text().catch(() => '');
|
|
153
|
-
throwApiError(res, body, `sendChatMessage failed: ${res.status} ${res.statusText}`);
|
|
154
|
-
}
|
|
155
|
-
const data = (await res.json().catch(() => null));
|
|
156
|
-
const delivery = data?.['delivery'];
|
|
157
|
-
const coverage = coverageFrom(data?.['coverage']);
|
|
158
|
-
return {
|
|
159
|
-
success: Boolean(data?.['success']),
|
|
160
|
-
message: String(data?.['message'] ?? 'ok'),
|
|
161
|
-
messageId: String(data?.['messageId'] ?? input.messageId),
|
|
162
|
-
chatId: String(data?.['chatId'] ?? chatId),
|
|
163
|
-
// Passed through as the server reported it, or absent. Never reconstructed
|
|
164
|
-
// from the request: the whole point is that the destination may not be the
|
|
165
|
-
// one the caller named.
|
|
166
|
-
...(delivery && typeof delivery === 'object'
|
|
167
|
-
? { delivery: delivery }
|
|
168
|
-
: {}),
|
|
169
|
-
...(coverage ? { coverage } : {}),
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
export async function listMyChats(creds, filters = {}) {
|
|
173
|
-
assertCreds(creds, 'list my chats');
|
|
174
|
-
const query = new URLSearchParams();
|
|
175
|
-
if (filters.participantId)
|
|
176
|
-
query.set('participantId', filters.participantId);
|
|
177
|
-
if (filters.readable !== undefined)
|
|
178
|
-
query.set('readable', String(filters.readable));
|
|
179
|
-
const qs = query.toString();
|
|
180
|
-
// empty array only for a genuine empty 200; any failure (non-2xx /
|
|
181
|
-
// network) throws so ziggs_chat_list reports a real error instead of "you
|
|
182
|
-
// have no chats". HTTP failures are ApiError (status/body/code).
|
|
183
|
-
let res;
|
|
184
|
-
try {
|
|
185
|
-
res = await fetch(`${getBackendUrl()}/chats/mine${qs ? `?${qs}` : ''}`, {
|
|
186
|
-
method: 'GET',
|
|
187
|
-
headers: buildHeaders(creds),
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
catch (e) {
|
|
191
|
-
runtimeLog.warn('ChatClient', `⚠️ listMyChats failed: ${e.message}`);
|
|
192
|
-
throw new Error(`GET /chats/mine network error: ${e.message}`);
|
|
193
|
-
}
|
|
194
|
-
if (!res.ok) {
|
|
195
|
-
const body = await res.text().catch(() => '');
|
|
196
|
-
runtimeLog.warn('ChatClient', `⚠️ listMyChats failed: ${res.status} ${res.statusText} ${body?.slice(0, 200)}`);
|
|
197
|
-
throwApiError(res, body, `GET /chats/mine failed: ${res.status}`);
|
|
198
|
-
}
|
|
199
|
-
const data = await res.json().catch(() => null);
|
|
200
|
-
return Array.isArray(data?.['chats']) ? data['chats'] : [];
|
|
201
|
-
}
|
|
202
|
-
export class ChatClient {
|
|
203
|
-
creds;
|
|
204
|
-
/**
|
|
205
|
-
* @param operatorKey Agent-scoped or fleet operator key.
|
|
206
|
-
* @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
|
|
207
|
-
*/
|
|
208
|
-
constructor(operatorKey, agentId) {
|
|
209
|
-
if (!operatorKey)
|
|
210
|
-
throw new Error('ChatClient: operatorKey is required');
|
|
211
|
-
// agentId may be absent for agent-scoped keys; the Creds-based
|
|
212
|
-
// standalone functions still assert it per call.
|
|
213
|
-
this.creds = { operatorKey, agentId };
|
|
214
|
-
}
|
|
215
|
-
open(participant, opts) { return openConversation(participant, this.creds, opts); }
|
|
216
|
-
addMember(input) { return addChatMember(input, this.creds); }
|
|
217
|
-
sendMessage(input) { return sendChatMessage(input, this.creds); }
|
|
218
|
-
listMine() { return listMyChats(this.creds); }
|
|
219
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
export interface ListMessagesOptions {
|
|
2
|
-
/** ISO timestamp; only entries with `timestamp > after` are returned. */
|
|
3
|
-
after?: string;
|
|
4
|
-
/** Page size, default 100, hard cap 1000. */
|
|
5
|
-
limit?: number;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* The chat message URL.
|
|
9
|
-
*
|
|
10
|
-
* `after` is a forward delta: the server returns that page only when both
|
|
11
|
-
* `after` and `direction=forward` are set. Omitting both is the newest page,
|
|
12
|
-
* which is how a person asks what just happened without already knowing a time.
|
|
13
|
-
*/
|
|
14
|
-
export declare function messagesListUrl(base: string, chatId: string, opts?: ListMessagesOptions): string;
|
|
15
|
-
export interface ListMessagesResult {
|
|
16
|
-
messages: unknown[];
|
|
17
|
-
latestSequence: string | null;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Read-side client for forward-delta message reads.
|
|
21
|
-
*
|
|
22
|
-
* Hits the canonical `GET /chats/:chatId/messages?after=&direction=forward&limit=`
|
|
23
|
-
* endpoint and returns a `{ messages, latestSequence }` envelope
|
|
24
|
-
* (`chat-messaging.controller.listMessagesForward` →
|
|
25
|
-
* `MessagesService.listForChat`).
|
|
26
|
-
*/
|
|
27
|
-
export declare class MessagesClient {
|
|
28
|
-
private readonly operatorKey;
|
|
29
|
-
private readonly agentId;
|
|
30
|
-
constructor(operatorKey: string, agentId: string);
|
|
31
|
-
list(chatId: string, opts?: ListMessagesOptions): Promise<ListMessagesResult>;
|
|
32
|
-
/**
|
|
33
|
-
* Newest page. No `after`, so the server walks backward from now.
|
|
34
|
-
* `list` is the forward delta and cannot answer "what just happened".
|
|
35
|
-
*/
|
|
36
|
-
listLatest(chatId: string, opts?: {
|
|
37
|
-
limit?: number;
|
|
38
|
-
}): Promise<ListMessagesResult>;
|
|
39
|
-
private _headers;
|
|
40
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { decodeOperatorKeyClaims } from '../shared/operatorKey.js';
|
|
2
|
-
import { buildOperatorHeaders } from './operatorHeaders.js';
|
|
3
|
-
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
4
|
-
import { throwApiError } from '../shared/apiError.js';
|
|
5
|
-
/**
|
|
6
|
-
* The chat message URL.
|
|
7
|
-
*
|
|
8
|
-
* `after` is a forward delta: the server returns that page only when both
|
|
9
|
-
* `after` and `direction=forward` are set. Omitting both is the newest page,
|
|
10
|
-
* which is how a person asks what just happened without already knowing a time.
|
|
11
|
-
*/
|
|
12
|
-
export function messagesListUrl(base, chatId, opts = {}) {
|
|
13
|
-
const url = new URL(`${base}/chats/${encodeURIComponent(chatId)}/messages`);
|
|
14
|
-
if (opts.after) {
|
|
15
|
-
url.searchParams.set('direction', 'forward');
|
|
16
|
-
url.searchParams.set('after', opts.after);
|
|
17
|
-
}
|
|
18
|
-
if (opts.limit != null)
|
|
19
|
-
url.searchParams.set('limit', String(opts.limit));
|
|
20
|
-
return url.toString();
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Read-side client for forward-delta message reads.
|
|
24
|
-
*
|
|
25
|
-
* Hits the canonical `GET /chats/:chatId/messages?after=&direction=forward&limit=`
|
|
26
|
-
* endpoint and returns a `{ messages, latestSequence }` envelope
|
|
27
|
-
* (`chat-messaging.controller.listMessagesForward` →
|
|
28
|
-
* `MessagesService.listForChat`).
|
|
29
|
-
*/
|
|
30
|
-
export class MessagesClient {
|
|
31
|
-
operatorKey;
|
|
32
|
-
agentId;
|
|
33
|
-
constructor(operatorKey, agentId) {
|
|
34
|
-
if (!operatorKey)
|
|
35
|
-
throw new Error('MessagesClient: operatorKey is required');
|
|
36
|
-
if (!agentId && !decodeOperatorKeyClaims(operatorKey)?.connectionClientId)
|
|
37
|
-
throw new Error('MessagesClient: agentId is required (operator-token impersonation)');
|
|
38
|
-
this.operatorKey = operatorKey;
|
|
39
|
-
this.agentId = agentId;
|
|
40
|
-
}
|
|
41
|
-
async list(chatId, opts = {}) {
|
|
42
|
-
if (!chatId)
|
|
43
|
-
return { messages: [], latestSequence: null };
|
|
44
|
-
// Forward-delta read mode. Backend routes to `listMessagesForward`
|
|
45
|
-
// only when BOTH `after` and `direction=forward` are present; without
|
|
46
|
-
// `after` the same handler falls into backward pagination and returns
|
|
47
|
-
// a different envelope. Default `after` to the unix epoch so the
|
|
48
|
-
// forward branch always wins when callers want "from the beginning".
|
|
49
|
-
const url = messagesListUrl(getBackendUrl(), chatId, {
|
|
50
|
-
after: opts.after || '1970-01-01T00:00:00.000Z',
|
|
51
|
-
limit: opts.limit,
|
|
52
|
-
});
|
|
53
|
-
const res = await fetch(url, { headers: this._headers() });
|
|
54
|
-
if (!res.ok) {
|
|
55
|
-
const body = await res.text().catch(() => '');
|
|
56
|
-
// Callers branch on ApiError.status (404 = chat deleted/not visible).
|
|
57
|
-
throwApiError(res, body, `MessagesClient.list failed: ${res.status}`);
|
|
58
|
-
}
|
|
59
|
-
return (await res.json());
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Newest page. No `after`, so the server walks backward from now.
|
|
63
|
-
* `list` is the forward delta and cannot answer "what just happened".
|
|
64
|
-
*/
|
|
65
|
-
async listLatest(chatId, opts = {}) {
|
|
66
|
-
if (!chatId)
|
|
67
|
-
return { messages: [], latestSequence: null };
|
|
68
|
-
const res = await fetch(messagesListUrl(getBackendUrl(), chatId, { limit: opts.limit }), { headers: this._headers() });
|
|
69
|
-
if (!res.ok) {
|
|
70
|
-
const body = await res.text().catch(() => '');
|
|
71
|
-
throwApiError(res, body, `MessagesClient.listLatest failed: ${res.status}`);
|
|
72
|
-
}
|
|
73
|
-
return (await res.json());
|
|
74
|
-
}
|
|
75
|
-
_headers() {
|
|
76
|
-
return {
|
|
77
|
-
'content-type': 'application/json',
|
|
78
|
-
...buildOperatorHeaders(this.operatorKey, this.agentId),
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
}
|