acn-client 0.10.0 → 0.12.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/dist/index.d.mts CHANGED
@@ -363,6 +363,96 @@ interface PaymentCapability {
363
363
  api_endpoint?: string;
364
364
  webhook_url?: string;
365
365
  }
366
+ /**
367
+ * Task status values for ACN task pool — mirrors backend `TaskStatus` enum
368
+ * (`acn.core.entities.task.TaskStatus`).
369
+ */
370
+ type TaskStatus = 'open' | 'in_progress' | 'submitted' | 'completed' | 'rejected' | 'cancelled';
371
+ /** ACN task (org-harness task pool). Aligns with server `TaskResponse`. */
372
+ interface Task {
373
+ task_id: string;
374
+ title: string;
375
+ description: string;
376
+ status: TaskStatus | string;
377
+ /** Decimal reward amount as a string (e.g. `"10.00"`). Use `parseFloat()` to display. */
378
+ reward: string;
379
+ reward_currency: string;
380
+ creator_id: string;
381
+ creator_name?: string;
382
+ task_type?: string;
383
+ required_tags?: string[];
384
+ /** Reward in numeric form — convenience alias, equals `parseFloat(reward)`. */
385
+ reward_amount?: number;
386
+ subnet_id: string | null;
387
+ created_at: string;
388
+ deadline?: string | null;
389
+ use_escrow?: boolean;
390
+ max_participants?: number | null;
391
+ active_participants_count?: number;
392
+ completed_count?: number;
393
+ metadata?: Record<string, unknown>;
394
+ }
395
+ /** A single agent participation on a task. */
396
+ interface Participation {
397
+ participation_id: string;
398
+ agent_id: string;
399
+ status: string;
400
+ submission_content: string | null;
401
+ submitted_at: string | null;
402
+ resubmit_count: number;
403
+ }
404
+ /** Response from POST /tasks/:id/accept. */
405
+ interface TaskAcceptResponse {
406
+ task: Task;
407
+ participation_id: string | null;
408
+ }
409
+ /** Request body for creating a task (POST /api/v1/tasks). */
410
+ interface TaskCreateRequest {
411
+ /** 3–200 chars */
412
+ title: string;
413
+ /** 10–10 000 chars */
414
+ description: string;
415
+ /**
416
+ * Reward per completion as a numeric string (e.g. `"10"` or `"0"`).
417
+ * Backend field name: `reward`.
418
+ */
419
+ reward: string;
420
+ /** Deadline in hours (1–2 160). Required. */
421
+ deadline_hours: number;
422
+ subnet_id?: string | null;
423
+ /** Default: "credits" */
424
+ reward_currency?: string;
425
+ /** Default: 1 */
426
+ max_participants?: number | null;
427
+ task_type?: string;
428
+ required_tags?: string[];
429
+ auto_approve?: boolean;
430
+ use_escrow?: boolean;
431
+ }
432
+ /** Options for listing tasks. */
433
+ interface TaskListOptions {
434
+ status?: TaskStatus | string;
435
+ creator_id?: string;
436
+ assignee_id?: string;
437
+ limit?: number;
438
+ offset?: number;
439
+ }
440
+ /** Response from GET /tasks. */
441
+ interface TaskListResponse {
442
+ tasks: Task[];
443
+ total: number;
444
+ has_more: boolean;
445
+ }
446
+ /** Response from GET /tasks/:id/participations. */
447
+ interface ParticipationListResponse {
448
+ participations: Participation[];
449
+ total: number;
450
+ }
451
+ /** Request body for PATCH /subnets/:id/harness. */
452
+ interface SubnetHarnessRequest {
453
+ harness_url: string | null;
454
+ harness_secret?: string | null;
455
+ }
366
456
  /**
367
457
  * Known ACN payment task status values.
368
458
  *
@@ -652,6 +742,19 @@ declare class ACNClient {
652
742
  * ```
653
743
  */
654
744
  joinACN(request: AgentJoinRequest): Promise<AgentJoinResponse>;
745
+ /**
746
+ * Resolve the authenticated agent (i.e. the one whose API key the client
747
+ * carries). Returns the full agent record. Useful for harnesses that
748
+ * need to know their own `agent_id` to skip echo-loops on webhook
749
+ * deliveries — when an ACN task.created event arrives whose `creator_id`
750
+ * matches the harness's own agent_id, the harness can recognise the task
751
+ * as one it issued itself and avoid re-mirroring it.
752
+ */
753
+ getMyAgent(): Promise<{
754
+ agent_id: string;
755
+ name: string;
756
+ [key: string]: unknown;
757
+ }>;
655
758
  /** Get agent by ID */
656
759
  getAgent(agentId: string): Promise<AgentInfo>;
657
760
  /** Search agents (status: online | offline | all; public list does not include verification_code) */
