@ziggs-ai/api-client 0.1.3 → 0.1.5
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/README.md +13 -7
- package/dist/ConnectionManager.d.ts +46 -0
- package/dist/ConnectionManager.js +132 -0
- package/dist/http/AgentSearchClient.d.ts +36 -0
- package/dist/http/AgentSearchClient.js +72 -0
- package/dist/http/AgreementClient.d.ts +153 -0
- package/dist/http/AgreementClient.js +477 -0
- package/dist/http/ArtifactsClient.d.ts +48 -0
- package/dist/http/ArtifactsClient.js +90 -0
- package/dist/http/ChatClient.d.ts +34 -0
- package/dist/http/ChatClient.js +104 -0
- package/dist/http/ContextDiscoveryClient.d.ts +23 -0
- package/dist/http/ContextDiscoveryClient.js +35 -0
- package/dist/http/ContextReadClient.d.ts +33 -0
- package/dist/http/ContextReadClient.js +54 -0
- package/dist/http/MarketplaceClient.d.ts +19 -0
- package/dist/http/MarketplaceClient.js +72 -0
- package/dist/http/MessagesClient.d.ts +26 -0
- package/dist/http/MessagesClient.js +49 -0
- package/dist/http/ScopeClient.d.ts +33 -0
- package/dist/http/ScopeClient.js +39 -0
- package/dist/http/TaskClient.d.ts +75 -0
- package/dist/http/TaskClient.js +352 -0
- package/dist/http/TelemetryClient.d.ts +11 -0
- package/dist/http/TelemetryClient.js +53 -0
- package/dist/http/index.d.ts +16 -0
- package/dist/http/index.js +11 -0
- package/dist/index.d.ts +9 -0
- package/{src → dist}/index.js +2 -12
- package/dist/shared/runtimeLog.d.ts +14 -0
- package/dist/shared/runtimeLog.js +64 -0
- package/dist/types.d.ts +130 -0
- package/dist/types.js +50 -0
- package/dist/utils/urlUtils.d.ts +2 -0
- package/dist/utils/urlUtils.js +8 -0
- package/dist/websocket/ControlSocket.d.ts +13 -0
- package/dist/websocket/ControlSocket.js +37 -0
- package/dist/websocket/WebSocketClient.d.ts +71 -0
- package/dist/websocket/WebSocketClient.js +233 -0
- package/dist/websocket/index.js +1 -0
- package/package.json +20 -7
- package/src/ConnectionManager.ts +172 -0
- package/src/http/AgentSearchClient.ts +115 -0
- package/src/http/AgreementClient.ts +721 -0
- package/src/http/ArtifactsClient.ts +133 -0
- package/src/http/ChatClient.ts +147 -0
- package/src/http/ContextDiscoveryClient.ts +52 -0
- package/src/http/ContextReadClient.ts +83 -0
- package/src/http/MarketplaceClient.ts +94 -0
- package/src/http/MessagesClient.ts +71 -0
- package/src/http/ScopeClient.ts +64 -0
- package/src/http/TaskClient.ts +450 -0
- package/src/http/{TelemetryClient.js → TelemetryClient.ts} +21 -7
- package/src/http/index.ts +26 -0
- package/src/index.ts +27 -0
- package/src/shared/runtimeLog.ts +68 -0
- package/src/types.ts +158 -0
- package/src/utils/urlUtils.ts +9 -0
- package/src/websocket/ControlSocket.ts +51 -0
- package/src/websocket/WebSocketClient.ts +315 -0
- package/src/websocket/index.ts +1 -0
- package/src/ConnectionManager.js +0 -179
- package/src/http/AgentSearchClient.js +0 -113
- package/src/http/ContextReader.js +0 -99
- package/src/http/ContextWriter.js +0 -98
- package/src/http/TaskClient.js +0 -612
- package/src/http/index.js +0 -6
- package/src/types.js +0 -28
- package/src/utils/urlUtils.js +0 -17
- package/src/websocket/ControlSocket.js +0 -55
- package/src/websocket/WebSocketClient.js +0 -318
- /package/{src/websocket/index.js → dist/websocket/index.d.ts} +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { runtimeLog } from '../shared/runtimeLog.js';
|
|
3
|
+
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
4
|
+
import { ApiError } from '../types.js';
|
|
5
|
+
function buildHeaders(creds) {
|
|
6
|
+
return {
|
|
7
|
+
'content-type': 'application/json',
|
|
8
|
+
Authorization: `Bearer ${creds.operatorKey}`,
|
|
9
|
+
'X-Agent-Id': creds.agentId,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function assertCreds(creds, op) {
|
|
13
|
+
if (!creds?.operatorKey)
|
|
14
|
+
throw new Error(`operatorKey is required for ${op}`);
|
|
15
|
+
if (!creds?.agentId)
|
|
16
|
+
throw new Error(`agentId is required for ${op}`);
|
|
17
|
+
}
|
|
18
|
+
function throwApiError(response, responseBody, defaultMessage) {
|
|
19
|
+
let message = defaultMessage;
|
|
20
|
+
if (responseBody) {
|
|
21
|
+
try {
|
|
22
|
+
const d = JSON.parse(responseBody);
|
|
23
|
+
message = d['details'] || d['error'] || d['message'] || defaultMessage;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
message = responseBody || defaultMessage;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
throw new ApiError(message, response.status, responseBody);
|
|
30
|
+
}
|
|
31
|
+
export async function openConversation(participantId, creds) {
|
|
32
|
+
if (!participantId)
|
|
33
|
+
throw new Error('participantId is required for openConversation');
|
|
34
|
+
assertCreds(creds, 'open conversation');
|
|
35
|
+
// Canonical REST: POST /chats with { participantId }, returns { chatId }.
|
|
36
|
+
const res = await fetch(`${getBackendUrl()}/chats`, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
headers: buildHeaders(creds),
|
|
39
|
+
body: JSON.stringify({ participantId }),
|
|
40
|
+
});
|
|
41
|
+
if (!res.ok) {
|
|
42
|
+
const body = await res.text().catch(() => '');
|
|
43
|
+
throwApiError(res, body, `openConversation failed: ${res.status} ${res.statusText}`);
|
|
44
|
+
}
|
|
45
|
+
const data = await res.json().catch(() => null);
|
|
46
|
+
if (!data?.['chatId'] || typeof data['chatId'] !== 'string') {
|
|
47
|
+
throw new Error('Invalid response: expected { chatId } from POST /chats');
|
|
48
|
+
}
|
|
49
|
+
return { chatId: data['chatId'] };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* POST /chats/:chatId/messages as an impersonated delegate agent.
|
|
53
|
+
* Requires operator token + X-Agent-Id (ZIG-222).
|
|
54
|
+
*/
|
|
55
|
+
export async function sendChatMessage(input, creds) {
|
|
56
|
+
assertCreds(creds, 'send chat message');
|
|
57
|
+
const entryType = input.entryType ?? 'message';
|
|
58
|
+
const contentType = input.contentType ?? 'text';
|
|
59
|
+
const res = await fetch(`${getBackendUrl()}/chats/${encodeURIComponent(input.chatId)}/messages`, {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: buildHeaders(creds),
|
|
62
|
+
body: JSON.stringify({
|
|
63
|
+
chatId: input.chatId,
|
|
64
|
+
messageId: input.messageId,
|
|
65
|
+
text: input.text,
|
|
66
|
+
entryType,
|
|
67
|
+
contentType,
|
|
68
|
+
receiver: input.receiverId,
|
|
69
|
+
underAgreementId: input.underAgreementId,
|
|
70
|
+
}),
|
|
71
|
+
});
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
const body = await res.text().catch(() => '');
|
|
74
|
+
throwApiError(res, body, `sendChatMessage failed: ${res.status} ${res.statusText}`);
|
|
75
|
+
}
|
|
76
|
+
const data = (await res.json().catch(() => null));
|
|
77
|
+
return {
|
|
78
|
+
success: Boolean(data?.['success']),
|
|
79
|
+
message: String(data?.['message'] ?? 'ok'),
|
|
80
|
+
messageId: String(data?.['messageId'] ?? input.messageId),
|
|
81
|
+
chatId: String(data?.['chatId'] ?? input.chatId),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export async function listMyChats(creds) {
|
|
85
|
+
assertCreds(creds, 'list my chats');
|
|
86
|
+
try {
|
|
87
|
+
// Canonical REST: GET /chats/mine.
|
|
88
|
+
const res = await fetch(`${getBackendUrl()}/chats/mine`, {
|
|
89
|
+
method: 'GET',
|
|
90
|
+
headers: buildHeaders(creds),
|
|
91
|
+
});
|
|
92
|
+
if (!res.ok) {
|
|
93
|
+
const body = await res.text().catch(() => '');
|
|
94
|
+
runtimeLog.warn('ChatClient', `⚠️ listMyChats failed: ${res.status} ${res.statusText} ${body?.slice(0, 200)}`);
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
const data = await res.json().catch(() => null);
|
|
98
|
+
return Array.isArray(data?.['chats']) ? data['chats'] : [];
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
runtimeLog.warn('ChatClient', `⚠️ listMyChats failed: ${e.message}`);
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
export interface ContextReachDescriptor {
|
|
3
|
+
grantId: string;
|
|
4
|
+
scope: {
|
|
5
|
+
kind: 'chat' | 'agreement' | 'org';
|
|
6
|
+
id: string;
|
|
7
|
+
};
|
|
8
|
+
temporal: 'from-now' | 'from-start';
|
|
9
|
+
watermarkAt: string;
|
|
10
|
+
expiresAt: string | null;
|
|
11
|
+
parentGrantId: string | null;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* ZIG-412 discovery — scope descriptors only, no content.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ContextDiscoveryClient {
|
|
18
|
+
private readonly operatorKey;
|
|
19
|
+
private readonly agentId;
|
|
20
|
+
private readonly baseUrl;
|
|
21
|
+
constructor(operatorKey: string, agentId: string, baseUrl?: string);
|
|
22
|
+
discover(): Promise<ContextReachDescriptor[]>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
3
|
+
/**
|
|
4
|
+
* ZIG-412 discovery — scope descriptors only, no content.
|
|
5
|
+
*/
|
|
6
|
+
export class ContextDiscoveryClient {
|
|
7
|
+
operatorKey;
|
|
8
|
+
agentId;
|
|
9
|
+
baseUrl;
|
|
10
|
+
constructor(operatorKey, agentId, baseUrl) {
|
|
11
|
+
if (!operatorKey) {
|
|
12
|
+
throw new Error('ContextDiscoveryClient: operatorKey is required');
|
|
13
|
+
}
|
|
14
|
+
if (!agentId) {
|
|
15
|
+
throw new Error('ContextDiscoveryClient: agentId is required (operator-token impersonation)');
|
|
16
|
+
}
|
|
17
|
+
this.operatorKey = operatorKey;
|
|
18
|
+
this.agentId = agentId;
|
|
19
|
+
this.baseUrl = baseUrl || getBackendUrl();
|
|
20
|
+
}
|
|
21
|
+
async discover() {
|
|
22
|
+
const res = await fetch(`${this.baseUrl}/context/discovery`, {
|
|
23
|
+
headers: {
|
|
24
|
+
Authorization: `Bearer ${this.operatorKey}`,
|
|
25
|
+
'X-Agent-Id': this.agentId,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
const body = await res.text().catch(() => '');
|
|
29
|
+
if (!res.ok) {
|
|
30
|
+
throw new Error(`ContextDiscoveryClient.discover ${res.status} ${body.slice(0, 200)}`);
|
|
31
|
+
}
|
|
32
|
+
const parsed = JSON.parse(body);
|
|
33
|
+
return parsed.reach ?? [];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
export type ContextReadType = 'messages' | 'artifacts' | 'agreements' | 'tasks';
|
|
3
|
+
export interface ContextReadQuery {
|
|
4
|
+
via: string;
|
|
5
|
+
cursor?: string;
|
|
6
|
+
limit?: number;
|
|
7
|
+
after?: string;
|
|
8
|
+
direction?: 'forward';
|
|
9
|
+
state?: string;
|
|
10
|
+
contextGrantId?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ContextReadEnvelope<T = unknown> {
|
|
13
|
+
type: ContextReadType;
|
|
14
|
+
via: {
|
|
15
|
+
kind: string;
|
|
16
|
+
id: string;
|
|
17
|
+
};
|
|
18
|
+
items: T[];
|
|
19
|
+
hasMore: boolean;
|
|
20
|
+
nextCursor: string | null;
|
|
21
|
+
latestSequence?: string | null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Protocol-first uniform context reads (ZIG-427).
|
|
25
|
+
* Wraps `GET /context/read/:type` — one client, one envelope, four types.
|
|
26
|
+
*/
|
|
27
|
+
export declare class ContextReadClient {
|
|
28
|
+
private readonly operatorKey;
|
|
29
|
+
private readonly agentId;
|
|
30
|
+
private readonly baseUrl;
|
|
31
|
+
constructor(operatorKey: string, agentId: string, baseUrl?: string);
|
|
32
|
+
read<T = unknown>(type: ContextReadType, query: ContextReadQuery): Promise<ContextReadEnvelope<T>>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
3
|
+
/**
|
|
4
|
+
* Protocol-first uniform context reads (ZIG-427).
|
|
5
|
+
* Wraps `GET /context/read/:type` — one client, one envelope, four types.
|
|
6
|
+
*/
|
|
7
|
+
export class ContextReadClient {
|
|
8
|
+
operatorKey;
|
|
9
|
+
agentId;
|
|
10
|
+
baseUrl;
|
|
11
|
+
constructor(operatorKey, agentId, baseUrl) {
|
|
12
|
+
if (!operatorKey)
|
|
13
|
+
throw new Error('ContextReadClient: operatorKey is required');
|
|
14
|
+
if (!agentId) {
|
|
15
|
+
throw new Error('ContextReadClient: agentId is required (operator-token impersonation)');
|
|
16
|
+
}
|
|
17
|
+
this.operatorKey = operatorKey;
|
|
18
|
+
this.agentId = agentId;
|
|
19
|
+
this.baseUrl = baseUrl || getBackendUrl();
|
|
20
|
+
}
|
|
21
|
+
async read(type, query) {
|
|
22
|
+
if (!query.via?.trim()) {
|
|
23
|
+
throw new Error('ContextReadClient.read: via is required');
|
|
24
|
+
}
|
|
25
|
+
const url = new URL(`${this.baseUrl}/context/read/${encodeURIComponent(type)}`);
|
|
26
|
+
url.searchParams.set('via', query.via.trim());
|
|
27
|
+
if (query.cursor)
|
|
28
|
+
url.searchParams.set('cursor', query.cursor);
|
|
29
|
+
if (query.limit != null)
|
|
30
|
+
url.searchParams.set('limit', String(query.limit));
|
|
31
|
+
if (query.after)
|
|
32
|
+
url.searchParams.set('after', query.after);
|
|
33
|
+
if (query.direction)
|
|
34
|
+
url.searchParams.set('direction', query.direction);
|
|
35
|
+
if (query.state)
|
|
36
|
+
url.searchParams.set('state', query.state);
|
|
37
|
+
if (query.contextGrantId) {
|
|
38
|
+
url.searchParams.set('contextGrantId', query.contextGrantId);
|
|
39
|
+
}
|
|
40
|
+
const headers = {
|
|
41
|
+
Authorization: `Bearer ${this.operatorKey}`,
|
|
42
|
+
'X-Agent-Id': this.agentId,
|
|
43
|
+
};
|
|
44
|
+
if (query.contextGrantId) {
|
|
45
|
+
headers['X-Context-Grant-Id'] = query.contextGrantId;
|
|
46
|
+
}
|
|
47
|
+
const res = await fetch(url.toString(), { headers });
|
|
48
|
+
const body = await res.text().catch(() => '');
|
|
49
|
+
if (!res.ok) {
|
|
50
|
+
throw new Error(`ContextReadClient.read ${type} ${res.status} ${body.slice(0, 200)}`);
|
|
51
|
+
}
|
|
52
|
+
return JSON.parse(body);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { type Creds, type Agreement } from '../types.js';
|
|
3
|
+
export interface PublishOfferPayload {
|
|
4
|
+
description: string;
|
|
5
|
+
price?: number;
|
|
6
|
+
lifecycle?: string;
|
|
7
|
+
expiresAt?: string;
|
|
8
|
+
maxExecutions?: number;
|
|
9
|
+
/** `hire` = claimer becomes the provider's principal on claim. Defaults to `service` server-side. */
|
|
10
|
+
engagementKind?: 'hire' | 'service';
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export declare function publishOffer(payload: PublishOfferPayload, creds: Creds): Promise<Agreement>;
|
|
14
|
+
export interface PullOffersOptions {
|
|
15
|
+
limit?: number;
|
|
16
|
+
since?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function pullOffers(options: PullOffersOptions | undefined, creds: Creds): Promise<Agreement[]>;
|
|
19
|
+
export declare function claimOffer(agreementId: string, creds: Creds): Promise<Agreement>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
3
|
+
import { ApiError } from '../types.js';
|
|
4
|
+
function getMarketplaceBaseUrl() { return `${getBackendUrl()}/marketplace`; }
|
|
5
|
+
function buildHeaders(creds) {
|
|
6
|
+
return {
|
|
7
|
+
'content-type': 'application/json',
|
|
8
|
+
Authorization: `Bearer ${creds.operatorKey}`,
|
|
9
|
+
'X-Agent-Id': creds.agentId,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function assertCreds(creds, op) {
|
|
13
|
+
if (!creds?.operatorKey)
|
|
14
|
+
throw new Error(`operatorKey is required for ${op}`);
|
|
15
|
+
if (!creds?.agentId)
|
|
16
|
+
throw new Error(`agentId is required for ${op}`);
|
|
17
|
+
}
|
|
18
|
+
function throwApiError(response, body, defaultMsg) {
|
|
19
|
+
let msg = defaultMsg;
|
|
20
|
+
try {
|
|
21
|
+
const d = JSON.parse(body);
|
|
22
|
+
msg = d['details'] || d['error'] || d['message'] || defaultMsg;
|
|
23
|
+
}
|
|
24
|
+
catch { /**/ }
|
|
25
|
+
throw new ApiError(msg, response.status);
|
|
26
|
+
}
|
|
27
|
+
export async function publishOffer(payload, creds) {
|
|
28
|
+
assertCreds(creds, 'marketplace offer publish');
|
|
29
|
+
const res = await fetch(`${getMarketplaceBaseUrl()}/offers/publish`, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: buildHeaders(creds),
|
|
32
|
+
body: JSON.stringify(payload || {}),
|
|
33
|
+
});
|
|
34
|
+
if (!res.ok) {
|
|
35
|
+
const body = await res.text().catch(() => '');
|
|
36
|
+
throwApiError(res, body, `Marketplace offer publish failed: ${res.status}`);
|
|
37
|
+
}
|
|
38
|
+
const data = await res.json().catch(() => null);
|
|
39
|
+
return (data?.['offer'] ?? data);
|
|
40
|
+
}
|
|
41
|
+
export async function pullOffers(options, creds) {
|
|
42
|
+
assertCreds(creds, 'marketplace offers pull');
|
|
43
|
+
const res = await fetch(`${getMarketplaceBaseUrl()}/offers/pull`, {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
headers: buildHeaders(creds),
|
|
46
|
+
body: JSON.stringify(options || {}),
|
|
47
|
+
});
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
const body = await res.text().catch(() => '');
|
|
50
|
+
throwApiError(res, body, `Marketplace offers pull failed: ${res.status}`);
|
|
51
|
+
}
|
|
52
|
+
const data = await res.json().catch(() => null);
|
|
53
|
+
return data?.['offers'] ?? [];
|
|
54
|
+
}
|
|
55
|
+
export async function claimOffer(agreementId, creds) {
|
|
56
|
+
if (!agreementId)
|
|
57
|
+
throw new Error('agreementId is required');
|
|
58
|
+
assertCreds(creds, 'marketplace offer claim');
|
|
59
|
+
const res = await fetch(`${getMarketplaceBaseUrl()}/offers/claim`, {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: buildHeaders(creds),
|
|
62
|
+
body: JSON.stringify({ agreementId }),
|
|
63
|
+
});
|
|
64
|
+
if (!res.ok) {
|
|
65
|
+
const body = await res.text().catch(() => '');
|
|
66
|
+
throwApiError(res, body, `Marketplace offer claim failed: ${res.status}`);
|
|
67
|
+
}
|
|
68
|
+
const data = await res.json().catch(() => null);
|
|
69
|
+
if (!data?.['ok'])
|
|
70
|
+
throw new Error(data?.['error'] || 'Claim failed');
|
|
71
|
+
return data['offer'];
|
|
72
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
export interface ListMessagesOptions {
|
|
3
|
+
/** ISO timestamp; only entries with `timestamp > after` are returned. */
|
|
4
|
+
after?: string;
|
|
5
|
+
/** Page size, default 100, hard cap 1000. */
|
|
6
|
+
limit?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ListMessagesResult {
|
|
9
|
+
messages: unknown[];
|
|
10
|
+
latestSequence: string | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Read-side client for forward-delta message reads.
|
|
14
|
+
*
|
|
15
|
+
* Hits the canonical `GET /chats/:chatId/messages?after=&direction=forward&limit=`
|
|
16
|
+
* endpoint and returns a `{ messages, latestSequence }` envelope
|
|
17
|
+
* (`chat-messaging.controller.listMessagesForward` →
|
|
18
|
+
* `MessagesService.listForChat`).
|
|
19
|
+
*/
|
|
20
|
+
export declare class MessagesClient {
|
|
21
|
+
private readonly operatorKey;
|
|
22
|
+
private readonly agentId;
|
|
23
|
+
constructor(operatorKey: string, agentId: string);
|
|
24
|
+
list(chatId: string, opts?: ListMessagesOptions): Promise<ListMessagesResult>;
|
|
25
|
+
private _headers;
|
|
26
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
3
|
+
/**
|
|
4
|
+
* Read-side client for forward-delta message reads.
|
|
5
|
+
*
|
|
6
|
+
* Hits the canonical `GET /chats/:chatId/messages?after=&direction=forward&limit=`
|
|
7
|
+
* endpoint and returns a `{ messages, latestSequence }` envelope
|
|
8
|
+
* (`chat-messaging.controller.listMessagesForward` →
|
|
9
|
+
* `MessagesService.listForChat`).
|
|
10
|
+
*/
|
|
11
|
+
export class MessagesClient {
|
|
12
|
+
operatorKey;
|
|
13
|
+
agentId;
|
|
14
|
+
constructor(operatorKey, agentId) {
|
|
15
|
+
if (!operatorKey)
|
|
16
|
+
throw new Error('MessagesClient: operatorKey is required');
|
|
17
|
+
if (!agentId)
|
|
18
|
+
throw new Error('MessagesClient: agentId is required (operator-token impersonation)');
|
|
19
|
+
this.operatorKey = operatorKey;
|
|
20
|
+
this.agentId = agentId;
|
|
21
|
+
}
|
|
22
|
+
async list(chatId, opts = {}) {
|
|
23
|
+
if (!chatId)
|
|
24
|
+
return { messages: [], latestSequence: null };
|
|
25
|
+
const url = new URL(`${getBackendUrl()}/chats/${encodeURIComponent(chatId)}/messages`);
|
|
26
|
+
// Forward-delta read mode. Backend routes to `listMessagesForward`
|
|
27
|
+
// only when BOTH `after` and `direction=forward` are present; without
|
|
28
|
+
// `after` the same handler falls into backward pagination and returns
|
|
29
|
+
// a different envelope. Default `after` to the unix epoch so the
|
|
30
|
+
// forward branch always wins when callers want "from the beginning".
|
|
31
|
+
url.searchParams.set('direction', 'forward');
|
|
32
|
+
url.searchParams.set('after', opts.after || '1970-01-01T00:00:00.000Z');
|
|
33
|
+
if (opts.limit != null)
|
|
34
|
+
url.searchParams.set('limit', String(opts.limit));
|
|
35
|
+
const res = await fetch(url.toString(), { headers: this._headers() });
|
|
36
|
+
if (!res.ok) {
|
|
37
|
+
const body = await res.text().catch(() => '');
|
|
38
|
+
throw new Error(`MessagesClient.list ${res.status} ${res.statusText} ${body.slice(0, 200)}`);
|
|
39
|
+
}
|
|
40
|
+
return (await res.json());
|
|
41
|
+
}
|
|
42
|
+
_headers() {
|
|
43
|
+
return {
|
|
44
|
+
'content-type': 'application/json',
|
|
45
|
+
Authorization: `Bearer ${this.operatorKey}`,
|
|
46
|
+
'X-Agent-Id': this.agentId,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
export type ScopeKind = 'chat' | 'agreement' | 'task' | 'counterparty';
|
|
3
|
+
export interface PartyRef {
|
|
4
|
+
id: string;
|
|
5
|
+
role: 'payer' | 'provider' | 'creator' | 'proposedTo' | 'providerPrincipal';
|
|
6
|
+
}
|
|
7
|
+
export interface ScopeResult {
|
|
8
|
+
via: {
|
|
9
|
+
kind: ScopeKind;
|
|
10
|
+
id: string;
|
|
11
|
+
};
|
|
12
|
+
agent: string;
|
|
13
|
+
accessible: {
|
|
14
|
+
chats: string[];
|
|
15
|
+
agreements: string[];
|
|
16
|
+
tasks: string[];
|
|
17
|
+
counterparties: PartyRef[];
|
|
18
|
+
};
|
|
19
|
+
permissions: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Client for `GET /scope?via=<kind>:<id>`. Returns the access graph reachable
|
|
23
|
+
* from an entry point for the impersonated agent. Used by `runTurn` to
|
|
24
|
+
* bootstrap "what does my current session-key resolve to" before fanning out
|
|
25
|
+
* to primitive reads.
|
|
26
|
+
*/
|
|
27
|
+
export declare class ScopeClient {
|
|
28
|
+
private readonly operatorKey;
|
|
29
|
+
private readonly agentId;
|
|
30
|
+
constructor(operatorKey: string, agentId: string);
|
|
31
|
+
get(kind: ScopeKind, id: string): Promise<ScopeResult>;
|
|
32
|
+
private _headers;
|
|
33
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { getBackendUrl } from '../utils/urlUtils.js';
|
|
3
|
+
/**
|
|
4
|
+
* Client for `GET /scope?via=<kind>:<id>`. Returns the access graph reachable
|
|
5
|
+
* from an entry point for the impersonated agent. Used by `runTurn` to
|
|
6
|
+
* bootstrap "what does my current session-key resolve to" before fanning out
|
|
7
|
+
* to primitive reads.
|
|
8
|
+
*/
|
|
9
|
+
export class ScopeClient {
|
|
10
|
+
operatorKey;
|
|
11
|
+
agentId;
|
|
12
|
+
constructor(operatorKey, agentId) {
|
|
13
|
+
if (!operatorKey)
|
|
14
|
+
throw new Error('ScopeClient: operatorKey is required');
|
|
15
|
+
if (!agentId)
|
|
16
|
+
throw new Error('ScopeClient: agentId is required (operator-token impersonation)');
|
|
17
|
+
this.operatorKey = operatorKey;
|
|
18
|
+
this.agentId = agentId;
|
|
19
|
+
}
|
|
20
|
+
async get(kind, id) {
|
|
21
|
+
if (!id)
|
|
22
|
+
throw new Error('ScopeClient.get: id is required');
|
|
23
|
+
const url = new URL(`${getBackendUrl()}/scope`);
|
|
24
|
+
url.searchParams.set('via', `${kind}:${id}`);
|
|
25
|
+
const res = await fetch(url.toString(), { headers: this._headers() });
|
|
26
|
+
if (!res.ok) {
|
|
27
|
+
const body = await res.text().catch(() => '');
|
|
28
|
+
throw new Error(`ScopeClient.get ${res.status} ${res.statusText} ${body.slice(0, 200)}`);
|
|
29
|
+
}
|
|
30
|
+
return (await res.json());
|
|
31
|
+
}
|
|
32
|
+
_headers() {
|
|
33
|
+
return {
|
|
34
|
+
'content-type': 'application/json',
|
|
35
|
+
Authorization: `Bearer ${this.operatorKey}`,
|
|
36
|
+
'X-Agent-Id': this.agentId,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { type Creds, type Task, type TaskState, type Agreement } from '../types.js';
|
|
3
|
+
export interface CreateTaskData {
|
|
4
|
+
description: string;
|
|
5
|
+
agreementId: string;
|
|
6
|
+
parentTaskId?: string;
|
|
7
|
+
plan?: unknown;
|
|
8
|
+
idempotencyKey?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function createTask(taskData: CreateTaskData, creds: Creds): Promise<Task>;
|
|
11
|
+
export declare function getTask(taskId: string, creds: Creds): Promise<Task>;
|
|
12
|
+
export interface UpdateTaskStateData {
|
|
13
|
+
result?: unknown;
|
|
14
|
+
errorMessage?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function updateTaskState(taskId: string, state: TaskState, data: UpdateTaskStateData | undefined, creds: Creds): Promise<Task>;
|
|
17
|
+
export declare function getActiveTasksForAgent(agentId: string, creds: Creds): Promise<Task[]>;
|
|
18
|
+
export declare function getActiveTasksForChat(chatId: string, creds: Creds): Promise<Task[]>;
|
|
19
|
+
export declare function cancelTask(taskId: string, creds: Creds): Promise<Task>;
|
|
20
|
+
export declare function getSubtasks(parentTaskId: string, creds: Creds): Promise<Task[]>;
|
|
21
|
+
export interface PlanReplaceStep {
|
|
22
|
+
stepId: string;
|
|
23
|
+
description: string;
|
|
24
|
+
order: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function replaceTaskPlan(taskId: string, steps: PlanReplaceStep[], creds: Creds): Promise<Task>;
|
|
27
|
+
export interface PublishToLedgerPayload {
|
|
28
|
+
description: string;
|
|
29
|
+
chatId?: string;
|
|
30
|
+
payerId?: string;
|
|
31
|
+
parentTaskId?: string;
|
|
32
|
+
price?: number;
|
|
33
|
+
lifecycle?: string;
|
|
34
|
+
expiresAt?: string;
|
|
35
|
+
maxExecutions?: number;
|
|
36
|
+
agreementDescription?: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function publishToLedger(payload: PublishToLedgerPayload, creds: Creds): Promise<Agreement>;
|
|
39
|
+
export interface PullFromLedgerOptions {
|
|
40
|
+
limit?: number;
|
|
41
|
+
since?: string;
|
|
42
|
+
}
|
|
43
|
+
export declare function pullFromLedger(options: PullFromLedgerOptions | undefined, creds: Creds): Promise<Agreement[]>;
|
|
44
|
+
export declare function claimLedgerTask(agreementId: string, creds: Creds, options?: {
|
|
45
|
+
idempotencyKey?: string;
|
|
46
|
+
}): Promise<Agreement>;
|
|
47
|
+
export declare function reportTask(taskId: string, message: string | undefined, creds: Creds): Promise<Task>;
|
|
48
|
+
export declare function setTaskSatisfaction(taskId: string, satisfaction: 'positive' | 'negative', creds: Creds): Promise<Task>;
|
|
49
|
+
export interface CountTasksFilters {
|
|
50
|
+
chatId?: string;
|
|
51
|
+
state?: string;
|
|
52
|
+
userId?: string;
|
|
53
|
+
agentId?: string;
|
|
54
|
+
}
|
|
55
|
+
export declare function countTasks(filters: CountTasksFilters | undefined, creds: Creds): Promise<number>;
|
|
56
|
+
export declare class TaskClient {
|
|
57
|
+
private creds;
|
|
58
|
+
constructor(operatorKey: string, agentId: string);
|
|
59
|
+
createTask(data: CreateTaskData): Promise<Task>;
|
|
60
|
+
getTask(taskId: string): Promise<Task>;
|
|
61
|
+
updateTaskState(taskId: string, state: TaskState, data?: UpdateTaskStateData): Promise<Task>;
|
|
62
|
+
getActiveTasksForAgent(agentId: string): Promise<Task[]>;
|
|
63
|
+
getActiveTasksForChat(chatId: string): Promise<Task[]>;
|
|
64
|
+
cancelTask(taskId: string): Promise<Task>;
|
|
65
|
+
getSubtasks(parentTaskId: string): Promise<Task[]>;
|
|
66
|
+
replaceTaskPlan(taskId: string, steps: PlanReplaceStep[]): Promise<Task>;
|
|
67
|
+
publishToLedger(payload: PublishToLedgerPayload): Promise<Agreement>;
|
|
68
|
+
pullFromLedger(options?: PullFromLedgerOptions): Promise<Agreement[]>;
|
|
69
|
+
claimLedgerTask(taskId: string, options?: {
|
|
70
|
+
idempotencyKey?: string;
|
|
71
|
+
}): Promise<Agreement>;
|
|
72
|
+
reportTask(taskId: string, message?: string): Promise<Task>;
|
|
73
|
+
setTaskSatisfaction(taskId: string, satisfaction: 'positive' | 'negative'): Promise<Task>;
|
|
74
|
+
countTasks(filters?: CountTasksFilters): Promise<number>;
|
|
75
|
+
}
|