@virtuals-protocol/acp-node 0.3.0-beta.14 → 0.3.0-beta.16

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.js CHANGED
@@ -35,7 +35,7 @@ var require_package = __commonJS({
35
35
  "package.json"(exports2, module2) {
36
36
  module2.exports = {
37
37
  name: "@virtuals-protocol/acp-node",
38
- version: "0.3.0-beta.14",
38
+ version: "0.3.0-beta.16",
39
39
  main: "./dist/index.js",
40
40
  module: "./dist/index.mjs",
41
41
  types: "./dist/index.d.ts",
@@ -3974,6 +3974,7 @@ var AcpJobOffering = class {
3974
3974
  var acpJobOffering_default = AcpJobOffering;
3975
3975
 
3976
3976
  // src/acpJob.ts
3977
+ var util = __toESM(require("util"));
3977
3978
  var AcpJob = class {
3978
3979
  constructor(acpClient, id, clientAddress, providerAddress, evaluatorAddress, price, priceTokenAddress, memos, phase, context, contractAddress, netPayableAmount) {
3979
3980
  this.acpClient = acpClient;
@@ -4348,10 +4349,28 @@ var AcpJob = class {
4348
4349
  waitMs = Math.min(waitMs * 2, maxWaitMs);
4349
4350
  }
4350
4351
  }
4352
+ [util.inspect.custom]() {
4353
+ return {
4354
+ id: this.id,
4355
+ clientAddress: this.clientAddress,
4356
+ providerAddress: this.providerAddress,
4357
+ name: this.name,
4358
+ requirement: this.requirement,
4359
+ priceType: this.priceType,
4360
+ priceValue: this.priceValue,
4361
+ priceTokenAddress: this.priceTokenAddress,
4362
+ memos: this.memos,
4363
+ phase: this.phase,
4364
+ context: this.context,
4365
+ contractAddress: this.contractAddress,
4366
+ netPayableAmount: this.netPayableAmount
4367
+ };
4368
+ }
4351
4369
  };
4352
4370
  var acpJob_default = AcpJob;
4353
4371
 
4354
4372
  // src/acpMemo.ts
4373
+ var import_util = __toESM(require("util"));
4355
4374
  var AcpMemo = class {
4356
4375
  constructor(contractClient, id, type, content, nextPhase, status, senderAddress, signedReason, expiry, payableDetails, txHash, signedTxHash) {
4357
4376
  this.contractClient = contractClient;
@@ -4391,6 +4410,21 @@ var AcpMemo = class {
4391
4410
  const payload = this.contractClient.signMemo(this.id, approved, reason);
4392
4411
  return await this.contractClient.handleOperation([payload]);
4393
4412
  }
4413
+ [import_util.default.inspect.custom]() {
4414
+ return {
4415
+ id: this.id,
4416
+ senderAddress: this.senderAddress,
4417
+ type: MemoType[this.type],
4418
+ status: this.status,
4419
+ content: this.content,
4420
+ signedReason: this.signedReason,
4421
+ txHash: this.txHash,
4422
+ signedTxHash: this.signedTxHash,
4423
+ nextPhase: AcpJobPhases[this.nextPhase],
4424
+ expiry: this.expiry,
4425
+ payableDetails: this.payableDetails
4426
+ };
4427
+ }
4394
4428
  };
4395
4429
  var acpMemo_default = AcpMemo;
4396
4430
 
@@ -4420,8 +4454,8 @@ var AcpClient = class {
4420
4454
  if (this.contractClients.length === 0) {
4421
4455
  throw new acpError_default("ACP contract client is required");
4422
4456
  }
4423
- this.contractClients.every((client) => {
4424
- if (client.contractAddress !== this.contractClients[0].contractAddress) {
4457
+ this.contractClients.forEach((client) => {
4458
+ if (client.walletAddress !== this.contractClients[0].walletAddress) {
4425
4459
  throw new acpError_default(
4426
4460
  "All contract clients must have the same agent wallet address"
4427
4461
  );
@@ -4429,7 +4463,7 @@ var AcpClient = class {
4429
4463
  });
4430
4464
  this.onNewTask = options.onNewTask;
4431
4465
  this.onEvaluate = options.onEvaluate || this.defaultOnEvaluate;
4432
- this.init();
4466
+ this.init(options.skipSocketConnection);
4433
4467
  }
4434
4468
  contractClientByAddress(address) {
4435
4469
  if (!address) {
@@ -4453,12 +4487,12 @@ var AcpClient = class {
4453
4487
  await job.evaluate(true, "Evaluated by default");
4454
4488
  }
4455
4489
  get walletAddress() {
4456
- if (Array.isArray(this.acpContractClient)) {
4457
- return this.acpContractClient[0].walletAddress;
4458
- }
4459
4490
  return this.acpContractClient.walletAddress;
4460
4491
  }
4461
- async init() {
4492
+ async init(skipSocketConnection = false) {
4493
+ if (skipSocketConnection) {
4494
+ return;
4495
+ }
4462
4496
  const socket = (0, import_socket.io)(this.acpUrl, {
4463
4497
  auth: {
4464
4498
  walletAddress: this.walletAddress
@@ -4564,7 +4598,7 @@ var AcpClient = class {
4564
4598
  process.on("SIGTERM", cleanup);
4565
4599
  }
4566
4600
  async browseAgents(keyword, options) {
4567
- let { cluster, sort_by, top_k, graduationStatus, onlineStatus } = options;
4601
+ let { cluster, sort_by, top_k, graduationStatus, onlineStatus, showHiddenOfferings } = options;
4568
4602
  top_k = top_k ?? 5;
4569
4603
  let url = `${this.acpUrl}/api/agents/v4/search?search=${keyword}`;
4570
4604
  if (sort_by && sort_by.length > 0) {
@@ -4585,6 +4619,9 @@ var AcpClient = class {
4585
4619
  if (onlineStatus) {
4586
4620
  url += `&onlineStatus=${onlineStatus}`;
4587
4621
  }
4622
+ if (showHiddenOfferings) {
4623
+ url += `&showHiddenOfferings=${showHiddenOfferings}`;
4624
+ }
4588
4625
  const response = await fetch(url);
4589
4626
  const data = await response.json();
4590
4627
  const availableContractClientAddresses = this.contractClients.map(
@@ -4622,7 +4659,7 @@ var AcpClient = class {
4622
4659
  twitterHandle: agent.twitterHandle,
4623
4660
  walletAddress: agent.walletAddress,
4624
4661
  metrics: agent.metrics,
4625
- resource: agent.resources
4662
+ resources: agent.resources
4626
4663
  };
4627
4664
  });
4628
4665
  }
@@ -4693,209 +4730,142 @@ var AcpClient = class {
4693
4730
  return jobId;
4694
4731
  }
4695
4732
  async getActiveJobs(page = 1, pageSize = 10) {
4696
- let url = `${this.acpUrl}/api/jobs/active?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4697
- try {
4698
- const response = await fetch(url, {
4699
- headers: {
4700
- "wallet-address": this.walletAddress
4701
- }
4702
- });
4703
- const data = await response.json();
4704
- if (data.error) {
4705
- throw new acpError_default(data.error.message);
4706
- }
4707
- return data.data.map((job) => {
4708
- return new acpJob_default(
4709
- this,
4710
- job.id,
4711
- job.clientAddress,
4712
- job.providerAddress,
4713
- job.evaluatorAddress,
4714
- job.price,
4715
- job.priceTokenAddress,
4716
- job.memos.map((memo) => {
4717
- return new acpMemo_default(
4718
- this.contractClientByAddress(job.contractAddress),
4719
- memo.id,
4720
- memo.memoType,
4721
- memo.content,
4722
- memo.nextPhase,
4723
- memo.status,
4724
- memo.senderAddress,
4725
- memo.signedReason,
4726
- memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4727
- memo.payableDetails,
4728
- memo.txHash,
4729
- memo.signedTxHash
4730
- );
4731
- }),
4732
- job.phase,
4733
- job.context,
4734
- job.contractAddress,
4735
- job.netPayableAmount
4736
- );
4737
- });
4738
- } catch (error) {
4739
- throw new acpError_default("Failed to get active jobs", error);
4740
- }
4733
+ const url = `${this.acpUrl}/api/jobs/active?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4734
+ const rawJobs = await this._fetchJobList(url);
4735
+ return this._hydrateJobs(rawJobs, { logPrefix: "Active jobs" });
4741
4736
  }
4742
4737
  async getPendingMemoJobs(page = 1, pageSize = 10) {
4743
- let url = `${this.acpUrl}/api/jobs/pending-memos?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4744
- try {
4745
- const response = await fetch(url, {
4746
- headers: {
4747
- "wallet-address": this.acpContractClient.walletAddress
4748
- }
4749
- });
4750
- const data = await response.json();
4751
- if (data.error) {
4752
- throw new acpError_default(data.error.message);
4753
- }
4754
- return data.data.map((job) => {
4755
- return new acpJob_default(
4756
- this,
4757
- job.id,
4758
- job.clientAddress,
4759
- job.providerAddress,
4760
- job.evaluatorAddress,
4761
- job.price,
4762
- job.priceTokenAddress,
4763
- job.memos.map((memo) => {
4764
- return new acpMemo_default(
4765
- this.contractClientByAddress(job.contractAddress),
4766
- memo.id,
4767
- memo.memoType,
4768
- memo.content,
4769
- memo.nextPhase,
4770
- memo.status,
4771
- memo.senderAddress,
4772
- memo.signedReason,
4773
- memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4774
- typeof memo.payableDetails === "string" ? tryParseJson(memo.payableDetails) || void 0 : memo.payableDetails,
4775
- memo.txHash,
4776
- memo.signedTxHash
4777
- );
4778
- }),
4779
- job.phase,
4780
- job.context,
4781
- job.contractAddress,
4782
- job.netPayableAmount
4783
- );
4784
- });
4785
- } catch (error) {
4786
- throw new acpError_default("Failed to get pending memo jobs", error);
4787
- }
4738
+ const url = `${this.acpUrl}/api/jobs/pending-memos?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4739
+ const rawJobs = await this._fetchJobList(url);
4740
+ return this._hydrateJobs(rawJobs, { logPrefix: "Pending memo jobs" });
4788
4741
  }
4789
4742
  async getCompletedJobs(page = 1, pageSize = 10) {
4790
- let url = `${this.acpUrl}/api/jobs/completed?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4791
- try {
4792
- const response = await fetch(url, {
4793
- headers: {
4794
- "wallet-address": this.acpContractClient.walletAddress
4795
- }
4796
- });
4797
- const data = await response.json();
4798
- if (data.error) {
4799
- throw new acpError_default(data.error.message);
4800
- }
4801
- return data.data.map((job) => {
4802
- return new acpJob_default(
4803
- this,
4804
- job.id,
4805
- job.clientAddress,
4806
- job.providerAddress,
4807
- job.evaluatorAddress,
4808
- job.price,
4809
- job.priceTokenAddress,
4810
- job.memos.map((memo) => {
4811
- return new acpMemo_default(
4812
- this.contractClientByAddress(job.contractAddress),
4813
- memo.id,
4814
- memo.memoType,
4815
- memo.content,
4816
- memo.nextPhase,
4817
- memo.status,
4818
- memo.senderAddress,
4819
- memo.signedReason,
4820
- memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4821
- memo.payableDetails,
4822
- memo.txHash,
4823
- memo.signedTxHash
4824
- );
4825
- }),
4826
- job.phase,
4827
- job.context,
4828
- job.contractAddress,
4829
- job.netPayableAmount
4830
- );
4831
- });
4832
- } catch (error) {
4833
- throw new acpError_default("Failed to get completed jobs", error);
4834
- }
4743
+ const url = `${this.acpUrl}/api/jobs/completed?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4744
+ const rawJobs = await this._fetchJobList(url);
4745
+ return this._hydrateJobs(rawJobs, { logPrefix: "Completed jobs" });
4835
4746
  }
4836
4747
  async getCancelledJobs(page = 1, pageSize = 10) {
4837
- let url = `${this.acpUrl}/api/jobs/cancelled?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4748
+ const url = `${this.acpUrl}/api/jobs/cancelled?pagination[page]=${page}&pagination[pageSize]=${pageSize}`;
4749
+ const rawJobs = await this._fetchJobList(url);
4750
+ return this._hydrateJobs(rawJobs, { logPrefix: "Cancelled jobs" });
4751
+ }
4752
+ async _fetchJobList(url) {
4753
+ let response;
4838
4754
  try {
4839
- const response = await fetch(url, {
4755
+ response = await fetch(url, {
4840
4756
  headers: {
4841
4757
  "wallet-address": this.walletAddress
4842
4758
  }
4843
4759
  });
4844
- const data = await response.json();
4845
- if (data.error) {
4846
- throw new acpError_default(data.error.message);
4847
- }
4848
- return data.data.map((job) => {
4849
- return new acpJob_default(
4850
- this,
4851
- job.id,
4852
- job.clientAddress,
4853
- job.providerAddress,
4854
- job.evaluatorAddress,
4855
- job.price,
4856
- job.priceTokenAddress,
4857
- job.memos.map((memo) => {
4858
- return new acpMemo_default(
4859
- this.contractClientByAddress(job.contractAddress),
4860
- memo.id,
4861
- memo.memoType,
4862
- memo.content,
4863
- memo.nextPhase,
4864
- memo.status,
4865
- memo.senderAddress,
4866
- memo.signedReason,
4867
- memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4868
- memo.payableDetails,
4869
- memo.txHash,
4870
- memo.signedTxHash
4871
- );
4872
- }),
4873
- job.phase,
4874
- job.context,
4875
- job.contractAddress,
4876
- job.netPayableAmount
4760
+ } catch (err) {
4761
+ throw new acpError_default("Failed to fetch ACP jobs (network error)", err);
4762
+ }
4763
+ let data;
4764
+ try {
4765
+ data = await response.json();
4766
+ } catch (err) {
4767
+ throw new acpError_default("Failed to parse ACP jobs response", err);
4768
+ }
4769
+ if (data.error) {
4770
+ throw new acpError_default(data.error.message);
4771
+ }
4772
+ return data.data;
4773
+ }
4774
+ _hydrateJobs(rawJobs, options) {
4775
+ const jobs = [];
4776
+ const errors = [];
4777
+ for (const job of rawJobs) {
4778
+ try {
4779
+ const memos = job.memos.map(
4780
+ (memo) => new acpMemo_default(
4781
+ this.contractClientByAddress(job.contractAddress),
4782
+ memo.id,
4783
+ memo.memoType,
4784
+ memo.content,
4785
+ memo.nextPhase,
4786
+ memo.status,
4787
+ memo.senderAddress,
4788
+ memo.signedReason,
4789
+ memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4790
+ memo.payableDetails,
4791
+ memo.txHash,
4792
+ memo.signedTxHash
4793
+ )
4877
4794
  );
4878
- });
4879
- } catch (error) {
4880
- throw new acpError_default("Failed to get cancelled jobs", error);
4795
+ jobs.push(
4796
+ new acpJob_default(
4797
+ this,
4798
+ job.id,
4799
+ job.clientAddress,
4800
+ job.providerAddress,
4801
+ job.evaluatorAddress,
4802
+ job.price,
4803
+ job.priceTokenAddress,
4804
+ memos,
4805
+ job.phase,
4806
+ job.context,
4807
+ job.contractAddress,
4808
+ job.netPayableAmount
4809
+ )
4810
+ );
4811
+ } catch (err) {
4812
+ errors.push({ jobId: job.id, error: err });
4813
+ }
4814
+ }
4815
+ if (errors.length > 0) {
4816
+ console.warn(
4817
+ `${options?.logPrefix ?? "Skipped"} ${errors.length} malformed job(s)
4818
+ ` + JSON.stringify(
4819
+ errors.map((e) => ({ jobId: e.jobId, message: e.error.message })),
4820
+ null,
4821
+ 2
4822
+ )
4823
+ );
4881
4824
  }
4825
+ return jobs;
4882
4826
  }
4883
4827
  async getJobById(jobId) {
4884
- let url = `${this.acpUrl}/api/jobs/${jobId}`;
4828
+ const url = `${this.acpUrl}/api/jobs/${jobId}`;
4829
+ let response;
4885
4830
  try {
4886
- const response = await fetch(url, {
4831
+ response = await fetch(url, {
4887
4832
  headers: {
4888
4833
  "wallet-address": this.acpContractClient.walletAddress
4889
4834
  }
4890
4835
  });
4891
- const data = await response.json();
4892
- if (data.error) {
4893
- throw new acpError_default(data.error.message);
4894
- }
4895
- const job = data.data;
4896
- if (!job) {
4897
- return;
4898
- }
4836
+ } catch (err) {
4837
+ throw new acpError_default("Failed to fetch job by id (network error)", err);
4838
+ }
4839
+ let data;
4840
+ try {
4841
+ data = await response.json();
4842
+ } catch (err) {
4843
+ throw new acpError_default("Failed to parse job by id response", err);
4844
+ }
4845
+ if (data.error) {
4846
+ throw new acpError_default(data.error.message);
4847
+ }
4848
+ const job = data.data;
4849
+ if (!job) {
4850
+ return void 0;
4851
+ }
4852
+ try {
4853
+ const memos = job.memos.map(
4854
+ (memo) => new acpMemo_default(
4855
+ this.contractClientByAddress(job.contractAddress),
4856
+ memo.id,
4857
+ memo.memoType,
4858
+ memo.content,
4859
+ memo.nextPhase,
4860
+ memo.status,
4861
+ memo.senderAddress,
4862
+ memo.signedReason,
4863
+ memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4864
+ memo.payableDetails,
4865
+ memo.txHash,
4866
+ memo.signedTxHash
4867
+ )
4868
+ );
4899
4869
  return new acpJob_default(
4900
4870
  this,
4901
4871
  job.id,
@@ -4904,47 +4874,42 @@ var AcpClient = class {
4904
4874
  job.evaluatorAddress,
4905
4875
  job.price,
4906
4876
  job.priceTokenAddress,
4907
- job.memos.map((memo) => {
4908
- return new acpMemo_default(
4909
- this.contractClientByAddress(job.contractAddress),
4910
- memo.id,
4911
- memo.memoType,
4912
- memo.content,
4913
- memo.nextPhase,
4914
- memo.status,
4915
- memo.senderAddress,
4916
- memo.signedReason,
4917
- memo.expiry ? new Date(parseInt(memo.expiry) * 1e3) : void 0,
4918
- memo.payableDetails,
4919
- memo.txHash,
4920
- memo.signedTxHash
4921
- );
4922
- }),
4877
+ memos,
4923
4878
  job.phase,
4924
4879
  job.context,
4925
4880
  job.contractAddress,
4926
4881
  job.netPayableAmount
4927
4882
  );
4928
- } catch (error) {
4929
- throw new acpError_default("Failed to get job by id", error);
4883
+ } catch (err) {
4884
+ throw new acpError_default(`Failed to hydrate job ${jobId}`, err);
4930
4885
  }
4931
4886
  }
4932
4887
  async getMemoById(jobId, memoId) {
4933
- let url = `${this.acpUrl}/api/jobs/${jobId}/memos/${memoId}`;
4888
+ const url = `${this.acpUrl}/api/jobs/${jobId}/memos/${memoId}`;
4889
+ let response;
4934
4890
  try {
4935
- const response = await fetch(url, {
4891
+ response = await fetch(url, {
4936
4892
  headers: {
4937
4893
  "wallet-address": this.walletAddress
4938
4894
  }
4939
4895
  });
4940
- const data = await response.json();
4941
- if (data.error) {
4942
- throw new acpError_default(data.error.message);
4943
- }
4944
- const memo = data.data;
4945
- if (!memo) {
4946
- return;
4947
- }
4896
+ } catch (err) {
4897
+ throw new acpError_default("Failed to fetch memo by id (network error)", err);
4898
+ }
4899
+ let data;
4900
+ try {
4901
+ data = await response.json();
4902
+ } catch (err) {
4903
+ throw new acpError_default("Failed to parse memo by id response", err);
4904
+ }
4905
+ if (data.error) {
4906
+ throw new acpError_default(data.error.message);
4907
+ }
4908
+ const memo = data.data;
4909
+ if (!memo) {
4910
+ return void 0;
4911
+ }
4912
+ try {
4948
4913
  return new acpMemo_default(
4949
4914
  this.contractClientByAddress(memo.contractAddress),
4950
4915
  memo.id,
@@ -4959,8 +4924,11 @@ var AcpClient = class {
4959
4924
  memo.txHash,
4960
4925
  memo.signedTxHash
4961
4926
  );
4962
- } catch (error) {
4963
- throw new acpError_default("Failed to get memo by id", error);
4927
+ } catch (err) {
4928
+ throw new acpError_default(
4929
+ `Failed to hydrate memo ${memoId} for job ${jobId}`,
4930
+ err
4931
+ );
4964
4932
  }
4965
4933
  }
4966
4934
  async getAgent(walletAddress) {
@@ -5200,7 +5168,7 @@ var AcpContractClient = class _AcpContractClient extends baseAcpContractClient_d
5200
5168
  );
5201
5169
  }
5202
5170
  await this.validateSessionKeyOnChain(sessionSignerAddress, sessionEntityKeyId);
5203
- console.log("Connected to ACP:", {
5171
+ console.log("Connected to ACP with v1 Contract Client (Legacy):", {
5204
5172
  agentWalletAddress: this.agentWalletAddress,
5205
5173
  whitelistedWalletAddress: sessionSignerAddress,
5206
5174
  entityId: sessionEntityKeyId