@@ -661,6 +764,30 @@ declare class ACNClient {
661
764
  success: boolean;
662
765
  message: string;
663
766
  }>;
767
+ /**
768
+ * Rotate the agent's API key (H1).
769
+ *
770
+ * Returns a fresh `acn_*` plaintext key exactly once. The old key
771
+ * stops working immediately — including any in-process auth caches
772
+ * the gateway holds for it. Update the local SDK's stored key with
773
+ * the returned value before the next request:
774
+ *
775
+ * ```ts
776
+ * const { api_key } = await client.rotateApiKey(agentId);
777
+ * client.config.apiKey = api_key; // or rebuild the client
778
+ * ```
779
+ *
780
+ * Authorization is dual-track on the server: any one of the agent's
781
+ * current key (the common scheduled-rotation path) or the owner's
782
+ * Auth0 JWT (the recovery path when the agent has lost its key) is
783
+ * accepted.
784
+ */
785
+ rotateApiKey(agentId: string): Promise<{
786
+ success: boolean;
787
+ agent_id: string;
788
+ api_key: string;
789
+ message: string;
790
+ }>;
664
791
  /** Send agent heartbeat */
665
792
  heartbeat(agentId: string): Promise<{
666
793
  success: boolean;
@@ -1110,6 +1237,41 @@ declare class ACNClient {
1110
1237
  limit?: number;
1111
1238
  offset?: number;
1112
1239
  }): Promise<AllowlistListResponse>;
1240
+ /** Create a new task in the org-harness task pool. */
1241
+ createTask(request: TaskCreateRequest): Promise<Task>;
1242
+ /** Get task details by ID. */
1243
+ getTask(taskId: string): Promise<Task>;
1244
+ /** List tasks with optional filters. */
1245
+ listTasks(options?: TaskListOptions): Promise<TaskListResponse>;
1246
+ /** Accept a task (join as participant). Returns the task and a participation_id. */
1247
+ acceptTask(taskId: string, message?: string): Promise<TaskAcceptResponse>;
1248
+ /**
1249
+ * Submit work for a task.
1250
+ *
1251
+ * @param submissionContent - The deliverable text (5–50 000 chars)
1252
+ * @param artifacts - Optional artifact references
1253
+ * @param participationId - Required when max_participants > 1
1254
+ */
1255
+ submitTask(taskId: string, submissionContent: string, options?: {
1256
+ artifacts?: Record<string, unknown>[];
1257
+ participationId?: string;
1258
+ }): Promise<Task>;
1259
+ /**
1260
+ * Review a task submission (approve or reject).
1261
+ * Only callable by the task creator or subnet owner.
1262
+ */
1263
+ reviewTask(taskId: string, approved: boolean,
1264
+ /** Review notes sent as the `notes` field — max 5 000 chars. */
1265
+ notes?: string): Promise<Task>;
1266
+ /** Cancel a task. */
1267
+ cancelTask(taskId: string): Promise<Task>;
1268
+ /** List all participations for a task. */
1269
+ getTaskParticipations(taskId: string): Promise<Participation[]>;
1270
+ /**
1271
+ * Register (or clear) an org-harness webhook URL for a subnet.
1272
+ * Pass `harnessUrl: null` to deregister.
1273
+ */
1274
+ registerSubnetHarness(subnetId: string, harnessUrl: string | null, harnessSecret?: string | null): Promise<void>;
1113
1275
  }
1114
1276
  /**
1115
1277
  * ACN API Error
@@ -1225,4 +1387,4 @@ declare class ACNRealtime {
1225
1387
  */
1226
1388
  declare function subscribeToACN<T = unknown>(baseUrl: string, channel: string, handler: WSEventHandler<T>): () => void;
1227
1389
 
