@hashgraphonline/conversational-agent 0.2.217 → 0.2.218

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.
@@ -1,59 +1,65 @@
1
1
  import { BaseHederaQueryTool } from "hedera-agent-kit";
2
+ import { Size, Duration } from "@ethersphere/bee-js";
2
3
  import { z } from "zod";
3
- import { getUploadPostageBatchId, errorHasStatus, getErrorMessage, getResponseWithStructuredContent } from "./index62.js";
4
- import { BAD_REQUEST_STATUS } from "./index63.js";
5
- const UploadDataSchema = z.object({
6
- data: z.string(),
7
- redundancyLevel: z.number().optional(),
8
- postageBatchId: z.string().optional()
4
+ import { makeDate, errorHasStatus, getErrorMessage, getResponseWithStructuredContent } from "./index62.js";
5
+ import { NOT_FOUND_STATUS, GATEWAY_STAMP_ERROR_MESSAGE, BAD_REQUEST_STATUS } from "./index63.js";
6
+ const ExtendPostageStampSchema = z.object({
7
+ postageBatchId: z.string(),
8
+ duration: z.string().optional(),
9
+ size: z.number().optional()
9
10
  });
10
- class UploadDataTool extends BaseHederaQueryTool {
11
+ class ExtendPostageStampTool extends BaseHederaQueryTool {
11
12
  constructor(params) {
12
13
  const { bee, config, ...rest } = params;
13
14
  super(rest);
14
- this.name = "swarm-upload-data";
15
- this.description = `
16
- Upload text data to Swarm.
17
- data: Arbitrary string to upload.
18
- redundancyLevel: Redundancy level for fault tolerance: 0 - none, 1 - medium, 2 - strong, 3 - insane, 4 - paranoid (higher values provide better fault tolerance but increase storage overhead). Optional, value is 0 if not requested.
19
- postageBatchId: The postage stamp batch ID which will be used to perform the upload, if it is provided.
15
+ this.name = "swarm-extend-postage-stamp";
16
+ this.description = `Increase the duration (relative to current duration) or size (in megabytes) of a postage stamp.
17
+ postageBatchId: The id of the batch for which extend is performed.
18
+ size: The storage size in MB (Megabytes). These other size units convert like this to MB: 1 byte = 0.000001 MB, 1 KB = 0.001 MB, 1GB= 1000MB.
19
+ duration: Duration for which the data should be stored. Time to live of the postage stamp, e.g. 1d - 1 day, 1w - 1 week, 1month - 1 month.
20
20
  `;
21
21
  this.namespace = "swarm";
22
- this.specificInputSchema = UploadDataSchema;
22
+ this.specificInputSchema = ExtendPostageStampSchema;
23
23
  this.bee = bee;
24
24
  this.config = config;
25
25
  }
26
26
  async executeQuery(input) {
27
- const { data, redundancyLevel, postageBatchId: inputPostageBatchId } = input;
28
- if (!data) {
27
+ const { postageBatchId, duration, size } = input;
28
+ if (!postageBatchId) {
29
29
  this.logger.error(
30
- "Missing required parameter: data."
30
+ "Missing required parameter: postageBatchId."
31
31
  );
32
- throw new Error("Missing required parameter: data.");
32
+ throw new Error("Missing required parameter: postageBatchId.");
33
+ } else if (!duration && !size) {
34
+ this.logger.error(
35
+ "You need at least one parameter from duration and size."
36
+ );
37
+ throw new Error("You need at least one parameter from duration and size.");
33
38
  }
34
- let postageBatchId = "";
39
+ const extendSize = !!size ? Size.fromMegabytes(size) : Size.fromBytes(1);
40
+ let extendDuration = Duration.ZERO;
35
41
  try {
36
- postageBatchId = await getUploadPostageBatchId(
37
- inputPostageBatchId,
38
- this.bee,
39
- this.config
40
- );
41
- } catch (error) {
42
- let errorMessage = "Upload data failed.";
43
- if (error instanceof Error) {
44
- errorMessage = error.message;
42
+ if (duration) {
43
+ extendDuration = Duration.fromMilliseconds(makeDate(duration));
45
44
  }
46
- this.logger.error(errorMessage);
47
- throw new Error(errorMessage);
45
+ } catch (makeDateError) {
46
+ this.logger.error(
47
+ "Invalid parameter: duration."
48
+ );
49
+ throw new Error("Invalid parameter: duration.");
48
50
  }
49
- const binaryData = Buffer.from(data);
50
- const options = redundancyLevel ? { redundancyLevel } : void 0;
51
- let result;
51
+ let extendStorageResponse;
52
52
  try {
53
- result = await this.bee.uploadData(postageBatchId, binaryData, options);
53
+ extendStorageResponse = await this.bee.extendStorage(
54
+ postageBatchId,
55
+ extendSize,
56
+ extendDuration
57
+ );
54
58
  } catch (error) {
55
- let errorMessage = "Unable to upload data.";
56
- if (errorHasStatus(error, BAD_REQUEST_STATUS)) {
59
+ let errorMessage = "Extend failed.";
60
+ if (errorHasStatus(error, NOT_FOUND_STATUS)) {
61
+ errorMessage = GATEWAY_STAMP_ERROR_MESSAGE;
62
+ } else if (errorHasStatus(error, BAD_REQUEST_STATUS)) {
57
63
  errorMessage = getErrorMessage(error);
58
64
  }
59
65
  this.logger.error(
@@ -63,13 +69,11 @@ class UploadDataTool extends BaseHederaQueryTool {
63
69
  throw new Error(errorMessage);
64
70
  }
65
71
  return getResponseWithStructuredContent({
66
- reference: result.reference.toString(),
67
- url: this.bee.url + "/bytes/" + result.reference.toString(),
68
- message: "Data successfully uploaded to Swarm"
72
+ postageBatchId: extendStorageResponse.toHex()
69
73
  });
70
74
  }
71
75
  }
72
76
  export {
73
- UploadDataTool
77
+ ExtendPostageStampTool
74
78
  };
75
79
  //# sourceMappingURL=index49.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index49.js","sources":["../../src/plugins/community/swarm/tools/UploadDataTool.ts"],"sourcesContent":["import {\r\n BaseHederaQueryTool,\r\n HederaAgentKit,\r\n type GenericPluginContext,\r\n} from \"hedera-agent-kit\";\r\nimport { Bee } from \"@ethersphere/bee-js\";\r\nimport { z } from \"zod\";\r\nimport {\r\n errorHasStatus,\r\n getErrorMessage,\r\n getResponseWithStructuredContent,\r\n getUploadPostageBatchId,\r\n ToolResponse,\r\n} from \"../utils\";\r\nimport { BAD_REQUEST_STATUS } from \"../constants\";\r\nimport { SwarmConfig } from \"../config\";\r\n\r\nconst UploadDataSchema = z.object({\r\n data: z.string(),\r\n redundancyLevel: z.number().optional(),\r\n postageBatchId: z.string().optional(),\r\n});\r\n\r\nexport class UploadDataTool extends BaseHederaQueryTool<typeof UploadDataSchema> {\r\n name = \"swarm-upload-data\";\r\n description = `\r\n Upload text data to Swarm.\r\n data: Arbitrary string to upload.\r\n redundancyLevel: Redundancy level for fault tolerance: 0 - none, 1 - medium, 2 - strong, 3 - insane, 4 - paranoid (higher values provide better fault tolerance but increase storage overhead). Optional, value is 0 if not requested.\r\n postageBatchId: The postage stamp batch ID which will be used to perform the upload, if it is provided.\r\n `;\r\n namespace = \"swarm\";\r\n specificInputSchema = UploadDataSchema;\r\n bee: Bee;\r\n config: SwarmConfig;\r\n \r\n constructor(params: {\r\n hederaKit: HederaAgentKit;\r\n config: SwarmConfig;\r\n logger?: GenericPluginContext['logger'];\r\n bee: Bee;\r\n }) {\r\n const { bee, config, ...rest } = params;\r\n super(rest);\r\n this.bee = bee;\r\n this.config = config;\r\n }\r\n \r\n protected async executeQuery(\r\n input: z.infer<typeof UploadDataSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { data, redundancyLevel, postageBatchId: inputPostageBatchId } = input;\r\n\r\n if (!data) {\r\n this.logger.error(\r\n 'Missing required parameter: data.'\r\n );\r\n\r\n throw new Error('Missing required parameter: data.');\r\n }\r\n\r\n let postageBatchId = \"\";\r\n\r\n try {\r\n postageBatchId = await getUploadPostageBatchId(\r\n inputPostageBatchId,\r\n this.bee,\r\n this.config,\r\n );\r\n } catch (error) {\r\n let errorMessage = 'Upload data failed.';\r\n if (error instanceof Error) {\r\n errorMessage = error.message;\r\n }\r\n this.logger.error(errorMessage);\r\n\r\n throw new Error(errorMessage);\r\n }\r\n\r\n const binaryData = Buffer.from(data);\r\n\r\n const options = redundancyLevel ? { redundancyLevel } : undefined;\r\n\r\n let result;\r\n\r\n try {\r\n result = await this.bee.uploadData(postageBatchId, binaryData, options);\r\n } catch (error) {\r\n let errorMessage = 'Unable to upload data.';\r\n\r\n if (errorHasStatus(error, BAD_REQUEST_STATUS)) {\r\n errorMessage = getErrorMessage(error);\r\n }\r\n\r\n this.logger.error(\r\n errorMessage,\r\n error\r\n );\r\n \r\n throw new Error(errorMessage);\r\n }\r\n\r\n return getResponseWithStructuredContent({\r\n reference: result.reference.toString(),\r\n url: this.bee.url + \"/bytes/\" + result.reference.toString(),\r\n message: 'Data successfully uploaded to Swarm',\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;AAiBA,MAAM,mBAAmB,EAAE,OAAO;AAAA,EAChC,MAAM,EAAE,OAAA;AAAA,EACR,iBAAiB,EAAE,OAAA,EAAS,SAAA;AAAA,EAC5B,gBAAgB,EAAE,OAAA,EAAS,SAAA;AAC7B,CAAC;AAEM,MAAM,uBAAuB,oBAA6C;AAAA,EAa/E,YAAY,QAKT;AACD,UAAM,EAAE,KAAK,QAAQ,GAAG,SAAS;AACjC,UAAM,IAAI;AAnBZ,SAAA,OAAO;AACP,SAAA,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAMd,SAAA,YAAY;AACZ,SAAA,sBAAsB;AAYpB,SAAK,MAAM;AACX,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAgB,aACZ,OAC8B;AAChC,UAAM,EAAE,MAAM,iBAAiB,gBAAgB,wBAAwB;AAEvE,QAAI,CAAC,MAAM;AACT,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAEA,QAAI,iBAAiB;AAErB,QAAI;AACF,uBAAiB,MAAM;AAAA,QACrB;AAAA,QACA,KAAK;AAAA,QACL,KAAK;AAAA,MAAA;AAAA,IAET,SAAS,OAAO;AACd,UAAI,eAAe;AACnB,UAAI,iBAAiB,OAAO;AAC1B,uBAAe,MAAM;AAAA,MACvB;AACA,WAAK,OAAO,MAAM,YAAY;AAE9B,YAAM,IAAI,MAAM,YAAY;AAAA,IAC9B;AAEA,UAAM,aAAa,OAAO,KAAK,IAAI;AAEnC,UAAM,UAAU,kBAAkB,EAAE,gBAAA,IAAoB;AAExD,QAAI;AAEJ,QAAI;AACF,eAAS,MAAM,KAAK,IAAI,WAAW,gBAAgB,YAAY,OAAO;AAAA,IACxE,SAAS,OAAO;AACd,UAAI,eAAe;AAEnB,UAAI,eAAe,OAAO,kBAAkB,GAAG;AAC7C,uBAAe,gBAAgB,KAAK;AAAA,MACtC;AAEA,WAAK,OAAO;AAAA,QACV;AAAA,QACA;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,YAAY;AAAA,IAC9B;AAEA,WAAO,iCAAiC;AAAA,MACpC,WAAW,OAAO,UAAU,SAAA;AAAA,MAC5B,KAAK,KAAK,IAAI,MAAM,YAAY,OAAO,UAAU,SAAA;AAAA,MACjD,SAAS;AAAA,IAAA,CACV;AAAA,EACL;AACF;"}
1
+ {"version":3,"file":"index49.js","sources":["../../src/plugins/community/swarm/tools/ExtendPostageStampTool.ts"],"sourcesContent":["import {\r\n BaseHederaQueryTool,\r\n HederaAgentKit,\r\n type GenericPluginContext,\r\n} from \"hedera-agent-kit\";\r\nimport { BatchId, Bee, Duration, Size } from \"@ethersphere/bee-js\";\r\nimport { z } from \"zod\";\r\nimport {\r\n errorHasStatus,\r\n getErrorMessage,\r\n getResponseWithStructuredContent,\r\n makeDate,\r\n ToolResponse,\r\n} from \"../utils\";\r\nimport { BAD_REQUEST_STATUS, GATEWAY_STAMP_ERROR_MESSAGE, NOT_FOUND_STATUS } from \"../constants\";\r\nimport { SwarmConfig } from \"../config\";\r\n\r\nconst ExtendPostageStampSchema = z.object({\r\n postageBatchId: z.string(),\r\n duration: z.string().optional(),\r\n size: z.number().optional(),\r\n});\r\n\r\nexport class ExtendPostageStampTool extends BaseHederaQueryTool<typeof ExtendPostageStampSchema> {\r\n name = \"swarm-extend-postage-stamp\";\r\n description = `Increase the duration (relative to current duration) or size (in megabytes) of a postage stamp.\r\n postageBatchId: The id of the batch for which extend is performed.\r\n size: The storage size in MB (Megabytes). These other size units convert like this to MB: 1 byte = 0.000001 MB, 1 KB = 0.001 MB, 1GB= 1000MB.\r\n duration: Duration for which the data should be stored. Time to live of the postage stamp, e.g. 1d - 1 day, 1w - 1 week, 1month - 1 month.\r\n `;\r\n namespace = \"swarm\";\r\n specificInputSchema = ExtendPostageStampSchema;\r\n bee: Bee;\r\n config: SwarmConfig;\r\n \r\n constructor(params: {\r\n hederaKit: HederaAgentKit;\r\n config: SwarmConfig;\r\n logger?: GenericPluginContext['logger'];\r\n bee: Bee;\r\n }) {\r\n const { bee, config, ...rest } = params;\r\n super(rest);\r\n this.bee = bee;\r\n this.config = config;\r\n }\r\n \r\n protected async executeQuery(\r\n input: z.infer<typeof ExtendPostageStampSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { postageBatchId, duration, size } = input;\r\n\r\n if (!postageBatchId) {\r\n this.logger.error(\r\n 'Missing required parameter: postageBatchId.'\r\n );\r\n\r\n throw new Error('Missing required parameter: postageBatchId.');\r\n } else if (!duration && !size) {\r\n this.logger.error(\r\n 'You need at least one parameter from duration and size.'\r\n );\r\n\r\n throw new Error('You need at least one parameter from duration and size.');\r\n }\r\n\r\n // If size is missing, Size.fromBytes(1) will get smallest depth and not increase size.\r\n const extendSize = !!size ? Size.fromMegabytes(size) : Size.fromBytes(1); \r\n let extendDuration = Duration.ZERO;\r\n\r\n try {\r\n if (duration) {\r\n extendDuration = Duration.fromMilliseconds(makeDate(duration));\r\n }\r\n } catch (makeDateError) {\r\n this.logger.error(\r\n 'Invalid parameter: duration.'\r\n );\r\n\r\n throw new Error('Invalid parameter: duration.');\r\n }\r\n\r\n let extendStorageResponse;\r\n\r\n try {\r\n extendStorageResponse = await this.bee.extendStorage(\r\n postageBatchId,\r\n extendSize,\r\n extendDuration\r\n );\r\n } catch (error) {\r\n let errorMessage = 'Extend failed.';\r\n\r\n if (errorHasStatus(error, NOT_FOUND_STATUS)) {\r\n errorMessage = GATEWAY_STAMP_ERROR_MESSAGE;\r\n } else if (errorHasStatus(error, BAD_REQUEST_STATUS)) {\r\n errorMessage = getErrorMessage(error);\r\n }\r\n\r\n this.logger.error(\r\n errorMessage,\r\n error\r\n );\r\n\r\n throw new Error(errorMessage);\r\n }\r\n\r\n return getResponseWithStructuredContent({\r\n postageBatchId: extendStorageResponse.toHex(),\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;;AAiBA,MAAM,2BAA2B,EAAE,OAAO;AAAA,EACxC,gBAAgB,EAAE,OAAA;AAAA,EAClB,UAAU,EAAE,OAAA,EAAS,SAAA;AAAA,EACrB,MAAM,EAAE,OAAA,EAAS,SAAA;AACnB,CAAC;AAEM,MAAM,+BAA+B,oBAAqD;AAAA,EAY/F,YAAY,QAKT;AACD,UAAM,EAAE,KAAK,QAAQ,GAAG,SAAS;AACjC,UAAM,IAAI;AAlBZ,SAAA,OAAO;AACP,SAAA,cAAc;AAAA;AAAA;AAAA;AAAA;AAKd,SAAA,YAAY;AACZ,SAAA,sBAAsB;AAYpB,SAAK,MAAM;AACX,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAgB,aACd,OACgC;AAChC,UAAM,EAAE,gBAAgB,UAAU,KAAA,IAAS;AAE3C,QAAI,CAAC,gBAAgB;AACnB,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D,WAAW,CAAC,YAAY,CAAC,MAAM;AAC7B,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC3E;AAGA,UAAM,aAAa,CAAC,CAAC,OAAO,KAAK,cAAc,IAAI,IAAI,KAAK,UAAU,CAAC;AACvE,QAAI,iBAAiB,SAAS;AAE9B,QAAI;AACF,UAAI,UAAU;AACZ,yBAAiB,SAAS,iBAAiB,SAAS,QAAQ,CAAC;AAAA,MAC/D;AAAA,IACF,SAAS,eAAe;AACtB,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AAEA,QAAI;AAEJ,QAAI;AACF,8BAAwB,MAAM,KAAK,IAAI;AAAA,QACrC;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,SAAS,OAAO;AACd,UAAI,eAAe;AAEnB,UAAI,eAAe,OAAO,gBAAgB,GAAG;AAC3C,uBAAe;AAAA,MACjB,WAAW,eAAe,OAAO,kBAAkB,GAAG;AACpD,uBAAe,gBAAgB,KAAK;AAAA,MACtC;AAEA,WAAK,OAAO;AAAA,QACV;AAAA,QACA;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,YAAY;AAAA,IAC9B;AAEA,WAAO,iCAAiC;AAAA,MACtC,gBAAgB,sBAAsB,MAAA;AAAA,IAAM,CAC7C;AAAA,EACH;AACF;"}
@@ -1,57 +1,75 @@
1
- import { z } from "zod";
2
- import { errorHasStatus, getErrorMessage, getResponseWithStructuredContent } from "./index62.js";
3
1
  import { BaseHederaQueryTool } from "hedera-agent-kit";
4
- import { BAD_REQUEST_STATUS } from "./index63.js";
5
- const DownloadDataSchema = z.object({
6
- reference: z.string()
2
+ import { z } from "zod";
3
+ import { getResponseWithStructuredContent } from "./index62.js";
4
+ import { GATEWAY_TAG_ERROR_MESSAGE } from "./index63.js";
5
+ const QueryUploadProgressSchema = z.object({
6
+ tagId: z.string()
7
7
  });
8
- class DownloadDataTool extends BaseHederaQueryTool {
8
+ class QueryUploadProgressTool extends BaseHederaQueryTool {
9
9
  constructor(params) {
10
10
  const { bee, config, ...rest } = params;
11
11
  super(rest);
12
- this.name = "swarm-download-data";
13
- this.description = `
14
- Downloads immutable data from a Swarm content address hash.
15
- reference: Swarm reference hash.
12
+ this.name = "swarm-query-upload-progress";
13
+ this.description = `Query upload progress for a specific upload session identified with the returned Tag ID.
14
+ tagId: Tag ID returned by swarm-upload-file and swarm-upload-folder tools to track upload progress.
16
15
  `;
17
16
  this.namespace = "swarm";
18
- this.specificInputSchema = DownloadDataSchema;
17
+ this.specificInputSchema = QueryUploadProgressSchema;
19
18
  this.bee = bee;
20
19
  this.config = config;
21
20
  }
22
21
  async executeQuery(input) {
23
- const { reference } = input;
24
- if (!reference) {
22
+ if (!input?.tagId) {
25
23
  this.logger.error(
26
- "Missing required parameter: reference."
24
+ "Missing required parameter: tagId."
27
25
  );
28
- throw new Error("Missing required parameter: reference.");
26
+ throw new Error("Missing required parameter: tagId.");
29
27
  }
30
- const isRefNotSwarmHash = reference.length !== 64 && reference.length !== 66;
31
- if (isRefNotSwarmHash) {
28
+ const tagUid = Number.parseInt(input.tagId, 10);
29
+ if (Number.isNaN(tagUid)) {
32
30
  this.logger.error(
33
- "Invalid Swarm content address hash value for reference."
31
+ "Invalid tagId format. Expected a numeric string."
34
32
  );
35
- throw new Error("Invalid Swarm content address hash value for reference.");
33
+ throw new Error("Invalid tagId format. Expected a numeric string.");
36
34
  }
37
- let data;
38
35
  try {
39
- data = await this.bee.downloadData(reference);
36
+ const tag = await this.bee.retrieveTag(tagUid);
37
+ const synced = tag.synced ?? 0;
38
+ const seen = tag.seen ?? 0;
39
+ const processed = synced + seen;
40
+ const total = tag.split ?? 0;
41
+ const startedAt = tag.startedAt;
42
+ const processedPercentage = total > 0 ? Math.round(processed / total * 100) : 0;
43
+ const isComplete = processedPercentage === 100;
44
+ let tagDeleted = false;
45
+ if (isComplete) {
46
+ try {
47
+ await this.bee.deleteTag(tagUid);
48
+ tagDeleted = true;
49
+ } catch {
50
+ }
51
+ }
52
+ return getResponseWithStructuredContent({
53
+ processedPercentage,
54
+ message: isComplete ? "Upload completed successfully." : `Upload progress: ${processedPercentage}% processed`,
55
+ startedAt,
56
+ tagAddress: tag.address
57
+ });
40
58
  } catch (error) {
41
- let errorMessage = "Downloading data failed.";
42
- if (errorHasStatus(error, BAD_REQUEST_STATUS)) {
43
- errorMessage = getErrorMessage(error);
59
+ let errorMessage = `Failed to retrieve upload progress: ${error?.message ?? "Unknown error"}`;
60
+ const status = error?.status ?? error?.response?.status;
61
+ if (status === 404) {
62
+ errorMessage = `Tag with ID ${input.tagId} does not exist or has been deleted. ` + GATEWAY_TAG_ERROR_MESSAGE;
44
63
  }
45
- this.logger.error(errorMessage, error);
64
+ this.logger.error(
65
+ errorMessage,
66
+ error
67
+ );
46
68
  throw new Error(errorMessage);
47
69
  }
48
- const textData = data.toUtf8();
49
- return getResponseWithStructuredContent({
50
- textData
51
- });
52
70
  }
53
71
  }
54
72
  export {
55
- DownloadDataTool
73
+ QueryUploadProgressTool
56
74
  };
57
75
  //# sourceMappingURL=index50.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index50.js","sources":["../../src/plugins/community/swarm/tools/DownloadDataTool.ts"],"sourcesContent":["import { Bee } from \"@ethersphere/bee-js\";\r\nimport { z } from \"zod\";\r\nimport { errorHasStatus, getErrorMessage, getResponseWithStructuredContent, ToolResponse } from \"../utils\";\r\nimport { BaseHederaQueryTool, GenericPluginContext, HederaAgentKit } from \"hedera-agent-kit\";\r\nimport { SwarmConfig } from \"../config\";\r\nimport { BAD_REQUEST_STATUS } from \"../constants\";\r\n\r\nconst DownloadDataSchema = z.object({\r\n reference: z.string(),\r\n});\r\n\r\nexport class DownloadDataTool extends BaseHederaQueryTool<typeof DownloadDataSchema> {\r\n name = \"swarm-download-data\";\r\n description = `\r\n Downloads immutable data from a Swarm content address hash.\r\n reference: Swarm reference hash.\r\n `;\r\n namespace = \"swarm\";\r\n specificInputSchema = DownloadDataSchema;\r\n bee: Bee;\r\n config: SwarmConfig;\r\n \r\n constructor(params: {\r\n hederaKit: HederaAgentKit;\r\n config: SwarmConfig;\r\n logger?: GenericPluginContext['logger'];\r\n bee: Bee;\r\n }) {\r\n const { bee, config, ...rest } = params;\r\n super(rest);\r\n this.bee = bee;\r\n this.config = config;\r\n }\r\n\r\n protected async executeQuery(\r\n input: z.infer<typeof DownloadDataSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { reference } = input;\r\n\r\n if (!reference) {\r\n this.logger.error(\r\n 'Missing required parameter: reference.'\r\n );\r\n\r\n throw new Error(\"Missing required parameter: reference.\");\r\n }\r\n\r\n const isRefNotSwarmHash =\r\n reference.length !== 64 && reference.length !== 66;\r\n\r\n if (isRefNotSwarmHash) {\r\n this.logger.error(\r\n 'Invalid Swarm content address hash value for reference.'\r\n );\r\n\r\n throw new Error(\"Invalid Swarm content address hash value for reference.\");\r\n }\r\n\r\n let data;\r\n try {\r\n data = await this.bee.downloadData(reference);\r\n } catch (error) {\r\n let errorMessage = 'Downloading data failed.';\r\n\r\n if (errorHasStatus(error, BAD_REQUEST_STATUS)) {\r\n errorMessage = getErrorMessage(error);\r\n }\r\n\r\n this.logger.error(errorMessage, error);\r\n throw new Error(errorMessage);\r\n }\r\n\r\n const textData = data.toUtf8();\r\n\r\n return getResponseWithStructuredContent({\r\n textData,\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;AAOA,MAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,WAAW,EAAE,OAAA;AACf,CAAC;AAEM,MAAM,yBAAyB,oBAA+C;AAAA,EAWnF,YAAY,QAKT;AACD,UAAM,EAAE,KAAK,QAAQ,GAAG,SAAS;AACjC,UAAM,IAAI;AAjBZ,SAAA,OAAO;AACP,SAAA,cAAc;AAAA;AAAA;AAAA;AAId,SAAA,YAAY;AACZ,SAAA,sBAAsB;AAYpB,SAAK,MAAM;AACX,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAgB,aACZ,OAC8B;AAChC,UAAM,EAAE,cAAc;AAEtB,QAAI,CAAC,WAAW;AACd,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAEA,UAAM,oBACJ,UAAU,WAAW,MAAM,UAAU,WAAW;AAElD,QAAI,mBAAmB;AACrB,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC3E;AAEA,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,KAAK,IAAI,aAAa,SAAS;AAAA,IAC9C,SAAS,OAAO;AACd,UAAI,eAAe;AAEnB,UAAI,eAAe,OAAO,kBAAkB,GAAG;AAC7C,uBAAe,gBAAgB,KAAK;AAAA,MACtC;AAEA,WAAK,OAAO,MAAM,cAAc,KAAK;AACrC,YAAM,IAAI,MAAM,YAAY;AAAA,IAC9B;AAEA,UAAM,WAAW,KAAK,OAAA;AAEtB,WAAO,iCAAiC;AAAA,MACtC;AAAA,IAAA,CACD;AAAA,EACH;AACF;"}
1
+ {"version":3,"file":"index50.js","sources":["../../src/plugins/community/swarm/tools/QueryUploadProgressTool.ts"],"sourcesContent":["import {\r\n type GenericPluginContext,\r\n BaseHederaQueryTool,\r\n type HederaAgentKit,\r\n} from \"hedera-agent-kit\";\r\nimport { Bee } from \"@ethersphere/bee-js\";\r\nimport { z } from \"zod\";\r\nimport {\r\n errorHasStatus,\r\n getResponseWithStructuredContent,\r\n ToolResponse,\r\n} from \"../utils\";\r\nimport { GATEWAY_TAG_ERROR_MESSAGE } from \"../constants\";\r\nimport { SwarmConfig } from \"../config\";\r\n\r\nconst QueryUploadProgressSchema = z.object({\r\n tagId: z.string(),\r\n});\r\n\r\nexport class QueryUploadProgressTool extends BaseHederaQueryTool<typeof QueryUploadProgressSchema> {\r\n name = \"swarm-query-upload-progress\";\r\n description = `Query upload progress for a specific upload session identified with the returned Tag ID.\r\n tagId: Tag ID returned by swarm-upload-file and swarm-upload-folder tools to track upload progress.\r\n `;\r\n namespace = \"swarm\";\r\n specificInputSchema = QueryUploadProgressSchema;\r\n bee: Bee;\r\n config: SwarmConfig;\r\n \r\n constructor(params: {\r\n hederaKit: HederaAgentKit;\r\n config: SwarmConfig;\r\n logger?: GenericPluginContext['logger'];\r\n bee: Bee;\r\n }) {\r\n const { bee, config, ...rest } = params;\r\n super(rest);\r\n this.bee = bee;\r\n this.config = config;\r\n }\r\n\r\n protected async executeQuery(\r\n input: z.infer<typeof QueryUploadProgressSchema>\r\n ): Promise<ToolResponse | string> {\r\n if (!input?.tagId) {\r\n this.logger.error(\r\n 'Missing required parameter: tagId.'\r\n );\r\n\r\n throw new Error('Missing required parameter: tagId.');\r\n }\r\n\r\n const tagUid = Number.parseInt(input.tagId, 10);\r\n if (Number.isNaN(tagUid)) {\r\n this.logger.error(\r\n 'Invalid tagId format. Expected a numeric string.'\r\n );\r\n\r\n throw new Error('Invalid tagId format. Expected a numeric string.');\r\n }\r\n\r\n try {\r\n const tag = await this.bee.retrieveTag(tagUid);\r\n\r\n const synced = tag.synced ?? 0;\r\n const seen = tag.seen ?? 0;\r\n const processed = synced + seen;\r\n const total = tag.split ?? 0;\r\n const startedAt = tag.startedAt;\r\n\r\n const processedPercentage =\r\n total > 0 ? Math.round((processed / total) * 100) : 0;\r\n const isComplete = processedPercentage === 100;\r\n\r\n let tagDeleted = false;\r\n if (isComplete) {\r\n try {\r\n await this.bee.deleteTag(tagUid);\r\n tagDeleted = true;\r\n } catch {\r\n // Non-fatal: if deletion fails we still return progress\r\n }\r\n }\r\n\r\n return getResponseWithStructuredContent({\r\n processedPercentage,\r\n message: isComplete\r\n ? \"Upload completed successfully.\"\r\n : `Upload progress: ${processedPercentage}% processed`,\r\n startedAt,\r\n tagAddress: tag.address,\r\n });\r\n } catch (error: any) {\r\n let errorMessage = `Failed to retrieve upload progress: ${error?.message ?? \"Unknown error\"}`;\r\n \r\n const status = error?.status ?? error?.response?.status;\r\n if (status === 404) {\r\n errorMessage = `Tag with ID ${input.tagId} does not exist or has been deleted. ` + GATEWAY_TAG_ERROR_MESSAGE;\r\n }\r\n \r\n this.logger.error(\r\n errorMessage,\r\n error\r\n );\r\n \r\n throw new Error(errorMessage);\r\n }\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;AAeA,MAAM,4BAA4B,EAAE,OAAO;AAAA,EACzC,OAAO,EAAE,OAAA;AACX,CAAC;AAEM,MAAM,gCAAgC,oBAAsD;AAAA,EAUjG,YAAY,QAKT;AACD,UAAM,EAAE,KAAK,QAAQ,GAAG,SAAS;AACjC,UAAM,IAAI;AAhBZ,SAAA,OAAO;AACP,SAAA,cAAc;AAAA;AAAA;AAGd,SAAA,YAAY;AACZ,SAAA,sBAAsB;AAYpB,SAAK,MAAM;AACX,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAgB,aACZ,OAC8B;AAChC,QAAI,CAAC,OAAO,OAAO;AACjB,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AAEA,UAAM,SAAS,OAAO,SAAS,MAAM,OAAO,EAAE;AAC9C,QAAI,OAAO,MAAM,MAAM,GAAG;AACxB,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,kDAAkD;AAAA,IACpE;AAEA,QAAI;AACF,YAAM,MAAM,MAAM,KAAK,IAAI,YAAY,MAAM;AAE7C,YAAM,SAAS,IAAI,UAAU;AAC7B,YAAM,OAAO,IAAI,QAAQ;AACzB,YAAM,YAAY,SAAS;AAC3B,YAAM,QAAQ,IAAI,SAAS;AAC3B,YAAM,YAAY,IAAI;AAEtB,YAAM,sBACJ,QAAQ,IAAI,KAAK,MAAO,YAAY,QAAS,GAAG,IAAI;AACtD,YAAM,aAAa,wBAAwB;AAE3C,UAAI,aAAa;AACjB,UAAI,YAAY;AACd,YAAI;AACF,gBAAM,KAAK,IAAI,UAAU,MAAM;AAC/B,uBAAa;AAAA,QACf,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,aAAO,iCAAiC;AAAA,QACtC;AAAA,QACA,SAAS,aACL,mCACA,oBAAoB,mBAAmB;AAAA,QAC3C;AAAA,QACA,YAAY,IAAI;AAAA,MAAA,CACjB;AAAA,IACH,SAAS,OAAY;AACnB,UAAI,eAAe,uCAAuC,OAAO,WAAW,eAAe;AAE3F,YAAM,SAAS,OAAO,UAAU,OAAO,UAAU;AACjD,UAAI,WAAW,KAAK;AAClB,uBAAe,eAAe,MAAM,KAAK,0CAA0C;AAAA,MACrF;AAEA,WAAK,OAAO;AAAA,QACV;AAAA,QACA;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,YAAY;AAAA,IAC9B;AAAA,EACF;AACF;"}
@@ -1,103 +1,124 @@
1
- import { BaseHederaQueryTool } from "hedera-agent-kit";
2
- import { Size, Duration } from "@ethersphere/bee-js";
1
+ import { MantarayNode } from "@ethersphere/bee-js";
3
2
  import { z } from "zod";
4
- import { makeDate, runWithTimeout, errorHasStatus, getErrorMessage } from "./index62.js";
5
- import { CALL_TIMEOUT, POSTAGE_CREATE_TIMEOUT_MESSAGE, GATEWAY_STAMP_ERROR_MESSAGE, NOT_FOUND_STATUS, BAD_REQUEST_STATUS } from "./index63.js";
6
- const CreatePostageStampSchema = z.object({
7
- size: z.number(),
8
- duration: z.string(),
9
- label: z.string().optional()
3
+ import fs from "fs";
4
+ import path from "path";
5
+ import { BaseHederaQueryTool } from "hedera-agent-kit";
6
+ import { promisify } from "util";
7
+ const DownloadFilesSchema = z.object({
8
+ reference: z.string(),
9
+ filePath: z.string().optional()
10
10
  });
11
- class CreatePostageStampTool extends BaseHederaQueryTool {
11
+ class DownloadFilesTool extends BaseHederaQueryTool {
12
12
  constructor(params) {
13
13
  const { bee, config, ...rest } = params;
14
14
  super(rest);
15
- this.name = "swarm-create-postage-stamp";
16
- this.description = `
17
- Buy postage stamp based on size in megabytes and duration.
18
- size: The storage size in MB (Megabytes). These other size units convert like this to MB: 1 byte = 0.000001 MB, 1 KB = 0.001 MB, 1GB= 1000MB.
19
- duration: Duration for which the data should be stored. Time to live of the postage stamp, e.g. 1d - 1 day, 1w - 1 week, 1month - 1 month.
20
- label: Sets label for the postage batch (omit if the user didn't ask for one). Do not set a label with with specific capacity values because they can get misleading.
15
+ this.name = "swarm-download-files";
16
+ this.description = `Download folder, files from a Swarm reference and save to file path or return file list of the reference.
17
+ Prioritizes this tool over swarm-download-data if there is no assumption about the data type.
18
+ reference: Swarm reference hash.
19
+ filePath: Optional file path to save the downloaded content (only available in stdio mode). If not provided list of files in the manifest will be returned.
21
20
  `;
22
21
  this.namespace = "swarm";
23
- this.specificInputSchema = CreatePostageStampSchema;
22
+ this.specificInputSchema = DownloadFilesSchema;
24
23
  this.bee = bee;
25
24
  this.config = config;
26
25
  }
27
26
  async executeQuery(input) {
28
- const { size, duration, label } = input;
29
- if (!size) {
30
- this.logger.error(
31
- "Missing required parameter: size."
32
- );
33
- throw new Error("Missing required parameter: size.");
34
- } else if (!duration) {
27
+ const { reference, filePath } = input;
28
+ if (!reference) {
35
29
  this.logger.error(
36
- "Missing required parameter: duration."
30
+ "Missing required parameter: reference."
37
31
  );
38
- throw new Error("Missing required parameter: duration.");
32
+ throw new Error("Missing required parameter: reference.");
39
33
  }
40
- let durationMs;
34
+ this.logger.info(`[API] Downloading folder from Swarm with reference: ${reference}.`);
35
+ let isManifest = false;
36
+ let node;
41
37
  try {
42
- durationMs = makeDate(duration);
43
- } catch (makeDateError) {
44
- this.logger.error(
45
- "Invalid parameter: duration."
46
- );
47
- throw new Error("Invalid parameter: duration.");
38
+ node = await MantarayNode.unmarshal(this.bee, reference);
39
+ await node.loadRecursively(this.bee);
40
+ isManifest = true;
41
+ } catch (error) {
48
42
  }
49
- let buyStorageResponse;
50
- try {
51
- let options = {};
52
- if (label !== void 0) {
53
- options = {
54
- label
43
+ if (isManifest) {
44
+ if (filePath) {
45
+ const destinationFolder = filePath;
46
+ if (!fs.existsSync(destinationFolder)) {
47
+ await promisify(fs.mkdir)(destinationFolder, { recursive: true });
48
+ }
49
+ const nodes = node.collect();
50
+ if (nodes.length === 1) {
51
+ const node2 = nodes[0];
52
+ const data = await this.bee.downloadData(node2.targetAddress);
53
+ await promisify(fs.writeFile)(
54
+ path.join(
55
+ destinationFolder,
56
+ node2.fullPathString.split("\\").slice(-1)[0]
57
+ ),
58
+ data.toUint8Array()
59
+ );
60
+ } else {
61
+ for (const node2 of nodes) {
62
+ const parsedPath = path.parse(node2.fullPathString);
63
+ const nodeDestFolder = path.join(destinationFolder, parsedPath.dir);
64
+ if (!fs.existsSync(nodeDestFolder)) {
65
+ await promisify(fs.mkdir)(nodeDestFolder, { recursive: true });
66
+ }
67
+ const data = await this.bee.downloadData(node2.targetAddress);
68
+ await promisify(fs.writeFile)(
69
+ path.join(destinationFolder, node2.fullPathString),
70
+ data.toUint8Array()
71
+ );
72
+ }
73
+ }
74
+ return {
75
+ content: [
76
+ {
77
+ type: "text",
78
+ text: JSON.stringify(
79
+ {
80
+ reference,
81
+ manifestNodeCount: nodes.length,
82
+ savedTo: destinationFolder,
83
+ message: `Manifest content (${nodes.length} files) successfully downloaded to ${destinationFolder}`
84
+ },
85
+ null,
86
+ 2
87
+ )
88
+ }
89
+ ]
55
90
  };
56
- }
57
- const buyStoragePromise = this.bee.buyStorage(
58
- Size.fromMegabytes(size),
59
- Duration.fromMilliseconds(durationMs),
60
- options
61
- );
62
- const [response, hasTimedOut] = await runWithTimeout(
63
- buyStoragePromise,
64
- CALL_TIMEOUT
65
- );
66
- if (hasTimedOut) {
67
- return JSON.stringify({
91
+ } else {
92
+ const nodes = node.collect();
93
+ const filesList = nodes.map((node2) => ({
94
+ path: node2.fullPathString || "/",
95
+ targetAddress: Array.from(node2.targetAddress).map((e) => e.toString(16).padStart(2, "0")).join(""),
96
+ metadata: node2.metadata
97
+ }));
98
+ return {
68
99
  content: [
69
100
  {
70
101
  type: "text",
71
- text: POSTAGE_CREATE_TIMEOUT_MESSAGE
102
+ text: JSON.stringify(
103
+ {
104
+ reference,
105
+ type: "manifest",
106
+ files: filesList,
107
+ message: "This is a manifest with multiple files. Provide a filePath to download all files or download individual files using their specific references."
108
+ },
109
+ null,
110
+ 2
111
+ )
72
112
  }
73
113
  ]
74
- });
75
- }
76
- buyStorageResponse = response;
77
- } catch (error) {
78
- let errorMessage = "Unable to buy storage.";
79
- if (errorHasStatus(error, NOT_FOUND_STATUS)) {
80
- errorMessage = GATEWAY_STAMP_ERROR_MESSAGE;
81
- } else if (errorHasStatus(error, BAD_REQUEST_STATUS)) {
82
- errorMessage = getErrorMessage(error);
114
+ };
83
115
  }
84
- this.logger.error(
85
- errorMessage,
86
- error
87
- );
88
- throw new Error(errorMessage);
116
+ } else {
117
+ return "Try swarm-download-data tool instead since the given reference is not a manifest.";
89
118
  }
90
- return {
91
- content: [
92
- {
93
- type: "text",
94
- text: `Postage batch ID: ${buyStorageResponse.toHex()}`
95
- }
96
- ]
97
- };
98
119
  }
99
120
  }
100
121
  export {
101
- CreatePostageStampTool
122
+ DownloadFilesTool
102
123
  };
103
124
  //# sourceMappingURL=index51.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index51.js","sources":["../../src/plugins/community/swarm/tools/CreatePostageStampTool.ts"],"sourcesContent":["import {\r\n BaseHederaQueryTool,\r\n HederaAgentKit,\r\n type GenericPluginContext,\r\n} from \"hedera-agent-kit\";\r\nimport { BatchId, Bee, Duration, Size } from \"@ethersphere/bee-js\";\r\nimport { z } from \"zod\";\r\nimport {\r\n errorHasStatus,\r\n getErrorMessage,\r\n makeDate,\r\n runWithTimeout,\r\n ToolResponse,\r\n} from \"../utils\";\r\nimport { BAD_REQUEST_STATUS, CALL_TIMEOUT, GATEWAY_STAMP_ERROR_MESSAGE, NOT_FOUND_STATUS, POSTAGE_CREATE_TIMEOUT_MESSAGE } from \"../constants\";\r\nimport { SwarmConfig } from \"../config\";\r\n\r\nconst CreatePostageStampSchema = z.object({\r\n size: z.number(),\r\n duration: z.string(),\r\n label: z.string().optional(),\r\n});\r\n\r\nexport class CreatePostageStampTool extends BaseHederaQueryTool<typeof CreatePostageStampSchema> {\r\n name = \"swarm-create-postage-stamp\";\r\n description = `\r\n Buy postage stamp based on size in megabytes and duration.\r\n size: The storage size in MB (Megabytes). These other size units convert like this to MB: 1 byte = 0.000001 MB, 1 KB = 0.001 MB, 1GB= 1000MB.\r\n duration: Duration for which the data should be stored. Time to live of the postage stamp, e.g. 1d - 1 day, 1w - 1 week, 1month - 1 month.\r\n label: Sets label for the postage batch (omit if the user didn't ask for one). Do not set a label with with specific capacity values because they can get misleading.\r\n `;\r\n namespace = \"swarm\";\r\n specificInputSchema = CreatePostageStampSchema;\r\n bee: Bee;\r\n config: SwarmConfig;\r\n \r\n constructor(params: {\r\n hederaKit: HederaAgentKit;\r\n config: SwarmConfig;\r\n logger?: GenericPluginContext['logger'];\r\n bee: Bee;\r\n }) {\r\n const { bee, config, ...rest } = params;\r\n super(rest);\r\n this.bee = bee;\r\n this.config = config;\r\n }\r\n \r\n protected async executeQuery(\r\n input: z.infer<typeof CreatePostageStampSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { size, duration, label } = input;\r\n\r\n if (!size) {\r\n this.logger.error(\r\n 'Missing required parameter: size.'\r\n );\r\n \r\n throw new Error('Missing required parameter: size.');\r\n } else if (!duration) {\r\n this.logger.error(\r\n 'Missing required parameter: duration.'\r\n );\r\n \r\n throw new Error('Missing required parameter: duration.');\r\n }\r\n\r\n let durationMs;\r\n\r\n try {\r\n durationMs = makeDate(duration);\r\n } catch (makeDateError) {\r\n this.logger.error(\r\n 'Invalid parameter: duration.'\r\n );\r\n\r\n throw new Error('Invalid parameter: duration.');\r\n }\r\n\r\n let buyStorageResponse: BatchId;\r\n\r\n try {\r\n let options = {};\r\n if (label !== undefined) {\r\n options = {\r\n label\r\n };\r\n }\r\n const buyStoragePromise = this.bee.buyStorage(\r\n Size.fromMegabytes(size),\r\n Duration.fromMilliseconds(durationMs),\r\n options\r\n );\r\n const [response, hasTimedOut] = await runWithTimeout(\r\n buyStoragePromise,\r\n CALL_TIMEOUT\r\n );\r\n\r\n if (hasTimedOut) {\r\n return JSON.stringify({\r\n content: [\r\n {\r\n type: 'text',\r\n text: POSTAGE_CREATE_TIMEOUT_MESSAGE,\r\n },\r\n ],\r\n });\r\n }\r\n\r\n buyStorageResponse = response as BatchId;\r\n } catch (error) {\r\n let errorMessage = 'Unable to buy storage.';\r\n\r\n if (errorHasStatus(error, NOT_FOUND_STATUS)) {\r\n errorMessage = GATEWAY_STAMP_ERROR_MESSAGE;\r\n } else if (errorHasStatus(error, BAD_REQUEST_STATUS)) {\r\n errorMessage = getErrorMessage(error);\r\n }\r\n\r\n this.logger.error(\r\n errorMessage,\r\n error\r\n );\r\n\r\n throw new Error(errorMessage);\r\n }\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Postage batch ID: ${buyStorageResponse.toHex()}`,\r\n },\r\n ],\r\n };\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;;AAiBA,MAAM,2BAA2B,EAAE,OAAO;AAAA,EACxC,MAAM,EAAE,OAAA;AAAA,EACR,UAAU,EAAE,OAAA;AAAA,EACZ,OAAO,EAAE,OAAA,EAAS,SAAA;AACpB,CAAC;AAEM,MAAM,+BAA+B,oBAAqD;AAAA,EAa/F,YAAY,QAKT;AACD,UAAM,EAAE,KAAK,QAAQ,GAAG,SAAS;AACjC,UAAM,IAAI;AAnBZ,SAAA,OAAO;AACP,SAAA,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAMd,SAAA,YAAY;AACZ,SAAA,sBAAsB;AAYpB,SAAK,MAAM;AACX,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAgB,aACZ,OAC8B;AAChC,UAAM,EAAE,MAAM,UAAU,MAAA,IAAU;AAElC,QAAI,CAAC,MAAM;AACT,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD,WAAW,CAAC,UAAU;AACpB,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAEA,QAAI;AAEJ,QAAI;AACF,mBAAa,SAAS,QAAQ;AAAA,IAChC,SAAS,eAAe;AACtB,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AAEA,QAAI;AAEJ,QAAI;AACF,UAAI,UAAU,CAAA;AACd,UAAI,UAAU,QAAW;AACvB,kBAAU;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,oBAAoB,KAAK,IAAI;AAAA,QACjC,KAAK,cAAc,IAAI;AAAA,QACvB,SAAS,iBAAiB,UAAU;AAAA,QACpC;AAAA,MAAA;AAEF,YAAM,CAAC,UAAU,WAAW,IAAI,MAAM;AAAA,QACpC;AAAA,QACA;AAAA,MAAA;AAGF,UAAI,aAAa;AACf,eAAO,KAAK,UAAU;AAAA,UACpB,SAAS;AAAA,YACP;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YAAA;AAAA,UACR;AAAA,QACF,CACD;AAAA,MACH;AAEA,2BAAqB;AAAA,IACvB,SAAS,OAAO;AACd,UAAI,eAAe;AAEnB,UAAI,eAAe,OAAO,gBAAgB,GAAG;AAC3C,uBAAe;AAAA,MACjB,WAAW,eAAe,OAAO,kBAAkB,GAAG;AACpD,uBAAe,gBAAgB,KAAK;AAAA,MACtC;AAEA,WAAK,OAAO;AAAA,QACV;AAAA,QACA;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,YAAY;AAAA,IAC9B;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM,qBAAqB,mBAAmB,MAAA,CAAO;AAAA,QAAA;AAAA,MACvD;AAAA,IACF;AAAA,EAEJ;AACF;"}
1
+ {"version":3,"file":"index51.js","sources":["../../src/plugins/community/swarm/tools/DownloadFilesTool.ts"],"sourcesContent":["import { Bee, MantarayNode } from \"@ethersphere/bee-js\";\r\nimport { z } from \"zod\";\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport { BaseHederaQueryTool, GenericPluginContext, HederaAgentKit } from \"hedera-agent-kit\";\r\nimport { promisify } from \"util\";\r\nimport { ToolResponse } from \"../utils\";\r\nimport { SwarmConfig } from \"../config\";\r\n\r\nconst DownloadFilesSchema = z.object({\r\n reference: z.string(),\r\n filePath: z.string().optional()\r\n});\r\n\r\nexport class DownloadFilesTool extends BaseHederaQueryTool<typeof DownloadFilesSchema> {\r\n name = \"swarm-download-files\";\r\n description = `Download folder, files from a Swarm reference and save to file path or return file list of the reference.\r\n Prioritizes this tool over swarm-download-data if there is no assumption about the data type.\r\n reference: Swarm reference hash.\r\n filePath: Optional file path to save the downloaded content (only available in stdio mode). If not provided list of files in the manifest will be returned.\r\n `;\r\n namespace = \"swarm\";\r\n specificInputSchema = DownloadFilesSchema;\r\n bee: Bee; \r\n config: SwarmConfig;\r\n\r\n constructor(params: {\r\n hederaKit: HederaAgentKit;\r\n config: SwarmConfig;\r\n logger?: GenericPluginContext['logger'];\r\n bee: Bee;\r\n }) {\r\n const { bee, config, ...rest } = params;\r\n super(rest);\r\n this.bee = bee;\r\n this.config = config;\r\n }\r\n\r\n protected async executeQuery(\r\n input: z.infer<typeof DownloadFilesSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { reference, filePath } = input;\r\n \r\n if (!reference) {\r\n this.logger.error(\r\n 'Missing required parameter: reference.'\r\n );\r\n \r\n throw new Error(\"Missing required parameter: reference.\");\r\n }\r\n\r\n this.logger.info(`[API] Downloading folder from Swarm with reference: ${reference}.`);\r\n\r\n // Check if the reference is a manifest\r\n let isManifest = false;\r\n let node: MantarayNode;\r\n\r\n try {\r\n node = await MantarayNode.unmarshal(this.bee, reference);\r\n await node.loadRecursively(this.bee);\r\n isManifest = true;\r\n } catch (error) {\r\n // ignore\r\n }\r\n\r\n if (isManifest) {\r\n if (filePath) {\r\n const destinationFolder = filePath;\r\n\r\n if (!fs.existsSync(destinationFolder)) {\r\n await promisify(fs.mkdir)(destinationFolder, { recursive: true });\r\n }\r\n\r\n const nodes = node!.collect();\r\n\r\n if (nodes.length === 1) {\r\n const node = nodes[0];\r\n const data = await this.bee.downloadData(node.targetAddress);\r\n await promisify(fs.writeFile)(\r\n path.join(\r\n destinationFolder,\r\n node.fullPathString.split(\"\\\\\").slice(-1)[0]\r\n ),\r\n data.toUint8Array()\r\n );\r\n } else {\r\n // Download each node\r\n for (const node of nodes) {\r\n const parsedPath = path.parse(node.fullPathString);\r\n const nodeDestFolder = path.join(destinationFolder, parsedPath.dir);\r\n // Create subdirectories if necessary\r\n if (!fs.existsSync(nodeDestFolder)) {\r\n await promisify(fs.mkdir)(nodeDestFolder, { recursive: true });\r\n }\r\n\r\n const data = await this.bee.downloadData(node.targetAddress);\r\n await promisify(fs.writeFile)(\r\n path.join(destinationFolder, node.fullPathString),\r\n data.toUint8Array()\r\n );\r\n }\r\n }\r\n\r\n return {\r\n content: [\r\n {\r\n type: \"text\",\r\n text: JSON.stringify(\r\n {\r\n reference: reference,\r\n manifestNodeCount: nodes.length,\r\n savedTo: destinationFolder,\r\n message: `Manifest content (${nodes.length} files) successfully downloaded to ${destinationFolder}`,\r\n },\r\n null,\r\n 2\r\n ),\r\n },\r\n ],\r\n };\r\n } else {\r\n // regular file\r\n const nodes = node!.collect();\r\n const filesList = nodes.map((node) => ({\r\n path: node.fullPathString || \"/\",\r\n targetAddress: Array.from(node.targetAddress)\r\n .map((e) => e.toString(16).padStart(2, \"0\"))\r\n .join(\"\"),\r\n metadata: node.metadata,\r\n }));\r\n\r\n return {\r\n content: [\r\n {\r\n type: \"text\",\r\n text: JSON.stringify(\r\n {\r\n reference: reference,\r\n type: \"manifest\",\r\n files: filesList,\r\n message:\r\n \"This is a manifest with multiple files. Provide a filePath to download all files or download individual files using their specific references.\",\r\n },\r\n null,\r\n 2\r\n ),\r\n },\r\n ],\r\n };\r\n }\r\n } else {\r\n return \"Try swarm-download-data tool instead since the given reference is not a manifest.\";\r\n }\r\n }\r\n}\r\n"],"names":["node"],"mappings":"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"}