@hashgraphonline/standards-agent-kit 0.2.124 → 0.2.127
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/standards-agent-kit.cjs +1 -1
- package/dist/cjs/standards-agent-kit.cjs.map +1 -1
- package/dist/es/standards-agent-kit.es34.js +65 -23
- package/dist/es/standards-agent-kit.es34.js.map +1 -1
- package/dist/es/standards-agent-kit.es35.js +1 -1
- package/dist/es/standards-agent-kit.es35.js.map +1 -1
- package/dist/es/standards-agent-kit.es36.js +2 -3
- package/dist/es/standards-agent-kit.es36.js.map +1 -1
- package/dist/es/standards-agent-kit.es37.js +1 -1
- package/dist/es/standards-agent-kit.es37.js.map +1 -1
- package/dist/umd/standards-agent-kit.umd.js +1 -1
- package/dist/umd/standards-agent-kit.umd.js.map +1 -1
- package/package.json +27 -30
- package/src/tools/inscriber/InscribeFromBufferTool.ts +2 -5
- package/src/tools/inscriber/InscribeFromFileTool.ts +1 -1
- package/src/tools/inscriber/InscribeFromUrlTool.ts +148 -66
- package/src/tools/inscriber/InscribeHashinalTool.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hashgraphonline/standards-agent-kit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.127",
|
|
4
4
|
"description": "A modular SDK for building on-chain autonomous agents using Hashgraph Online Standards, including HCS-10 for agent discovery and communication.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/standards-agent-kit.cjs",
|
|
@@ -21,33 +21,6 @@
|
|
|
21
21
|
"LICENSE",
|
|
22
22
|
"README.md"
|
|
23
23
|
],
|
|
24
|
-
"scripts": {
|
|
25
|
-
"clean": "rimraf dist",
|
|
26
|
-
"build:es": "BUILD_FORMAT=es vite build",
|
|
27
|
-
"build:cjs": "BUILD_FORMAT=cjs vite build",
|
|
28
|
-
"build:umd": "BUILD_FORMAT=umd vite build",
|
|
29
|
-
"build": "pnpm run clean && pnpm run build:es && pnpm run build:cjs && pnpm run build:umd",
|
|
30
|
-
"test": "jest",
|
|
31
|
-
"lint": "eslint . --ext .ts",
|
|
32
|
-
"lint:fix": "eslint . --ext .ts --fix",
|
|
33
|
-
"prepare": "pnpm run build",
|
|
34
|
-
"prepublishOnly": "pnpm run build",
|
|
35
|
-
"release": "pnpm publish --access public",
|
|
36
|
-
"release:canary": "pnpm run prepublishOnly && pnpm publish --tag canary --access public",
|
|
37
|
-
"version:canary": "pnpm version prerelease --preid canary --no-git-tag-version",
|
|
38
|
-
"publish:canary": "pnpm run version:canary && pnpm run release:canary",
|
|
39
|
-
"demo:cli": "tsx examples/cli-demo.ts",
|
|
40
|
-
"demo:interactive": "tsx examples/interactive-demo.ts",
|
|
41
|
-
"demo:langchain": "tsx examples/langchain-demo.ts",
|
|
42
|
-
"demo:plugin": "tsx examples/plugin-system-example.ts",
|
|
43
|
-
"demo:plugin:weather": "tsx examples/plugins/weather/index.ts",
|
|
44
|
-
"demo:plugin:defi": "tsx examples/plugins/defi/index.ts",
|
|
45
|
-
"demo:plugin:openconvai": "tsx examples/openconvai-plugin-example.ts",
|
|
46
|
-
"demo:inscription-quotes": "tsx examples/inscription-quote-demo.ts",
|
|
47
|
-
"standards-agent:start": "tsx examples/standards-expert/cli.ts -- start",
|
|
48
|
-
"standards-agent:process-docs": "tsx examples/standards-expert/cli.ts -- process-docs --all-repos",
|
|
49
|
-
"typecheck": "tsc --noEmit"
|
|
50
|
-
},
|
|
51
24
|
"keywords": [
|
|
52
25
|
"hedera",
|
|
53
26
|
"hcs10",
|
|
@@ -128,5 +101,29 @@
|
|
|
128
101
|
"vite-plugin-node-polyfills": "^0.23.0",
|
|
129
102
|
"vite-plugin-string-replace": "^1.1.3"
|
|
130
103
|
},
|
|
131
|
-
"
|
|
132
|
-
|
|
104
|
+
"scripts": {
|
|
105
|
+
"clean": "rimraf dist",
|
|
106
|
+
"build:es": "BUILD_FORMAT=es vite build",
|
|
107
|
+
"build:cjs": "BUILD_FORMAT=cjs vite build",
|
|
108
|
+
"build:umd": "BUILD_FORMAT=umd vite build",
|
|
109
|
+
"build": "pnpm run clean && pnpm run build:es && pnpm run build:cjs && pnpm run build:umd",
|
|
110
|
+
"test": "jest",
|
|
111
|
+
"lint": "eslint . --ext .ts",
|
|
112
|
+
"lint:fix": "eslint . --ext .ts --fix",
|
|
113
|
+
"release": "pnpm publish --access public",
|
|
114
|
+
"release:canary": "pnpm run prepublishOnly && pnpm publish --tag canary --access public",
|
|
115
|
+
"version:canary": "pnpm version prerelease --preid canary --no-git-tag-version",
|
|
116
|
+
"publish:canary": "pnpm run version:canary && pnpm run release:canary",
|
|
117
|
+
"demo:cli": "tsx examples/cli-demo.ts",
|
|
118
|
+
"demo:interactive": "tsx examples/interactive-demo.ts",
|
|
119
|
+
"demo:langchain": "tsx examples/langchain-demo.ts",
|
|
120
|
+
"demo:plugin": "tsx examples/plugin-system-example.ts",
|
|
121
|
+
"demo:plugin:weather": "tsx examples/plugins/weather/index.ts",
|
|
122
|
+
"demo:plugin:defi": "tsx examples/plugins/defi/index.ts",
|
|
123
|
+
"demo:plugin:openconvai": "tsx examples/openconvai-plugin-example.ts",
|
|
124
|
+
"demo:inscription-quotes": "tsx examples/inscription-quote-demo.ts",
|
|
125
|
+
"standards-agent:start": "tsx examples/standards-expert/cli.ts -- start",
|
|
126
|
+
"standards-agent:process-docs": "tsx examples/standards-expert/cli.ts -- process-docs --all-repos",
|
|
127
|
+
"typecheck": "tsc --noEmit"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -126,7 +126,7 @@ export class InscribeFromBufferTool extends BaseInscriberQueryTool<
|
|
|
126
126
|
mimeType: resolvedMimeType,
|
|
127
127
|
sizeBytes: buffer.length,
|
|
128
128
|
},
|
|
129
|
-
message: `Quote
|
|
129
|
+
message: `Estimated Quote for buffer content: ${resolvedFileName} (${(buffer.length / 1024).toFixed(2)} KB)\nTotal cost: ${quote.totalCostHbar} HBAR`,
|
|
130
130
|
};
|
|
131
131
|
} catch (error) {
|
|
132
132
|
const errorMessage =
|
|
@@ -135,16 +135,13 @@ export class InscribeFromBufferTool extends BaseInscriberQueryTool<
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
const timeoutMs =
|
|
139
|
-
params.timeoutMs || (options.waitForConfirmation ? 60000 : undefined);
|
|
140
|
-
|
|
141
138
|
try {
|
|
142
139
|
const result = await this.executeInscription(
|
|
143
140
|
buffer,
|
|
144
141
|
resolvedFileName,
|
|
145
142
|
resolvedMimeType,
|
|
146
143
|
options,
|
|
147
|
-
timeoutMs
|
|
144
|
+
params.timeoutMs
|
|
148
145
|
);
|
|
149
146
|
return this.formatInscriptionResult(result, options);
|
|
150
147
|
} catch (error) {
|
|
@@ -199,7 +199,7 @@ export class InscribeFromFileTool extends BaseInscriberQueryTool<
|
|
|
199
199
|
sizeBytes: fileContent.length,
|
|
200
200
|
filePath: params.filePath,
|
|
201
201
|
},
|
|
202
|
-
message: `Quote
|
|
202
|
+
message: `Estimated Quote for file: ${fileName} (${(
|
|
203
203
|
fileContent.length / 1024
|
|
204
204
|
).toFixed(2)} KB)\nTotal cost: ${
|
|
205
205
|
quote.totalCostHbar
|
|
@@ -7,7 +7,12 @@ import { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';
|
|
|
7
7
|
* Schema for inscribing from URL
|
|
8
8
|
*/
|
|
9
9
|
const inscribeFromUrlSchema = z.object({
|
|
10
|
-
url: z
|
|
10
|
+
url: z
|
|
11
|
+
.string()
|
|
12
|
+
.url()
|
|
13
|
+
.describe(
|
|
14
|
+
'ONLY direct file download URLs with file extensions (.pdf, .jpg, .png, .json, .zip). NEVER use for web pages, articles, or when you already have content to inscribe.'
|
|
15
|
+
),
|
|
11
16
|
mode: z
|
|
12
17
|
.enum(['file', 'hashinal'])
|
|
13
18
|
.optional()
|
|
@@ -35,25 +40,28 @@ const inscribeFromUrlSchema = z.object({
|
|
|
35
40
|
.int()
|
|
36
41
|
.positive()
|
|
37
42
|
.optional()
|
|
38
|
-
.describe(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
.describe('API key for inscription service'),
|
|
43
|
+
.describe(
|
|
44
|
+
'Timeout in milliseconds for inscription (default: no timeout - waits until completion)'
|
|
45
|
+
),
|
|
46
|
+
apiKey: z.string().optional().describe('API key for inscription service'),
|
|
43
47
|
quoteOnly: z
|
|
44
48
|
.boolean()
|
|
45
49
|
.optional()
|
|
46
50
|
.default(false)
|
|
47
|
-
.describe(
|
|
51
|
+
.describe(
|
|
52
|
+
'If true, returns a cost quote instead of executing the inscription'
|
|
53
|
+
),
|
|
48
54
|
});
|
|
49
55
|
|
|
50
|
-
|
|
51
56
|
/**
|
|
52
57
|
* Tool for inscribing content from URL
|
|
53
58
|
*/
|
|
54
|
-
export class InscribeFromUrlTool extends BaseInscriberQueryTool<
|
|
59
|
+
export class InscribeFromUrlTool extends BaseInscriberQueryTool<
|
|
60
|
+
typeof inscribeFromUrlSchema
|
|
61
|
+
> {
|
|
55
62
|
name = 'inscribeFromUrl';
|
|
56
|
-
description =
|
|
63
|
+
description =
|
|
64
|
+
'ONLY for direct FILE DOWNLOAD URLs ending with file extensions (.pdf, .jpg, .png, .json, .zip). NEVER use for web pages, articles, or ANY HTML content - it WILL FAIL. If you have already retrieved content from any source (including MCP tools), you MUST use inscribeFromBuffer instead. This tool downloads files from URLs - it does NOT inscribe content you already have. When asked to "inscribe it" after retrieving content, ALWAYS use inscribeFromBuffer with the actual content. Set quoteOnly=true to get cost estimates without executing the inscription.';
|
|
57
65
|
|
|
58
66
|
get specificInputSchema() {
|
|
59
67
|
return inscribeFromUrlSchema;
|
|
@@ -63,8 +71,10 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
|
|
|
63
71
|
params: z.infer<typeof inscribeFromUrlSchema>,
|
|
64
72
|
_runManager?: CallbackManagerForToolRun
|
|
65
73
|
): Promise<unknown> {
|
|
66
|
-
console.log(
|
|
67
|
-
|
|
74
|
+
console.log(
|
|
75
|
+
`[DEBUG] InscribeFromUrlTool.executeQuery called with URL: ${params.url}`
|
|
76
|
+
);
|
|
77
|
+
|
|
68
78
|
if (!params.url || params.url.trim() === '') {
|
|
69
79
|
throw new Error('URL cannot be empty. Please provide a valid URL.');
|
|
70
80
|
}
|
|
@@ -72,95 +82,137 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
|
|
|
72
82
|
try {
|
|
73
83
|
const urlObj = new URL(params.url);
|
|
74
84
|
if (!urlObj.protocol || !urlObj.host) {
|
|
75
|
-
throw new Error(
|
|
85
|
+
throw new Error(
|
|
86
|
+
'Invalid URL format. Please provide a complete URL with protocol (http/https).'
|
|
87
|
+
);
|
|
76
88
|
}
|
|
77
89
|
if (!['http:', 'https:'].includes(urlObj.protocol)) {
|
|
78
|
-
throw new Error(
|
|
90
|
+
throw new Error(
|
|
91
|
+
'Only HTTP and HTTPS URLs are supported for inscription.'
|
|
92
|
+
);
|
|
79
93
|
}
|
|
80
|
-
|
|
81
94
|
} catch (error) {
|
|
82
|
-
if (
|
|
95
|
+
if (
|
|
96
|
+
error instanceof Error &&
|
|
97
|
+
error.message.includes('Cannot inscribe content from')
|
|
98
|
+
) {
|
|
83
99
|
throw error;
|
|
84
100
|
}
|
|
85
|
-
throw new Error(
|
|
101
|
+
throw new Error(
|
|
102
|
+
`Invalid URL: ${params.url}. Please provide a valid URL.`
|
|
103
|
+
);
|
|
86
104
|
}
|
|
87
105
|
|
|
88
|
-
console.log(
|
|
106
|
+
console.log(
|
|
107
|
+
`[InscribeFromUrlTool] Validating URL content before inscription...`
|
|
108
|
+
);
|
|
89
109
|
try {
|
|
90
110
|
const controller = new AbortController();
|
|
91
111
|
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
|
92
|
-
|
|
112
|
+
|
|
93
113
|
try {
|
|
94
114
|
const headResponse = await fetch(params.url, {
|
|
95
115
|
method: 'HEAD',
|
|
96
116
|
signal: controller.signal,
|
|
97
117
|
});
|
|
98
|
-
|
|
118
|
+
|
|
99
119
|
clearTimeout(timeoutId);
|
|
100
|
-
|
|
120
|
+
|
|
101
121
|
if (!headResponse.ok) {
|
|
102
|
-
throw new Error(
|
|
122
|
+
throw new Error(
|
|
123
|
+
`URL returned error status ${headResponse.status}: ${headResponse.statusText}. Cannot inscribe content from inaccessible URLs.`
|
|
124
|
+
);
|
|
103
125
|
}
|
|
104
126
|
|
|
105
127
|
const contentType = headResponse.headers.get('content-type') || '';
|
|
106
128
|
const contentLength = headResponse.headers.get('content-length');
|
|
107
|
-
|
|
129
|
+
|
|
108
130
|
const webPageContentTypes = [
|
|
109
131
|
'text/html',
|
|
110
132
|
'application/xhtml+xml',
|
|
111
|
-
'text/xml'
|
|
133
|
+
'text/xml',
|
|
112
134
|
];
|
|
113
|
-
|
|
114
|
-
if (
|
|
115
|
-
|
|
135
|
+
|
|
136
|
+
if (
|
|
137
|
+
webPageContentTypes.some((type) =>
|
|
138
|
+
contentType.toLowerCase().includes(type)
|
|
139
|
+
)
|
|
140
|
+
) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`URL returns HTML/web page content (Content-Type: ${contentType}). This tool only works with direct file URLs (PDFs, images, JSON, etc.). For web page content, first retrieve the content using the appropriate MCP tool or web scraper, then use inscribeFromBuffer to inscribe it.`
|
|
143
|
+
);
|
|
116
144
|
}
|
|
117
|
-
|
|
145
|
+
|
|
118
146
|
if (contentLength && parseInt(contentLength) === 0) {
|
|
119
|
-
throw new Error(
|
|
147
|
+
throw new Error(
|
|
148
|
+
'URL returns empty content (Content-Length: 0). Cannot inscribe empty content.'
|
|
149
|
+
);
|
|
120
150
|
}
|
|
121
151
|
|
|
122
152
|
if (contentLength && parseInt(contentLength) < 10) {
|
|
123
|
-
throw new Error(
|
|
153
|
+
throw new Error(
|
|
154
|
+
`URL content is too small (${contentLength} bytes). Content must be at least 10 bytes.`
|
|
155
|
+
);
|
|
124
156
|
}
|
|
125
|
-
|
|
157
|
+
|
|
126
158
|
if (!contentType || contentType === 'application/octet-stream') {
|
|
127
|
-
console.log(
|
|
128
|
-
|
|
159
|
+
console.log(
|
|
160
|
+
`[InscribeFromUrlTool] Content-Type unclear, fetching first 1KB to verify...`
|
|
161
|
+
);
|
|
162
|
+
|
|
129
163
|
const getController = new AbortController();
|
|
130
164
|
const getTimeoutId = setTimeout(() => getController.abort(), 5000);
|
|
131
|
-
|
|
165
|
+
|
|
132
166
|
try {
|
|
133
167
|
const getResponse = await fetch(params.url, {
|
|
134
168
|
signal: getController.signal,
|
|
135
169
|
headers: {
|
|
136
|
-
|
|
137
|
-
}
|
|
170
|
+
Range: 'bytes=0-1023', // Get first 1KB
|
|
171
|
+
},
|
|
138
172
|
});
|
|
139
|
-
|
|
173
|
+
|
|
140
174
|
clearTimeout(getTimeoutId);
|
|
141
|
-
|
|
142
|
-
if (getResponse.ok || getResponse.status === 206) {
|
|
175
|
+
|
|
176
|
+
if (getResponse.ok || getResponse.status === 206) {
|
|
177
|
+
// 206 is partial content
|
|
143
178
|
const buffer = await getResponse.arrayBuffer();
|
|
144
179
|
const bytes = new Uint8Array(buffer);
|
|
145
|
-
const text = new TextDecoder('utf-8', { fatal: false }).decode(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
180
|
+
const text = new TextDecoder('utf-8', { fatal: false }).decode(
|
|
181
|
+
bytes.slice(0, 512)
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
if (
|
|
185
|
+
text.toLowerCase().includes('<!doctype html') ||
|
|
186
|
+
text.toLowerCase().includes('<html') ||
|
|
187
|
+
text.match(/<meta\s+[^>]*>/i) ||
|
|
188
|
+
text.match(/<title>/i)
|
|
189
|
+
) {
|
|
190
|
+
throw new Error(
|
|
191
|
+
`URL returns HTML content. This tool only works with direct file URLs. For web page content, first retrieve it using the appropriate tool, then use inscribeFromBuffer.`
|
|
192
|
+
);
|
|
152
193
|
}
|
|
153
194
|
}
|
|
154
195
|
} catch (getError) {
|
|
155
196
|
clearTimeout(getTimeoutId);
|
|
156
|
-
if (
|
|
197
|
+
if (
|
|
198
|
+
getError instanceof Error &&
|
|
199
|
+
getError.message.includes('HTML content')
|
|
200
|
+
) {
|
|
157
201
|
throw getError;
|
|
158
202
|
}
|
|
159
|
-
console.log(
|
|
203
|
+
console.log(
|
|
204
|
+
`[InscribeFromUrlTool] Could not perform partial GET validation: ${
|
|
205
|
+
getError instanceof Error ? getError.message : 'Unknown error'
|
|
206
|
+
}`
|
|
207
|
+
);
|
|
160
208
|
}
|
|
161
209
|
}
|
|
162
210
|
|
|
163
|
-
console.log(
|
|
211
|
+
console.log(
|
|
212
|
+
`[InscribeFromUrlTool] URL validation passed. Content-Type: ${contentType}, Content-Length: ${
|
|
213
|
+
contentLength || 'unknown'
|
|
214
|
+
}`
|
|
215
|
+
);
|
|
164
216
|
} catch (fetchError) {
|
|
165
217
|
clearTimeout(timeoutId);
|
|
166
218
|
throw fetchError;
|
|
@@ -168,11 +220,20 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
|
|
|
168
220
|
} catch (error) {
|
|
169
221
|
if (error instanceof Error) {
|
|
170
222
|
if (error.name === 'AbortError') {
|
|
171
|
-
console.log(
|
|
172
|
-
|
|
223
|
+
console.log(
|
|
224
|
+
`[InscribeFromUrlTool] Warning: URL validation timed out after 10 seconds. Proceeding with inscription attempt.`
|
|
225
|
+
);
|
|
226
|
+
} else if (
|
|
227
|
+
error.message.includes('URL returned error') ||
|
|
228
|
+
error.message.includes('empty content') ||
|
|
229
|
+
error.message.includes('too small') ||
|
|
230
|
+
error.message.includes('HTML')
|
|
231
|
+
) {
|
|
173
232
|
throw error;
|
|
174
233
|
} else {
|
|
175
|
-
console.log(
|
|
234
|
+
console.log(
|
|
235
|
+
`[InscribeFromUrlTool] Warning: Could not validate URL with HEAD request: ${error.message}. Proceeding with inscription attempt.`
|
|
236
|
+
);
|
|
176
237
|
}
|
|
177
238
|
}
|
|
178
239
|
}
|
|
@@ -182,11 +243,17 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
|
|
|
182
243
|
metadata: params.metadata,
|
|
183
244
|
tags: params.tags,
|
|
184
245
|
chunkSize: params.chunkSize,
|
|
185
|
-
waitForConfirmation: params.quoteOnly
|
|
246
|
+
waitForConfirmation: params.quoteOnly
|
|
247
|
+
? false
|
|
248
|
+
: params.waitForConfirmation ?? true,
|
|
186
249
|
waitMaxAttempts: 10,
|
|
187
250
|
waitIntervalMs: 3000,
|
|
188
251
|
apiKey: params.apiKey,
|
|
189
|
-
network: this.inscriberBuilder['hederaKit'].client.network
|
|
252
|
+
network: this.inscriberBuilder['hederaKit'].client.network
|
|
253
|
+
.toString()
|
|
254
|
+
.includes('mainnet')
|
|
255
|
+
? 'mainnet'
|
|
256
|
+
: 'testnet',
|
|
190
257
|
quoteOnly: params.quoteOnly,
|
|
191
258
|
};
|
|
192
259
|
|
|
@@ -196,7 +263,7 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
|
|
|
196
263
|
{ type: 'url', url: params.url },
|
|
197
264
|
options
|
|
198
265
|
);
|
|
199
|
-
|
|
266
|
+
|
|
200
267
|
return {
|
|
201
268
|
success: true,
|
|
202
269
|
quote: {
|
|
@@ -207,22 +274,27 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
|
|
|
207
274
|
contentInfo: {
|
|
208
275
|
url: params.url,
|
|
209
276
|
},
|
|
210
|
-
message: `Quote
|
|
277
|
+
message: `Estimated Quote for URL: ${params.url}\nTotal cost: ${quote.totalCostHbar} HBAR`,
|
|
211
278
|
};
|
|
212
279
|
} catch (error) {
|
|
213
280
|
const errorMessage =
|
|
214
|
-
error instanceof Error
|
|
281
|
+
error instanceof Error
|
|
282
|
+
? error.message
|
|
283
|
+
: 'Failed to generate inscription quote';
|
|
215
284
|
throw new Error(`Quote generation failed: ${errorMessage}`);
|
|
216
285
|
}
|
|
217
286
|
}
|
|
218
287
|
|
|
219
288
|
try {
|
|
220
289
|
let result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>;
|
|
221
|
-
|
|
290
|
+
|
|
222
291
|
if (params.timeoutMs) {
|
|
223
292
|
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
224
293
|
setTimeout(
|
|
225
|
-
() =>
|
|
294
|
+
() =>
|
|
295
|
+
reject(
|
|
296
|
+
new Error(`Inscription timed out after ${params.timeoutMs}ms`)
|
|
297
|
+
),
|
|
226
298
|
params.timeoutMs
|
|
227
299
|
);
|
|
228
300
|
});
|
|
@@ -232,7 +304,7 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
|
|
|
232
304
|
{ type: 'url', url: params.url },
|
|
233
305
|
options
|
|
234
306
|
),
|
|
235
|
-
timeoutPromise
|
|
307
|
+
timeoutPromise,
|
|
236
308
|
]);
|
|
237
309
|
} else {
|
|
238
310
|
result = await this.inscriberBuilder.inscribe(
|
|
@@ -242,18 +314,28 @@ export class InscribeFromUrlTool extends BaseInscriberQueryTool<typeof inscribeF
|
|
|
242
314
|
}
|
|
243
315
|
|
|
244
316
|
if (result.confirmed && !result.quote) {
|
|
245
|
-
const topicId =
|
|
317
|
+
const topicId =
|
|
318
|
+
result.inscription?.topic_id || (result.result as any).topicId;
|
|
246
319
|
const network = options.network || 'testnet';
|
|
247
|
-
const cdnUrl = topicId
|
|
248
|
-
|
|
320
|
+
const cdnUrl = topicId
|
|
321
|
+
? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}`
|
|
322
|
+
: null;
|
|
323
|
+
return `Successfully inscribed and confirmed content on the Hedera network!\n\nTransaction ID: ${
|
|
324
|
+
(result.result as any).transactionId
|
|
325
|
+
}\nTopic ID: ${topicId || 'N/A'}${
|
|
326
|
+
cdnUrl ? `\nView inscription: ${cdnUrl}` : ''
|
|
327
|
+
}\n\nThe inscription is now available.`;
|
|
249
328
|
} else if (!result.quote && !result.confirmed) {
|
|
250
|
-
return `Successfully submitted inscription to the Hedera network!\n\nTransaction ID: ${
|
|
329
|
+
return `Successfully submitted inscription to the Hedera network!\n\nTransaction ID: ${
|
|
330
|
+
(result.result as any).transactionId
|
|
331
|
+
}\n\nThe inscription is processing and will be confirmed shortly.`;
|
|
251
332
|
} else {
|
|
252
333
|
return 'Inscription operation completed.';
|
|
253
334
|
}
|
|
254
335
|
} catch (error) {
|
|
255
|
-
const errorMessage =
|
|
336
|
+
const errorMessage =
|
|
337
|
+
error instanceof Error ? error.message : 'Failed to inscribe from URL';
|
|
256
338
|
throw new Error(`Inscription failed: ${errorMessage}`);
|
|
257
339
|
}
|
|
258
340
|
}
|
|
259
|
-
}
|
|
341
|
+
}
|
|
@@ -120,7 +120,7 @@ export class InscribeHashinalTool extends BaseInscriberQueryTool<typeof inscribe
|
|
|
120
120
|
creator: params.creator,
|
|
121
121
|
type: params.type,
|
|
122
122
|
},
|
|
123
|
-
message: `Quote
|
|
123
|
+
message: `Estimated Quote for Hashinal NFT: ${params.name}\nCreator: ${params.creator}\nTotal cost: ${quote.totalCostHbar} HBAR`,
|
|
124
124
|
};
|
|
125
125
|
} catch (error) {
|
|
126
126
|
const errorMessage =
|