1228
- export { ACNClient, type ACNClientOptions, ACNError, ACNRealtime, type ActivityEntry, type AgentActivity, type AgentAnalytics, type AgentInfo, type AgentJoinRequest, type AgentJoinResponse, type AgentRegisterRequest, type AgentRegisterResponse, type AgentSearchOptions, type AgentSearchResponse, type AgentStatus, type AllowlistActionResponse, type AllowlistEntry, type AllowlistListResponse, type ApiResponse, type AttentionFee, type AuditEvent, type AuditQueryOptions, type BroadcastBySkillRequest, type BroadcastByTagRequest, type BroadcastRequest, type BroadcastStrategy, type CommunicationPolicyMode, type CommunicationPolicyResponse, type ComponentHealth, type DashboardData, type FollowActionResponse, type FollowCheckResponse, KNOWN_PAYMENT_TASK_STATUSES, type ManifestContentResponse, type ManifestEntry, type ManifestListResponse, type Message, type MessageType, type MetricsData, type PaymentCapability, type PaymentDiscoveryOptions, type PaymentMethod, type PaymentNetwork, type PaymentRoleStats, type PaymentStats, type PaymentTask, type PaymentTaskStatus, type SendMessageRequest, type SendMessageResponse, type SubnetCreateRequest, type SubnetCreateResponse, type SubnetInfo, type SystemHealth, type WSConnectionOptions, type WSEventHandler, type WSEventType, type WSMessage, type WSState, subscribeToACN };
1390
+ export { ACNClient, type ACNClientOptions, ACNError, ACNRealtime, type ActivityEntry, type AgentActivity, type AgentAnalytics, type AgentInfo, type AgentJoinRequest, type AgentJoinResponse, type AgentRegisterRequest, type AgentRegisterResponse, type AgentSearchOptions, type AgentSearchResponse, type AgentStatus, type AllowlistActionResponse, type AllowlistEntry, type AllowlistListResponse, type ApiResponse, type AttentionFee, type AuditEvent, type AuditQueryOptions, type BroadcastBySkillRequest, type BroadcastByTagRequest, type BroadcastRequest, type BroadcastStrategy, type CommunicationPolicyMode, type CommunicationPolicyResponse, type ComponentHealth, type DashboardData, type FollowActionResponse, type FollowCheckResponse, KNOWN_PAYMENT_TASK_STATUSES, type ManifestContentResponse, type ManifestEntry, type ManifestListResponse, type Message, type MessageType, type MetricsData, type Participation, type ParticipationListResponse, type PaymentCapability, type PaymentDiscoveryOptions, type PaymentMethod, type PaymentNetwork, type PaymentRoleStats, type PaymentStats, type PaymentTask, type PaymentTaskStatus, type SendMessageRequest, type SendMessageResponse, type SubnetCreateRequest, type SubnetCreateResponse, type SubnetHarnessRequest, type SubnetInfo, type SystemHealth, type Task, type TaskAcceptResponse, type TaskCreateRequest, type TaskListOptions, type TaskListResponse, type TaskStatus, type WSConnectionOptions, type WSEventHandler, type WSEventType, type WSMessage, type WSState, subscribeToACN };
package/dist/index.d.ts CHANGED
@@ -363,6 +363,96 @@ interface PaymentCapability {
363
363
  api_endpoint?: string;
364
364
  webhook_url?: string;
365
365
  }
366
+ /**
367
+ * Task status values for ACN task pool — mirrors backend `TaskStatus` enum
368
+ * (`acn.core.entities.task.TaskStatus`).
369
+ */
370
+ type TaskStatus = 'open' | 'in_progress' | 'submitted' | 'completed' | 'rejected' | 'cancelled';
371
+ /** ACN task (org-harness task pool). Aligns with server `TaskResponse`. */
372
+ interface Task {
373
+ task_id: string;
374
+ title: string;
375
+ description: string;
376
+ status: TaskStatus | string;
377
+ /** Decimal reward amount as a string (e.g. `"10.00"`). Use `parseFloat()` to display. */
378
+ reward: string;
379
+ reward_currency: string;
380
+ creator_id: string;
381
+ creator_name?: string;
382
+ task_type?: string;
383
+ required_tags?: string[];
384
+ /** Reward in numeric form — convenience alias, equals `parseFloat(reward)`. */
385
+ reward_amount?: number;
386
+ subnet_id: string | null;
387
+ created_at: string;
388
+ deadline?: string | null;
389
+ use_escrow?: boolean;
390
+ max_participants?: number | null;
391
+ active_participants_count?: number;
392
+ completed_count?: number;
393
+ metadata?: Record<string, unknown>;
394
+ }
395
+ /** A single agent participation on a task. */
396
+ interface Participation {
397
+ participation_id: string;
398
+ agent_id: string;
399
+ status: string;
400
+ submission_content: string | null;
401
+ submitted_at: string | null;
402
+ resubmit_count: number;
403
+ }
404
+ /** Response from POST /tasks/:id/accept. */
405
+ interface TaskAcceptResponse {
406
+ task: Task;
407
+ participation_id: string | null;
408
+ }
409
+ /** Request body for creating a task (POST /api/v1/tasks). */
410
+ interface TaskCreateRequest {
411
+ /** 3–200 chars */
412
+ title: string;
413
+ /** 10–10 000 chars */
414
+ description: string;
415
+ /**
416
+ * Reward per completion as a numeric string (e.g. `"10"` or `"0"`).
417
+ * Backend field name: `reward`.
418
+ */
419
+ reward: string;
420
+ /** Deadline in hours (1–2 160). Required. */
421
+ deadline_hours: number;
422
+ subnet_id?: string | null;
423
+ /** Default: "credits" */
424
+ reward_currency?: string;
425
+ /** Default: 1 */
426
+ max_participants?: number | null;
427
+ task_type?: string;
428
+ required_tags?: string[];
429
+ auto_approve?: boolean;
430
+ use_escrow?: boolean;
431
+ }
432
+ /** Options for listing tasks. */
433
+ interface TaskListOptions {
434
+ status?: TaskStatus | string;
435
+ creator_id?: string;
436
+ assignee_id?: string;
437
+ limit?: number;
438
+ offset?: number;
439
+ }
440
+ /** Response from GET /tasks. */
441
+ interface TaskListResponse {
442
+ tasks: Task[];
443
+ total: number;
444
+ has_more: boolean;
445
+ }
446
+ /** Response from GET /tasks/:id/participations. */
447
+ interface ParticipationListResponse {
448
+ participations: Participation[];
449
+ total: number;
450
+ }
451
+ /** Request body for PATCH /subnets/:id/harness. */
452
+ interface SubnetHarnessRequest {
453
+ harness_url: string | null;
454
+ harness_secret?: string | null;
455
+ }
366
456
  /**
367
457
  * Known ACN payment task status values.
368
458
  *
@@ -652,6 +742,19 @@ declare class ACNClient {
652
742
  * ```
653
743
  */
