@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,38 +1,102 @@
1
1
  import { BaseHederaQueryTool } from "hedera-agent-kit";
2
2
  import { z } from "zod";
3
- import { errorHasStatus, getBatchSummary, getResponseWithStructuredContent } from "./index62.js";
4
- import { NOT_FOUND_STATUS, GATEWAY_STAMP_ERROR_MESSAGE } from "./index63.js";
5
- const GetPostageStampSchema = z.object({
6
- postageBatchId: z.string()
3
+ import { promisify } from "util";
4
+ import fs from "fs";
5
+ import { getUploadPostageBatchId, errorHasStatus, getErrorMessage, getResponseWithStructuredContent } from "./index62.js";
6
+ import { DEFAULT_DEFERRED_UPLOAD_SIZE_THRESHOLD_MB, GATEWAY_TAG_ERROR_MESSAGE, NOT_FOUND_STATUS, BAD_REQUEST_STATUS } from "./index63.js";
7
+ const UploadFileSchema = z.object({
8
+ data: z.string(),
9
+ isPath: z.boolean(),
10
+ redundancyLevel: z.number().optional(),
11
+ postageBatchId: z.string().optional()
7
12
  });
8
- class GetPostageStampTool extends BaseHederaQueryTool {
13
+ class UploadFileTool extends BaseHederaQueryTool {
9
14
  constructor(params) {
10
15
  const { bee, config, ...rest } = params;
11
16
  super(rest);
12
- this.name = "swarm-get-postage-stamp";
13
- this.description = `Get a specific postage stamp based on postageBatchId.
14
- postageBatchId: The id of the stamp which is requested.
15
- `;
17
+ this.name = "swarm-upload-file";
18
+ this.description = `Upload a file to Swarm.
19
+ data: base64 encoded file content or file path.
20
+ isPath: Wether the data parameter is a path.
21
+ redundancyLevel: Redundancy level for fault tolerance (higher values provide better fault tolerance but increase storage overhead). 0 - none, 1 - medium, 2 - strong, 3 - insane, 4 - paranoid.
22
+ postageBatchId: The postage stamp batch ID which will be used to perform the upload, if it is provided.`;
16
23
  this.namespace = "swarm";
17
- this.specificInputSchema = GetPostageStampSchema;
24
+ this.specificInputSchema = UploadFileSchema;
18
25
  this.bee = bee;
19
26
  this.config = config;
20
27
  }
21
28
  async executeQuery(input) {
22
- const { postageBatchId } = input;
23
- if (!postageBatchId) {
29
+ const { data, isPath, redundancyLevel: inputRedundancyLevel, postageBatchId: inputPostageBatchId } = input;
30
+ if (!data) {
24
31
  this.logger.error(
25
- "Missing required parameter: postageBatchId."
32
+ "Missing required parameter: data."
26
33
  );
27
- throw new Error("Missing required parameter: postageBatchId.");
34
+ throw new Error("Missing required parameter: data.");
28
35
  }
29
- let rawPostageBatch;
36
+ let postageBatchId = "";
30
37
  try {
31
- rawPostageBatch = await this.bee.getPostageBatch(postageBatchId);
38
+ postageBatchId = await getUploadPostageBatchId(
39
+ inputPostageBatchId,
40
+ this.bee,
41
+ this.config
42
+ );
43
+ } catch (error) {
44
+ let errorMessage = "Upload file failed.";
45
+ if (error instanceof Error) {
46
+ errorMessage = error.message;
47
+ }
48
+ this.logger.error(errorMessage);
49
+ throw new Error(errorMessage);
50
+ }
51
+ let binaryData;
52
+ let name;
53
+ if (isPath) {
54
+ try {
55
+ binaryData = await promisify(fs.readFile)(data);
56
+ } catch (fileError) {
57
+ this.logger.error(
58
+ `Unable to read file at path: ${data}.`,
59
+ fileError
60
+ );
61
+ throw new Error(`Unable to read file at path: ${data}.`);
62
+ }
63
+ name = data.split("/").pop();
64
+ } else {
65
+ binaryData = Buffer.from(data, "base64");
66
+ }
67
+ const redundancyLevel = inputRedundancyLevel;
68
+ const options = {};
69
+ const deferredUploadSizeThreshold = Number(this.config.deferredUploadSizeThresholdMB) || DEFAULT_DEFERRED_UPLOAD_SIZE_THRESHOLD_MB;
70
+ const deferred = binaryData.length > deferredUploadSizeThreshold * 1024 * 1024;
71
+ options.deferred = deferred;
72
+ if (redundancyLevel) {
73
+ options.redundancyLevel = redundancyLevel;
74
+ }
75
+ let message = "File successfully uploaded to Swarm";
76
+ let tagId = void 0;
77
+ if (deferred) {
78
+ try {
79
+ const tag = await this.bee.createTag();
80
+ options.tag = tag.uid;
81
+ tagId = tag.uid.toString();
82
+ message = "File upload started in deferred mode. Use query_upload_progress to track progress.";
83
+ } catch (error) {
84
+ if (errorHasStatus(error, NOT_FOUND_STATUS)) {
85
+ this.logger.error(
86
+ GATEWAY_TAG_ERROR_MESSAGE,
87
+ error
88
+ );
89
+ throw new Error(GATEWAY_TAG_ERROR_MESSAGE);
90
+ }
91
+ }
92
+ }
93
+ let result;
94
+ try {
95
+ result = await this.bee.uploadFile(postageBatchId, binaryData, name, options);
32
96
  } catch (error) {
33
- let errorMessage = "Retrieval of postage batch failed.";
34
- if (errorHasStatus(error, NOT_FOUND_STATUS)) {
35
- errorMessage = GATEWAY_STAMP_ERROR_MESSAGE;
97
+ let errorMessage = "Unable to upload file.";
98
+ if (errorHasStatus(error, BAD_REQUEST_STATUS)) {
99
+ errorMessage = getErrorMessage(error);
36
100
  }
37
101
  this.logger.error(
38
102
  errorMessage,
@@ -40,19 +104,15 @@ class GetPostageStampTool extends BaseHederaQueryTool {
40
104
  );
41
105
  throw new Error(errorMessage);
42
106
  }
43
- const batch = {
44
- ...rawPostageBatch,
45
- batchID: rawPostageBatch.batchID.toHex()
46
- };
47
- const batchSummary = getBatchSummary(rawPostageBatch);
48
- const content = {
49
- raw: batch,
50
- summary: batchSummary
51
- };
52
- return getResponseWithStructuredContent(content);
107
+ return getResponseWithStructuredContent({
108
+ reference: result.reference.toString(),
109
+ url: this.bee.url + "/bzz/" + result.reference.toString(),
110
+ message,
111
+ tagId
112
+ });
53
113
  }
54
114
  }
55
115
  export {
56
- GetPostageStampTool
116
+ UploadFileTool
57
117
  };
58
118
  //# sourceMappingURL=index55.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index55.js","sources":["../../src/plugins/community/swarm/tools/GetPostageStampTool.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 PostageBatchCurated,\r\n PostageBatchSummary,\r\n ResponseContent,\r\n} from \"../model\";\r\nimport {\r\n errorHasStatus,\r\n getBatchSummary,\r\n getResponseWithStructuredContent,\r\n ToolResponse,\r\n} from \"../utils\";\r\nimport { GATEWAY_STAMP_ERROR_MESSAGE, NOT_FOUND_STATUS } from \"../constants\";\r\nimport { SwarmConfig } from \"../config\";\r\n\r\nconst GetPostageStampSchema = z.object({\r\n postageBatchId: z.string(),\r\n});\r\n\r\nexport class GetPostageStampTool extends BaseHederaQueryTool<typeof GetPostageStampSchema> {\r\n name = \"swarm-get-postage-stamp\";\r\n description = `Get a specific postage stamp based on postageBatchId.\r\n postageBatchId: The id of the stamp which is requested.\r\n `;\r\n namespace = \"swarm\";\r\n specificInputSchema = GetPostageStampSchema;\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 GetPostageStampSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { postageBatchId } = input;\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 }\r\n\r\n let rawPostageBatch;\r\n\r\n try {\r\n rawPostageBatch = await this.bee.getPostageBatch(postageBatchId);\r\n } catch (error) {\r\n let errorMessage = 'Retrieval of postage batch failed.';\r\n \r\n if (errorHasStatus(error, NOT_FOUND_STATUS)) {\r\n errorMessage = GATEWAY_STAMP_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 const batch: PostageBatchCurated = {\r\n ...rawPostageBatch,\r\n batchID: rawPostageBatch.batchID.toHex(),\r\n };\r\n const batchSummary: PostageBatchSummary = getBatchSummary(rawPostageBatch);\r\n\r\n const content: ResponseContent<PostageBatchCurated, PostageBatchSummary> = {\r\n raw: batch,\r\n summary: batchSummary,\r\n };\r\n\r\n return getResponseWithStructuredContent(content);\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;AAqBA,MAAM,wBAAwB,EAAE,OAAO;AAAA,EACrC,gBAAgB,EAAE,OAAA;AACpB,CAAC;AAEM,MAAM,4BAA4B,oBAAkD;AAAA,EAUzF,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,UAAM,EAAE,mBAAmB;AAC3B,QAAI,CAAC,gBAAgB;AACnB,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AAEA,QAAI;AAEJ,QAAI;AACF,wBAAkB,MAAM,KAAK,IAAI,gBAAgB,cAAc;AAAA,IACjE,SAAS,OAAO;AACd,UAAI,eAAe;AAEnB,UAAI,eAAe,OAAO,gBAAgB,GAAG;AAC3C,uBAAe;AAAA,MACjB;AAEA,WAAK,OAAO;AAAA,QACV;AAAA,QACA;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,YAAY;AAAA,IAC9B;AAEA,UAAM,QAA6B;AAAA,MACjC,GAAG;AAAA,MACH,SAAS,gBAAgB,QAAQ,MAAA;AAAA,IAAM;AAEzC,UAAM,eAAoC,gBAAgB,eAAe;AAEzE,UAAM,UAAqE;AAAA,MACzE,KAAK;AAAA,MACL,SAAS;AAAA,IAAA;AAGX,WAAO,iCAAiC,OAAO;AAAA,EACjD;AACF;"}
1
+ {"version":3,"file":"index55.js","sources":["../../src/plugins/community/swarm/tools/UploadFileTool.ts"],"sourcesContent":["import {\r\n BaseHederaQueryTool,\r\n HederaAgentKit,\r\n type GenericPluginContext,\r\n} from \"hedera-agent-kit\";\r\nimport { Bee, FileUploadOptions } from \"@ethersphere/bee-js\";\r\nimport { z } from \"zod\";\r\nimport { promisify } from \"util\";\r\nimport fs from \"fs\";\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, DEFAULT_DEFERRED_UPLOAD_SIZE_THRESHOLD_MB, GATEWAY_TAG_ERROR_MESSAGE, NOT_FOUND_STATUS } from \"../constants\";\r\nimport { SwarmConfig } from \"../config\";\r\n\r\nconst UploadFileSchema = z.object({\r\n data: z.string(),\r\n isPath: z.boolean(),\r\n redundancyLevel: z.number().optional(),\r\n postageBatchId: z.string().optional(),\r\n});\r\n\r\nexport class UploadFileTool extends BaseHederaQueryTool<typeof UploadFileSchema> {\r\n name = \"swarm-upload-file\";\r\n description = `Upload a file to Swarm.\r\n data: base64 encoded file content or file path.\r\n isPath: Wether the data parameter is a path.\r\n redundancyLevel: Redundancy level for fault tolerance (higher values provide better fault tolerance but increase storage overhead). 0 - none, 1 - medium, 2 - strong, 3 - insane, 4 - paranoid.\r\n postageBatchId: The postage stamp batch ID which will be used to perform the upload, if it is provided.`;\r\n namespace = \"swarm\";\r\n specificInputSchema = UploadFileSchema;\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 UploadFileSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { data, isPath, redundancyLevel: inputRedundancyLevel, 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 file 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 let binaryData: Buffer;\r\n let name: string | undefined;\r\n\r\n if (isPath) {\r\n // Read file from path\r\n try {\r\n binaryData = await promisify(fs.readFile)(data);\r\n } catch (fileError) {\r\n this.logger.error(\r\n `Unable to read file at path: ${data}.`,\r\n fileError\r\n );\r\n\r\n throw new Error(`Unable to read file at path: ${data}.`);\r\n }\r\n\r\n name = data.split(\"/\").pop();\r\n } else {\r\n binaryData = Buffer.from(data, \"base64\");\r\n }\r\n\r\n const redundancyLevel = inputRedundancyLevel;\r\n const options: FileUploadOptions = {};\r\n const deferredUploadSizeThreshold = Number(this.config.deferredUploadSizeThresholdMB) ||\r\n DEFAULT_DEFERRED_UPLOAD_SIZE_THRESHOLD_MB;\r\n const deferred =\r\n binaryData.length > deferredUploadSizeThreshold * 1024 * 1024;\r\n options.deferred = deferred;\r\n if (redundancyLevel) {\r\n options.redundancyLevel = redundancyLevel;\r\n }\r\n\r\n let message = \"File successfully uploaded to Swarm\";\r\n let tagId: string | undefined = undefined;\r\n // Create tag for deferred uploads or when explicitly requested\r\n if (deferred) {\r\n try {\r\n const tag = await this.bee.createTag();\r\n options.tag = tag.uid;\r\n tagId = tag.uid.toString();\r\n message =\r\n \"File upload started in deferred mode. Use query_upload_progress to track progress.\";\r\n } catch (error) {\r\n if (errorHasStatus(error, NOT_FOUND_STATUS)) {\r\n this.logger.error(\r\n GATEWAY_TAG_ERROR_MESSAGE,\r\n error\r\n );\r\n\r\n throw new Error(GATEWAY_TAG_ERROR_MESSAGE);\r\n }\r\n }\r\n }\r\n\r\n let result;\r\n\r\n try {\r\n // Start the deferred upload\r\n result = await this.bee.uploadFile(postageBatchId, binaryData, name, options);\r\n } catch (error) {\r\n let errorMessage = 'Unable to upload file.';\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 + \"/bzz/\" + result.reference.toString(),\r\n message,\r\n tagId,\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}
@@ -1,83 +1,108 @@
1
- import { Wallet } from "@ethereumjs/wallet";
2
- import { z } from "zod";
3
- import crypto from "crypto";
4
- import { hexToBytes, errorHasStatus, getErrorMessage, getResponseWithStructuredContent } from "./index62.js";
5
1
  import { BaseHederaQueryTool } from "hedera-agent-kit";
2
+ import { z } from "zod";
3
+ import { promisify } from "util";
4
+ import fs from "fs";
5
+ import { getUploadPostageBatchId, errorHasStatus, getErrorMessage, getResponseWithStructuredContent } from "./index62.js";
6
6
  import { BAD_REQUEST_STATUS } from "./index63.js";
7
- const ReadFeedSchema = z.object({
8
- memoryTopic: z.string(),
9
- owner: z.string().optional()
7
+ const UploadFolderSchema = z.object({
8
+ folderPath: z.string(),
9
+ redundancyLevel: z.number().optional(),
10
+ postageBatchId: z.string().optional()
10
11
  });
11
- class ReadFeedTool extends BaseHederaQueryTool {
12
+ class UploadFolderTool extends BaseHederaQueryTool {
12
13
  constructor(params) {
13
14
  const { bee, config, ...rest } = params;
14
15
  super(rest);
15
- this.name = "swarm-read-feed";
16
- this.description = `Retrieve the latest data from the feed of a given topic.
17
- memoryTopic: Feed topic.
18
- owner: When accessing external memory or feed, ethereum address of the owner must be set.
19
- `;
16
+ this.name = "swarm-upload-folder";
17
+ this.description = `Upload a folder to Swarm.
18
+ folderPath: Path to the folder to upload.
19
+ redundancyLevel: Redundancy level for fault tolerance (higher values provide better fault tolerance but increase storage overhead). 0 - none, 1 - medium, 2 - strong, 3 - insane, 4 - paranoid.
20
+ postageBatchId: The postage stamp batch ID which will be used to perform the upload, if it is provided.`;
20
21
  this.namespace = "swarm";
21
- this.specificInputSchema = ReadFeedSchema;
22
+ this.specificInputSchema = UploadFolderSchema;
22
23
  this.bee = bee;
23
24
  this.config = config;
24
25
  }
25
26
  async executeQuery(input) {
26
- const { memoryTopic, owner } = input;
27
- if (!memoryTopic) {
27
+ const { folderPath, redundancyLevel: inputRedundancyLevel, postageBatchId: inputPostageBatchId } = input;
28
+ if (!folderPath) {
28
29
  this.logger.error(
29
- "Missing required parameter: memoryTopic."
30
+ "Missing required parameter: folderPath."
30
31
  );
31
- throw new Error("Missing required parameter: memoryTopic.");
32
+ throw new Error("Missing required parameter: folderPath.");
32
33
  }
33
- this.logger.info(`[API] Downloading text from Swarm feed with topic: ${memoryTopic}.`);
34
- if (!this.config.beeFeedPK) {
35
- this.logger.error("Feed private key not configured.");
36
- throw new Error("Feed private key not configured.");
34
+ const stats = await promisify(fs.stat)(folderPath);
35
+ if (!stats.isDirectory()) {
36
+ this.logger.error(
37
+ `Path is not a directory: ${folderPath}.`
38
+ );
39
+ throw new Error(`Path is not a directory: ${folderPath}.`);
37
40
  }
38
- let topic = memoryTopic;
39
- if (topic.startsWith("0x")) {
40
- topic = topic.slice(2);
41
+ let postageBatchId = "";
42
+ try {
43
+ postageBatchId = await getUploadPostageBatchId(
44
+ inputPostageBatchId,
45
+ this.bee,
46
+ this.config
47
+ );
48
+ } catch (error) {
49
+ let errorMessage = "Upload folder failed.";
50
+ if (error instanceof Error) {
51
+ errorMessage = error.message;
52
+ }
53
+ this.logger.error(errorMessage);
54
+ throw new Error(errorMessage);
41
55
  }
42
- const isHexString = /^[0-9a-fA-F]{64}$/.test(topic);
43
- if (!isHexString) {
44
- const hash = crypto.createHash("sha256").update(memoryTopic).digest("hex");
45
- topic = hash;
56
+ const redundancyLevel = inputRedundancyLevel;
57
+ const options = {};
58
+ if (redundancyLevel) {
59
+ options.redundancyLevel = redundancyLevel;
46
60
  }
47
- const topicBytes = hexToBytes(topic);
48
- let feedOwner = owner;
49
- if (!feedOwner) {
50
- const feedPrivateKey = hexToBytes(this.config.beeFeedPK);
51
- const signer = new Wallet(feedPrivateKey);
52
- feedOwner = signer.getAddressString().slice(2);
53
- } else {
54
- if (feedOwner.startsWith("0x")) {
55
- feedOwner = feedOwner.slice(2);
56
- }
57
- if (feedOwner.length !== 40) {
58
- this.logger.error("Owner must be a valid Ethereum address.");
59
- throw new Error("Owner must be a valid Ethereum address.");
61
+ const deferred = true;
62
+ options.deferred = deferred;
63
+ let message = "Folder successfully uploaded to Swarm";
64
+ let tagId = void 0;
65
+ {
66
+ try {
67
+ const tag = await this.bee.createTag();
68
+ tagId = tag.uid.toString();
69
+ options.tag = tag.uid;
70
+ message = "Folder upload started in deferred mode. Use swarm-query-upload-progress to track progress.";
71
+ } catch (error) {
72
+ this.logger.error(
73
+ "Failed to create tag",
74
+ error
75
+ );
76
+ options.deferred = false;
60
77
  }
61
78
  }
62
- let textData;
79
+ let result;
63
80
  try {
64
- const feedReader = this.bee.makeFeedReader(topicBytes, feedOwner);
65
- const latestUpdate = await feedReader.downloadPayload();
66
- textData = latestUpdate.payload.toUtf8();
81
+ result = await this.bee.uploadFilesFromDirectory(
82
+ postageBatchId,
83
+ folderPath,
84
+ options
85
+ );
67
86
  } catch (error) {
68
- let errorMessage = "Reading feed failed.";
87
+ let errorMessage = "Unable to upload folder.";
69
88
  if (errorHasStatus(error, BAD_REQUEST_STATUS)) {
70
89
  errorMessage = getErrorMessage(error);
71
90
  }
72
- this.logger.error(errorMessage, error);
91
+ this.logger.error(
92
+ errorMessage,
93
+ error
94
+ );
73
95
  throw new Error(errorMessage);
74
96
  }
75
97
  return getResponseWithStructuredContent({
76
- textData
98
+ reference: result.reference.toString(),
99
+ url: this.bee.url + "/bzz/" + result.reference.toString(),
100
+ message,
101
+ tagId
77
102
  });
78
103
  }
79
104
  }
80
105
  export {
81
- ReadFeedTool
106
+ UploadFolderTool
82
107
  };
83
108
  //# sourceMappingURL=index56.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index56.js","sources":["../../src/plugins/community/swarm/tools/ReadFeedTool.ts"],"sourcesContent":["import { Bee } from \"@ethersphere/bee-js\";\r\nimport { Wallet } from \"@ethereumjs/wallet\";\r\nimport { z } from \"zod\";\r\nimport crypto from \"crypto\";\r\nimport { errorHasStatus, getErrorMessage, getResponseWithStructuredContent, hexToBytes, 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 ReadFeedSchema = z.object({\r\n memoryTopic: z.string(),\r\n owner: z.string().optional()\r\n});\r\n\r\nexport class ReadFeedTool extends BaseHederaQueryTool<typeof ReadFeedSchema> {\r\n name = \"swarm-read-feed\";\r\n description = `Retrieve the latest data from the feed of a given topic.\r\n memoryTopic: Feed topic.\r\n owner: When accessing external memory or feed, ethereum address of the owner must be set.\r\n `;\r\n namespace = \"swarm\";\r\n specificInputSchema = ReadFeedSchema;\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 ReadFeedSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { memoryTopic, owner } = input;\r\n\r\n if (!memoryTopic) {\r\n this.logger.error(\r\n 'Missing required parameter: memoryTopic.'\r\n );\r\n\r\n throw new Error('Missing required parameter: memoryTopic.');\r\n }\r\n\r\n this.logger.info(`[API] Downloading text from Swarm feed with topic: ${memoryTopic}.`);\r\n\r\n if (!this.config.beeFeedPK) {\r\n this.logger.error('Feed private key not configured.');\r\n\r\n throw new Error('Feed private key not configured.');\r\n }\r\n\r\n // Process topic - if not a hex string, hash it\r\n let topic = memoryTopic;\r\n if (topic.startsWith(\"0x\")) {\r\n topic = topic.slice(2);\r\n }\r\n const isHexString = /^[0-9a-fA-F]{64}$/.test(topic);\r\n\r\n if (!isHexString) {\r\n // Hash the topic string using SHA-256\r\n const hash = crypto.createHash(\"sha256\").update(memoryTopic).digest(\"hex\");\r\n topic = hash;\r\n }\r\n\r\n // Convert topic string to bytes\r\n const topicBytes = hexToBytes(topic);\r\n\r\n let feedOwner = owner;\r\n if (!feedOwner) {\r\n const feedPrivateKey = hexToBytes(this.config.beeFeedPK);\r\n const signer = new Wallet(feedPrivateKey);\r\n feedOwner = signer.getAddressString().slice(2);\r\n } else {\r\n if (feedOwner.startsWith(\"0x\")) {\r\n feedOwner = feedOwner.slice(2);\r\n }\r\n if (feedOwner.length !== 40) {\r\n this.logger.error('Owner must be a valid Ethereum address.');\r\n\r\n throw new Error('Owner must be a valid Ethereum address.');\r\n }\r\n }\r\n\r\n let textData;\r\n \r\n try {\r\n const feedReader = this.bee.makeFeedReader(topicBytes, feedOwner);\r\n const latestUpdate = await feedReader.downloadPayload();\r\n textData = latestUpdate.payload.toUtf8();\r\n } catch (error) {\r\n let errorMessage = 'Reading feed failed.';\r\n if (errorHasStatus(error, BAD_REQUEST_STATUS)) {\r\n errorMessage = getErrorMessage(error);\r\n }\r\n this.logger.error(errorMessage, error);\r\n throw new Error(errorMessage);\r\n }\r\n \r\n return getResponseWithStructuredContent({\r\n textData,\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;;;AASA,MAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,aAAa,EAAE,OAAA;AAAA,EACf,OAAO,EAAE,OAAA,EAAS,SAAA;AACpB,CAAC;AAEM,MAAM,qBAAqB,oBAA2C;AAAA,EAW3E,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;AACjC,UAAM,EAAE,aAAa,MAAA,IAAU;AAE9B,QAAI,CAAC,aAAa;AAChB,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AAEA,SAAK,OAAO,KAAK,sDAAsD,WAAW,GAAG;AAErF,QAAI,CAAC,KAAK,OAAO,WAAW;AAC1B,WAAK,OAAO,MAAM,kCAAkC;AAEpD,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AAGA,QAAI,QAAQ;AACZ,QAAI,MAAM,WAAW,IAAI,GAAG;AAC1B,cAAQ,MAAM,MAAM,CAAC;AAAA,IACvB;AACA,UAAM,cAAc,oBAAoB,KAAK,KAAK;AAElD,QAAI,CAAC,aAAa;AAEhB,YAAM,OAAO,OAAO,WAAW,QAAQ,EAAE,OAAO,WAAW,EAAE,OAAO,KAAK;AACzE,cAAQ;AAAA,IACV;AAGA,UAAM,aAAa,WAAW,KAAK;AAEnC,QAAI,YAAY;AAChB,QAAI,CAAC,WAAW;AACd,YAAM,iBAAiB,WAAW,KAAK,OAAO,SAAS;AACvD,YAAM,SAAS,IAAI,OAAO,cAAc;AACxC,kBAAY,OAAO,mBAAmB,MAAM,CAAC;AAAA,IAC/C,OAAO;AACL,UAAI,UAAU,WAAW,IAAI,GAAG;AAC9B,oBAAY,UAAU,MAAM,CAAC;AAAA,MAC/B;AACA,UAAI,UAAU,WAAW,IAAI;AAC3B,aAAK,OAAO,MAAM,yCAAyC;AAE3D,cAAM,IAAI,MAAM,yCAAyC;AAAA,MAC3D;AAAA,IACF;AAEA,QAAI;AAEJ,QAAI;AACF,YAAM,aAAa,KAAK,IAAI,eAAe,YAAY,SAAS;AAChE,YAAM,eAAe,MAAM,WAAW,gBAAA;AACtC,iBAAW,aAAa,QAAQ,OAAA;AAAA,IAClC,SAAS,OAAO;AACd,UAAI,eAAe;AACnB,UAAI,eAAe,OAAO,kBAAkB,GAAG;AAC7C,uBAAe,gBAAgB,KAAK;AAAA,MACtC;AACA,WAAK,OAAO,MAAM,cAAc,KAAK;AACrC,YAAM,IAAI,MAAM,YAAY;AAAA,IAC9B;AAEA,WAAO,iCAAiC;AAAA,MACtC;AAAA,IAAA,CACD;AAAA,EACH;AACF;"}
1
+ {"version":3,"file":"index56.js","sources":["../../src/plugins/community/swarm/tools/UploadFolderTool.ts"],"sourcesContent":["import {\r\n BaseHederaQueryTool,\r\n HederaAgentKit,\r\n type GenericPluginContext,\r\n} from \"hedera-agent-kit\";\r\nimport { Bee, CollectionUploadOptions } from \"@ethersphere/bee-js\";\r\nimport { z } from \"zod\";\r\nimport { promisify } from \"util\";\r\nimport fs from \"fs\";\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 UploadFolderSchema = z.object({\r\n folderPath: z.string(),\r\n redundancyLevel: z.number().optional(),\r\n postageBatchId: z.string().optional(),\r\n});\r\n\r\nexport class UploadFolderTool extends BaseHederaQueryTool<typeof UploadFolderSchema> {\r\n name = \"swarm-upload-folder\";\r\n description = `Upload a folder to Swarm.\r\n folderPath: Path to the folder to upload. \r\n redundancyLevel: Redundancy level for fault tolerance (higher values provide better fault tolerance but increase storage overhead). 0 - none, 1 - medium, 2 - strong, 3 - insane, 4 - paranoid. \r\n postageBatchId: The postage stamp batch ID which will be used to perform the upload, if it is provided.`;\r\n namespace = \"swarm\";\r\n specificInputSchema = UploadFolderSchema;\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 UploadFolderSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { folderPath, redundancyLevel: inputRedundancyLevel, postageBatchId: inputPostageBatchId } = input;\r\n\r\n if (!folderPath) {\r\n this.logger.error(\r\n 'Missing required parameter: folderPath.'\r\n );\r\n\r\n throw new Error('Missing required parameter: folderPath.');\r\n }\r\n\r\n // Check if folder exists\r\n const stats = await promisify(fs.stat)(folderPath);\r\n if (!stats.isDirectory()) {\r\n this.logger.error(\r\n `Path is not a directory: ${folderPath}.`\r\n );\r\n\r\n throw new Error(`Path is not a directory: ${folderPath}.`);\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 folder 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 redundancyLevel = inputRedundancyLevel;\r\n const options: CollectionUploadOptions = {};\r\n\r\n if (redundancyLevel) {\r\n options.redundancyLevel = redundancyLevel;\r\n }\r\n\r\n const deferred = true;\r\n options.deferred = deferred;\r\n let message = 'Folder successfully uploaded to Swarm';\r\n\r\n let tagId: string | undefined = undefined;\r\n\r\n if (deferred) {\r\n try {\r\n const tag = await this.bee.createTag();\r\n tagId = tag.uid.toString();\r\n options.tag = tag.uid;\r\n message =\r\n 'Folder upload started in deferred mode. Use swarm-query-upload-progress to track progress.';\r\n } catch (error) {\r\n this.logger.error(\r\n 'Failed to create tag',\r\n error\r\n );\r\n options.deferred = false;\r\n }\r\n }\r\n\r\n let result;\r\n\r\n try {\r\n // Start the deferred upload\r\n result = await this.bee.uploadFilesFromDirectory(\r\n postageBatchId,\r\n folderPath,\r\n options\r\n );\r\n } catch (error) {\r\n let errorMessage = 'Unable to upload folder.';\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 + \"/bzz/\" + result.reference.toString(),\r\n message,\r\n tagId,\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;;;AAmBA,MAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,YAAY,EAAE,OAAA;AAAA,EACd,iBAAiB,EAAE,OAAA,EAAS,SAAA;AAAA,EAC5B,gBAAgB,EAAE,OAAA,EAAS,SAAA;AAC7B,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,YAAY,iBAAiB,sBAAsB,gBAAgB,wBAAwB;AAEnG,QAAI,CAAC,YAAY;AACf,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAGA,UAAM,QAAQ,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU;AACjD,QAAI,CAAC,MAAM,eAAe;AACxB,WAAK,OAAO;AAAA,QACV,4BAA4B,UAAU;AAAA,MAAA;AAGxC,YAAM,IAAI,MAAM,4BAA4B,UAAU,GAAG;AAAA,IAC3D;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,kBAAkB;AACxB,UAAM,UAAmC,CAAA;AAEzC,QAAI,iBAAiB;AACnB,cAAQ,kBAAkB;AAAA,IAC5B;AAEA,UAAM,WAAW;AACjB,YAAQ,WAAW;AACnB,QAAI,UAAU;AAEd,QAAI,QAA4B;AAElB;AACZ,UAAI;AACF,cAAM,MAAM,MAAM,KAAK,IAAI,UAAA;AAC3B,gBAAQ,IAAI,IAAI,SAAA;AAChB,gBAAQ,MAAM,IAAI;AAClB,kBACE;AAAA,MACJ,SAAS,OAAO;AACd,aAAK,OAAO;AAAA,UACV;AAAA,UACA;AAAA,QAAA;AAEF,gBAAQ,WAAW;AAAA,MACrB;AAAA,IACF;AAEA,QAAI;AAEJ,QAAI;AAEF,eAAS,MAAM,KAAK,IAAI;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,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,MACtC,WAAW,OAAO,UAAU,SAAA;AAAA,MAC5B,KAAK,KAAK,IAAI,MAAM,UAAU,OAAO,UAAU,SAAA;AAAA,MAC/C;AAAA,MACA;AAAA,IAAA,CACD;AAAA,EACH;AACF;"}
@@ -1,100 +1,8 @@
1
- import { BaseHederaQueryTool } from "hedera-agent-kit";
2
- import { z } from "zod";
3
- import crypto from "crypto";
4
- import { getUploadPostageBatchId, hexToBytes, errorHasStatus, getErrorMessage, getResponseWithStructuredContent } from "./index62.js";
5
- import { BAD_REQUEST_STATUS } from "./index63.js";
6
- import { Wallet } from "@ethereumjs/wallet";
7
- const UpdateFeedSchema = z.object({
8
- data: z.string(),
9
- memoryTopic: z.string(),
10
- postageBatchId: z.string().optional()
11
- });
12
- class UpdateFeedTool extends BaseHederaQueryTool {
13
- constructor(params) {
14
- const { bee, config, ...rest } = params;
15
- super(rest);
16
- this.name = "swarm-update-feed";
17
- this.description = `Update the feed of a given topic with new data.
18
- data: Arbitrary string to upload.
19
- memoryTopic: If provided, uploads the data to a feed with this topic. It is the label of the memory that can be used later to retrieve the data instead of its content hash. If not a hex string, it will be hashed to create a feed topic.
20
- postageBatchId: The postage stamp batch ID which will be used to perform the upload, if it is provided.`;
21
- this.namespace = "swarm";
22
- this.specificInputSchema = UpdateFeedSchema;
23
- this.bee = bee;
24
- this.config = config;
25
- }
26
- async executeQuery(input) {
27
- const { data, memoryTopic, postageBatchId: inputPostageBatchId } = input;
28
- if (!data) {
29
- this.logger.error(
30
- "Missing required parameter: data."
31
- );
32
- throw new Error("Missing required parameter: data.");
33
- } else if (!memoryTopic) {
34
- this.logger.error(
35
- "Missing required parameter: topic."
36
- );
37
- throw new Error("Missing required parameter: topic.");
38
- }
39
- let postageBatchId = "";
40
- try {
41
- postageBatchId = await getUploadPostageBatchId(
42
- inputPostageBatchId,
43
- this.bee,
44
- this.config
45
- );
46
- } catch (error) {
47
- let errorMessage = "Update feed failed.";
48
- if (error instanceof Error) {
49
- errorMessage = error.message;
50
- }
51
- this.logger.error(errorMessage);
52
- throw new Error(errorMessage);
53
- }
54
- const binaryData = Buffer.from(data);
55
- if (!this.config.beeFeedPK) {
56
- this.logger.error("Feed private key not configured.");
57
- throw new Error("Feed private key not configured.");
58
- }
59
- let topic = memoryTopic;
60
- if (topic.startsWith("0x")) {
61
- topic = topic.slice(2);
62
- }
63
- const isHexString = /^[0-9a-fA-F]{64}$/.test(memoryTopic);
64
- if (!isHexString) {
65
- const hash = crypto.createHash("sha256").update(memoryTopic).digest("hex");
66
- topic = hash;
67
- }
68
- const topicBytes = hexToBytes(topic);
69
- const feedPrivateKey = hexToBytes(this.config.beeFeedPK);
70
- const signer = new Wallet(feedPrivateKey);
71
- const owner = signer.getAddressString().slice(2);
72
- let result;
73
- try {
74
- const feedWriter = this.bee.makeFeedWriter(topicBytes, feedPrivateKey);
75
- result = await feedWriter.uploadPayload(postageBatchId, binaryData);
76
- } catch (error) {
77
- let errorMessage = "Unable to update feed.";
78
- if (errorHasStatus(error, BAD_REQUEST_STATUS)) {
79
- errorMessage = getErrorMessage(error);
80
- }
81
- this.logger.error(
82
- errorMessage,
83
- error
84
- );
85
- throw new Error(errorMessage);
86
- }
87
- const reference = result.reference.toString();
88
- return getResponseWithStructuredContent({
89
- reference,
90
- topicString: memoryTopic,
91
- topic,
92
- feedUrl: `${this.bee.url}/feeds/${owner}/${topic}`,
93
- message: "Data successfully uploaded to Swarm and linked to feed."
94
- });
95
- }
96
- }
1
+ const ERROR_MESSAGES = {
2
+ TOO_MANY_REQUESTS: "Too many requests. Please wait a moment and try again.",
3
+ RATE_LIMITED: "I'm receiving too many requests right now. Please wait a moment and try again."
4
+ };
97
5
  export {
98
- UpdateFeedTool
6
+ ERROR_MESSAGES
99
7
  };
100
8
  //# sourceMappingURL=index57.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index57.js","sources":["../../src/plugins/community/swarm/tools/UpdateFeedTool.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 crypto from \"crypto\";\r\nimport {\r\n errorHasStatus,\r\n getErrorMessage,\r\n getResponseWithStructuredContent,\r\n getUploadPostageBatchId,\r\n hexToBytes,\r\n ToolResponse,\r\n} from \"../utils\";\r\nimport { BAD_REQUEST_STATUS } from \"../constants\";\r\nimport { Wallet } from \"@ethereumjs/wallet\";\r\nimport { SwarmConfig } from \"../config\";\r\n\r\nconst UpdateFeedSchema = z.object({\r\n data: z.string(),\r\n memoryTopic: z.string(),\r\n postageBatchId: z.string().optional(),\r\n});\r\n\r\nexport class UpdateFeedTool extends BaseHederaQueryTool<typeof UpdateFeedSchema> {\r\n name = \"swarm-update-feed\";\r\n description = `Update the feed of a given topic with new data.\r\n data: Arbitrary string to upload.\r\n memoryTopic: If provided, uploads the data to a feed with this topic. It is the label of the memory that can be used later to retrieve the data instead of its content hash. If not a hex string, it will be hashed to create a feed topic.\r\n postageBatchId: The postage stamp batch ID which will be used to perform the upload, if it is provided.`;\r\n namespace = \"swarm\";\r\n specificInputSchema = UpdateFeedSchema;\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 UpdateFeedSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { data, memoryTopic, postageBatchId: inputPostageBatchId } = input;\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 } else if (!memoryTopic) {\r\n this.logger.error(\r\n 'Missing required parameter: topic.'\r\n );\r\n\r\n throw new Error('Missing required parameter: topic.');\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 = 'Update feed 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 // Feed upload if memoryTopic is specified\r\n if (!this.config.beeFeedPK) {\r\n this.logger.error('Feed private key not configured.');\r\n\r\n throw new Error('Feed private key not configured.');\r\n }\r\n\r\n // Process topic - if not a hex string, hash it\r\n let topic = memoryTopic;\r\n if (topic.startsWith(\"0x\")) {\r\n topic = topic.slice(2);\r\n }\r\n const isHexString = /^[0-9a-fA-F]{64}$/.test(memoryTopic);\r\n\r\n if (!isHexString) {\r\n // Hash the topic string using SHA-256\r\n const hash = crypto\r\n .createHash(\"sha256\")\r\n .update(memoryTopic)\r\n .digest(\"hex\");\r\n topic = hash;\r\n }\r\n\r\n // Convert topic string to bytes\r\n const topicBytes = hexToBytes(topic);\r\n\r\n const feedPrivateKey = hexToBytes(this.config.beeFeedPK);\r\n const signer = new Wallet(feedPrivateKey);\r\n const owner = signer.getAddressString().slice(2);\r\n\r\n let result;\r\n\r\n try {\r\n const feedWriter = this.bee.makeFeedWriter(topicBytes, feedPrivateKey);\r\n\r\n result = await feedWriter.uploadPayload(postageBatchId!, binaryData);\r\n } catch (error) {\r\n let errorMessage = 'Unable to update feed.';\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 const reference = result.reference.toString();\r\n\r\n return getResponseWithStructuredContent({\r\n reference,\r\n topicString: memoryTopic,\r\n topic: topic,\r\n feedUrl: `${this.bee.url}/feeds/${owner}/${topic}`,\r\n message: 'Data successfully uploaded to Swarm and linked to feed.',\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;;;AAoBA,MAAM,mBAAmB,EAAE,OAAO;AAAA,EAChC,MAAM,EAAE,OAAA;AAAA,EACR,aAAa,EAAE,OAAA;AAAA,EACf,gBAAgB,EAAE,OAAA,EAAS,SAAA;AAC7B,CAAC;AAEM,MAAM,uBAAuB,oBAA6C;AAAA,EAW/E,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,MAAM,aAAa,gBAAgB,wBAAyB;AACnE,QAAI,CAAC,MAAM;AACV,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD,WAAW,CAAC,aAAa;AACvB,WAAK,OAAO;AAAA,QACV;AAAA,MAAA;AAGF,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;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;AAGnC,QAAI,CAAC,KAAK,OAAO,WAAW;AAC1B,WAAK,OAAO,MAAM,kCAAkC;AAEpD,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AAGA,QAAI,QAAQ;AACZ,QAAI,MAAM,WAAW,IAAI,GAAG;AAC1B,cAAQ,MAAM,MAAM,CAAC;AAAA,IACvB;AACA,UAAM,cAAc,oBAAoB,KAAK,WAAW;AAExD,QAAI,CAAC,aAAa;AAEhB,YAAM,OAAO,OACV,WAAW,QAAQ,EACnB,OAAO,WAAW,EAClB,OAAO,KAAK;AACf,cAAQ;AAAA,IACV;AAGA,UAAM,aAAa,WAAW,KAAK;AAEnC,UAAM,iBAAiB,WAAW,KAAK,OAAO,SAAS;AACvD,UAAM,SAAS,IAAI,OAAO,cAAc;AACxC,UAAM,QAAQ,OAAO,iBAAA,EAAmB,MAAM,CAAC;AAE/C,QAAI;AAEJ,QAAI;AACF,YAAM,aAAa,KAAK,IAAI,eAAe,YAAY,cAAc;AAErE,eAAS,MAAM,WAAW,cAAc,gBAAiB,UAAU;AAAA,IACrE,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,UAAM,YAAY,OAAO,UAAU,SAAA;AAEnC,WAAO,iCAAiC;AAAA,MACtC;AAAA,MACA,aAAa;AAAA,MACb;AAAA,MACA,SAAS,GAAG,KAAK,IAAI,GAAG,UAAU,KAAK,IAAI,KAAK;AAAA,MAChD,SAAS;AAAA,IAAA,CACV;AAAA,EACH;AACF;"}
1
+ {"version":3,"file":"index57.js","sources":["../../src/constants/messages.ts"],"sourcesContent":["/**\n * Common error messages and user feedback strings\n */\nexport const ERROR_MESSAGES = {\n TOO_MANY_REQUESTS: 'Too many requests. Please wait a moment and try again.',\n RATE_LIMITED: \"I'm receiving too many requests right now. Please wait a moment and try again.\",\n SYSTEM_ERROR: 'System error occurred',\n INVALID_INPUT: 'Invalid input provided',\n NETWORK_ERROR: 'Network error occurred',\n} as const;\n\n/**\n * Common success and status messages\n */\nexport const STATUS_MESSAGES = {\n OPERATION_SUCCESSFUL: 'Operation completed successfully',\n PROCESSING: 'Processing your request...',\n READY: 'Ready to process requests',\n INITIALIZING: 'Initializing...',\n} as const;"],"names":[],"mappings":"AAGO,MAAM,iBAAiB;AAAA,EAC5B,mBAAmB;AAAA,EACnB,cAAc;AAIhB;"}