@hashgraphonline/standards-agent-kit 0.2.119 → 0.2.121

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.
Files changed (132) hide show
  1. package/dist/cjs/config/ContentReferenceConfig.d.ts +8 -0
  2. package/dist/cjs/index.d.ts +2 -0
  3. package/dist/cjs/standards-agent-kit.cjs +1 -1
  4. package/dist/cjs/standards-agent-kit.cjs.map +1 -1
  5. package/dist/cjs/tools/hcs6/CreateDynamicRegistryTool.d.ts +7 -7
  6. package/dist/cjs/tools/hcs6/QueryDynamicRegistryTool.d.ts +3 -3
  7. package/dist/cjs/tools/hcs6/RegisterDynamicHashinalTool.d.ts +7 -7
  8. package/dist/cjs/tools/hcs6/UpdateDynamicHashinalTool.d.ts +7 -7
  9. package/dist/cjs/tools/inscriber/InscribeFromBufferTool.d.ts +7 -6
  10. package/dist/cjs/tools/inscriber/base-inscriber-tools.d.ts +11 -0
  11. package/dist/cjs/tools/inscriber/inscriber-tool-params.d.ts +3 -0
  12. package/dist/cjs/types/content-resolver.d.ts +6 -0
  13. package/dist/es/config/ContentReferenceConfig.d.ts +8 -0
  14. package/dist/es/index.d.ts +2 -0
  15. package/dist/es/standards-agent-kit.es.js +42 -40
  16. package/dist/es/standards-agent-kit.es.js.map +1 -1
  17. package/dist/es/standards-agent-kit.es10.js +72 -23
  18. package/dist/es/standards-agent-kit.es10.js.map +1 -1
  19. package/dist/es/standards-agent-kit.es11.js +27 -27
  20. package/dist/es/standards-agent-kit.es11.js.map +1 -1
  21. package/dist/es/standards-agent-kit.es12.js +20 -30
  22. package/dist/es/standards-agent-kit.es12.js.map +1 -1
  23. package/dist/es/standards-agent-kit.es13.js +27 -37
  24. package/dist/es/standards-agent-kit.es13.js.map +1 -1
  25. package/dist/es/standards-agent-kit.es14.js +48 -60
  26. package/dist/es/standards-agent-kit.es14.js.map +1 -1
  27. package/dist/es/standards-agent-kit.es15.js +60 -23
  28. package/dist/es/standards-agent-kit.es15.js.map +1 -1
  29. package/dist/es/standards-agent-kit.es16.js +23 -23
  30. package/dist/es/standards-agent-kit.es16.js.map +1 -1
  31. package/dist/es/standards-agent-kit.es17.js +23 -33
  32. package/dist/es/standards-agent-kit.es17.js.map +1 -1
  33. package/dist/es/standards-agent-kit.es18.js +34 -10
  34. package/dist/es/standards-agent-kit.es18.js.map +1 -1
  35. package/dist/es/standards-agent-kit.es19.js +16 -155
  36. package/dist/es/standards-agent-kit.es19.js.map +1 -1
  37. package/dist/es/standards-agent-kit.es2.js +21 -1567
  38. package/dist/es/standards-agent-kit.es2.js.map +1 -1
  39. package/dist/es/standards-agent-kit.es20.js +150 -22
  40. package/dist/es/standards-agent-kit.es20.js.map +1 -1
  41. package/dist/es/standards-agent-kit.es21.js +25 -39
  42. package/dist/es/standards-agent-kit.es21.js.map +1 -1
  43. package/dist/es/standards-agent-kit.es22.js +26 -28
  44. package/dist/es/standards-agent-kit.es22.js.map +1 -1
  45. package/dist/es/standards-agent-kit.es23.js +16 -19
  46. package/dist/es/standards-agent-kit.es23.js.map +1 -1
  47. package/dist/es/standards-agent-kit.es24.js +21 -15
  48. package/dist/es/standards-agent-kit.es24.js.map +1 -1
  49. package/dist/es/standards-agent-kit.es25.js +18 -21
  50. package/dist/es/standards-agent-kit.es25.js.map +1 -1
  51. package/dist/es/standards-agent-kit.es26.js +35 -32
  52. package/dist/es/standards-agent-kit.es26.js.map +1 -1
  53. package/dist/es/standards-agent-kit.es27.js +38 -25
  54. package/dist/es/standards-agent-kit.es27.js.map +1 -1
  55. package/dist/es/standards-agent-kit.es28.js +24 -37
  56. package/dist/es/standards-agent-kit.es28.js.map +1 -1
  57. package/dist/es/standards-agent-kit.es29.js +26 -43
  58. package/dist/es/standards-agent-kit.es29.js.map +1 -1
  59. package/dist/es/standards-agent-kit.es3.js +1532 -55
  60. package/dist/es/standards-agent-kit.es3.js.map +1 -1
  61. package/dist/es/standards-agent-kit.es30.js +35 -40
  62. package/dist/es/standards-agent-kit.es30.js.map +1 -1
  63. package/dist/es/standards-agent-kit.es31.js +35 -39
  64. package/dist/es/standards-agent-kit.es31.js.map +1 -1
  65. package/dist/es/standards-agent-kit.es32.js +39 -23
  66. package/dist/es/standards-agent-kit.es32.js.map +1 -1
  67. package/dist/es/standards-agent-kit.es33.js +39 -168
  68. package/dist/es/standards-agent-kit.es33.js.map +1 -1
  69. package/dist/es/standards-agent-kit.es34.js +93 -96
  70. package/dist/es/standards-agent-kit.es34.js.map +1 -1
  71. package/dist/es/standards-agent-kit.es35.js +99 -64
  72. package/dist/es/standards-agent-kit.es35.js.map +1 -1
  73. package/dist/es/standards-agent-kit.es36.js +166 -64
  74. package/dist/es/standards-agent-kit.es36.js.map +1 -1
  75. package/dist/es/standards-agent-kit.es37.js +87 -30
  76. package/dist/es/standards-agent-kit.es37.js.map +1 -1
  77. package/dist/es/standards-agent-kit.es38.js +38 -242
  78. package/dist/es/standards-agent-kit.es38.js.map +1 -1
  79. package/dist/es/standards-agent-kit.es39.js +246 -138
  80. package/dist/es/standards-agent-kit.es39.js.map +1 -1
  81. package/dist/es/standards-agent-kit.es4.js +39 -33
  82. package/dist/es/standards-agent-kit.es4.js.map +1 -1
  83. package/dist/es/standards-agent-kit.es40.js +134 -26
  84. package/dist/es/standards-agent-kit.es40.js.map +1 -1
  85. package/dist/es/standards-agent-kit.es41.js +27 -22
  86. package/dist/es/standards-agent-kit.es41.js.map +1 -1
  87. package/dist/es/standards-agent-kit.es42.js +24 -3
  88. package/dist/es/standards-agent-kit.es42.js.map +1 -1
  89. package/dist/es/standards-agent-kit.es43.js +7 -0
  90. package/dist/es/standards-agent-kit.es43.js.map +1 -0
  91. package/dist/es/standards-agent-kit.es5.js +65 -32
  92. package/dist/es/standards-agent-kit.es5.js.map +1 -1
  93. package/dist/es/standards-agent-kit.es6.js +35 -311
  94. package/dist/es/standards-agent-kit.es6.js.map +1 -1
  95. package/dist/es/standards-agent-kit.es7.js +320 -20
  96. package/dist/es/standards-agent-kit.es7.js.map +1 -1
  97. package/dist/es/standards-agent-kit.es8.js +19 -227
  98. package/dist/es/standards-agent-kit.es8.js.map +1 -1
  99. package/dist/es/standards-agent-kit.es9.js +216 -65
  100. package/dist/es/standards-agent-kit.es9.js.map +1 -1
  101. package/dist/es/tools/hcs6/CreateDynamicRegistryTool.d.ts +7 -7
  102. package/dist/es/tools/hcs6/QueryDynamicRegistryTool.d.ts +3 -3
  103. package/dist/es/tools/hcs6/RegisterDynamicHashinalTool.d.ts +7 -7
  104. package/dist/es/tools/hcs6/UpdateDynamicHashinalTool.d.ts +7 -7
  105. package/dist/es/tools/inscriber/InscribeFromBufferTool.d.ts +7 -6
  106. package/dist/es/tools/inscriber/base-inscriber-tools.d.ts +11 -0
  107. package/dist/es/tools/inscriber/inscriber-tool-params.d.ts +3 -0
  108. package/dist/es/types/content-resolver.d.ts +6 -0
  109. package/dist/umd/config/ContentReferenceConfig.d.ts +8 -0
  110. package/dist/umd/index.d.ts +2 -0
  111. package/dist/umd/standards-agent-kit.umd.js +1 -1
  112. package/dist/umd/standards-agent-kit.umd.js.map +1 -1
  113. package/dist/umd/tools/hcs6/CreateDynamicRegistryTool.d.ts +7 -7
  114. package/dist/umd/tools/hcs6/QueryDynamicRegistryTool.d.ts +3 -3
  115. package/dist/umd/tools/hcs6/RegisterDynamicHashinalTool.d.ts +7 -7
  116. package/dist/umd/tools/hcs6/UpdateDynamicHashinalTool.d.ts +7 -7
  117. package/dist/umd/tools/inscriber/InscribeFromBufferTool.d.ts +7 -6
  118. package/dist/umd/tools/inscriber/base-inscriber-tools.d.ts +11 -0
  119. package/dist/umd/tools/inscriber/inscriber-tool-params.d.ts +3 -0
  120. package/dist/umd/types/content-resolver.d.ts +6 -0
  121. package/package.json +2 -2
  122. package/src/builders/hcs10/hcs10-builder.ts +2 -3
  123. package/src/config/ContentReferenceConfig.ts +30 -0
  124. package/src/index.ts +3 -1
  125. package/src/tools/hcs6/CreateDynamicRegistryTool.ts +22 -33
  126. package/src/tools/hcs6/QueryDynamicRegistryTool.ts +23 -33
  127. package/src/tools/hcs6/RegisterDynamicHashinalTool.ts +25 -35
  128. package/src/tools/hcs6/UpdateDynamicHashinalTool.ts +25 -36
  129. package/src/tools/inscriber/InscribeFromBufferTool.ts +239 -120
  130. package/src/tools/inscriber/base-inscriber-tools.ts +19 -0
  131. package/src/tools/inscriber/inscriber-tool-params.ts +3 -0
  132. package/src/types/content-resolver.ts +11 -0