654
744
  joinACN(request: AgentJoinRequest): Promise<AgentJoinResponse>;
745
+ /**
746
+ * Resolve the authenticated agent (i.e. the one whose API key the client
747
+ * carries). Returns the full agent record. Useful for harnesses that
748
+ * need to know their own `agent_id` to skip echo-loops on webhook
749
+ * deliveries — when an ACN task.created event arrives whose `creator_id`
750
+ * matches the harness's own agent_id, the harness can recognise the task
751
+ * as one it issued itself and avoid re-mirroring it.
752
+ */
753
+ getMyAgent(): Promise<{
754
+ agent_id: string;
755
+ name: string;
756
+ [key: string]: unknown;
757
+ }>;
655
758
  /** Get agent by ID */
656
759
  getAgent(agentId: string): Promise<AgentInfo>;
657
760
  /** Search agents (status: online | offline | all; public list does not include verification_code) */
@@ -661,6 +764,30 @@ declare class ACNClient {
661
764
  success: boolean;
662
765
  message: string;
663
766
  }>;
767
+ /**
768
+ * Rotate the agent's API key (H1).
769
+ *
770
+ * Returns a fresh `acn_*` plaintext key exactly once. The old key
771
+ * stops working immediately — including any in-process auth caches
772
+ * the gateway holds for it. Update the local SDK's stored key with
773
+ * the returned value before the next request:
774
+ *
775
+ * ```ts
776
+ * const { api_key } = await client.rotateApiKey(agentId);
777
+ * client.config.apiKey = api_key; // or rebuild the client
778
+ * ```
779
+ *
780
+ * Authorization is dual-track on the server: any one of the agent's
781
+ * current key (the common scheduled-rotation path) or the owner's
782
+ * Auth0 JWT (the recovery path when the agent has lost its key) is
783
+ * accepted.
784
+ */
785
+ rotateApiKey(agentId: string): Promise<{
786
+ success: boolean;
787
+ agent_id: string;
788
+ api_key: string;
789
+ message: string;
790
+ }>;
664
791
  /** Send agent heartbeat */
665
792
  heartbeat(agentId: string): Promise<{
666
793
  success: boolean;
@@ -1110,6 +1237,41 @@ declare class ACNClient {
1110
1237
  limit?: number;
1111
1238
  offset?: number;
1112
1239
  }): Promise<AllowlistListResponse>;
1240
+ /** Create a new task in the org-harness task pool. */
1241
+ createTask(request: TaskCreateRequest): Promise<Task>;
1242
+ /** Get task details by ID. */
1243
+ getTask(taskId: string): Promise<Task>;
1244
+ /** List tasks with optional filters. */
1245
+ listTasks(options?: TaskListOptions): Promise<TaskListResponse>;
1246
+ /** Accept a task (join as participant). Returns the task and a participation_id. */
1247
+ acceptTask(taskId: string, message?: string): Promise<TaskAcceptResponse>;
1248
+ /**
1249
+ * Submit work for a task.
1250
+ *
1251
+ * @param submissionContent - The deliverable text (5–50 000 chars)
1252
+ * @param artifacts - Optional artifact references
1253
+ * @param participationId - Required when max_participants > 1
1254
+ */
1255
+ submitTask(taskId: string, submissionContent: string, options?: {
1256
+ artifacts?: Record<string, unknown>[];
1257
+ participationId?: string;
1258
+ }): Promise<Task>;
1259
+ /**
1260
+ * Review a task submission (approve or reject).
1261
+ * Only callable by the task creator or subnet owner.
1262
+ */
1263
+ reviewTask(taskId: string, approved: boolean,
1264
+ /** Review notes sent as the `notes` field — max 5 000 chars. */
1265
+ notes?: string): Promise<Task>;
1266
+ /** Cancel a task. */
1267
+ cancelTask(taskId: string): Promise<Task>;
1268
+ /** List all participations for a task. */
1269
+ getTaskParticipations(taskId: string): Promise<Participation[]>;
1270
+ /**
1271
+ * Register (or clear) an org-harness webhook URL for a subnet.
1272
+ * Pass `harnessUrl: null` to deregister.
1273
+ */
1274
+ registerSubnetHarness(subnetId: string, harnessUrl: string | null, harnessSecret?: string | null): Promise<void>;
1113
1275
  }
