@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.
- package/dist/cjs/config/ContentReferenceConfig.d.ts +8 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/standards-agent-kit.cjs +1 -1
- package/dist/cjs/standards-agent-kit.cjs.map +1 -1
- package/dist/cjs/tools/hcs6/CreateDynamicRegistryTool.d.ts +7 -7
- package/dist/cjs/tools/hcs6/QueryDynamicRegistryTool.d.ts +3 -3
- package/dist/cjs/tools/hcs6/RegisterDynamicHashinalTool.d.ts +7 -7
- package/dist/cjs/tools/hcs6/UpdateDynamicHashinalTool.d.ts +7 -7
- package/dist/cjs/tools/inscriber/InscribeFromBufferTool.d.ts +7 -6
- package/dist/cjs/tools/inscriber/base-inscriber-tools.d.ts +11 -0
- package/dist/cjs/tools/inscriber/inscriber-tool-params.d.ts +3 -0
- package/dist/cjs/types/content-resolver.d.ts +6 -0
- package/dist/es/config/ContentReferenceConfig.d.ts +8 -0
- package/dist/es/index.d.ts +2 -0
- package/dist/es/standards-agent-kit.es.js +42 -40
- package/dist/es/standards-agent-kit.es.js.map +1 -1
- package/dist/es/standards-agent-kit.es10.js +72 -23
- package/dist/es/standards-agent-kit.es10.js.map +1 -1
- package/dist/es/standards-agent-kit.es11.js +27 -27
- package/dist/es/standards-agent-kit.es11.js.map +1 -1
- package/dist/es/standards-agent-kit.es12.js +20 -30
- package/dist/es/standards-agent-kit.es12.js.map +1 -1
- package/dist/es/standards-agent-kit.es13.js +27 -37
- package/dist/es/standards-agent-kit.es13.js.map +1 -1
- package/dist/es/standards-agent-kit.es14.js +48 -60
- package/dist/es/standards-agent-kit.es14.js.map +1 -1
- package/dist/es/standards-agent-kit.es15.js +60 -23
- package/dist/es/standards-agent-kit.es15.js.map +1 -1
- package/dist/es/standards-agent-kit.es16.js +23 -23
- package/dist/es/standards-agent-kit.es16.js.map +1 -1
- package/dist/es/standards-agent-kit.es17.js +23 -33
- package/dist/es/standards-agent-kit.es17.js.map +1 -1
- package/dist/es/standards-agent-kit.es18.js +34 -10
- package/dist/es/standards-agent-kit.es18.js.map +1 -1
- package/dist/es/standards-agent-kit.es19.js +16 -155
- package/dist/es/standards-agent-kit.es19.js.map +1 -1
- package/dist/es/standards-agent-kit.es2.js +21 -1567
- package/dist/es/standards-agent-kit.es2.js.map +1 -1
- package/dist/es/standards-agent-kit.es20.js +150 -22
- package/dist/es/standards-agent-kit.es20.js.map +1 -1
- package/dist/es/standards-agent-kit.es21.js +25 -39
- package/dist/es/standards-agent-kit.es21.js.map +1 -1
- package/dist/es/standards-agent-kit.es22.js +26 -28
- package/dist/es/standards-agent-kit.es22.js.map +1 -1
- package/dist/es/standards-agent-kit.es23.js +16 -19
- package/dist/es/standards-agent-kit.es23.js.map +1 -1
- package/dist/es/standards-agent-kit.es24.js +21 -15
- package/dist/es/standards-agent-kit.es24.js.map +1 -1
- package/dist/es/standards-agent-kit.es25.js +18 -21
- package/dist/es/standards-agent-kit.es25.js.map +1 -1
- package/dist/es/standards-agent-kit.es26.js +35 -32
- package/dist/es/standards-agent-kit.es26.js.map +1 -1
- package/dist/es/standards-agent-kit.es27.js +38 -25
- package/dist/es/standards-agent-kit.es27.js.map +1 -1
- package/dist/es/standards-agent-kit.es28.js +24 -37
- package/dist/es/standards-agent-kit.es28.js.map +1 -1
- package/dist/es/standards-agent-kit.es29.js +26 -43
- package/dist/es/standards-agent-kit.es29.js.map +1 -1
- package/dist/es/standards-agent-kit.es3.js +1532 -55
- package/dist/es/standards-agent-kit.es3.js.map +1 -1
- package/dist/es/standards-agent-kit.es30.js +35 -40
- package/dist/es/standards-agent-kit.es30.js.map +1 -1
- package/dist/es/standards-agent-kit.es31.js +35 -39
- package/dist/es/standards-agent-kit.es31.js.map +1 -1
- package/dist/es/standards-agent-kit.es32.js +39 -23
- package/dist/es/standards-agent-kit.es32.js.map +1 -1
- package/dist/es/standards-agent-kit.es33.js +39 -168
- package/dist/es/standards-agent-kit.es33.js.map +1 -1
- package/dist/es/standards-agent-kit.es34.js +93 -96
- package/dist/es/standards-agent-kit.es34.js.map +1 -1
- package/dist/es/standards-agent-kit.es35.js +99 -64
- package/dist/es/standards-agent-kit.es35.js.map +1 -1
- package/dist/es/standards-agent-kit.es36.js +166 -64
- package/dist/es/standards-agent-kit.es36.js.map +1 -1
- package/dist/es/standards-agent-kit.es37.js +87 -30
- package/dist/es/standards-agent-kit.es37.js.map +1 -1
- package/dist/es/standards-agent-kit.es38.js +38 -242
- package/dist/es/standards-agent-kit.es38.js.map +1 -1
- package/dist/es/standards-agent-kit.es39.js +246 -138
- package/dist/es/standards-agent-kit.es39.js.map +1 -1
- package/dist/es/standards-agent-kit.es4.js +39 -33
- package/dist/es/standards-agent-kit.es4.js.map +1 -1
- package/dist/es/standards-agent-kit.es40.js +134 -26
- package/dist/es/standards-agent-kit.es40.js.map +1 -1
- package/dist/es/standards-agent-kit.es41.js +27 -22
- package/dist/es/standards-agent-kit.es41.js.map +1 -1
- package/dist/es/standards-agent-kit.es42.js +24 -3
- package/dist/es/standards-agent-kit.es42.js.map +1 -1
- package/dist/es/standards-agent-kit.es43.js +7 -0
- package/dist/es/standards-agent-kit.es43.js.map +1 -0
- package/dist/es/standards-agent-kit.es5.js +65 -32
- package/dist/es/standards-agent-kit.es5.js.map +1 -1
- package/dist/es/standards-agent-kit.es6.js +35 -311
- package/dist/es/standards-agent-kit.es6.js.map +1 -1
- package/dist/es/standards-agent-kit.es7.js +320 -20
- package/dist/es/standards-agent-kit.es7.js.map +1 -1
- package/dist/es/standards-agent-kit.es8.js +19 -227
- package/dist/es/standards-agent-kit.es8.js.map +1 -1
- package/dist/es/standards-agent-kit.es9.js +216 -65
- package/dist/es/standards-agent-kit.es9.js.map +1 -1
- package/dist/es/tools/hcs6/CreateDynamicRegistryTool.d.ts +7 -7
- package/dist/es/tools/hcs6/QueryDynamicRegistryTool.d.ts +3 -3
- package/dist/es/tools/hcs6/RegisterDynamicHashinalTool.d.ts +7 -7
- package/dist/es/tools/hcs6/UpdateDynamicHashinalTool.d.ts +7 -7
- package/dist/es/tools/inscriber/InscribeFromBufferTool.d.ts +7 -6
- package/dist/es/tools/inscriber/base-inscriber-tools.d.ts +11 -0
- package/dist/es/tools/inscriber/inscriber-tool-params.d.ts +3 -0
- package/dist/es/types/content-resolver.d.ts +6 -0
- package/dist/umd/config/ContentReferenceConfig.d.ts +8 -0
- package/dist/umd/index.d.ts +2 -0
- package/dist/umd/standards-agent-kit.umd.js +1 -1
- package/dist/umd/standards-agent-kit.umd.js.map +1 -1
- package/dist/umd/tools/hcs6/CreateDynamicRegistryTool.d.ts +7 -7
- package/dist/umd/tools/hcs6/QueryDynamicRegistryTool.d.ts +3 -3
- package/dist/umd/tools/hcs6/RegisterDynamicHashinalTool.d.ts +7 -7
- package/dist/umd/tools/hcs6/UpdateDynamicHashinalTool.d.ts +7 -7
- package/dist/umd/tools/inscriber/InscribeFromBufferTool.d.ts +7 -6
- package/dist/umd/tools/inscriber/base-inscriber-tools.d.ts +11 -0
- package/dist/umd/tools/inscriber/inscriber-tool-params.d.ts +3 -0
- package/dist/umd/types/content-resolver.d.ts +6 -0
- package/package.json +2 -2
- package/src/builders/hcs10/hcs10-builder.ts +2 -3
- package/src/config/ContentReferenceConfig.ts +30 -0
- package/src/index.ts +3 -1
- package/src/tools/hcs6/CreateDynamicRegistryTool.ts +22 -33
- package/src/tools/hcs6/QueryDynamicRegistryTool.ts +23 -33
- package/src/tools/hcs6/RegisterDynamicHashinalTool.ts +25 -35
- package/src/tools/hcs6/UpdateDynamicHashinalTool.ts +25 -36
- package/src/tools/inscriber/InscribeFromBufferTool.ts +239 -120
- package/src/tools/inscriber/base-inscriber-tools.ts +19 -0
- package/src/tools/inscriber/inscriber-tool-params.ts +3 -0
- 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
|
|
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
|
-
.
|
|
15
|
-
.describe(
|
|
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(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
73
|
-
|
|
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
|
-
|
|
78
|
-
|
|
130
|
+
throw new Error(
|
|
131
|
+
'No fileName provided. A valid fileName is required for inscription.'
|
|
132
|
+
);
|
|
79
133
|
}
|
|
134
|
+
}
|
|
80
135
|
|
|
81
|
-
|
|
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
|
-
|
|
106
|
-
|
|
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
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
throw new Error(
|
|
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.
|
|
116
|
-
|
|
117
|
-
|
|
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 =
|
|
124
|
-
|
|
125
|
-
|
|
167
|
+
const hasOnlyEmptyLinks =
|
|
168
|
+
emptyHtmlPattern.test(contentStr) &&
|
|
169
|
+
contentStr.replace(/<[^>]+>/g, '').trim().length < 50;
|
|
170
|
+
|
|
126
171
|
if (hasOnlyEmptyLinks) {
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
}
|