@@ -1,18 +1,21 @@
1
1
  import { z } from 'zod';
2
2
  import { BaseInscriberQueryTool } from './base-inscriber-tools';
3
- import { InscriptionOptions } from '@hashgraphonline/standards-sdk';
3
+ import { InscriptionOptions, ContentResolverRegistry } from '@hashgraphonline/standards-sdk';
4
4
  import { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';
5
+ import { loadConfig } from '../../config/ContentReferenceConfig';
5
6
 
6
- /**
7
- * Schema for inscribing from buffer
8
- */
9
7
  const inscribeFromBufferSchema = z.object({
10
- base64Data: z.string().min(1, 'Data cannot be empty').describe('The FULL content to inscribe as plain text or base64. When asked to "inscribe it" after retrieving content, pass ALL the content you retrieved here as plain text - NOT a summary, NOT URLs, NOT truncated. Example: if you fetched Wikipedia articles, pass the complete article text you received.'),
11
- fileName: z.string().min(1, 'File name cannot be empty').describe('Name for the inscribed content. Required for all inscriptions.'),
12
- mimeType: z
8
+ base64Data: z
13
9
  .string()
14
- .optional()
15
- .describe('MIME type of the content'),
10
+ .min(1, 'Data cannot be empty')
11
+ .describe(
12
+ 'The content to inscribe. Accept BOTH plain text AND base64. Also accepts content reference IDs in format "content-ref:[id]". When user says "inscribe it" or "inscribe the content", use the EXACT content from your previous message or from MCP tool results. DO NOT generate new content. DO NOT create repetitive text. Pass the actual search results or other retrieved content EXACTLY as you received it.'
13
+ ),
14
+ fileName: z
15
+ .string()
16
+ .min(1, 'File name cannot be empty')
17
+ .describe('Name for the inscribed content. Required for all inscriptions.'),
18
+ mimeType: z.string().optional().describe('MIME type of the content'),
16
19
  mode: z
17
20
  .enum(['file', 'hashinal'])
18
21
  .optional()
@@ -40,20 +43,20 @@ const inscribeFromBufferSchema = z.object({
40
43
  .int()
41
44
  .positive()
42
45
  .optional()
43
- .describe('Timeout in milliseconds for inscription (default: no timeout - waits until completion)'),
44
- apiKey: z
45
- .string()
46
- .optional()
47
- .describe('API key for inscription service'),
46
+ .describe(
47
+ 'Timeout in milliseconds for inscription (default: no timeout - waits until completion)'
48
+ ),
49
+ apiKey: z.string().optional().describe('API key for inscription service'),
48
50
  });
49
51
 
50
-
51
- /**
52
- * Tool for inscribing content from buffer
53
- */
54
- export class InscribeFromBufferTool extends BaseInscriberQueryTool<typeof inscribeFromBufferSchema> {
52
+ export class InscribeFromBufferTool extends BaseInscriberQueryTool<
53
+ typeof inscribeFromBufferSchema
54
+ > {
55
55
  name = 'inscribeFromBuffer';
56
- description = 'PRIMARY inscription tool for ANY content you have already retrieved. USE THIS when asked to "inscribe it" after fetching content from MCP tools, search results, or any text data. Pass THE FULL CONTENT as plain text in base64Data field - the tool accepts both plain text and base64. CRITICAL: Pass the COMPLETE content you retrieved, NOT a summary or truncated version. Example: If you fetched Wikipedia articles with full text, pass ALL that text here as plain text.';
56
+ description =
57
+ 'Inscribe content that you have already retrieved or displayed. When user says "inscribe it" after you showed search results or other content, use THIS tool. The base64Data field accepts PLAIN TEXT (not just base64) and content reference IDs in format "content-ref:[id]". Pass the EXACT content from your previous response or MCP tool output. DO NOT generate new content or create repetitive text. Content references are automatically resolved to the original content for inscription.';
58
+
59
+ private config = loadConfig();
57
60
 
58
61
  get specificInputSchema() {
59
62
  return inscribeFromBufferSchema;
@@ -63,129 +66,245 @@ export class InscribeFromBufferTool extends BaseInscriberQueryTool<typeof inscri
63
66
  params: z.infer<typeof inscribeFromBufferSchema>,
64
67
  _runManager?: CallbackManagerForToolRun
65
68
  ): Promise<unknown> {
66
- console.log(`[DEBUG] InscribeFromBufferTool.executeQuery called`);
67
- console.log(`[DEBUG] Buffer tool received base64Data length: ${params.base64Data?.length || 0}`);
68
- console.log(`[DEBUG] Buffer tool fileName: ${params.fileName}`);
69
- console.log(`[DEBUG] Buffer tool mimeType: ${params.mimeType}`);
70
-
69
+ this.validateInput(params);
70
+
71
+ const resolvedContent = await this.resolveContent(
72
+ params.base64Data,
73
+ params.mimeType,
74
+ params.fileName
75
+ );
76
+
77
+ this.validateContent(resolvedContent.buffer);
78
+
79
+ const buffer = resolvedContent.buffer;
80
+ const resolvedMimeType = resolvedContent.mimeType || params.mimeType;
81
+ const resolvedFileName = resolvedContent.fileName || params.fileName;
82
+
83
+ const options: InscriptionOptions = {
84
+ mode: params.mode,
85
+ metadata: params.metadata,
86
+ tags: params.tags,
87
+ chunkSize: params.chunkSize,
88
+ waitForConfirmation: params.waitForConfirmation ?? true,
89
+ waitMaxAttempts: 10,
90
+ waitIntervalMs: 3000,
91
+ apiKey: params.apiKey,
92
+ network: this.inscriberBuilder['hederaKit'].client.network
93
+ .toString()
94
+ .includes('mainnet')
95
+ ? 'mainnet'
96
+ : 'testnet',
97
+ };
98
+
99
+ const timeoutMs =
100
+ params.timeoutMs || (options.waitForConfirmation ? 60000 : undefined);
101
+
102
+ try {
103
+ const result = await this.executeInscription(
104
+ buffer,
105
+ resolvedFileName,
106
+ resolvedMimeType,
107
+ options,
108
+ timeoutMs
109
+ );
110
+ return this.formatInscriptionResult(result, options);
111
+ } catch (error) {
112
+ const errorMessage =
113
+ error instanceof Error
114
+ ? error.message
115
+ : 'Failed to inscribe from buffer';
116
+ throw new Error(`Inscription failed: ${errorMessage}`);
117
+ }
118
+ }
119
+
120
+ private validateInput(
121
+ params: z.infer<typeof inscribeFromBufferSchema>
122
+ ): void {
71
123
  if (!params.base64Data || params.base64Data.trim() === '') {
72
- console.log(`[InscribeFromBufferTool] ERROR: No data provided`);
73
- throw new Error('No data provided. Cannot inscribe empty content. Please provide valid base64 encoded data.');
124
+ throw new Error(
125
+ 'No data provided. Cannot inscribe empty content. Please provide valid content, plain text, base64 encoded data, or a content reference ID.'
126
+ );
74
127
  }
75
128
 
76
129
  if (!params.fileName || params.fileName.trim() === '') {
77
- console.log(`[InscribeFromBufferTool] ERROR: No fileName provided`);
78
- throw new Error('No fileName provided. A valid fileName is required for inscription.');
130
+ throw new Error(
131
+ 'No fileName provided. A valid fileName is required for inscription.'
132
+ );
79
133
  }
134
+ }
80
135
 
81
- let buffer: Buffer;
82
-
83
- // First check if it's valid base64
84
- const isValidBase64 = /^[A-Za-z0-9+/]*={0,2}$/.test(params.base64Data);
85
-
86
- if (isValidBase64) {
87
- // Try to decode as base64
88
- try {
89
- buffer = Buffer.from(params.base64Data, 'base64');
90
- console.log(`[InscribeFromBufferTool] Successfully decoded base64 data`);
91
- } catch (error) {
92
- console.log(`[InscribeFromBufferTool] ERROR: Failed to decode base64`);
93
- throw new Error('Failed to decode base64 data. Please ensure the data is properly encoded.');
94
- }
95
- } else {
96
- // Not base64, treat as plain text and encode it
97
- console.log(`[InscribeFromBufferTool] WARNING: Data is not base64 encoded, treating as plain text`);
98
- buffer = Buffer.from(params.base64Data, 'utf8');
99
- console.log(`[InscribeFromBufferTool] Converted plain text to buffer`);
100
- }
101
-
102
- console.log(`[InscribeFromBufferTool] Buffer length after conversion: ${buffer.length}`);
103
-
136
+ private validateContent(buffer: Buffer): void {
104
137
  if (buffer.length === 0) {
105
- console.log(`[InscribeFromBufferTool] ERROR: Buffer is empty after conversion`);
106
- throw new Error('Buffer is empty after conversion. The provided data appears to be invalid or empty.');
138
+ throw new Error(
139
+ 'Buffer is empty after conversion. The provided data appears to be invalid or empty.'
140
+ );
107
141
  }
108
142
 
109
- if (buffer.length < 10) {
110
- console.log(`[InscribeFromBufferTool] WARNING: Buffer is very small (${buffer.length} bytes)`);
111
- console.log(`[InscribeFromBufferTool] Buffer content preview: ${buffer.toString('utf8', 0, Math.min(buffer.length, 50))}`);
112
- throw new Error(`Buffer content is too small (${buffer.length} bytes). This may indicate empty or invalid content. Please verify the source data contains actual content.`);
143
+ if (buffer.length > this.config.maxInscriptionSize) {
144
+ const maxSizeKB = Math.round(this.config.maxInscriptionSize / 1024);
145
+ const bufferSizeKB = Math.round(buffer.length / 1024);
146
+ throw new Error(
147
+ `Content is too large for inscription (${bufferSizeKB}KB, max ${maxSizeKB}KB). Please summarize or extract key information before inscribing.`
148
+ );
113
149
  }
114
150
 
115
- if (buffer.toString('utf8', 0, Math.min(buffer.length, 100)).trim() === '') {
116
- console.log(`[InscribeFromBufferTool] ERROR: Buffer contains only whitespace or empty content`);
117
- throw new Error('Buffer contains only whitespace or empty content. Cannot inscribe meaningless data.');
151
+ if (buffer.length < this.config.minContentSize) {
152
+ throw new Error(
153
+ `Buffer content is too small (${buffer.length} bytes). This may indicate empty or invalid content. Please verify the source data contains actual content.`
154
+ );
155
+ }
156
+
157
+ if (
158
+ buffer.toString('utf8', 0, Math.min(buffer.length, 100)).trim() === ''
159
+ ) {
160
+ throw new Error(
161
+ 'Buffer contains only whitespace or empty content. Cannot inscribe meaningless data.'
162
+ );
118
163
  }
119
164
 
120
- // Check for empty HTML pattern (just links with no content)
121
165
  const contentStr = buffer.toString('utf8');
122
166
  const emptyHtmlPattern = /<a\s+href=["'][^"']+["']\s*>\s*<\/a>/i;
123
- const hasOnlyEmptyLinks = emptyHtmlPattern.test(contentStr) &&
124
- contentStr.replace(/<[^>]+>/g, '').trim().length < 50;
125
-
167
+ const hasOnlyEmptyLinks =
168
+ emptyHtmlPattern.test(contentStr) &&
169
+ contentStr.replace(/<[^>]+>/g, '').trim().length < 50;
170
+
126
171
  if (hasOnlyEmptyLinks) {
127
- console.log(`[InscribeFromBufferTool] ERROR: Buffer contains empty HTML with just links and no content`);
128
- throw new Error('Buffer contains empty HTML with only links and no actual content. When inscribing content from external sources, use the actual article text you retrieved, not empty HTML with links.');
172
+ throw new Error(
173
+ 'Buffer contains empty HTML with only links and no actual content. When inscribing content from external sources, use the actual article text you retrieved, not empty HTML with links.'
174
+ );
129
175
  }
176
+ }
130
177
 
131
- const options: InscriptionOptions = {
132
- mode: params.mode,
133
- metadata: params.metadata,
134
- tags: params.tags,
135
- chunkSize: params.chunkSize,
136
- waitForConfirmation: params.waitForConfirmation ?? true,
137
- waitMaxAttempts: 10,
138
- waitIntervalMs: 3000,
139
- apiKey: params.apiKey,
140
- network: this.inscriberBuilder['hederaKit'].client.network.toString().includes('mainnet') ? 'mainnet' : 'testnet',
178
+ private async executeInscription(
179
+ buffer: Buffer,
180
+ fileName: string,
181
+ mimeType: string | undefined,
182
+ options: InscriptionOptions,
183
+ timeoutMs?: number
184
+ ): Promise<Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>> {
185
+ const inscriptionData = {
186
+ type: 'buffer' as const,
187
+ buffer,
188
+ fileName,
189
+ mimeType,
141
190
  };
142
191
 
143
- try {
144
- let result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>;
145
-
146
- if (params.timeoutMs) {
147
- const timeoutPromise = new Promise<never>((_, reject) => {
148
- setTimeout(
149
- () => reject(new Error(`Inscription timed out after ${params.timeoutMs}ms`)),
150
- params.timeoutMs
151
- );
152
- });
153
-
154
- result = await Promise.race([
155
- this.inscriberBuilder.inscribe(
156
- {
157
- type: 'buffer',
158
- buffer,
159
- fileName: params.fileName,
160
- mimeType: params.mimeType,
161
- },
162
- options
163
- ),
164
- timeoutPromise,
165
- ]);
166
- } else {
167
- result = await this.inscriberBuilder.inscribe(
168
- {
169
- type: 'buffer',
170
- buffer,
171
- fileName: params.fileName,
172
- mimeType: params.mimeType,
173
- },
174
- options
192
+ if (timeoutMs) {
193
+ const timeoutPromise = new Promise<never>((_, reject) => {
194
+ setTimeout(
195
+ () => reject(new Error(`Inscription timed out after ${timeoutMs}ms`)),
196
+ timeoutMs
175
197
  );
198
+ });
199
+
200
+ return Promise.race([
201
+ this.inscriberBuilder.inscribe(inscriptionData, options),
202
+ timeoutPromise,
203
+ ]);
204
+ }
205
+
206
+ return this.inscriberBuilder.inscribe(inscriptionData, options);
207
+ }
208
+
209
+ private formatInscriptionResult(
210
+ result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>,
211
+ options: InscriptionOptions
212
+ ): string {
213
+ if (result.confirmed) {
214
+ const topicId = result.inscription?.topic_id || result.result.topicId;
215
+ const network = options.network || 'testnet';
216
+ const cdnUrl = topicId
217
+ ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}`
218
+ : null;
219
+ return `Successfully inscribed and confirmed content on the Hedera network!\n\nTransaction ID: ${
220
+ result.result.transactionId
221
+ }\nTopic ID: ${topicId || 'N/A'}${
222
+ cdnUrl ? `\nView inscription: ${cdnUrl}` : ''
223
+ }\n\nThe inscription is now available.`;
224
+ }
225
+
226
+ return `Successfully submitted inscription to the Hedera network!\n\nTransaction ID: ${result.result.transactionId}\n\nThe inscription is processing and will be confirmed shortly.`;
227
+ }
228
+
229
+ private async resolveContent(
230
+ input: string,
231
+ providedMimeType?: string,
232
+ providedFileName?: string
233
+ ): Promise<{
234
+ buffer: Buffer;
235
+ mimeType?: string;
236
+ fileName?: string;
237
+ wasReference?: boolean;
238
+ }> {
239
+ const trimmedInput = input.trim();
240
+
241
+ // Try to get resolver from either injected dependency or registry
242
+ const resolver = this.getContentResolver() || ContentResolverRegistry.getResolver();
243
+
244
+ if (!resolver) {
245
+ // No resolver available, handle content directly
246
+ return this.handleDirectContent(trimmedInput, providedMimeType, providedFileName);
247
+ }
248
+
249
+ const referenceId = resolver.extractReferenceId(trimmedInput);
250
+
251
+ if (referenceId) {
252
+ try {
253
+ const resolution = await resolver.resolveReference(referenceId);
254
+
255
+ return {
256
+ buffer: resolution.content,
257
+ mimeType: resolution.metadata?.mimeType || providedMimeType,
258
+ fileName: resolution.metadata?.fileName || providedFileName,
259
+ wasReference: true,
260
+ };
261
+ } catch (error) {
262
+ const errorMsg =
263
+ error instanceof Error
264
+ ? error.message
265
+ : 'Unknown error resolving reference';
266
+ throw new Error(`Reference resolution failed: ${errorMsg}`);
176
267
  }
268
+ }
269
+
270
+ // No reference found, handle as direct content
271
+ return this.handleDirectContent(trimmedInput, providedMimeType, providedFileName);
272
+ }
273
+
274
+ private handleDirectContent(
275
+ input: string,
276
+ providedMimeType?: string,
277
+ providedFileName?: string
278
+ ): {
279
+ buffer: Buffer;
280
+ mimeType?: string;
281
+ fileName?: string;
282
+ wasReference?: boolean;
283
+ } {
284
+ const isValidBase64 = /^[A-Za-z0-9+/]*={0,2}$/.test(input);
177
285
 
178
- if (result.confirmed) {
179
- const topicId = result.inscription?.topic_id || result.result.topicId;
180
- const network = options.network || 'testnet';
181
- const cdnUrl = topicId ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}` : null;
182
- return `Successfully inscribed and confirmed content on the Hedera network!\n\nTransaction ID: ${result.result.transactionId}\nTopic ID: ${topicId || 'N/A'}${cdnUrl ? `\nView inscription: ${cdnUrl}` : ''}\n\nThe inscription is now available.`;
183
- } else {
184
- return `Successfully submitted inscription to the Hedera network!\n\nTransaction ID: ${result.result.transactionId}\n\nThe inscription is processing and will be confirmed shortly.`;
286
+ if (isValidBase64) {
287
+ try {
288
+ const buffer = Buffer.from(input, 'base64');
289
+ return {
290
+ buffer,
291
+ mimeType: providedMimeType,
292
+ fileName: providedFileName,
293
+ wasReference: false,
294
+ };
295
+ } catch (error) {
296
+ throw new Error(
297
+ 'Failed to decode base64 data. Please ensure the data is properly encoded.'
298
+ );
185
299
  }
186
- } catch (error) {
187
- const errorMessage = error instanceof Error ? error.message : 'Failed to inscribe from buffer';
188
- throw new Error(`Inscription failed: ${errorMessage}`);
189
300
  }
301
+
302
+ const buffer = Buffer.from(input, 'utf8');
303
+ return {
304
+ buffer,
305
+ mimeType: providedMimeType || 'text/plain',
306
+ fileName: providedFileName,
307
+ wasReference: false,
308
+ };
190
309
  }
191
- }
310
+ }
@@ -8,6 +8,7 @@ import {
8
8
  InscriberTransactionToolParams,
9
9
  InscriberQueryToolParams,
10
10
  } from './inscriber-tool-params';
11
+ import type { ContentResolverInterface } from '../../types/content-resolver';
11
12
  import { z } from 'zod';
12
13
 
13
14
  /**
@@ -21,11 +22,13 @@ export abstract class BaseInscriberTransactionTool<
21
22
  > = z.ZodObject<z.ZodRawShape>
22
23
  > extends BaseHederaTransactionTool<T> {
23
24
  protected inscriberBuilder: InscriberBuilder;
25
+ protected contentResolver: ContentResolverInterface | null;
24
26
  namespace = 'inscriber' as const;
25
27
 
26
28
  constructor(params: InscriberTransactionToolParams) {
27
29
  super(params);
28
30
  this.inscriberBuilder = params.inscriberBuilder;
31
+ this.contentResolver = params.contentResolver || null;
29
32
  }
30
33
 
31
34
  /**
@@ -34,6 +37,13 @@ export abstract class BaseInscriberTransactionTool<
34
37
  protected getServiceBuilder(): BaseServiceBuilder {
35
38
  return this.inscriberBuilder;
36
39
  }
40
+
41
+ /**
42
+ * Get content resolver with fallback to registry
43
+ */
44
+ protected getContentResolver(): ContentResolverInterface | null {
45
+ return this.contentResolver;
46
+ }
37
47
  }
38
48
 
39
49
  /**
@@ -47,11 +57,13 @@ export abstract class BaseInscriberQueryTool<
47
57
  > = z.ZodObject<z.ZodRawShape>
48
58
  > extends BaseHederaQueryTool<T> {
49
59
  protected inscriberBuilder: InscriberBuilder;
60
+ protected contentResolver: ContentResolverInterface | null;
50
61
  namespace = 'inscriber' as const;
51
62
 
52
63
  constructor(params: InscriberQueryToolParams) {
53
64
  super(params);
54
65
  this.inscriberBuilder = params.inscriberBuilder;
66
+ this.contentResolver = params.contentResolver || null;
55
67
  }
56
68
 
57
69
  /**
@@ -60,4 +72,11 @@ export abstract class BaseInscriberQueryTool<
60
72
  protected getServiceBuilder(): BaseServiceBuilder {
61
73
  return this.inscriberBuilder;
62
74
  }
75
+
76
+ /**
77
+ * Get content resolver with fallback to registry
78
+ */
79
+ protected getContentResolver(): ContentResolverInterface | null {
80
+ return this.contentResolver;
81
+ }
63
82
  }
@@ -1,6 +1,7 @@
1
1
  import { HederaAgentKit } from 'hedera-agent-kit';
2
2
  import type { BasePluginContext } from 'hedera-agent-kit';
3
3
  import { InscriberBuilder } from '../../builders/inscriber/inscriber-builder';
4
+ import type { ContentResolverInterface } from '../../types/content-resolver';
4
5
 
5
6
  /**
6
7
  * Parameters for Inscriber transaction tools
@@ -9,6 +10,7 @@ export interface InscriberTransactionToolParams {
9
10
  hederaKit: HederaAgentKit;
10
11
  inscriberBuilder: InscriberBuilder;
11
12
  logger?: BasePluginContext['logger'];
13
+ contentResolver?: ContentResolverInterface;
12
14
  }
13
15
 
14
16
  /**
@@ -18,4 +20,5 @@ export interface InscriberQueryToolParams {
18
20
  hederaKit: HederaAgentKit;
19
21
  inscriberBuilder: InscriberBuilder;
20
22
  logger?: BasePluginContext['logger'];
23
+ contentResolver?: ContentResolverInterface;
21
24
  }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Content Resolver Types
3
+ *
4
+ * Re-export types from standards-sdk for content resolution.
5
+ */
6
+
7
+ export type {
8
+ ContentResolverInterface,
9
+ ReferenceResolutionResult,
10
+ ContentStoreInterface
11
+ } from '@hashgraphonline/standards-sdk';