1114
1276
  /**
1115
1277
  * ACN API Error
@@ -1225,4 +1387,4 @@ declare class ACNRealtime {
1225
1387
  */
1226
1388
  declare function subscribeToACN<T = unknown>(baseUrl: string, channel: string, handler: WSEventHandler<T>): () => void;
1227
1389
 
1228
- export { ACNClient, type ACNClientOptions, ACNError, ACNRealtime, type ActivityEntry, type AgentActivity, type AgentAnalytics, type AgentInfo, type AgentJoinRequest, type AgentJoinResponse, type AgentRegisterRequest, type AgentRegisterResponse, type AgentSearchOptions, type AgentSearchResponse, type AgentStatus, type AllowlistActionResponse, type AllowlistEntry, type AllowlistListResponse, type ApiResponse, type AttentionFee, type AuditEvent, type AuditQueryOptions, type BroadcastBySkillRequest, type BroadcastByTagRequest, type BroadcastRequest, type BroadcastStrategy, type CommunicationPolicyMode, type CommunicationPolicyResponse, type ComponentHealth, type DashboardData, type FollowActionResponse, type FollowCheckResponse, KNOWN_PAYMENT_TASK_STATUSES, type ManifestContentResponse, type ManifestEntry, type ManifestListResponse, type Message, type MessageType, type MetricsData, type PaymentCapability, type PaymentDiscoveryOptions, type PaymentMethod, type PaymentNetwork, type PaymentRoleStats, type PaymentStats, type PaymentTask, type PaymentTaskStatus, type SendMessageRequest, type SendMessageResponse, type SubnetCreateRequest, type SubnetCreateResponse, type SubnetInfo, type SystemHealth, type WSConnectionOptions, type WSEventHandler, type WSEventType, type WSMessage, type WSState, subscribeToACN };
1390
+ export { ACNClient, type ACNClientOptions, ACNError, ACNRealtime, type ActivityEntry, type AgentActivity, type AgentAnalytics, type AgentInfo, type AgentJoinRequest, type AgentJoinResponse, type AgentRegisterRequest, type AgentRegisterResponse, type AgentSearchOptions, type AgentSearchResponse, type AgentStatus, type AllowlistActionResponse, type AllowlistEntry, type AllowlistListResponse, type ApiResponse, type AttentionFee, type AuditEvent, type AuditQueryOptions, type BroadcastBySkillRequest, type BroadcastByTagRequest, type BroadcastRequest, type BroadcastStrategy, type CommunicationPolicyMode, type CommunicationPolicyResponse, type ComponentHealth, type DashboardData, type FollowActionResponse, type FollowCheckResponse, KNOWN_PAYMENT_TASK_STATUSES, type ManifestContentResponse, type ManifestEntry, type ManifestListResponse, type Message, type MessageType, type MetricsData, type Participation, type ParticipationListResponse, type PaymentCapability, type PaymentDiscoveryOptions, type PaymentMethod, type PaymentNetwork, type PaymentRoleStats, type PaymentStats, type PaymentTask, type PaymentTaskStatus, type SendMessageRequest, type SendMessageResponse, type SubnetCreateRequest, type SubnetCreateResponse, type SubnetHarnessRequest, type SubnetInfo, type SystemHealth, type Task, type TaskAcceptResponse, type TaskCreateRequest, type TaskListOptions, type TaskListResponse, type TaskStatus, type WSConnectionOptions, type WSEventHandler, type WSEventType, type WSMessage, type WSState, subscribeToACN };
package/dist/index.js CHANGED
@@ -53,7 +53,7 @@ var ACNClient = class {
53
53
  this.timeout = options.timeout ?? 3e4;
54
54
  this.headers = options.headers ?? {};
55
55
  if (options.apiKey) {
56
- this.headers["X-API-Key"] = options.apiKey;
56
+ this.headers["Authorization"] = `Bearer ${options.apiKey}`;
57
57
  }
58
58
  }
59
59
  }
