@hashgraphonline/standards-agent-kit 0.2.134 → 0.2.136
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/interfaces/FormValidatable.d.ts +4 -13
- package/dist/cjs/standards-agent-kit.cjs +1 -1
- package/dist/cjs/standards-agent-kit.cjs.map +1 -1
- package/dist/cjs/tools/inscriber/InscribeHashinalTool.d.ts +1 -8
- package/dist/cjs/tools/inscriber/base-inscriber-tools.d.ts +19 -0
- package/dist/es/interfaces/FormValidatable.d.ts +4 -13
- package/dist/es/standards-agent-kit.es33.js +12 -0
- package/dist/es/standards-agent-kit.es33.js.map +1 -1
- package/dist/es/standards-agent-kit.es34.js +2 -2
- package/dist/es/standards-agent-kit.es34.js.map +1 -1
- package/dist/es/standards-agent-kit.es36.js +2 -2
- package/dist/es/standards-agent-kit.es36.js.map +1 -1
- package/dist/es/standards-agent-kit.es37.js +25 -26
- package/dist/es/standards-agent-kit.es37.js.map +1 -1
- package/dist/es/standards-agent-kit.es44.js +1 -1
- package/dist/es/standards-agent-kit.es44.js.map +1 -1
- package/dist/es/standards-agent-kit.es51.js +2 -2
- package/dist/es/standards-agent-kit.es51.js.map +1 -1
- package/dist/es/tools/inscriber/InscribeHashinalTool.d.ts +1 -8
- package/dist/es/tools/inscriber/base-inscriber-tools.d.ts +19 -0
- package/dist/umd/interfaces/FormValidatable.d.ts +4 -13
- 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/inscriber/InscribeHashinalTool.d.ts +1 -8
- package/dist/umd/tools/inscriber/base-inscriber-tools.d.ts +19 -0
- package/package.json +2 -2
- package/src/interfaces/FormValidatable.ts +9 -12
- package/src/tools/inscriber/InscribeFromBufferTool.ts +2 -2
- package/src/tools/inscriber/InscribeFromUrlTool.ts +2 -2
- package/src/tools/inscriber/InscribeHashinalTool.ts +43 -50
- package/src/tools/inscriber/base-inscriber-tools.ts +26 -0
- package/src/types/inscription-response.ts +2 -2
|
@@ -37,6 +37,7 @@ declare const inscribeHashinalSchema: import('../..').ZodSchemaWithRender<{
|
|
|
37
37
|
export declare class InscribeHashinalTool extends BaseInscriberQueryTool implements FormValidatable {
|
|
38
38
|
name: string;
|
|
39
39
|
description: string;
|
|
40
|
+
getEntityResolutionPreferences(): Record<string, string>;
|
|
40
41
|
get specificInputSchema(): z.ZodObject<z.ZodRawShape>;
|
|
41
42
|
private _schemaWithRenderConfig?;
|
|
42
43
|
get schema(): z.ZodObject<z.ZodRawShape>;
|
|
@@ -50,14 +51,6 @@ export declare class InscribeHashinalTool extends BaseInscriberQueryTool impleme
|
|
|
50
51
|
* Returns the focused schema for form generation
|
|
51
52
|
*/
|
|
52
53
|
getFormSchema(): z.ZodObject<z.ZodRawShape>;
|
|
53
|
-
/**
|
|
54
|
-
* Implementation of FormValidatable interface
|
|
55
|
-
* Validates metadata quality and provides detailed feedback
|
|
56
|
-
*/
|
|
57
|
-
validateMetadataQuality(input: unknown): {
|
|
58
|
-
needsForm: boolean;
|
|
59
|
-
reason: string;
|
|
60
|
-
};
|
|
61
54
|
protected executeQuery(params: z.infer<typeof inscribeHashinalSchema>, _runManager?: CallbackManagerForToolRun): Promise<InscriptionResponse>;
|
|
62
55
|
/**
|
|
63
56
|
* Creates HashLink block configuration for Hashinal inscriptions.
|
|
@@ -4,12 +4,22 @@ import { InscriberTransactionToolParams, InscriberQueryToolParams } from './insc
|
|
|
4
4
|
import { ContentResolverInterface } from '../../types/content-resolver';
|
|
5
5
|
import { InscriptionInput, InscriptionOptions, QuoteResult } from '@hashgraphonline/standards-sdk';
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
+
/**
|
|
8
|
+
* Event emitted when an entity is created during inscription
|
|
9
|
+
*/
|
|
10
|
+
export interface EntityCreationEvent {
|
|
11
|
+
entityId: string;
|
|
12
|
+
entityName: string;
|
|
13
|
+
entityType: string;
|
|
14
|
+
transactionId?: string;
|
|
15
|
+
}
|
|
7
16
|
/**
|
|
8
17
|
* Base class for Inscriber transaction tools
|
|
9
18
|
*/
|
|
10
19
|
export declare abstract class BaseInscriberTransactionTool<T extends z.ZodObject<z.ZodRawShape, z.UnknownKeysParam, z.ZodTypeAny> = z.ZodObject<z.ZodRawShape>> extends BaseHederaTransactionTool<T> {
|
|
11
20
|
protected inscriberBuilder: InscriberBuilder;
|
|
12
21
|
protected contentResolver: ContentResolverInterface | null;
|
|
22
|
+
protected onEntityCreated?: (event: EntityCreationEvent) => void;
|
|
13
23
|
namespace: "inscriber";
|
|
14
24
|
constructor(params: InscriberTransactionToolParams);
|
|
15
25
|
/**
|
|
@@ -20,6 +30,10 @@ export declare abstract class BaseInscriberTransactionTool<T extends z.ZodObject
|
|
|
20
30
|
* Get content resolver with fallback to registry
|
|
21
31
|
*/
|
|
22
32
|
protected getContentResolver(): ContentResolverInterface | null;
|
|
33
|
+
/**
|
|
34
|
+
* Set entity creation handler for automatic entity storage
|
|
35
|
+
*/
|
|
36
|
+
setEntityCreationHandler(handler: (event: EntityCreationEvent) => void): void;
|
|
23
37
|
/**
|
|
24
38
|
* Generate a quote for an inscription without executing it
|
|
25
39
|
* @param input - The inscription input data
|
|
@@ -34,6 +48,7 @@ export declare abstract class BaseInscriberTransactionTool<T extends z.ZodObject
|
|
|
34
48
|
export declare abstract class BaseInscriberQueryTool<T extends z.ZodObject<z.ZodRawShape, z.UnknownKeysParam, z.ZodTypeAny> = z.ZodObject<z.ZodRawShape>> extends BaseHederaQueryTool<T> {
|
|
35
49
|
protected inscriberBuilder: InscriberBuilder;
|
|
36
50
|
protected contentResolver: ContentResolverInterface | null;
|
|
51
|
+
protected onEntityCreated?: (event: EntityCreationEvent) => void;
|
|
37
52
|
namespace: "inscriber";
|
|
38
53
|
constructor(params: InscriberQueryToolParams);
|
|
39
54
|
/**
|
|
@@ -44,6 +59,10 @@ export declare abstract class BaseInscriberQueryTool<T extends z.ZodObject<z.Zod
|
|
|
44
59
|
* Get content resolver with fallback to registry
|
|
45
60
|
*/
|
|
46
61
|
protected getContentResolver(): ContentResolverInterface | null;
|
|
62
|
+
/**
|
|
63
|
+
* Set entity creation handler for automatic entity storage
|
|
64
|
+
*/
|
|
65
|
+
setEntityCreationHandler(handler: (event: EntityCreationEvent) => void): void;
|
|
47
66
|
/**
|
|
48
67
|
* Generate a quote for an inscription without executing it
|
|
49
68
|
* @param input - The inscription input data
|
|
@@ -16,28 +16,19 @@ export interface FormValidatable {
|
|
|
16
16
|
*/
|
|
17
17
|
getFormSchema(): z.ZodSchema;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
20
|
-
* @param input The input data to analyze
|
|
21
|
-
* @returns Object indicating if form is needed and the reason
|
|
22
|
-
*/
|
|
23
|
-
validateMetadataQuality?(input: unknown): {
|
|
24
|
-
needsForm: boolean;
|
|
25
|
-
reason: string;
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Optional method to define which fields are essential for this tool
|
|
19
|
+
* Defines which fields are essential for this tool
|
|
29
20
|
* Essential fields are always shown in forms even if marked as optional
|
|
30
21
|
* @returns Array of field names that are essential for user experience
|
|
31
22
|
*/
|
|
32
|
-
getEssentialFields
|
|
23
|
+
getEssentialFields(): string[];
|
|
33
24
|
/**
|
|
34
|
-
*
|
|
25
|
+
* Determines if a field value should be considered empty
|
|
35
26
|
* Allows tools to define custom empty logic for their specific data types
|
|
36
27
|
* @param fieldName The name of the field
|
|
37
28
|
* @param value The value to check
|
|
38
29
|
* @returns true if the field should be considered empty
|
|
39
30
|
*/
|
|
40
|
-
isFieldEmpty
|
|
31
|
+
isFieldEmpty(fieldName: string, value: unknown): boolean;
|
|
41
32
|
}
|
|
42
33
|
/**
|
|
43
34
|
* Type guard to check if a tool implements FormValidatable
|
|
@@ -18,6 +18,12 @@ class BaseInscriberTransactionTool extends BaseHederaTransactionTool {
|
|
|
18
18
|
getContentResolver() {
|
|
19
19
|
return this.contentResolver;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Set entity creation handler for automatic entity storage
|
|
23
|
+
*/
|
|
24
|
+
setEntityCreationHandler(handler) {
|
|
25
|
+
this.onEntityCreated = handler;
|
|
26
|
+
}
|
|
21
27
|
/**
|
|
22
28
|
* Generate a quote for an inscription without executing it
|
|
23
29
|
* @param input - The inscription input data
|
|
@@ -58,6 +64,12 @@ class BaseInscriberQueryTool extends BaseHederaQueryTool {
|
|
|
58
64
|
getContentResolver() {
|
|
59
65
|
return this.contentResolver;
|
|
60
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Set entity creation handler for automatic entity storage
|
|
69
|
+
*/
|
|
70
|
+
setEntityCreationHandler(handler) {
|
|
71
|
+
this.onEntityCreated = handler;
|
|
72
|
+
}
|
|
61
73
|
/**
|
|
62
74
|
* Generate a quote for an inscription without executing it
|
|
63
75
|
* @param input - The inscription input data
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standards-agent-kit.es33.js","sources":["../../src/tools/inscriber/base-inscriber-tools.ts"],"sourcesContent":["import {\n BaseHederaTransactionTool,\n BaseHederaQueryTool,\n BaseServiceBuilder,\n} from 'hedera-agent-kit';\nimport { InscriberBuilder } from '../../builders/inscriber/inscriber-builder';\nimport {\n InscriberTransactionToolParams,\n InscriberQueryToolParams,\n} from './inscriber-tool-params';\nimport type { ContentResolverInterface } from '../../types/content-resolver';\nimport {\n InscriptionInput,\n InscriptionOptions,\n QuoteResult,\n} from '@hashgraphonline/standards-sdk';\nimport { z } from 'zod';\n\n/**\n * Base class for Inscriber transaction tools\n */\nexport abstract class BaseInscriberTransactionTool<\n T extends z.ZodObject<\n z.ZodRawShape,\n z.UnknownKeysParam,\n z.ZodTypeAny\n > = z.ZodObject<z.ZodRawShape>\n> extends BaseHederaTransactionTool<T> {\n protected inscriberBuilder: InscriberBuilder;\n protected contentResolver: ContentResolverInterface | null;\n namespace = 'inscriber' as const;\n\n constructor(params: InscriberTransactionToolParams) {\n super(params);\n this.inscriberBuilder = params.inscriberBuilder;\n this.contentResolver = params.contentResolver || null;\n }\n\n /**\n * Override to return the InscriberBuilder\n */\n protected getServiceBuilder(): BaseServiceBuilder {\n return this.inscriberBuilder;\n }\n\n /**\n * Get content resolver with fallback to registry\n */\n protected getContentResolver(): ContentResolverInterface | null {\n return this.contentResolver;\n }\n\n /**\n * Generate a quote for an inscription without executing it\n * @param input - The inscription input data\n * @param options - Inscription options\n * @returns Promise containing the quote result\n */\n protected async generateInscriptionQuote(\n input: InscriptionInput,\n options: InscriptionOptions\n ): Promise<QuoteResult> {\n const network = this.inscriberBuilder['hederaKit'].client.network;\n const networkType = network.toString().includes('mainnet')\n ? 'mainnet'\n : 'testnet';\n\n const quoteOptions = {\n ...options,\n quoteOnly: true,\n network: networkType as 'mainnet' | 'testnet',\n };\n\n const result = await this.inscriberBuilder.inscribe(input, quoteOptions);\n\n if (!result.quote || result.confirmed) {\n throw new Error('Failed to generate quote - unexpected response type');\n }\n\n return result.result as QuoteResult;\n }\n}\n\n/**\n * Base class for Inscriber query tools\n */\nexport abstract class BaseInscriberQueryTool<\n T extends z.ZodObject<\n z.ZodRawShape,\n z.UnknownKeysParam,\n z.ZodTypeAny\n > = z.ZodObject<z.ZodRawShape>\n> extends BaseHederaQueryTool<T> {\n protected inscriberBuilder: InscriberBuilder;\n protected contentResolver: ContentResolverInterface | null;\n namespace = 'inscriber' as const;\n\n constructor(params: InscriberQueryToolParams) {\n super(params);\n this.inscriberBuilder = params.inscriberBuilder;\n this.contentResolver = params.contentResolver || null;\n }\n\n /**\n * Override to return the InscriberBuilder\n */\n protected getServiceBuilder(): BaseServiceBuilder {\n return this.inscriberBuilder;\n }\n\n /**\n * Get content resolver with fallback to registry\n */\n protected getContentResolver(): ContentResolverInterface | null {\n return this.contentResolver;\n }\n\n /**\n * Generate a quote for an inscription without executing it\n * @param input - The inscription input data\n * @param options - Inscription options\n * @returns Promise containing the quote result\n */\n protected async generateInscriptionQuote(\n input: InscriptionInput,\n options: InscriptionOptions\n ): Promise<QuoteResult> {\n const network = this.inscriberBuilder['hederaKit'].client.network;\n const networkType = network.toString().includes('mainnet')\n ? 'mainnet'\n : 'testnet';\n\n const quoteOptions = {\n ...options,\n quoteOnly: true,\n network: networkType as 'mainnet' | 'testnet',\n };\n\n const result = await this.inscriberBuilder.inscribe(input, quoteOptions);\n\n if (!result.quote || result.confirmed) {\n throw new Error('Failed to generate quote - unexpected response type');\n }\n\n return result.result as QuoteResult;\n }\n}"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"standards-agent-kit.es33.js","sources":["../../src/tools/inscriber/base-inscriber-tools.ts"],"sourcesContent":["import {\n BaseHederaTransactionTool,\n BaseHederaQueryTool,\n BaseServiceBuilder,\n} from 'hedera-agent-kit';\nimport { InscriberBuilder } from '../../builders/inscriber/inscriber-builder';\nimport {\n InscriberTransactionToolParams,\n InscriberQueryToolParams,\n} from './inscriber-tool-params';\nimport type { ContentResolverInterface } from '../../types/content-resolver';\nimport {\n InscriptionInput,\n InscriptionOptions,\n QuoteResult,\n} from '@hashgraphonline/standards-sdk';\nimport { z } from 'zod';\n\n/**\n * Event emitted when an entity is created during inscription\n */\nexport interface EntityCreationEvent {\n entityId: string;\n entityName: string;\n entityType: string;\n transactionId?: string;\n}\n\n/**\n * Base class for Inscriber transaction tools\n */\nexport abstract class BaseInscriberTransactionTool<\n T extends z.ZodObject<\n z.ZodRawShape,\n z.UnknownKeysParam,\n z.ZodTypeAny\n > = z.ZodObject<z.ZodRawShape>\n> extends BaseHederaTransactionTool<T> {\n protected inscriberBuilder: InscriberBuilder;\n protected contentResolver: ContentResolverInterface | null;\n protected onEntityCreated?: (event: EntityCreationEvent) => void;\n namespace = 'inscriber' as const;\n\n constructor(params: InscriberTransactionToolParams) {\n super(params);\n this.inscriberBuilder = params.inscriberBuilder;\n this.contentResolver = params.contentResolver || null;\n }\n\n /**\n * Override to return the InscriberBuilder\n */\n protected getServiceBuilder(): BaseServiceBuilder {\n return this.inscriberBuilder;\n }\n\n /**\n * Get content resolver with fallback to registry\n */\n protected getContentResolver(): ContentResolverInterface | null {\n return this.contentResolver;\n }\n\n /**\n * Set entity creation handler for automatic entity storage\n */\n setEntityCreationHandler(handler: (event: EntityCreationEvent) => void): void {\n this.onEntityCreated = handler;\n }\n\n /**\n * Generate a quote for an inscription without executing it\n * @param input - The inscription input data\n * @param options - Inscription options\n * @returns Promise containing the quote result\n */\n protected async generateInscriptionQuote(\n input: InscriptionInput,\n options: InscriptionOptions\n ): Promise<QuoteResult> {\n const network = this.inscriberBuilder['hederaKit'].client.network;\n const networkType = network.toString().includes('mainnet')\n ? 'mainnet'\n : 'testnet';\n\n const quoteOptions = {\n ...options,\n quoteOnly: true,\n network: networkType as 'mainnet' | 'testnet',\n };\n\n const result = await this.inscriberBuilder.inscribe(input, quoteOptions);\n\n if (!result.quote || result.confirmed) {\n throw new Error('Failed to generate quote - unexpected response type');\n }\n\n return result.result as QuoteResult;\n }\n}\n\n/**\n * Base class for Inscriber query tools\n */\nexport abstract class BaseInscriberQueryTool<\n T extends z.ZodObject<\n z.ZodRawShape,\n z.UnknownKeysParam,\n z.ZodTypeAny\n > = z.ZodObject<z.ZodRawShape>\n> extends BaseHederaQueryTool<T> {\n protected inscriberBuilder: InscriberBuilder;\n protected contentResolver: ContentResolverInterface | null;\n protected onEntityCreated?: (event: EntityCreationEvent) => void;\n namespace = 'inscriber' as const;\n\n constructor(params: InscriberQueryToolParams) {\n super(params);\n this.inscriberBuilder = params.inscriberBuilder;\n this.contentResolver = params.contentResolver || null;\n }\n\n /**\n * Override to return the InscriberBuilder\n */\n protected getServiceBuilder(): BaseServiceBuilder {\n return this.inscriberBuilder;\n }\n\n /**\n * Get content resolver with fallback to registry\n */\n protected getContentResolver(): ContentResolverInterface | null {\n return this.contentResolver;\n }\n\n /**\n * Set entity creation handler for automatic entity storage\n */\n setEntityCreationHandler(handler: (event: EntityCreationEvent) => void): void {\n this.onEntityCreated = handler;\n }\n\n /**\n * Generate a quote for an inscription without executing it\n * @param input - The inscription input data\n * @param options - Inscription options\n * @returns Promise containing the quote result\n */\n protected async generateInscriptionQuote(\n input: InscriptionInput,\n options: InscriptionOptions\n ): Promise<QuoteResult> {\n const network = this.inscriberBuilder['hederaKit'].client.network;\n const networkType = network.toString().includes('mainnet')\n ? 'mainnet'\n : 'testnet';\n\n const quoteOptions = {\n ...options,\n quoteOnly: true,\n network: networkType as 'mainnet' | 'testnet',\n };\n\n const result = await this.inscriberBuilder.inscribe(input, quoteOptions);\n\n if (!result.quote || result.confirmed) {\n throw new Error('Failed to generate quote - unexpected response type');\n }\n\n return result.result as QuoteResult;\n }\n}"],"names":[],"mappings":";AA+BO,MAAe,qCAMZ,0BAA6B;AAAA,EAMrC,YAAY,QAAwC;AAClD,UAAM,MAAM;AAHd,SAAA,YAAY;AAIV,SAAK,mBAAmB,OAAO;AAC/B,SAAK,kBAAkB,OAAO,mBAAmB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKU,oBAAwC;AAChD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKU,qBAAsD;AAC9D,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,yBAAyB,SAAqD;AAC5E,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAgB,yBACd,OACA,SACsB;AACtB,UAAM,UAAU,KAAK,iBAAiB,WAAW,EAAE,OAAO;AAC1D,UAAM,cAAc,QAAQ,SAAA,EAAW,SAAS,SAAS,IACrD,YACA;AAEJ,UAAM,eAAe;AAAA,MACnB,GAAG;AAAA,MACH,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAGX,UAAM,SAAS,MAAM,KAAK,iBAAiB,SAAS,OAAO,YAAY;AAEvE,QAAI,CAAC,OAAO,SAAS,OAAO,WAAW;AACrC,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,WAAO,OAAO;AAAA,EAChB;AACF;AAKO,MAAe,+BAMZ,oBAAuB;AAAA,EAM/B,YAAY,QAAkC;AAC5C,UAAM,MAAM;AAHd,SAAA,YAAY;AAIV,SAAK,mBAAmB,OAAO;AAC/B,SAAK,kBAAkB,OAAO,mBAAmB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKU,oBAAwC;AAChD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKU,qBAAsD;AAC9D,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,yBAAyB,SAAqD;AAC5E,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAgB,yBACd,OACA,SACsB;AACtB,UAAM,UAAU,KAAK,iBAAiB,WAAW,EAAE,OAAO;AAC1D,UAAM,cAAc,QAAQ,SAAA,EAAW,SAAS,SAAS,IACrD,YACA;AAEJ,UAAM,eAAe;AAAA,MACnB,GAAG;AAAA,MACH,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAGX,UAAM,SAAS,MAAM,KAAK,iBAAiB,SAAS,OAAO,YAAY;AAEvE,QAAI,CAAC,OAAO,SAAS,OAAO,WAAW;AACrC,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,WAAO,OAAO;AAAA,EAChB;AACF;"}
|
|
@@ -155,8 +155,8 @@ class InscribeFromUrlTool extends BaseInscriberQueryTool {
|
|
|
155
155
|
tags: params.tags,
|
|
156
156
|
chunkSize: params.chunkSize,
|
|
157
157
|
waitForConfirmation: params.quoteOnly ? false : params.waitForConfirmation ?? true,
|
|
158
|
-
waitMaxAttempts:
|
|
159
|
-
waitIntervalMs:
|
|
158
|
+
waitMaxAttempts: 60,
|
|
159
|
+
waitIntervalMs: 5e3,
|
|
160
160
|
apiKey: params.apiKey,
|
|
161
161
|
network: this.inscriberBuilder["hederaKit"].client.network.toString().includes("mainnet") ? "mainnet" : "testnet",
|
|
162
162
|
quoteOnly: params.quoteOnly
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standards-agent-kit.es34.js","sources":["../../src/tools/inscriber/InscribeFromUrlTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport { InscriptionOptions, Logger } from '@hashgraphonline/standards-sdk';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\n\nconst logger = new Logger({ module: 'InscribeFromUrlTool' });\n\n/**\n * Schema for inscribing from URL\n */\nconst inscribeFromUrlSchema = z.object({\n url: z\n .string()\n .url()\n .describe(\n '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.'\n ),\n mode: z\n .enum(['file', 'hashinal'])\n .optional()\n .describe('Inscription mode: file or hashinal NFT'),\n metadata: z\n .record(z.unknown())\n .optional()\n .describe('Metadata to attach to the inscription'),\n tags: z\n .array(z.string())\n .optional()\n .describe('Tags to categorize the inscription'),\n chunkSize: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Chunk size for large files'),\n waitForConfirmation: z\n .boolean()\n .optional()\n .describe('Whether to wait for inscription confirmation'),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Timeout in milliseconds for inscription (default: no timeout - waits until completion)'\n ),\n apiKey: z.string().optional().describe('API key for inscription service'),\n quoteOnly: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'If true, returns a cost quote instead of executing the inscription'\n ),\n});\n\n/**\n * Tool for inscribing content from URL\n */\nexport class InscribeFromUrlTool extends BaseInscriberQueryTool<\n typeof inscribeFromUrlSchema\n> {\n name = 'inscribeFromUrl';\n description =\n '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.';\n\n get specificInputSchema() {\n return inscribeFromUrlSchema;\n }\n\n protected async executeQuery(\n params: z.infer<typeof inscribeFromUrlSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<unknown> {\n logger.debug(`InscribeFromUrlTool.executeQuery called with URL: ${params.url}`);\n\n if (!params.url || params.url.trim() === '') {\n throw new Error('URL cannot be empty. Please provide a valid URL.');\n }\n\n try {\n const urlObj = new URL(params.url);\n if (!urlObj.protocol || !urlObj.host) {\n throw new Error(\n 'Invalid URL format. Please provide a complete URL with protocol (http/https).'\n );\n }\n if (!['http:', 'https:'].includes(urlObj.protocol)) {\n throw new Error(\n 'Only HTTP and HTTPS URLs are supported for inscription.'\n );\n }\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes('Cannot inscribe content from')\n ) {\n throw error;\n }\n throw new Error(\n `Invalid URL: ${params.url}. Please provide a valid URL.`\n );\n }\n\n logger.info('Validating URL content before inscription...');\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 10000);\n\n try {\n const headResponse = await fetch(params.url, {\n method: 'HEAD',\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!headResponse.ok) {\n throw new Error(\n `URL returned error status ${headResponse.status}: ${headResponse.statusText}. Cannot inscribe content from inaccessible URLs.`\n );\n }\n\n const contentType = headResponse.headers.get('content-type') || '';\n const contentLength = headResponse.headers.get('content-length');\n\n const webPageContentTypes = [\n 'text/html',\n 'application/xhtml+xml',\n 'text/xml',\n ];\n\n if (\n webPageContentTypes.some((type) =>\n contentType.toLowerCase().includes(type)\n )\n ) {\n throw new Error(\n `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.`\n );\n }\n\n if (contentLength && parseInt(contentLength) === 0) {\n throw new Error(\n 'URL returns empty content (Content-Length: 0). Cannot inscribe empty content.'\n );\n }\n\n if (contentLength && parseInt(contentLength) < 10) {\n throw new Error(\n `URL content is too small (${contentLength} bytes). Content must be at least 10 bytes.`\n );\n }\n\n if (!contentType || contentType === 'application/octet-stream') {\n logger.info('Content-Type unclear, fetching first 1KB to verify...');\n\n const getController = new AbortController();\n const getTimeoutId = setTimeout(() => getController.abort(), 5000);\n\n try {\n const getResponse = await fetch(params.url, {\n signal: getController.signal,\n headers: {\n Range: 'bytes=0-1023', // Get first 1KB\n },\n });\n\n clearTimeout(getTimeoutId);\n\n if (getResponse.ok || getResponse.status === 206) {\n\n const buffer = await getResponse.arrayBuffer();\n const bytes = new Uint8Array(buffer);\n const text = new TextDecoder('utf-8', { fatal: false }).decode(\n bytes.slice(0, 512)\n );\n\n if (\n text.toLowerCase().includes('<!doctype html') ||\n text.toLowerCase().includes('<html') ||\n text.match(/<meta\\s+[^>]*>/i) ||\n text.match(/<title>/i)\n ) {\n throw new Error(\n `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.`\n );\n }\n }\n } catch (getError) {\n clearTimeout(getTimeoutId);\n if (\n getError instanceof Error &&\n getError.message.includes('HTML content')\n ) {\n throw getError;\n }\n logger.warn(\n `Could not perform partial GET validation: ${\n getError instanceof Error ? getError.message : 'Unknown error'\n }`\n );\n }\n }\n\n logger.info(\n `URL validation passed. Content-Type: ${contentType}, Content-Length: ${\n contentLength || 'unknown'\n }`\n );\n } catch (fetchError) {\n clearTimeout(timeoutId);\n throw fetchError;\n }\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n logger.warn(\n 'URL validation timed out after 10 seconds. Proceeding with inscription attempt.'\n );\n } else if (\n error.message.includes('URL returned error') ||\n error.message.includes('empty content') ||\n error.message.includes('too small') ||\n error.message.includes('HTML')\n ) {\n throw error;\n } else {\n logger.warn(\n `Could not validate URL with HEAD request: ${error.message}. Proceeding with inscription attempt.`\n );\n }\n }\n }\n\n const options: InscriptionOptions = {\n mode: params.mode,\n metadata: params.metadata,\n tags: params.tags,\n chunkSize: params.chunkSize,\n waitForConfirmation: params.quoteOnly\n ? false\n : params.waitForConfirmation ?? true,\n waitMaxAttempts: 10,\n waitIntervalMs: 3000,\n apiKey: params.apiKey,\n network: this.inscriberBuilder['hederaKit'].client.network\n .toString()\n .includes('mainnet')\n ? 'mainnet'\n : 'testnet',\n quoteOnly: params.quoteOnly,\n };\n\n if (params.quoteOnly) {\n try {\n const quote = await this.generateInscriptionQuote(\n { type: 'url', url: params.url },\n options\n );\n\n return {\n success: true,\n quote: {\n totalCostHbar: quote.totalCostHbar,\n validUntil: quote.validUntil,\n breakdown: quote.breakdown,\n },\n contentInfo: {\n url: params.url,\n },\n message: `Estimated Quote for URL: ${params.url}\\nTotal cost: ${quote.totalCostHbar} HBAR`,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to generate inscription quote';\n throw new Error(`Quote generation failed: ${errorMessage}`);\n }\n }\n\n try {\n let result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>;\n\n if (params.timeoutMs) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(\n () =>\n reject(\n new Error(`Inscription timed out after ${params.timeoutMs}ms`)\n ),\n params.timeoutMs\n );\n });\n\n result = await Promise.race([\n this.inscriberBuilder.inscribe(\n { type: 'url', url: params.url },\n options\n ),\n timeoutPromise,\n ]);\n } else {\n result = await this.inscriberBuilder.inscribe(\n { type: 'url', url: params.url },\n options\n );\n }\n\n if (result.confirmed && !result.quote) {\n const topicId =\n result.inscription?.topic_id || (result.result as any).topicId;\n const network = options.network || 'testnet';\n const cdnUrl = topicId\n ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}`\n : null;\n return `Successfully inscribed and confirmed content on the Hedera network!\\n\\nTransaction ID: ${\n (result.result as any).transactionId\n }\\nTopic ID: ${topicId || 'N/A'}${\n cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''\n }\\n\\nThe inscription is now available.`;\n } else if (!result.quote && !result.confirmed) {\n return `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${\n (result.result as any).transactionId\n }\\n\\nThe inscription is processing and will be confirmed shortly.`;\n } else {\n return 'Inscription operation completed.';\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Failed to inscribe from URL';\n throw new Error(`Inscription failed: ${errorMessage}`);\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"standards-agent-kit.es34.js","sources":["../../src/tools/inscriber/InscribeFromUrlTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport { InscriptionOptions, Logger } from '@hashgraphonline/standards-sdk';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\n\nconst logger = new Logger({ module: 'InscribeFromUrlTool' });\n\n/**\n * Schema for inscribing from URL\n */\nconst inscribeFromUrlSchema = z.object({\n url: z\n .string()\n .url()\n .describe(\n '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.'\n ),\n mode: z\n .enum(['file', 'hashinal'])\n .optional()\n .describe('Inscription mode: file or hashinal NFT'),\n metadata: z\n .record(z.unknown())\n .optional()\n .describe('Metadata to attach to the inscription'),\n tags: z\n .array(z.string())\n .optional()\n .describe('Tags to categorize the inscription'),\n chunkSize: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Chunk size for large files'),\n waitForConfirmation: z\n .boolean()\n .optional()\n .describe('Whether to wait for inscription confirmation'),\n timeoutMs: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\n 'Timeout in milliseconds for inscription (default: no timeout - waits until completion)'\n ),\n apiKey: z.string().optional().describe('API key for inscription service'),\n quoteOnly: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'If true, returns a cost quote instead of executing the inscription'\n ),\n});\n\n/**\n * Tool for inscribing content from URL\n */\nexport class InscribeFromUrlTool extends BaseInscriberQueryTool<\n typeof inscribeFromUrlSchema\n> {\n name = 'inscribeFromUrl';\n description =\n '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.';\n\n get specificInputSchema() {\n return inscribeFromUrlSchema;\n }\n\n protected async executeQuery(\n params: z.infer<typeof inscribeFromUrlSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<unknown> {\n logger.debug(`InscribeFromUrlTool.executeQuery called with URL: ${params.url}`);\n\n if (!params.url || params.url.trim() === '') {\n throw new Error('URL cannot be empty. Please provide a valid URL.');\n }\n\n try {\n const urlObj = new URL(params.url);\n if (!urlObj.protocol || !urlObj.host) {\n throw new Error(\n 'Invalid URL format. Please provide a complete URL with protocol (http/https).'\n );\n }\n if (!['http:', 'https:'].includes(urlObj.protocol)) {\n throw new Error(\n 'Only HTTP and HTTPS URLs are supported for inscription.'\n );\n }\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes('Cannot inscribe content from')\n ) {\n throw error;\n }\n throw new Error(\n `Invalid URL: ${params.url}. Please provide a valid URL.`\n );\n }\n\n logger.info('Validating URL content before inscription...');\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 10000);\n\n try {\n const headResponse = await fetch(params.url, {\n method: 'HEAD',\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!headResponse.ok) {\n throw new Error(\n `URL returned error status ${headResponse.status}: ${headResponse.statusText}. Cannot inscribe content from inaccessible URLs.`\n );\n }\n\n const contentType = headResponse.headers.get('content-type') || '';\n const contentLength = headResponse.headers.get('content-length');\n\n const webPageContentTypes = [\n 'text/html',\n 'application/xhtml+xml',\n 'text/xml',\n ];\n\n if (\n webPageContentTypes.some((type) =>\n contentType.toLowerCase().includes(type)\n )\n ) {\n throw new Error(\n `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.`\n );\n }\n\n if (contentLength && parseInt(contentLength) === 0) {\n throw new Error(\n 'URL returns empty content (Content-Length: 0). Cannot inscribe empty content.'\n );\n }\n\n if (contentLength && parseInt(contentLength) < 10) {\n throw new Error(\n `URL content is too small (${contentLength} bytes). Content must be at least 10 bytes.`\n );\n }\n\n if (!contentType || contentType === 'application/octet-stream') {\n logger.info('Content-Type unclear, fetching first 1KB to verify...');\n\n const getController = new AbortController();\n const getTimeoutId = setTimeout(() => getController.abort(), 5000);\n\n try {\n const getResponse = await fetch(params.url, {\n signal: getController.signal,\n headers: {\n Range: 'bytes=0-1023', // Get first 1KB\n },\n });\n\n clearTimeout(getTimeoutId);\n\n if (getResponse.ok || getResponse.status === 206) {\n\n const buffer = await getResponse.arrayBuffer();\n const bytes = new Uint8Array(buffer);\n const text = new TextDecoder('utf-8', { fatal: false }).decode(\n bytes.slice(0, 512)\n );\n\n if (\n text.toLowerCase().includes('<!doctype html') ||\n text.toLowerCase().includes('<html') ||\n text.match(/<meta\\s+[^>]*>/i) ||\n text.match(/<title>/i)\n ) {\n throw new Error(\n `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.`\n );\n }\n }\n } catch (getError) {\n clearTimeout(getTimeoutId);\n if (\n getError instanceof Error &&\n getError.message.includes('HTML content')\n ) {\n throw getError;\n }\n logger.warn(\n `Could not perform partial GET validation: ${\n getError instanceof Error ? getError.message : 'Unknown error'\n }`\n );\n }\n }\n\n logger.info(\n `URL validation passed. Content-Type: ${contentType}, Content-Length: ${\n contentLength || 'unknown'\n }`\n );\n } catch (fetchError) {\n clearTimeout(timeoutId);\n throw fetchError;\n }\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n logger.warn(\n 'URL validation timed out after 10 seconds. Proceeding with inscription attempt.'\n );\n } else if (\n error.message.includes('URL returned error') ||\n error.message.includes('empty content') ||\n error.message.includes('too small') ||\n error.message.includes('HTML')\n ) {\n throw error;\n } else {\n logger.warn(\n `Could not validate URL with HEAD request: ${error.message}. Proceeding with inscription attempt.`\n );\n }\n }\n }\n\n const options: InscriptionOptions = {\n mode: params.mode,\n metadata: params.metadata,\n tags: params.tags,\n chunkSize: params.chunkSize,\n waitForConfirmation: params.quoteOnly\n ? false\n : params.waitForConfirmation ?? true,\n waitMaxAttempts: 60,\n waitIntervalMs: 5000,\n apiKey: params.apiKey,\n network: this.inscriberBuilder['hederaKit'].client.network\n .toString()\n .includes('mainnet')\n ? 'mainnet'\n : 'testnet',\n quoteOnly: params.quoteOnly,\n };\n\n if (params.quoteOnly) {\n try {\n const quote = await this.generateInscriptionQuote(\n { type: 'url', url: params.url },\n options\n );\n\n return {\n success: true,\n quote: {\n totalCostHbar: quote.totalCostHbar,\n validUntil: quote.validUntil,\n breakdown: quote.breakdown,\n },\n contentInfo: {\n url: params.url,\n },\n message: `Estimated Quote for URL: ${params.url}\\nTotal cost: ${quote.totalCostHbar} HBAR`,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to generate inscription quote';\n throw new Error(`Quote generation failed: ${errorMessage}`);\n }\n }\n\n try {\n let result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>;\n\n if (params.timeoutMs) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(\n () =>\n reject(\n new Error(`Inscription timed out after ${params.timeoutMs}ms`)\n ),\n params.timeoutMs\n );\n });\n\n result = await Promise.race([\n this.inscriberBuilder.inscribe(\n { type: 'url', url: params.url },\n options\n ),\n timeoutPromise,\n ]);\n } else {\n result = await this.inscriberBuilder.inscribe(\n { type: 'url', url: params.url },\n options\n );\n }\n\n if (result.confirmed && !result.quote) {\n const topicId =\n result.inscription?.topic_id || (result.result as any).topicId;\n const network = options.network || 'testnet';\n const cdnUrl = topicId\n ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}`\n : null;\n return `Successfully inscribed and confirmed content on the Hedera network!\\n\\nTransaction ID: ${\n (result.result as any).transactionId\n }\\nTopic ID: ${topicId || 'N/A'}${\n cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''\n }\\n\\nThe inscription is now available.`;\n } else if (!result.quote && !result.confirmed) {\n return `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${\n (result.result as any).transactionId\n }\\n\\nThe inscription is processing and will be confirmed shortly.`;\n } else {\n return 'Inscription operation completed.';\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Failed to inscribe from URL';\n throw new Error(`Inscription failed: ${errorMessage}`);\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -42,8 +42,8 @@ class InscribeFromBufferTool extends BaseInscriberQueryTool {
|
|
|
42
42
|
tags: params.tags,
|
|
43
43
|
chunkSize: params.chunkSize,
|
|
44
44
|
waitForConfirmation: params.quoteOnly ? false : params.waitForConfirmation ?? true,
|
|
45
|
-
waitMaxAttempts:
|
|
46
|
-
waitIntervalMs:
|
|
45
|
+
waitMaxAttempts: 60,
|
|
46
|
+
waitIntervalMs: 5e3,
|
|
47
47
|
apiKey: params.apiKey,
|
|
48
48
|
network: this.inscriberBuilder["hederaKit"].client.network.toString().includes("mainnet") ? "mainnet" : "testnet",
|
|
49
49
|
quoteOnly: params.quoteOnly
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standards-agent-kit.es36.js","sources":["../../src/tools/inscriber/InscribeFromBufferTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport { InscriptionOptions } from '@hashgraphonline/standards-sdk';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport { resolveContent } from '../../utils/content-resolver';\nimport { contentRefSchema } from '../../validation/content-ref-schemas';\nimport { loadConfig } from '../../config/ContentReferenceConfig';\n\nconst inscribeFromBufferSchema = z.object({\n base64Data: z.union([z.string(), contentRefSchema])\n .describe('Content to inscribe as base64 data, plain text, or content reference'),\n fileName: z.string().min(1).describe('Name for the inscribed content'),\n mimeType: z.string().optional().describe('MIME type of the content'),\n metadata: z.record(z.unknown()).optional().describe('Metadata to attach'),\n tags: z.array(z.string()).optional().describe('Tags to categorize the inscription'),\n chunkSize: z.number().int().positive().optional().describe('Chunk size for large files'),\n waitForConfirmation: z.boolean().optional().describe('Wait for inscription confirmation'),\n timeoutMs: z.number().int().positive().optional().describe('Timeout in milliseconds'),\n apiKey: z.string().optional().describe('API key for inscription service'),\n quoteOnly: z.boolean().optional().default(false).describe('Return cost quote only'),\n});\n\nexport class InscribeFromBufferTool extends BaseInscriberQueryTool<\n typeof inscribeFromBufferSchema\n> {\n name = 'inscribeFromBuffer';\n description =\n 'Use ONLY for inscribing regular files or content (NOT for NFT/Hashinal inscriptions). When user says \"inscribe it\" after you showed search results or other content WITHOUT mentioning NFT/hashinal, 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. Set quoteOnly=true to get cost estimates without executing the inscription. NEVER use this for Hashinal NFTs - always use InscribeHashinalTool instead when user mentions hashinal, NFT, dynamic, or minting.';\n\n private config = loadConfig();\n\n get specificInputSchema() {\n return inscribeFromBufferSchema;\n }\n\n protected async executeQuery(\n params: z.infer<typeof inscribeFromBufferSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<unknown> {\n this.validateInput(params);\n\n const resolvedContent = await resolveContent(\n params.base64Data,\n params.mimeType,\n params.fileName\n );\n\n this.validateContent(resolvedContent.buffer);\n\n const buffer = resolvedContent.buffer;\n const resolvedMimeType = resolvedContent.mimeType || params.mimeType;\n const resolvedFileName = resolvedContent.fileName || params.fileName;\n\n const options: InscriptionOptions = {\n mode: 'file',\n metadata: params.metadata,\n tags: params.tags,\n chunkSize: params.chunkSize,\n waitForConfirmation: params.quoteOnly\n ? false\n : params.waitForConfirmation ?? true,\n waitMaxAttempts: 10,\n waitIntervalMs: 3000,\n apiKey: params.apiKey,\n network: this.inscriberBuilder['hederaKit'].client.network\n .toString()\n .includes('mainnet')\n ? 'mainnet'\n : 'testnet',\n quoteOnly: params.quoteOnly,\n };\n\n if (params.quoteOnly) {\n try {\n const quote = await this.generateInscriptionQuote(\n {\n type: 'buffer',\n buffer,\n fileName: resolvedFileName,\n mimeType: resolvedMimeType,\n },\n options\n );\n\n return {\n success: true,\n quote: {\n totalCostHbar: quote.totalCostHbar,\n validUntil: quote.validUntil,\n breakdown: quote.breakdown,\n },\n contentInfo: {\n fileName: resolvedFileName,\n mimeType: resolvedMimeType,\n sizeBytes: buffer.length,\n },\n message: `Estimated Quote for buffer content: ${resolvedFileName} (${(\n buffer.length / 1024\n ).toFixed(2)} KB)\\nTotal cost: ${quote.totalCostHbar} HBAR`,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to generate inscription quote';\n throw new Error(`Quote generation failed: ${errorMessage}`);\n }\n }\n\n try {\n const result = await this.executeInscription(\n buffer,\n resolvedFileName,\n resolvedMimeType,\n options,\n params.timeoutMs\n );\n return this.formatInscriptionResult(result, options);\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to inscribe from buffer';\n throw new Error(`Inscription failed: ${errorMessage}`);\n }\n }\n\n private validateInput(\n params: z.infer<typeof inscribeFromBufferSchema>\n ): void {\n if (!params.base64Data || params.base64Data.trim() === '') {\n throw new Error(\n 'No data provided. Cannot inscribe empty content. Please provide valid content, plain text, base64 encoded data, or a content reference ID.'\n );\n }\n\n if (!params.fileName || params.fileName.trim() === '') {\n throw new Error(\n 'No fileName provided. A valid fileName is required for inscription.'\n );\n }\n }\n\n private validateContent(buffer: Buffer): void {\n if (buffer.length === 0) {\n throw new Error(\n 'Buffer is empty after conversion. The provided data appears to be invalid or empty.'\n );\n }\n\n if (buffer.length > this.config.maxInscriptionSize) {\n const maxSizeKB = Math.round(this.config.maxInscriptionSize / 1024);\n const bufferSizeKB = Math.round(buffer.length / 1024);\n throw new Error(\n `Content is too large for inscription (${bufferSizeKB}KB, max ${maxSizeKB}KB). Please summarize or extract key information before inscribing.`\n );\n }\n\n if (buffer.length < this.config.minContentSize) {\n throw new Error(\n `Buffer content is too small (${buffer.length} bytes). This may indicate empty or invalid content. Please verify the source data contains actual content.`\n );\n }\n\n if (\n buffer.toString('utf8', 0, Math.min(buffer.length, 100)).trim() === ''\n ) {\n throw new Error(\n 'Buffer contains only whitespace or empty content. Cannot inscribe meaningless data.'\n );\n }\n\n const contentStr = buffer.toString('utf8');\n const emptyHtmlPattern = /<a\\s+href=[\"'][^\"']+[\"']\\s*>\\s*<\\/a>/i;\n const hasOnlyEmptyLinks =\n emptyHtmlPattern.test(contentStr) &&\n contentStr.replace(/<[^>]+>/g, '').trim().length < 50;\n\n if (hasOnlyEmptyLinks) {\n throw new Error(\n '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.'\n );\n }\n }\n\n private async executeInscription(\n buffer: Buffer,\n fileName: string,\n mimeType: string | undefined,\n options: InscriptionOptions,\n timeoutMs?: number\n ): Promise<Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>> {\n const inscriptionData = {\n type: 'buffer' as const,\n buffer,\n fileName,\n mimeType,\n };\n\n if (timeoutMs) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(\n () => reject(new Error(`Inscription timed out after ${timeoutMs}ms`)),\n timeoutMs\n );\n });\n\n return Promise.race([\n this.inscriberBuilder.inscribe(inscriptionData, options),\n timeoutPromise,\n ]);\n }\n\n return this.inscriberBuilder.inscribe(inscriptionData, options);\n }\n\n private formatInscriptionResult(\n result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>,\n options: InscriptionOptions\n ): string {\n if (result.confirmed && !result.quote) {\n const topicId =\n result.inscription?.topic_id || (result.result as any).topicId;\n const network = options.network || 'testnet';\n const cdnUrl = topicId\n ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}`\n : null;\n return `Successfully inscribed and confirmed content on the Hedera network!\\n\\nTransaction ID: ${\n (result.result as any).transactionId\n }\\nTopic ID: ${topicId || 'N/A'}${\n cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''\n }\\n\\nThe inscription is now available.`;\n }\n\n if (!result.quote && !result.confirmed) {\n return `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${\n (result.result as any).transactionId\n }\\n\\nThe inscription is processing and will be confirmed shortly.`;\n }\n\n return 'Inscription operation completed.';\n }\n\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"standards-agent-kit.es36.js","sources":["../../src/tools/inscriber/InscribeFromBufferTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { BaseInscriberQueryTool } from './base-inscriber-tools';\nimport { InscriptionOptions } from '@hashgraphonline/standards-sdk';\nimport { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';\nimport { resolveContent } from '../../utils/content-resolver';\nimport { contentRefSchema } from '../../validation/content-ref-schemas';\nimport { loadConfig } from '../../config/ContentReferenceConfig';\n\nconst inscribeFromBufferSchema = z.object({\n base64Data: z.union([z.string(), contentRefSchema])\n .describe('Content to inscribe as base64 data, plain text, or content reference'),\n fileName: z.string().min(1).describe('Name for the inscribed content'),\n mimeType: z.string().optional().describe('MIME type of the content'),\n metadata: z.record(z.unknown()).optional().describe('Metadata to attach'),\n tags: z.array(z.string()).optional().describe('Tags to categorize the inscription'),\n chunkSize: z.number().int().positive().optional().describe('Chunk size for large files'),\n waitForConfirmation: z.boolean().optional().describe('Wait for inscription confirmation'),\n timeoutMs: z.number().int().positive().optional().describe('Timeout in milliseconds'),\n apiKey: z.string().optional().describe('API key for inscription service'),\n quoteOnly: z.boolean().optional().default(false).describe('Return cost quote only'),\n});\n\nexport class InscribeFromBufferTool extends BaseInscriberQueryTool<\n typeof inscribeFromBufferSchema\n> {\n name = 'inscribeFromBuffer';\n description =\n 'Use ONLY for inscribing regular files or content (NOT for NFT/Hashinal inscriptions). When user says \"inscribe it\" after you showed search results or other content WITHOUT mentioning NFT/hashinal, 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. Set quoteOnly=true to get cost estimates without executing the inscription. NEVER use this for Hashinal NFTs - always use InscribeHashinalTool instead when user mentions hashinal, NFT, dynamic, or minting.';\n\n private config = loadConfig();\n\n get specificInputSchema() {\n return inscribeFromBufferSchema;\n }\n\n protected async executeQuery(\n params: z.infer<typeof inscribeFromBufferSchema>,\n _runManager?: CallbackManagerForToolRun\n ): Promise<unknown> {\n this.validateInput(params);\n\n const resolvedContent = await resolveContent(\n params.base64Data,\n params.mimeType,\n params.fileName\n );\n\n this.validateContent(resolvedContent.buffer);\n\n const buffer = resolvedContent.buffer;\n const resolvedMimeType = resolvedContent.mimeType || params.mimeType;\n const resolvedFileName = resolvedContent.fileName || params.fileName;\n\n const options: InscriptionOptions = {\n mode: 'file',\n metadata: params.metadata,\n tags: params.tags,\n chunkSize: params.chunkSize,\n waitForConfirmation: params.quoteOnly\n ? false\n : params.waitForConfirmation ?? true,\n waitMaxAttempts: 60,\n waitIntervalMs: 5000,\n apiKey: params.apiKey,\n network: this.inscriberBuilder['hederaKit'].client.network\n .toString()\n .includes('mainnet')\n ? 'mainnet'\n : 'testnet',\n quoteOnly: params.quoteOnly,\n };\n\n if (params.quoteOnly) {\n try {\n const quote = await this.generateInscriptionQuote(\n {\n type: 'buffer',\n buffer,\n fileName: resolvedFileName,\n mimeType: resolvedMimeType,\n },\n options\n );\n\n return {\n success: true,\n quote: {\n totalCostHbar: quote.totalCostHbar,\n validUntil: quote.validUntil,\n breakdown: quote.breakdown,\n },\n contentInfo: {\n fileName: resolvedFileName,\n mimeType: resolvedMimeType,\n sizeBytes: buffer.length,\n },\n message: `Estimated Quote for buffer content: ${resolvedFileName} (${(\n buffer.length / 1024\n ).toFixed(2)} KB)\\nTotal cost: ${quote.totalCostHbar} HBAR`,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to generate inscription quote';\n throw new Error(`Quote generation failed: ${errorMessage}`);\n }\n }\n\n try {\n const result = await this.executeInscription(\n buffer,\n resolvedFileName,\n resolvedMimeType,\n options,\n params.timeoutMs\n );\n return this.formatInscriptionResult(result, options);\n } catch (error) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : 'Failed to inscribe from buffer';\n throw new Error(`Inscription failed: ${errorMessage}`);\n }\n }\n\n private validateInput(\n params: z.infer<typeof inscribeFromBufferSchema>\n ): void {\n if (!params.base64Data || params.base64Data.trim() === '') {\n throw new Error(\n 'No data provided. Cannot inscribe empty content. Please provide valid content, plain text, base64 encoded data, or a content reference ID.'\n );\n }\n\n if (!params.fileName || params.fileName.trim() === '') {\n throw new Error(\n 'No fileName provided. A valid fileName is required for inscription.'\n );\n }\n }\n\n private validateContent(buffer: Buffer): void {\n if (buffer.length === 0) {\n throw new Error(\n 'Buffer is empty after conversion. The provided data appears to be invalid or empty.'\n );\n }\n\n if (buffer.length > this.config.maxInscriptionSize) {\n const maxSizeKB = Math.round(this.config.maxInscriptionSize / 1024);\n const bufferSizeKB = Math.round(buffer.length / 1024);\n throw new Error(\n `Content is too large for inscription (${bufferSizeKB}KB, max ${maxSizeKB}KB). Please summarize or extract key information before inscribing.`\n );\n }\n\n if (buffer.length < this.config.minContentSize) {\n throw new Error(\n `Buffer content is too small (${buffer.length} bytes). This may indicate empty or invalid content. Please verify the source data contains actual content.`\n );\n }\n\n if (\n buffer.toString('utf8', 0, Math.min(buffer.length, 100)).trim() === ''\n ) {\n throw new Error(\n 'Buffer contains only whitespace or empty content. Cannot inscribe meaningless data.'\n );\n }\n\n const contentStr = buffer.toString('utf8');\n const emptyHtmlPattern = /<a\\s+href=[\"'][^\"']+[\"']\\s*>\\s*<\\/a>/i;\n const hasOnlyEmptyLinks =\n emptyHtmlPattern.test(contentStr) &&\n contentStr.replace(/<[^>]+>/g, '').trim().length < 50;\n\n if (hasOnlyEmptyLinks) {\n throw new Error(\n '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.'\n );\n }\n }\n\n private async executeInscription(\n buffer: Buffer,\n fileName: string,\n mimeType: string | undefined,\n options: InscriptionOptions,\n timeoutMs?: number\n ): Promise<Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>> {\n const inscriptionData = {\n type: 'buffer' as const,\n buffer,\n fileName,\n mimeType,\n };\n\n if (timeoutMs) {\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(\n () => reject(new Error(`Inscription timed out after ${timeoutMs}ms`)),\n timeoutMs\n );\n });\n\n return Promise.race([\n this.inscriberBuilder.inscribe(inscriptionData, options),\n timeoutPromise,\n ]);\n }\n\n return this.inscriberBuilder.inscribe(inscriptionData, options);\n }\n\n private formatInscriptionResult(\n result: Awaited<ReturnType<typeof this.inscriberBuilder.inscribe>>,\n options: InscriptionOptions\n ): string {\n if (result.confirmed && !result.quote) {\n const topicId =\n result.inscription?.topic_id || (result.result as any).topicId;\n const network = options.network || 'testnet';\n const cdnUrl = topicId\n ? `https://kiloscribe.com/api/inscription-cdn/${topicId}?network=${network}`\n : null;\n return `Successfully inscribed and confirmed content on the Hedera network!\\n\\nTransaction ID: ${\n (result.result as any).transactionId\n }\\nTopic ID: ${topicId || 'N/A'}${\n cdnUrl ? `\\nView inscription: ${cdnUrl}` : ''\n }\\n\\nThe inscription is now available.`;\n }\n\n if (!result.quote && !result.confirmed) {\n return `Successfully submitted inscription to the Hedera network!\\n\\nTransaction ID: ${\n (result.result as any).transactionId\n }\\n\\nThe inscription is processing and will be confirmed shortly.`;\n }\n\n return 'Inscription operation completed.';\n }\n\n}\n"],"names":[],"mappings":";;;;;AAQA,MAAM,2BAA2B,EAAE,OAAO;AAAA,EACxC,YAAY,EAAE,MAAM,CAAC,EAAE,OAAA,GAAU,gBAAgB,CAAC,EAC/C,SAAS,sEAAsE;AAAA,EAClF,UAAU,EAAE,OAAA,EAAS,IAAI,CAAC,EAAE,SAAS,gCAAgC;AAAA,EACrE,UAAU,EAAE,OAAA,EAAS,SAAA,EAAW,SAAS,0BAA0B;AAAA,EACnE,UAAU,EAAE,OAAO,EAAE,QAAA,CAAS,EAAE,SAAA,EAAW,SAAS,oBAAoB;AAAA,EACxE,MAAM,EAAE,MAAM,EAAE,OAAA,CAAQ,EAAE,SAAA,EAAW,SAAS,oCAAoC;AAAA,EAClF,WAAW,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAW,SAAA,EAAW,SAAS,4BAA4B;AAAA,EACvF,qBAAqB,EAAE,QAAA,EAAU,SAAA,EAAW,SAAS,mCAAmC;AAAA,EACxF,WAAW,EAAE,OAAA,EAAS,IAAA,EAAM,SAAA,EAAW,SAAA,EAAW,SAAS,yBAAyB;AAAA,EACpF,QAAQ,EAAE,OAAA,EAAS,SAAA,EAAW,SAAS,iCAAiC;AAAA,EACxE,WAAW,EAAE,UAAU,SAAA,EAAW,QAAQ,KAAK,EAAE,SAAS,wBAAwB;AACpF,CAAC;AAEM,MAAM,+BAA+B,uBAE1C;AAAA,EAFK,cAAA;AAAA,UAAA,GAAA,SAAA;AAGL,SAAA,OAAO;AACP,SAAA,cACE;AAEF,SAAQ,SAAS,WAAA;AAAA,EAAW;AAAA,EAE5B,IAAI,sBAAsB;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAgB,aACd,QACA,aACkB;AAClB,SAAK,cAAc,MAAM;AAEzB,UAAM,kBAAkB,MAAM;AAAA,MAC5B,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,IAAA;AAGT,SAAK,gBAAgB,gBAAgB,MAAM;AAE3C,UAAM,SAAS,gBAAgB;AAC/B,UAAM,mBAAmB,gBAAgB,YAAY,OAAO;AAC5D,UAAM,mBAAmB,gBAAgB,YAAY,OAAO;AAE5D,UAAM,UAA8B;AAAA,MAClC,MAAM;AAAA,MACN,UAAU,OAAO;AAAA,MACjB,MAAM,OAAO;AAAA,MACb,WAAW,OAAO;AAAA,MAClB,qBAAqB,OAAO,YACxB,QACA,OAAO,uBAAuB;AAAA,MAClC,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,QAAQ,OAAO;AAAA,MACf,SAAS,KAAK,iBAAiB,WAAW,EAAE,OAAO,QAChD,SAAA,EACA,SAAS,SAAS,IACjB,YACA;AAAA,MACJ,WAAW,OAAO;AAAA,IAAA;AAGpB,QAAI,OAAO,WAAW;AACpB,UAAI;AACF,cAAM,QAAQ,MAAM,KAAK;AAAA,UACvB;AAAA,YACE,MAAM;AAAA,YACN;AAAA,YACA,UAAU;AAAA,YACV,UAAU;AAAA,UAAA;AAAA,UAEZ;AAAA,QAAA;AAGF,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,YACL,eAAe,MAAM;AAAA,YACrB,YAAY,MAAM;AAAA,YAClB,WAAW,MAAM;AAAA,UAAA;AAAA,UAEnB,aAAa;AAAA,YACX,UAAU;AAAA,YACV,UAAU;AAAA,YACV,WAAW,OAAO;AAAA,UAAA;AAAA,UAEpB,SAAS,uCAAuC,gBAAgB,MAC9D,OAAO,SAAS,MAChB,QAAQ,CAAC,CAAC;AAAA,cAAqB,MAAM,aAAa;AAAA,QAAA;AAAA,MAExD,SAAS,OAAO;AACd,cAAM,eACJ,iBAAiB,QACb,MAAM,UACN;AACN,cAAM,IAAI,MAAM,4BAA4B,YAAY,EAAE;AAAA,MAC5D;AAAA,IACF;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,MAAA;AAET,aAAO,KAAK,wBAAwB,QAAQ,OAAO;AAAA,IACrD,SAAS,OAAO;AACd,YAAM,eACJ,iBAAiB,QACb,MAAM,UACN;AACN,YAAM,IAAI,MAAM,uBAAuB,YAAY,EAAE;AAAA,IACvD;AAAA,EACF;AAAA,EAEQ,cACN,QACM;AACN,QAAI,CAAC,OAAO,cAAc,OAAO,WAAW,KAAA,MAAW,IAAI;AACzD,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,CAAC,OAAO,YAAY,OAAO,SAAS,KAAA,MAAW,IAAI;AACrD,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAAA,EACF;AAAA,EAEQ,gBAAgB,QAAsB;AAC5C,QAAI,OAAO,WAAW,GAAG;AACvB,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,OAAO,SAAS,KAAK,OAAO,oBAAoB;AAClD,YAAM,YAAY,KAAK,MAAM,KAAK,OAAO,qBAAqB,IAAI;AAClE,YAAM,eAAe,KAAK,MAAM,OAAO,SAAS,IAAI;AACpD,YAAM,IAAI;AAAA,QACR,yCAAyC,YAAY,WAAW,SAAS;AAAA,MAAA;AAAA,IAE7E;AAEA,QAAI,OAAO,SAAS,KAAK,OAAO,gBAAgB;AAC9C,YAAM,IAAI;AAAA,QACR,gCAAgC,OAAO,MAAM;AAAA,MAAA;AAAA,IAEjD;AAEA,QACE,OAAO,SAAS,QAAQ,GAAG,KAAK,IAAI,OAAO,QAAQ,GAAG,CAAC,EAAE,KAAA,MAAW,IACpE;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAEA,UAAM,aAAa,OAAO,SAAS,MAAM;AACzC,UAAM,mBAAmB;AACzB,UAAM,oBACJ,iBAAiB,KAAK,UAAU,KAChC,WAAW,QAAQ,YAAY,EAAE,EAAE,KAAA,EAAO,SAAS;AAErD,QAAI,mBAAmB;AACrB,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAAA,EACF;AAAA,EAEA,MAAc,mBACZ,QACA,UACA,UACA,SACA,WACqE;AACrE,UAAM,kBAAkB;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,QAAI,WAAW;AACb,YAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD;AAAA,UACE,MAAM,OAAO,IAAI,MAAM,+BAA+B,SAAS,IAAI,CAAC;AAAA,UACpE;AAAA,QAAA;AAAA,MAEJ,CAAC;AAED,aAAO,QAAQ,KAAK;AAAA,QAClB,KAAK,iBAAiB,SAAS,iBAAiB,OAAO;AAAA,QACvD;AAAA,MAAA,CACD;AAAA,IACH;AAEA,WAAO,KAAK,iBAAiB,SAAS,iBAAiB,OAAO;AAAA,EAChE;AAAA,EAEQ,wBACN,QACA,SACQ;AACR,QAAI,OAAO,aAAa,CAAC,OAAO,OAAO;AACrC,YAAM,UACJ,OAAO,aAAa,YAAa,OAAO,OAAe;AACzD,YAAM,UAAU,QAAQ,WAAW;AACnC,YAAM,SAAS,UACX,8CAA8C,OAAO,YAAY,OAAO,KACxE;AACJ,aAAO;AAAA;AAAA,kBACJ,OAAO,OAAe,aACzB;AAAA,YAAe,WAAW,KAAK,GAC7B,SAAS;AAAA,oBAAuB,MAAM,KAAK,EAC7C;AAAA;AAAA;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,SAAS,CAAC,OAAO,WAAW;AACtC,aAAO;AAAA;AAAA,kBACJ,OAAO,OAAe,aACzB;AAAA;AAAA;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEF;"}
|
|
@@ -19,7 +19,7 @@ const HASHLINK_BLOCK_CONFIG = {
|
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
21
|
function getHashLinkBlockId(network) {
|
|
22
|
-
const config = HASHLINK_BLOCK_CONFIG
|
|
22
|
+
const config = network === "mainnet" ? HASHLINK_BLOCK_CONFIG.mainnet : HASHLINK_BLOCK_CONFIG.testnet;
|
|
23
23
|
if (!config || config.blockId === "0.0.TBD") {
|
|
24
24
|
return HASHLINK_BLOCK_CONFIG.testnet;
|
|
25
25
|
}
|
|
@@ -96,6 +96,16 @@ class InscribeHashinalTool extends BaseInscriberQueryTool {
|
|
|
96
96
|
this.name = "inscribeHashinal";
|
|
97
97
|
this.description = "Tool for inscribing Hashinal NFTs. CRITICAL: When user provides content (url/contentRef/base64Data), call with ONLY the content parameters - DO NOT auto-generate name, description, creator, or attributes. A form will be automatically shown to collect metadata from the user. Only include metadata parameters if the user explicitly provided them in their message.";
|
|
98
98
|
}
|
|
99
|
+
// Declare entity resolution preferences to preserve user-specified literal fields
|
|
100
|
+
getEntityResolutionPreferences() {
|
|
101
|
+
return {
|
|
102
|
+
name: "literal",
|
|
103
|
+
description: "literal",
|
|
104
|
+
creator: "literal",
|
|
105
|
+
attributes: "literal",
|
|
106
|
+
properties: "literal"
|
|
107
|
+
};
|
|
108
|
+
}
|
|
99
109
|
get specificInputSchema() {
|
|
100
110
|
const baseSchema = inscribeHashinalSchema._def?.schema || inscribeHashinalSchema;
|
|
101
111
|
return baseSchema;
|
|
@@ -185,12 +195,7 @@ class InscribeHashinalTool extends BaseInscriberQueryTool {
|
|
|
185
195
|
value: z.union([z.string(), z.number()]).describe('Trait value (e.g., "Epic", "Blue", 85)')
|
|
186
196
|
})
|
|
187
197
|
)
|
|
188
|
-
).withRender(
|
|
189
|
-
renderConfigs.array(
|
|
190
|
-
"NFT Attributes",
|
|
191
|
-
"Attribute"
|
|
192
|
-
)
|
|
193
|
-
).optional().describe("Collectible traits and characteristics."),
|
|
198
|
+
).withRender(renderConfigs.array("NFT Attributes", "Attribute")).optional().describe("Collectible traits and characteristics."),
|
|
194
199
|
type: z.string().optional().describe(
|
|
195
200
|
'Category or genre of the NFT (e.g., "Digital Art", "Photography", "Collectible Card)'
|
|
196
201
|
)
|
|
@@ -204,24 +209,6 @@ class InscribeHashinalTool extends BaseInscriberQueryTool {
|
|
|
204
209
|
});
|
|
205
210
|
return focusedSchema;
|
|
206
211
|
}
|
|
207
|
-
/**
|
|
208
|
-
* Implementation of FormValidatable interface
|
|
209
|
-
* Validates metadata quality and provides detailed feedback
|
|
210
|
-
*/
|
|
211
|
-
validateMetadataQuality(input) {
|
|
212
|
-
const inputObj = input;
|
|
213
|
-
const hasRequiredMetadata = !!(inputObj.name && inputObj.description && inputObj.creator);
|
|
214
|
-
if (!hasRequiredMetadata) {
|
|
215
|
-
return {
|
|
216
|
-
needsForm: true,
|
|
217
|
-
reason: "Missing essential metadata (name, description, creator) for NFT creation"
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
return {
|
|
221
|
-
needsForm: false,
|
|
222
|
-
reason: "All required metadata fields present"
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
212
|
async executeQuery(params, _runManager) {
|
|
226
213
|
if (!params.url && !params.contentRef && !params.base64Data) {
|
|
227
214
|
return createInscriptionError({
|
|
@@ -271,7 +258,7 @@ class InscribeHashinalTool extends BaseInscriberQueryTool {
|
|
|
271
258
|
tags: params.tags,
|
|
272
259
|
chunkSize: params.chunkSize,
|
|
273
260
|
waitForConfirmation: params.quoteOnly ? false : params.waitForConfirmation ?? true,
|
|
274
|
-
waitMaxAttempts:
|
|
261
|
+
waitMaxAttempts: 60,
|
|
275
262
|
waitIntervalMs: 5e3,
|
|
276
263
|
network: this.inscriberBuilder["hederaKit"].client.network.toString().includes("mainnet") ? "mainnet" : "testnet",
|
|
277
264
|
quoteOnly: params.quoteOnly
|
|
@@ -374,6 +361,12 @@ class InscribeHashinalTool extends BaseInscriberQueryTool {
|
|
|
374
361
|
attributes: params.attributes
|
|
375
362
|
}
|
|
376
363
|
});
|
|
364
|
+
this.onEntityCreated?.({
|
|
365
|
+
entityId: jsonTopicId || imageTopicId || "unknown",
|
|
366
|
+
entityName: params.name || "Unnamed Inscription",
|
|
367
|
+
entityType: "topicId",
|
|
368
|
+
transactionId: result.result?.transactionId
|
|
369
|
+
});
|
|
377
370
|
if (params.withHashLinkBlocks) {
|
|
378
371
|
try {
|
|
379
372
|
const blockData = await this.createHashLinkBlock(
|
|
@@ -413,6 +406,12 @@ class InscribeHashinalTool extends BaseInscriberQueryTool {
|
|
|
413
406
|
attributes: params.attributes
|
|
414
407
|
}
|
|
415
408
|
});
|
|
409
|
+
this.onEntityCreated?.({
|
|
410
|
+
entityId: jsonTopicId || imageTopicId || "unknown",
|
|
411
|
+
entityName: params.name || "Unnamed Inscription",
|
|
412
|
+
entityType: "topicId",
|
|
413
|
+
transactionId: result.result?.transactionId
|
|
414
|
+
});
|
|
416
415
|
if (params.withHashLinkBlocks) {
|
|
417
416
|
try {
|
|
418
417
|
const blockData = await this.createHashLinkBlock(
|