@ziggs-ai/api-client 0.1.20 → 0.1.22

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.
@@ -34,9 +34,13 @@ export interface AgentProfile {
34
34
  }
35
35
  export declare class AgentSearchClient {
36
36
  private readonly operatorKey;
37
- private readonly agentId;
37
+ private readonly agentId?;
38
38
  private readonly baseUrl;
39
- constructor(operatorKey: string, agentId: string);
39
+ /**
40
+ * @param operatorKey Agent-scoped or fleet operator key.
41
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
42
+ */
43
+ constructor(operatorKey: string, agentId?: string);
40
44
  searchAgents(query: string, options?: AgentSearchOptions): Promise<AgentSearchResult>;
41
45
  getAgentById(agentId: string): Promise<AgentSearchResult & Partial<AgentProfile>>;
42
46
  private _buildHeaders;
@@ -1,15 +1,18 @@
1
1
  import 'dotenv/config';
2
2
  import { runtimeLog } from '../shared/runtimeLog.js';
3
3
  import { getBackendUrl } from '../utils/urlUtils.js';
4
+ import { buildOperatorHeaders } from './operatorHeaders.js';
4
5
  export class AgentSearchClient {
5
6
  operatorKey;
6
7
  agentId;
7
8
  baseUrl;
9
+ /**
10
+ * @param operatorKey Agent-scoped or fleet operator key.
11
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
12
+ */
8
13
  constructor(operatorKey, agentId) {
9
14
  if (!operatorKey)
10
15
  throw new Error('AgentSearchClient: operatorKey is required');
11
- if (!agentId)
12
- throw new Error('AgentSearchClient: agentId is required (operator-token impersonation)');
13
16
  this.operatorKey = operatorKey;
14
17
  this.agentId = agentId;
15
18
  this.baseUrl = getBackendUrl();
@@ -63,10 +66,8 @@ export class AgentSearchClient {
63
66
  }
64
67
  }
65
68
  _buildHeaders() {
66
- return {
69
+ return buildOperatorHeaders(this.operatorKey, this.agentId, {
67
70
  'Content-Type': 'application/json',
68
- Authorization: `Bearer ${this.operatorKey}`,
69
- 'X-Agent-Id': this.agentId,
70
- };
71
+ });
71
72
  }
72
73
  }
@@ -176,7 +176,11 @@ export declare function linkUserToAgreement(agreementId: string, userId: string,
176
176
  export declare function getUsersForAgreement(agreementId: string, creds: Creds): Promise<unknown[]>;
177
177
  export declare class AgreementClient {
178
178
  private creds;
179
- constructor(operatorKey: string, agentId: string);
179
+ /**
180
+ * @param operatorKey Agent-scoped or fleet operator key.
181
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
182
+ */
183
+ constructor(operatorKey: string, agentId?: string);
180
184
  propose(data: ProposeDirectInput): Promise<Agreement>;
181
185
  proposeDirect(data: ProposeDirectInput): Promise<Agreement>;
182
186
  proposeBroadcast(data: ProposeBroadcastInput): Promise<Agreement>;
@@ -289,25 +289,31 @@ export async function getAgreement(agreementId, creds) {
289
289
  if (!agreementId)
290
290
  return null;
291
291
  assertCreds(creds, 'get agreement');
292
+ // ZIG-698 — a genuine 404 (and 200-with-no-agreement) is a real "not found"
293
+ // and returns null. Every other failure (403/5xx/network) must throw so the
294
+ // caller can tell "does not exist" from "could not fetch" instead of a 403
295
+ // masquerading as not-found. The MCP tool classifies the thrown status via
296
+ // toolError; the message keeps the status whitespace-delimited for that.
297
+ let res;
292
298
  try {
293
- const res = await fetch(`${getAgreementBaseUrl()}/${agreementId}`, {
299
+ res = await fetch(`${getAgreementBaseUrl()}/${agreementId}`, {
294
300
  method: 'GET',
295
301
  headers: buildHeaders(creds),
296
302
  });
297
- if (res.status === 404)
298
- return null;
299
- if (!res.ok) {
300
- const body = await res.text().catch(() => '');
301
- runtimeLog.warn('AgreementClient', `⚠️ Get agreement failed: ${res.status} ${res.statusText} ${body?.slice(0, 200)}`);
302
- return null;
303
- }
304
- const data = await res.json().catch(() => null);
305
- return data?.['agreement'] ?? null;
306
303
  }
307
304
  catch (e) {
308
305
  runtimeLog.warn('AgreementClient', `⚠️ Get agreement failed: ${e.message}`);
306
+ throw new Error(`GET /agreements/${agreementId} network error: ${e.message}`);
307
+ }
308
+ if (res.status === 404)
309
309
  return null;
310
+ if (!res.ok) {
311
+ const body = await res.text().catch(() => '');
312
+ runtimeLog.warn('AgreementClient', `⚠️ Get agreement failed: ${res.status} ${res.statusText} ${body?.slice(0, 200)}`);
313
+ throw new Error(`GET /agreements/${agreementId} ${res.status} ${body?.slice(0, 200)}`);
310
314
  }
315
+ const data = await res.json().catch(() => null);
316
+ return data?.['agreement'] ?? null;
311
317
  }
312
318
  export async function createAgreement(body, creds) {
313
319
  if (!body)
@@ -551,11 +557,15 @@ export async function getUsersForAgreement(agreementId, creds) {
551
557
  }
552
558
  export class AgreementClient {
553
559
  creds;
560
+ /**
561
+ * @param operatorKey Agent-scoped or fleet operator key.
562
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
563
+ */
554
564
  constructor(operatorKey, agentId) {
555
565
  if (!operatorKey)
556
566
  throw new Error('AgreementClient: operatorKey is required');
557
- if (!agentId)
558
- throw new Error('AgreementClient: agentId is required');
567
+ // agentId may be absent for agent-scoped keys (ZIG-642); the Creds-based
568
+ // standalone functions still assert it per call.
559
569
  this.creds = { operatorKey, agentId };
560
570
  }
561
571
  propose(data) { return proposeAgreement(data, this.creds); }
@@ -31,8 +31,12 @@ export interface WriteArtifactInput {
31
31
  */
32
32
  export declare class ArtifactsClient {
33
33
  private readonly operatorKey;
34
- private readonly agentId;
35
- constructor(operatorKey: string, agentId: string);
34
+ private readonly agentId?;
35
+ /**
36
+ * @param operatorKey Agent-scoped or fleet operator key.
37
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
38
+ */
39
+ constructor(operatorKey: string, agentId?: string);
36
40
  list(q: ListArtifactsQuery, opts?: ListArtifactsOptions): Promise<ListArtifactsResult>;
37
41
  /**
38
42
  * Record an agent thought as an `agent-private` artifact. Replaces the
@@ -1,6 +1,7 @@
1
1
  import 'dotenv/config';
2
2
  import { runtimeLog } from '../shared/runtimeLog.js';
3
3
  import { getBackendUrl } from '../utils/urlUtils.js';
4
+ import { buildOperatorHeaders } from './operatorHeaders.js';
4
5
  /**
5
6
  * Replaces `ContextReader`'s artifact reads + `ContextWriter`'s breadcrumb
6
7
  * writes. `visibility: 'agent-private'` is the new home for agent thoughts —
@@ -9,11 +10,13 @@ import { getBackendUrl } from '../utils/urlUtils.js';
9
10
  export class ArtifactsClient {
10
11
  operatorKey;
11
12
  agentId;
13
+ /**
14
+ * @param operatorKey Agent-scoped or fleet operator key.
15
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
16
+ */
12
17
  constructor(operatorKey, agentId) {
13
18
  if (!operatorKey)
14
19
  throw new Error('ArtifactsClient: operatorKey is required');
15
- if (!agentId)
16
- throw new Error('ArtifactsClient: agentId is required (operator-token impersonation)');
17
20
  this.operatorKey = operatorKey;
18
21
  this.agentId = agentId;
19
22
  }
@@ -81,10 +84,8 @@ export class ArtifactsClient {
81
84
  }
82
85
  }
83
86
  _headers() {
84
- return {
87
+ return buildOperatorHeaders(this.operatorKey, this.agentId, {
85
88
  'content-type': 'application/json',
86
- Authorization: `Bearer ${this.operatorKey}`,
87
- 'X-Agent-Id': this.agentId,
88
- };
89
+ });
89
90
  }
90
91
  }
@@ -70,7 +70,11 @@ export declare function sendChatMessage(input: SendChatMessageInput, creds: Cred
70
70
  export declare function listMyChats(creds: Creds): Promise<ChatSummary[]>;
71
71
  export declare class ChatClient {
72
72
  private creds;
73
- constructor(operatorKey: string, agentId: string);
73
+ /**
74
+ * @param operatorKey Agent-scoped or fleet operator key.
75
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
76
+ */
77
+ constructor(operatorKey: string, agentId?: string);
74
78
  open(participantId: string): Promise<{
75
79
  chatId: string;
76
80
  }>;
@@ -132,11 +132,15 @@ export async function listMyChats(creds) {
132
132
  }
133
133
  export class ChatClient {
134
134
  creds;
135
+ /**
136
+ * @param operatorKey Agent-scoped or fleet operator key.
137
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
138
+ */
135
139
  constructor(operatorKey, agentId) {
136
140
  if (!operatorKey)
137
141
  throw new Error('ChatClient: operatorKey is required');
138
- if (!agentId)
139
- throw new Error('ChatClient: agentId is required');
142
+ // agentId may be absent for agent-scoped keys (ZIG-642); the Creds-based
143
+ // standalone functions still assert it per call.
140
144
  this.creds = { operatorKey, agentId };
141
145
  }
142
146
  open(participantId) { return openConversation(participantId, this.creds); }
@@ -16,8 +16,12 @@ export interface ContextReachDescriptor {
16
16
  */
17
17
  export declare class ContextDiscoveryClient {
18
18
  private readonly operatorKey;
19
- private readonly agentId;
19
+ private readonly agentId?;
20
20
  private readonly baseUrl;
21
- constructor(operatorKey: string, agentId: string, baseUrl?: string);
21
+ /**
22
+ * @param operatorKey Agent-scoped or fleet operator key.
23
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
24
+ */
25
+ constructor(operatorKey: string, agentId?: string, baseUrl?: string);
22
26
  discover(): Promise<ContextReachDescriptor[]>;
23
27
  }
@@ -1,5 +1,6 @@
1
1
  import 'dotenv/config';
2
2
  import { getBackendUrl } from '../utils/urlUtils.js';
3
+ import { buildOperatorHeaders } from './operatorHeaders.js';
3
4
  /**
4
5
  * ZIG-412 discovery — scope descriptors only, no content.
5
6
  */
@@ -7,23 +8,21 @@ export class ContextDiscoveryClient {
7
8
  operatorKey;
8
9
  agentId;
9
10
  baseUrl;
11
+ /**
12
+ * @param operatorKey Agent-scoped or fleet operator key.
13
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
14
+ */
10
15
  constructor(operatorKey, agentId, baseUrl) {
11
16
  if (!operatorKey) {
12
17
  throw new Error('ContextDiscoveryClient: operatorKey is required');
13
18
  }
14
- if (!agentId) {
15
- throw new Error('ContextDiscoveryClient: agentId is required (operator-token impersonation)');
16
- }
17
19
  this.operatorKey = operatorKey;
18
20
  this.agentId = agentId;
19
21
  this.baseUrl = baseUrl || getBackendUrl();
20
22
  }
21
23
  async discover() {
22
24
  const res = await fetch(`${this.baseUrl}/context/discovery`, {
23
- headers: {
24
- Authorization: `Bearer ${this.operatorKey}`,
25
- 'X-Agent-Id': this.agentId,
26
- },
25
+ headers: buildOperatorHeaders(this.operatorKey, this.agentId),
27
26
  });
28
27
  const body = await res.text().catch(() => '');
29
28
  if (!res.ok) {
@@ -36,9 +36,13 @@ export interface DelegateContextGrantInput {
36
36
  */
37
37
  export declare class ContextGrantsClient {
38
38
  private readonly operatorKey;
39
- private readonly agentId;
39
+ private readonly agentId?;
40
40
  private readonly baseUrl;
41
- constructor(operatorKey: string, agentId: string, baseUrl?: string);
41
+ /**
42
+ * @param operatorKey Agent-scoped or fleet operator key.
43
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
44
+ */
45
+ constructor(operatorKey: string, agentId?: string, baseUrl?: string);
42
46
  issueGrant(input: IssueContextGrantInput): Promise<ContextGrantRecord>;
43
47
  delegateGrant(parentGrantId: string, input: DelegateContextGrantInput): Promise<ContextGrantRecord>;
44
48
  revokeGrant(grantId: string): Promise<{
@@ -1,19 +1,7 @@
1
1
  import 'dotenv/config';
2
2
  import { getBackendUrl } from '../utils/urlUtils.js';
3
3
  import { ApiError } from '../types.js';
4
- function buildHeaders(creds) {
5
- return {
6
- 'content-type': 'application/json',
7
- Authorization: `Bearer ${creds.operatorKey}`,
8
- 'X-Agent-Id': creds.agentId,
9
- };
10
- }
11
- function assertCreds(creds, op) {
12
- if (!creds?.operatorKey)
13
- throw new Error(`operatorKey is required for ${op}`);
14
- if (!creds?.agentId)
15
- throw new Error(`agentId is required for ${op}`);
16
- }
4
+ import { buildOperatorHeaders } from './operatorHeaders.js';
17
5
  function throwApiError(response, responseBody, defaultMessage) {
18
6
  let message = defaultMessage;
19
7
  if (responseBody) {
@@ -38,24 +26,23 @@ export class ContextGrantsClient {
38
26
  operatorKey;
39
27
  agentId;
40
28
  baseUrl;
29
+ /**
30
+ * @param operatorKey Agent-scoped or fleet operator key.
31
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
32
+ */
41
33
  constructor(operatorKey, agentId, baseUrl) {
42
34
  if (!operatorKey) {
43
35
  throw new Error('ContextGrantsClient: operatorKey is required');
44
36
  }
45
- if (!agentId) {
46
- throw new Error('ContextGrantsClient: agentId is required (operator-token impersonation)');
47
- }
48
37
  this.operatorKey = operatorKey;
49
38
  this.agentId = agentId;
50
39
  this.baseUrl = baseUrl || getBackendUrl();
51
40
  }
52
41
  async issueGrant(input) {
53
- assertCreds({ operatorKey: this.operatorKey, agentId: this.agentId }, 'issueGrant');
54
42
  const res = await fetch(`${this.baseUrl}/context/grants`, {
55
43
  method: 'POST',
56
- headers: buildHeaders({
57
- operatorKey: this.operatorKey,
58
- agentId: this.agentId,
44
+ headers: buildOperatorHeaders(this.operatorKey, this.agentId, {
45
+ 'content-type': 'application/json',
59
46
  }),
60
47
  body: JSON.stringify({
61
48
  holderId: input.holderId,
@@ -75,12 +62,10 @@ export class ContextGrantsClient {
75
62
  return parsed.grant;
76
63
  }
77
64
  async delegateGrant(parentGrantId, input) {
78
- assertCreds({ operatorKey: this.operatorKey, agentId: this.agentId }, 'delegateGrant');
79
65
  const res = await fetch(`${this.baseUrl}/context/grants/${encodeURIComponent(parentGrantId)}/delegate`, {
80
66
  method: 'POST',
81
- headers: buildHeaders({
82
- operatorKey: this.operatorKey,
83
- agentId: this.agentId,
67
+ headers: buildOperatorHeaders(this.operatorKey, this.agentId, {
68
+ 'content-type': 'application/json',
84
69
  }),
85
70
  body: JSON.stringify(input),
86
71
  });
@@ -95,12 +80,10 @@ export class ContextGrantsClient {
95
80
  return parsed.grant;
96
81
  }
97
82
  async revokeGrant(grantId) {
98
- assertCreds({ operatorKey: this.operatorKey, agentId: this.agentId }, 'revokeGrant');
99
83
  const res = await fetch(`${this.baseUrl}/context/grants/${encodeURIComponent(grantId)}`, {
100
84
  method: 'DELETE',
101
- headers: buildHeaders({
102
- operatorKey: this.operatorKey,
103
- agentId: this.agentId,
85
+ headers: buildOperatorHeaders(this.operatorKey, this.agentId, {
86
+ 'content-type': 'application/json',
104
87
  }),
105
88
  });
106
89
  const body = await res.text().catch(() => '');
@@ -40,7 +40,11 @@ export interface PullQuestsOptions {
40
40
  export declare function pullQuests(options: PullQuestsOptions | undefined, creds: Creds): Promise<Agreement[]>;
41
41
  export declare class MarketplaceClient {
42
42
  private creds;
43
- constructor(operatorKey: string, agentId: string);
43
+ /**
44
+ * @param operatorKey Agent-scoped or fleet operator key.
45
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
46
+ */
47
+ constructor(operatorKey: string, agentId?: string);
44
48
  publishOffer(payload: PublishOfferPayload): Promise<Agreement>;
45
49
  pullOffers(options?: PullOffersOptions): Promise<Agreement[]>;
46
50
  claimOffer(agreementId: string): Promise<Agreement>;
@@ -112,11 +112,15 @@ export async function pullQuests(options, creds) {
112
112
  }
113
113
  export class MarketplaceClient {
114
114
  creds;
115
+ /**
116
+ * @param operatorKey Agent-scoped or fleet operator key.
117
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
118
+ */
115
119
  constructor(operatorKey, agentId) {
116
120
  if (!operatorKey)
117
121
  throw new Error('MarketplaceClient: operatorKey is required');
118
- if (!agentId)
119
- throw new Error('MarketplaceClient: agentId is required');
122
+ // agentId may be absent for agent-scoped keys (ZIG-642); the Creds-based
123
+ // standalone functions still assert it per call.
120
124
  this.creds = { operatorKey, agentId };
121
125
  }
122
126
  publishOffer(payload) { return publishOffer(payload, this.creds); }
@@ -26,8 +26,12 @@ export interface ScopeResult {
26
26
  */
27
27
  export declare class ScopeClient {
28
28
  private readonly operatorKey;
29
- private readonly agentId;
30
- constructor(operatorKey: string, agentId: string);
29
+ private readonly agentId?;
30
+ /**
31
+ * @param operatorKey Agent-scoped or fleet operator key.
32
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
33
+ */
34
+ constructor(operatorKey: string, agentId?: string);
31
35
  get(kind: ScopeKind, id: string): Promise<ScopeResult>;
32
36
  private _headers;
33
37
  }
@@ -1,5 +1,6 @@
1
1
  import 'dotenv/config';
2
2
  import { getBackendUrl } from '../utils/urlUtils.js';
3
+ import { buildOperatorHeaders } from './operatorHeaders.js';
3
4
  /**
4
5
  * Client for `GET /scope?via=<kind>:<id>`. Returns the access graph reachable
5
6
  * from an entry point for the impersonated agent. Used by `runTurn` to
@@ -9,11 +10,13 @@ import { getBackendUrl } from '../utils/urlUtils.js';
9
10
  export class ScopeClient {
10
11
  operatorKey;
11
12
  agentId;
13
+ /**
14
+ * @param operatorKey Agent-scoped or fleet operator key.
15
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
16
+ */
12
17
  constructor(operatorKey, agentId) {
13
18
  if (!operatorKey)
14
19
  throw new Error('ScopeClient: operatorKey is required');
15
- if (!agentId)
16
- throw new Error('ScopeClient: agentId is required (operator-token impersonation)');
17
20
  this.operatorKey = operatorKey;
18
21
  this.agentId = agentId;
19
22
  }
@@ -30,10 +33,8 @@ export class ScopeClient {
30
33
  return (await res.json());
31
34
  }
32
35
  _headers() {
33
- return {
36
+ return buildOperatorHeaders(this.operatorKey, this.agentId, {
34
37
  'content-type': 'application/json',
35
- Authorization: `Bearer ${this.operatorKey}`,
36
- 'X-Agent-Id': this.agentId,
37
- };
38
+ });
38
39
  }
39
40
  }
@@ -50,7 +50,11 @@ export interface CountTasksFilters {
50
50
  export declare function countTasks(filters: CountTasksFilters | undefined, creds: Creds): Promise<number>;
51
51
  export declare class TaskClient {
52
52
  private creds;
53
- constructor(operatorKey: string, agentId: string);
53
+ /**
54
+ * @param operatorKey Agent-scoped or fleet operator key.
55
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
56
+ */
57
+ constructor(operatorKey: string, agentId?: string);
54
58
  createTask(data: CreateTaskData): Promise<Task>;
55
59
  getTask(taskId: string): Promise<Task>;
56
60
  updateTaskState(taskId: string, state: TaskState, data?: UpdateTaskStateData): Promise<Task>;
@@ -303,11 +303,15 @@ export async function countTasks(filters = {}, creds) {
303
303
  // ---------------------------------------------------------------------------
304
304
  export class TaskClient {
305
305
  creds;
306
+ /**
307
+ * @param operatorKey Agent-scoped or fleet operator key.
308
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
309
+ */
306
310
  constructor(operatorKey, agentId) {
307
311
  if (!operatorKey)
308
312
  throw new Error('TaskClient: operatorKey is required');
309
- if (!agentId)
310
- throw new Error('TaskClient: agentId is required');
313
+ // agentId may be absent for agent-scoped keys (ZIG-642); the Creds-based
314
+ // standalone functions still assert it per call.
311
315
  this.creds = { operatorKey, agentId };
312
316
  }
313
317
  createTask(data) { return createTask(data, this.creds); }
@@ -1,10 +1,14 @@
1
1
  import 'dotenv/config';
2
2
  export declare class TelemetryClient {
3
3
  private readonly operatorKey;
4
- private readonly agentId;
4
+ private readonly agentId?;
5
5
  private _queue;
6
6
  private _flushing;
7
- constructor(operatorKey: string, agentId: string);
7
+ /**
8
+ * @param operatorKey Agent-scoped or fleet operator key.
9
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
10
+ */
11
+ constructor(operatorKey: string, agentId?: string);
8
12
  send(payload: unknown): Promise<void>;
9
13
  private _flush;
10
14
  private _post;
@@ -1,16 +1,19 @@
1
1
  import 'dotenv/config';
2
2
  import { runtimeLog } from '../shared/runtimeLog.js';
3
3
  import { getBackendUrl } from '../utils/urlUtils.js';
4
+ import { buildOperatorHeaders } from './operatorHeaders.js';
4
5
  export class TelemetryClient {
5
6
  operatorKey;
6
7
  agentId;
7
8
  _queue;
8
9
  _flushing;
10
+ /**
11
+ * @param operatorKey Agent-scoped or fleet operator key.
12
+ * @param agentId Required for fleet keys (sent as X-Agent-Id). Omit for agent-scoped keys.
13
+ */
9
14
  constructor(operatorKey, agentId) {
10
15
  if (!operatorKey)
11
16
  throw new Error('TelemetryClient: operatorKey is required');
12
- if (!agentId)
13
- throw new Error('TelemetryClient: agentId is required (operator-token impersonation)');
14
17
  this.operatorKey = operatorKey;
15
18
  this.agentId = agentId;
16
19
  this._queue = [];
@@ -34,11 +37,9 @@ export class TelemetryClient {
34
37
  try {
35
38
  const res = await fetch(url, {
36
39
  method: 'POST',
37
- headers: {
40
+ headers: buildOperatorHeaders(this.operatorKey, this.agentId, {
38
41
  'content-type': 'application/json',
39
- Authorization: `Bearer ${this.operatorKey}`,
40
- 'X-Agent-Id': this.agentId,
41
- },
42
+ }),
42
43
  body: JSON.stringify({ payload }),
43
44
  });
44
45
  if (!res.ok) {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Auth headers for operator-key HTTP clients. `X-Agent-Id` is only sent when
3
+ * an agentId is present — agent-scoped keys identify the agent themselves;
4
+ * fleet keys must pass one (ZIG-642).
5
+ */
6
+ export declare function buildOperatorHeaders(operatorKey: string, agentId?: string, extra?: Record<string, string>): Record<string, string>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Auth headers for operator-key HTTP clients. `X-Agent-Id` is only sent when
3
+ * an agentId is present — agent-scoped keys identify the agent themselves;
4
+ * fleet keys must pass one (ZIG-642).
5
+ */
6
+ export function buildOperatorHeaders(operatorKey, agentId, extra) {
7
+ return {
8
+ Authorization: `Bearer ${operatorKey}`,
9
+ ...(agentId ? { 'X-Agent-Id': agentId } : {}),
10
+ ...extra,
11
+ };
12
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziggs-ai/api-client",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "HTTP and WebSocket client for the Ziggs backend API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",