@@ -168,6 +168,17 @@ var ACNClient = class {
168
168
  async joinACN(request) {
169
169
  return this.post("/api/v1/agents/join", request);
170
170
  }
171
+ /**
172
+ * Resolve the authenticated agent (i.e. the one whose API key the client
173
+ * carries). Returns the full agent record. Useful for harnesses that
174
+ * need to know their own `agent_id` to skip echo-loops on webhook
175
+ * deliveries — when an ACN task.created event arrives whose `creator_id`
176
+ * matches the harness's own agent_id, the harness can recognise the task
177
+ * as one it issued itself and avoid re-mirroring it.
178
+ */
179
+ async getMyAgent() {
180
+ return this.get("/api/v1/agents/me");
181
+ }
171
182
  /** Get agent by ID */
172
183
  async getAgent(agentId) {
173
184
  return this.get(`/api/v1/agents/${agentId}`);
@@ -183,6 +194,27 @@ var ACNClient = class {
183
194
  async unregisterAgent(agentId) {
184
195
  return this.delete(`/api/v1/agents/${agentId}`);
185
196
  }
197
+ /**
198
+ * Rotate the agent's API key (H1).
199
+ *
200
+ * Returns a fresh `acn_*` plaintext key exactly once. The old key
201
+ * stops working immediately — including any in-process auth caches
202
+ * the gateway holds for it. Update the local SDK's stored key with
203
+ * the returned value before the next request:
204
+ *
205
+ * ```ts
206
+ * const { api_key } = await client.rotateApiKey(agentId);
207
+ * client.config.apiKey = api_key; // or rebuild the client
208
+ * ```
209
+ *
210
+ * Authorization is dual-track on the server: any one of the agent's
211
+ * current key (the common scheduled-rotation path) or the owner's
212
+ * Auth0 JWT (the recovery path when the agent has lost its key) is
213
+ * accepted.
214
+ */
215
+ async rotateApiKey(agentId) {
216
+ return this.post(`/api/v1/agents/${agentId}/rotate-key`);
217
+ }
186
218
  /** Send agent heartbeat */
187
219
  async heartbeat(agentId) {
188
220
  return this.post(`/api/v1/agents/${agentId}/heartbeat`);
@@ -218,6 +250,18 @@ var ACNClient = class {
218
250
  async getSubnetAgents(subnetId) {
219
251
  return this.get(`/api/v1/subnets/${subnetId}/agents`);
220
252
  }
253
+ // ──────────────────────────────────────────────────────────────────────
254
+ // Subnet membership (agent-side)
255
+ //
256
+ // Canonical paths under `/api/v1/agents/{agent_id}/…`, matching every
257
+ // other agent-side operation (heartbeat / claim / transfer / wallets / …).
258
+ //
259
+ // Before 0.11.2 the SDK called `/api/v1/subnets/{agent_id}/subnets/{id}`
260
+ // because that was the only shape the backend served. Backend release
261
+ // carrying the canonical-routes patch (ACN PR #42) now serves both
262
+ // shapes — the legacy one is marked `deprecated=True` in OpenAPI and
263
+ // scheduled for removal. Requires ACN backend ≥ post-PR-#42.
264
+ // ──────────────────────────────────────────────────────────────────────
221
265
  /** Join agent to subnet */
222
266
  async joinSubnet(agentId, subnetId) {
223
267
  return this.post(`/api/v1/agents/${agentId}/subnets/${subnetId}`);
@@ -792,6 +836,81 @@ var ACNClient = class {
792
836
  async listAllowlist(agentId, options) {
793
837
  return this.get(`/api/v1/agents/${agentId}/allowlist`, options);
794
838
  }
839
+ // ============================================
840
+ // Task Pool Methods (Saga / Org-Harness)
841
+ // ============================================
842
+ /** Create a new task in the org-harness task pool. */
843
+ async createTask(request) {
844
+ return this.post("/api/v1/tasks", request);
845
+ }
846
+ /** Get task details by ID. */
847
+ async getTask(taskId) {
848
+ return this.get(`/api/v1/tasks/${taskId}`);
849
+ }
850
+ /** List tasks with optional filters. */
851
+ async listTasks(options) {
852
+ const params = {};
853
+ if (options?.status !== void 0) params.status = options.status;
854
+ if (options?.creator_id !== void 0) params.creator_id = options.creator_id;
855
+ if (options?.assignee_id !== void 0) params.assignee_id = options.assignee_id;
856
+ if (options?.limit !== void 0) params.limit = options.limit;
857
+ if (options?.offset !== void 0) params.offset = options.offset;
858
+ return this.get("/api/v1/tasks", params);
859
+ }
860
+ /** Accept a task (join as participant). Returns the task and a participation_id. */
861
+ async acceptTask(taskId, message) {
862
+ return this.post(`/api/v1/tasks/${taskId}/accept`, { message: message ?? "" });
863
+ }
864
+ /**
865
+ * Submit work for a task.
866
+ *
867
+ * @param submissionContent - The deliverable text (5–50 000 chars)
868
+ * @param artifacts - Optional artifact references
869
+ * @param participationId - Required when max_participants > 1
870
+ */
871
+ async submitTask(taskId, submissionContent, options) {
872
+ return this.post(`/api/v1/tasks/${taskId}/submit`, {
873
+ submission: submissionContent,
874
+ artifacts: options?.artifacts ?? [],
875
+ participation_id: options?.participationId
876
+ });
877
+ }
878
+ /**
879
+ * Review a task submission (approve or reject).
880
+ * Only callable by the task creator or subnet owner.
881
+ */
882
+ async reviewTask(taskId, approved, notes) {
883
+ return this.post(`/api/v1/tasks/${taskId}/review`, {
884
+ approved,
885
+ notes: notes ?? ""
886
+ });
887
+ }
888
+ /** Cancel a task. */
889
+ async cancelTask(taskId) {
890
+ return this.post(`/api/v1/tasks/${taskId}/cancel`, {});
891
+ }
892
+ /** List all participations for a task. */
893
+ async getTaskParticipations(taskId) {
894
+ const res = await this.get(
895
+ `/api/v1/tasks/${taskId}/participations`
896
+ );
897
+ return res.participations ?? [];
898
+ }
899
+ // ============================================
900
+ // Subnet Harness
901
+ // ============================================
902
+ /**
903
+ * Register (or clear) an org-harness webhook URL for a subnet.
904
+ * Pass `harnessUrl: null` to deregister.
905
+ */
906
+ async registerSubnetHarness(subnetId, harnessUrl, harnessSecret) {
907
+ await this.request("PATCH", `/api/v1/subnets/${subnetId}/harness`, {
908
+ body: {
909
+ harness_url: harnessUrl,
910
+ harness_secret: harnessSecret ?? null
911
+ }
912
+ });
913
+ }
795
914
  };
796
915
  var ACNError = class extends Error {
797
916
  constructor(status, message, options) {
package/dist/index.mjs CHANGED
@@ -13,7 +13,7 @@ var ACNClient = class {
13
13
  this.timeout = options.timeout ?? 3e4;
14
14
  this.headers = options.headers ?? {};
15
15
  if (options.apiKey) {
16
- this.headers["X-API-Key"] = options.apiKey;
16
+ this.headers["Authorization"] = `Bearer ${options.apiKey}`;
17
17
  }
18
18
  }
19
19
  }
@@ -128,6 +128,17 @@ var ACNClient = class {
128
128
  async joinACN(request) {
129
129
  return this.post("/api/v1/agents/join", request);
130
130
  }
131
+ /**
132
+ * Resolve the authenticated agent (i.e. the one whose API key the client
133
+ * carries). Returns the full agent record. Useful for harnesses that
134
+ * need to know their own `agent_id` to skip echo-loops on webhook
135
+ * deliveries — when an ACN task.created event arrives whose `creator_id`
136
+ * matches the harness's own agent_id, the harness can recognise the task
137
+ * as one it issued itself and avoid re-mirroring it.
138
+ */
139
+ async getMyAgent() {
140
+ return this.get("/api/v1/agents/me");
141
+ }
131
142
  /** Get agent by ID */
132
143
  async getAgent(agentId) {
133
144
  return this.get(`/api/v1/agents/${agentId}`);
@@ -143,6 +154,27 @@ var ACNClient = class {
143
154
  async unregisterAgent(agentId) {
144
155
  return this.delete(`/api/v1/agents/${agentId}`);
145
156
  }
157
+ /**
158
+ * Rotate the agent's API key (H1).
159
+ *
160
+ * Returns a fresh `acn_*` plaintext key exactly once. The old key
161
+ * stops working immediately — including any in-process auth caches
162
+ * the gateway holds for it. Update the local SDK's stored key with
163
+ * the returned value before the next request:
164
+ *
165
+ * ```ts
166
+ * const { api_key } = await client.rotateApiKey(agentId);
167
+ * client.config.apiKey = api_key; // or rebuild the client
168
+ * ```
169
+ *
170
+ * Authorization is dual-track on the server: any one of the agent's
171
+ * current key (the common scheduled-rotation path) or the owner's
172
+ * Auth0 JWT (the recovery path when the agent has lost its key) is
173
+ * accepted.
174
+ */
175
+ async rotateApiKey(agentId) {
176
+ return this.post(`/api/v1/agents/${agentId}/rotate-key`);
177
+ }
146
178
  /** Send agent heartbeat */
147
179
  async heartbeat(agentId) {
148
180
  return this.post(`/api/v1/agents/${agentId}/heartbeat`);
@@ -178,6 +210,18 @@ var ACNClient = class {
178
210
  async getSubnetAgents(subnetId) {
179
211
  return this.get(`/api/v1/subnets/${subnetId}/agents`);
180
212
  }
213
+ // ──────────────────────────────────────────────────────────────────────
214
+ // Subnet membership (agent-side)
215
+ //
216
+ // Canonical paths under `/api/v1/agents/{agent_id}/…`, matching every
217
+ // other agent-side operation (heartbeat / claim / transfer / wallets / …).
218
+ //
219
+ // Before 0.11.2 the SDK called `/api/v1/subnets/{agent_id}/subnets/{id}`
220
+ // because that was the only shape the backend served. Backend release
221
+ // carrying the canonical-routes patch (ACN PR #42) now serves both
222
+ // shapes — the legacy one is marked `deprecated=True` in OpenAPI and
223
+ // scheduled for removal. Requires ACN backend ≥ post-PR-#42.
224
+ // ──────────────────────────────────────────────────────────────────────
181
225
  /** Join agent to subnet */
182
226
  async joinSubnet(agentId, subnetId) {
183
227
  return this.post(`/api/v1/agents/${agentId}/subnets/${subnetId}`);
@@ -752,6 +796,81 @@ var ACNClient = class {
752
796
  async listAllowlist(agentId, options) {
753
797
  return this.get(`/api/v1/agents/${agentId}/allowlist`, options);
754
798
  }
799
+ // ============================================
800
+ // Task Pool Methods (Saga / Org-Harness)
801
+ // ============================================
802
+ /** Create a new task in the org-harness task pool. */
803
+ async createTask(request) {
804
+ return this.post("/api/v1/tasks", request);
805
+ }
806
+ /** Get task details by ID. */
807
+ async getTask(taskId) {
808
+ return this.get(`/api/v1/tasks/${taskId}`);
809
+ }
810
+ /** List tasks with optional filters. */
811
+ async listTasks(options) {
812
+ const params = {};
813
+ if (options?.status !== void 0) params.status = options.status;
814
+ if (options?.creator_id !== void 0) params.creator_id = options.creator_id;
815
+ if (options?.assignee_id !== void 0) params.assignee_id = options.assignee_id;
816
+ if (options?.limit !== void 0) params.limit = options.limit;
817
+ if (options?.offset !== void 0) params.offset = options.offset;
818
+ return this.get("/api/v1/tasks", params);
819
+ }
820
+ /** Accept a task (join as participant). Returns the task and a participation_id. */
821
+ async acceptTask(taskId, message) {
822
+ return this.post(`/api/v1/tasks/${taskId}/accept`, { message: message ?? "" });
823
+ }
824
+ /**
825
+ * Submit work for a task.
826
+ *
827
+ * @param submissionContent - The deliverable text (5–50 000 chars)
828
+ * @param artifacts - Optional artifact references
829
+ * @param participationId - Required when max_participants > 1
830
+ */
831
+ async submitTask(taskId, submissionContent, options) {
832
+ return this.post(`/api/v1/tasks/${taskId}/submit`, {
833
+ submission: submissionContent,
834
+ artifacts: options?.artifacts ?? [],
835
+ participation_id: options?.participationId
836
+ });
837
+ }
838
+ /**
839
+ * Review a task submission (approve or reject).
840
+ * Only callable by the task creator or subnet owner.
841
+ */
842
+ async reviewTask(taskId, approved, notes) {
843
+ return this.post(`/api/v1/tasks/${taskId}/review`, {
844
+ approved,
845
+ notes: notes ?? ""
846
+ });
847
+ }
848
+ /** Cancel a task. */
849
+ async cancelTask(taskId) {
850
+ return this.post(`/api/v1/tasks/${taskId}/cancel`, {});
851
+ }
852
+ /** List all participations for a task. */
853
+ async getTaskParticipations(taskId) {
854
+ const res = await this.get(
855
+ `/api/v1/tasks/${taskId}/participations`
856
+ );
857
+ return res.participations ?? [];
858
+ }
859
+ // ============================================
860
+ // Subnet Harness
861
+ // ============================================
862
+ /**
863
+ * Register (or clear) an org-harness webhook URL for a subnet.
864
+ * Pass `harnessUrl: null` to deregister.
865
+ */
866
+ async registerSubnetHarness(subnetId, harnessUrl, harnessSecret) {
867
+ await this.request("PATCH", `/api/v1/subnets/${subnetId}/harness`, {
868
+ body: {
869
+ harness_url: harnessUrl,
870
+ harness_secret: harnessSecret ?? null
871
+ }
872
+ });
873
+ }
755
874
  };
756
875
  var ACNError = class extends Error {
757
876
  constructor(status, message, options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acn-client",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Official TypeScript/JavaScript client for ACN (Agent Collaboration Network)",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",