@hashgraphonline/conversational-agent 0.1.217 → 0.1.219
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/cli/readme.md +181 -0
- package/dist/cjs/constants/entity-references.d.ts +18 -0
- package/dist/cjs/constants/form-priorities.d.ts +24 -0
- package/dist/cjs/constants/index.d.ts +4 -0
- package/dist/cjs/constants/messages.d.ts +19 -0
- package/dist/cjs/constants/test-constants.d.ts +42 -0
- package/dist/cjs/conversational-agent.d.ts +3 -8
- package/dist/{types/core/ToolRegistry.d.ts → cjs/core/tool-registry.d.ts} +11 -1
- package/dist/{types/execution/ExecutionPipeline.d.ts → cjs/execution/execution-pipeline.d.ts} +3 -3
- package/dist/cjs/forms/field-guidance-registry.d.ts +108 -0
- package/dist/cjs/forms/form-generator.d.ts +2 -7
- package/dist/cjs/forms/index.d.ts +3 -0
- package/dist/cjs/forms/types.d.ts +9 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +7 -12
- package/dist/cjs/langchain/external-tool-wrapper.d.ts +101 -0
- package/dist/{types/langchain/FormAwareAgentExecutor.d.ts → cjs/langchain/form-aware-agent-executor.d.ts} +19 -4
- package/dist/cjs/langchain/index.d.ts +3 -0
- package/dist/{types → cjs/langchain}/langchain-agent.d.ts +15 -7
- package/dist/cjs/mcp/adapters/index.d.ts +1 -0
- package/dist/cjs/mcp/adapters/langchain.d.ts +1 -1
- package/dist/{types/mcp/ContentProcessor.d.ts → cjs/mcp/content-processor.d.ts} +1 -1
- package/dist/cjs/mcp/index.d.ts +5 -0
- package/dist/{types/mcp/MCPClientManager.d.ts → cjs/mcp/mcp-client-manager.d.ts} +1 -1
- package/dist/cjs/memory/{ContentStorage.d.ts → content-storage.d.ts} +4 -4
- package/dist/cjs/memory/index.d.ts +5 -7
- package/dist/{types/memory/MemoryWindow.d.ts → cjs/memory/memory-window.d.ts} +1 -1
- package/dist/{types/memory/SmartMemoryManager.d.ts → cjs/memory/smart-memory-manager.d.ts} +1 -1
- package/dist/cjs/services/{ContentStoreManager.d.ts → content-store-manager.d.ts} +6 -6
- package/dist/cjs/services/context/resolution-context.d.ts +49 -0
- package/dist/cjs/services/entity-resolver.d.ts +58 -0
- package/dist/cjs/services/formatters/converters/index.d.ts +2 -0
- package/dist/cjs/services/formatters/converters/string-normalization-converter.d.ts +13 -0
- package/dist/cjs/services/formatters/converters/topic-id-to-hrl-converter.d.ts +17 -0
- package/dist/cjs/services/formatters/format-converter-registry.d.ts +66 -0
- package/dist/cjs/services/formatters/index.d.ts +3 -0
- package/dist/cjs/services/formatters/types.d.ts +29 -0
- package/dist/cjs/services/index.d.ts +3 -0
- package/dist/cjs/services/resolution/resolution-pipeline.d.ts +44 -0
- package/dist/cjs/tools/index.d.ts +1 -0
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/esm/index.js +40 -13
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index10.js +669 -13
- package/dist/esm/index10.js.map +1 -1
- package/dist/esm/index11.js +310 -95
- package/dist/esm/index11.js.map +1 -1
- package/dist/esm/index12.js +130 -95
- package/dist/esm/index12.js.map +1 -1
- package/dist/esm/index13.js +262 -153
- package/dist/esm/index13.js.map +1 -1
- package/dist/esm/index14.js +100 -664
- package/dist/esm/index14.js.map +1 -1
- package/dist/esm/index15.js +135 -408
- package/dist/esm/index15.js.map +1 -1
- package/dist/esm/index16.js +240 -122
- package/dist/esm/index16.js.map +1 -1
- package/dist/esm/index17.js +147 -135
- package/dist/esm/index17.js.map +1 -1
- package/dist/esm/index18.js +376 -533
- package/dist/esm/index18.js.map +1 -1
- package/dist/esm/index19.js +87 -214
- package/dist/esm/index19.js.map +1 -1
- package/dist/esm/index2.js +21 -4
- package/dist/esm/index2.js.map +1 -1
- package/dist/esm/index20.js +158 -92
- package/dist/esm/index20.js.map +1 -1
- package/dist/esm/index21.js +717 -44
- package/dist/esm/index21.js.map +1 -1
- package/dist/esm/index22.js +58 -96
- package/dist/esm/index22.js.map +1 -1
- package/dist/esm/index23.js +324 -34
- package/dist/esm/index23.js.map +1 -1
- package/dist/esm/index24.js +125 -712
- package/dist/esm/index24.js.map +1 -1
- package/dist/esm/index25.js +113 -133
- package/dist/esm/index25.js.map +1 -1
- package/dist/esm/index26.js +18 -152
- package/dist/esm/index26.js.map +1 -1
- package/dist/esm/index27.js +14 -210
- package/dist/esm/index27.js.map +1 -1
- package/dist/esm/index28.js +70 -173
- package/dist/esm/index28.js.map +1 -1
- package/dist/esm/index29.js +882 -220
- package/dist/esm/index29.js.map +1 -1
- package/dist/esm/index30.js +218 -126
- package/dist/esm/index30.js.map +1 -1
- package/dist/esm/index31.js +1258 -44
- package/dist/esm/index31.js.map +1 -1
- package/dist/esm/index32.js +132 -24
- package/dist/esm/index32.js.map +1 -1
- package/dist/esm/index33.js +104 -82
- package/dist/esm/index33.js.map +1 -1
- package/dist/esm/index34.js +43 -239
- package/dist/esm/index34.js.map +1 -1
- package/dist/esm/index35.js +106 -0
- package/dist/esm/index35.js.map +1 -0
- package/dist/esm/index36.js +24 -0
- package/dist/esm/index36.js.map +1 -0
- package/dist/esm/index37.js +8 -0
- package/dist/esm/index37.js.map +1 -0
- package/dist/esm/index38.js +15 -0
- package/dist/esm/index38.js.map +1 -0
- package/dist/esm/index39.js +258 -0
- package/dist/esm/index39.js.map +1 -0
- package/dist/esm/index40.js +187 -0
- package/dist/esm/index40.js.map +1 -0
- package/dist/esm/index41.js +30 -0
- package/dist/esm/index41.js.map +1 -0
- package/dist/esm/index42.js +10 -0
- package/dist/esm/index42.js.map +1 -0
- package/dist/esm/index43.js +95 -0
- package/dist/esm/index43.js.map +1 -0
- package/dist/esm/index5.js +2 -2
- package/dist/esm/index5.js.map +1 -1
- package/dist/esm/index6.js +44 -67
- package/dist/esm/index6.js.map +1 -1
- package/dist/esm/index7.js +9 -0
- package/dist/esm/index7.js.map +1 -1
- package/dist/esm/index8.js +13 -1095
- package/dist/esm/index8.js.map +1 -1
- package/dist/esm/index9.js +17 -13
- package/dist/esm/index9.js.map +1 -1
- package/dist/types/constants/entity-references.d.ts +18 -0
- package/dist/types/constants/form-priorities.d.ts +24 -0
- package/dist/types/constants/index.d.ts +4 -0
- package/dist/types/constants/messages.d.ts +19 -0
- package/dist/types/constants/test-constants.d.ts +42 -0
- package/dist/types/conversational-agent.d.ts +3 -8
- package/dist/{cjs/core/ToolRegistry.d.ts → types/core/tool-registry.d.ts} +11 -1
- package/dist/{cjs/execution/ExecutionPipeline.d.ts → types/execution/execution-pipeline.d.ts} +3 -3
- package/dist/types/forms/field-guidance-registry.d.ts +108 -0
- package/dist/types/forms/form-generator.d.ts +2 -7
- package/dist/types/forms/index.d.ts +3 -0
- package/dist/types/forms/types.d.ts +9 -1
- package/dist/types/index.d.ts +7 -12
- package/dist/types/langchain/external-tool-wrapper.d.ts +101 -0
- package/dist/{cjs/langchain/FormAwareAgentExecutor.d.ts → types/langchain/form-aware-agent-executor.d.ts} +19 -4
- package/dist/types/langchain/index.d.ts +3 -0
- package/dist/{cjs → types/langchain}/langchain-agent.d.ts +15 -7
- package/dist/types/mcp/adapters/index.d.ts +1 -0
- package/dist/types/mcp/adapters/langchain.d.ts +1 -1
- package/dist/{cjs/mcp/ContentProcessor.d.ts → types/mcp/content-processor.d.ts} +1 -1
- package/dist/types/mcp/index.d.ts +5 -0
- package/dist/{cjs/mcp/MCPClientManager.d.ts → types/mcp/mcp-client-manager.d.ts} +1 -1
- package/dist/types/memory/{ContentStorage.d.ts → content-storage.d.ts} +4 -4
- package/dist/types/memory/index.d.ts +5 -7
- package/dist/{cjs/memory/MemoryWindow.d.ts → types/memory/memory-window.d.ts} +1 -1
- package/dist/{cjs/memory/SmartMemoryManager.d.ts → types/memory/smart-memory-manager.d.ts} +1 -1
- package/dist/types/services/{ContentStoreManager.d.ts → content-store-manager.d.ts} +6 -6
- package/dist/types/services/context/resolution-context.d.ts +49 -0
- package/dist/types/services/entity-resolver.d.ts +58 -0
- package/dist/types/services/formatters/converters/index.d.ts +2 -0
- package/dist/types/services/formatters/converters/string-normalization-converter.d.ts +13 -0
- package/dist/types/services/formatters/converters/topic-id-to-hrl-converter.d.ts +17 -0
- package/dist/types/services/formatters/format-converter-registry.d.ts +66 -0
- package/dist/types/services/formatters/index.d.ts +3 -0
- package/dist/types/services/formatters/types.d.ts +29 -0
- package/dist/types/services/index.d.ts +3 -0
- package/dist/types/services/resolution/resolution-pipeline.d.ts +44 -0
- package/dist/types/tools/index.d.ts +1 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/package.json +30 -27
- package/src/agent-factory.ts +1 -1
- package/src/base-agent.ts +9 -0
- package/src/config/system-message.ts +2 -15
- package/src/constants/entity-references.ts +23 -0
- package/src/constants/form-priorities.ts +25 -0
- package/src/constants/index.ts +4 -0
- package/src/constants/messages.ts +20 -0
- package/src/constants/test-constants.ts +49 -0
- package/src/conversational-agent.ts +42 -69
- package/src/core/{ToolRegistry.ts → tool-registry.ts} +71 -1
- package/src/examples/external-tool-wrapper-example.ts +56 -0
- package/src/execution/{ExecutionPipeline.ts → execution-pipeline.ts} +3 -3
- package/src/forms/field-guidance-registry.ts +415 -0
- package/src/forms/field-type-registry.ts +49 -48
- package/src/forms/{FormEngine.ts → form-engine.ts} +66 -43
- package/src/forms/form-generator.ts +91 -17
- package/src/forms/index.ts +4 -1
- package/src/forms/types.ts +9 -1
- package/src/index.ts +7 -37
- package/src/langchain/external-tool-wrapper.ts +90 -0
- package/src/langchain/{FormAwareAgentExecutor.ts → form-aware-agent-executor.ts} +615 -231
- package/src/langchain/{FormValidatingToolWrapper.ts → form-validating-tool-wrapper.ts} +2 -1
- package/src/langchain/index.ts +3 -0
- package/src/{langchain-agent.ts → langchain/langchain-agent.ts} +389 -113
- package/src/mcp/adapters/index.ts +1 -0
- package/src/mcp/adapters/langchain.ts +27 -18
- package/src/mcp/{ContentProcessor.ts → content-processor.ts} +71 -47
- package/src/mcp/index.ts +5 -0
- package/src/mcp/{MCPClientManager.ts → mcp-client-manager.ts} +2 -2
- package/src/memory/{ContentStorage.ts → content-storage.ts} +263 -167
- package/src/memory/index.ts +5 -8
- package/src/memory/{MemoryWindow.ts → memory-window.ts} +47 -24
- package/src/memory/{SmartMemoryManager.ts → smart-memory-manager.ts} +49 -22
- package/src/plugins/hbar/HbarPlugin.ts +1 -1
- package/src/plugins/hcs-10/HCS10Plugin.ts +46 -28
- package/src/scripts/test-external-tool-wrapper.ts +6 -6
- package/src/scripts/test-inscribe-form-generation.ts +22 -21
- package/src/scripts/test-inscribe-wrapper-verification.ts +5 -4
- package/src/services/{ContentStoreManager.ts → content-store-manager.ts} +75 -33
- package/src/services/context/resolution-context.ts +80 -0
- package/src/services/entity-resolver.ts +425 -0
- package/src/services/formatters/converters/index.ts +2 -0
- package/src/services/formatters/converters/string-normalization-converter.ts +106 -0
- package/src/services/formatters/converters/topic-id-to-hrl-converter.ts +25 -0
- package/src/services/formatters/format-converter-registry.ts +229 -0
- package/src/services/formatters/index.ts +3 -0
- package/src/services/formatters/types.ts +31 -0
- package/src/services/index.ts +3 -0
- package/src/services/resolution/resolution-pipeline.ts +106 -0
- package/src/tools/index.ts +1 -0
- package/src/types/content-reference.ts +87 -60
- package/src/utils/index.ts +1 -0
- package/cli/dist/CLIApp.d.ts +0 -9
- package/cli/dist/CLIApp.js +0 -127
- package/cli/dist/LocalConversationalAgent.d.ts +0 -37
- package/cli/dist/LocalConversationalAgent.js +0 -58
- package/cli/dist/app.d.ts +0 -16
- package/cli/dist/app.js +0 -13
- package/cli/dist/cli.d.ts +0 -2
- package/cli/dist/cli.js +0 -51
- package/cli/dist/components/AppContainer.d.ts +0 -16
- package/cli/dist/components/AppContainer.js +0 -24
- package/cli/dist/components/AppScreens.d.ts +0 -2
- package/cli/dist/components/AppScreens.js +0 -259
- package/cli/dist/components/ChatScreen.d.ts +0 -15
- package/cli/dist/components/ChatScreen.js +0 -39
- package/cli/dist/components/DebugLoadingScreen.d.ts +0 -5
- package/cli/dist/components/DebugLoadingScreen.js +0 -31
- package/cli/dist/components/LoadingScreen.d.ts +0 -2
- package/cli/dist/components/LoadingScreen.js +0 -16
- package/cli/dist/components/LoadingScreenDebug.d.ts +0 -5
- package/cli/dist/components/LoadingScreenDebug.js +0 -27
- package/cli/dist/components/MCPConfigScreen.d.ts +0 -28
- package/cli/dist/components/MCPConfigScreen.js +0 -168
- package/cli/dist/components/ScreenRouter.d.ts +0 -12
- package/cli/dist/components/ScreenRouter.js +0 -22
- package/cli/dist/components/SetupScreen.d.ts +0 -15
- package/cli/dist/components/SetupScreen.js +0 -65
- package/cli/dist/components/SingleLoadingScreen.d.ts +0 -5
- package/cli/dist/components/SingleLoadingScreen.js +0 -27
- package/cli/dist/components/StatusBadge.d.ts +0 -7
- package/cli/dist/components/StatusBadge.js +0 -28
- package/cli/dist/components/TerminalWindow.d.ts +0 -8
- package/cli/dist/components/TerminalWindow.js +0 -24
- package/cli/dist/components/WelcomeScreen.d.ts +0 -11
- package/cli/dist/components/WelcomeScreen.js +0 -47
- package/cli/dist/context/AppContext.d.ts +0 -68
- package/cli/dist/context/AppContext.js +0 -363
- package/cli/dist/hooks/useInitializeAgent.d.ts +0 -19
- package/cli/dist/hooks/useInitializeAgent.js +0 -28
- package/cli/dist/hooks/useStableState.d.ts +0 -38
- package/cli/dist/hooks/useStableState.js +0 -68
- package/cli/dist/managers/AgentManager.d.ts +0 -57
- package/cli/dist/managers/AgentManager.js +0 -119
- package/cli/dist/managers/ConfigManager.d.ts +0 -53
- package/cli/dist/managers/ConfigManager.js +0 -173
- package/cli/dist/types.d.ts +0 -31
- package/cli/dist/types.js +0 -19
- package/dist/cjs/context/ReferenceContextManager.d.ts +0 -84
- package/dist/cjs/context/ReferenceResponseProcessor.d.ts +0 -76
- package/dist/cjs/services/EntityResolver.d.ts +0 -26
- package/dist/types/context/ReferenceContextManager.d.ts +0 -84
- package/dist/types/context/ReferenceResponseProcessor.d.ts +0 -76
- package/dist/types/services/EntityResolver.d.ts +0 -26
- package/src/context/ReferenceContextManager.ts +0 -350
- package/src/context/ReferenceResponseProcessor.ts +0 -295
- package/src/scripts/test-hedera-kit-wrapper.ts +0 -265
- package/src/services/EntityResolver.ts +0 -128
- /package/dist/cjs/forms/{FormEngine.d.ts → form-engine.d.ts} +0 -0
- /package/dist/cjs/langchain/{FormValidatingToolWrapper.d.ts → form-validating-tool-wrapper.d.ts} +0 -0
- /package/dist/cjs/memory/{ReferenceIdGenerator.d.ts → reference-id-generator.d.ts} +0 -0
- /package/dist/cjs/memory/{TokenCounter.d.ts → token-counter.d.ts} +0 -0
- /package/dist/cjs/tools/{EntityResolverTool.d.ts → entity-resolver-tool.d.ts} +0 -0
- /package/dist/cjs/utils/{ResponseFormatter.d.ts → response-formatter.d.ts} +0 -0
- /package/dist/types/forms/{FormEngine.d.ts → form-engine.d.ts} +0 -0
- /package/dist/types/langchain/{FormValidatingToolWrapper.d.ts → form-validating-tool-wrapper.d.ts} +0 -0
- /package/dist/types/memory/{ReferenceIdGenerator.d.ts → reference-id-generator.d.ts} +0 -0
- /package/dist/types/memory/{TokenCounter.d.ts → token-counter.d.ts} +0 -0
- /package/dist/types/tools/{EntityResolverTool.d.ts → entity-resolver-tool.d.ts} +0 -0
- /package/dist/types/utils/{ResponseFormatter.d.ts → response-formatter.d.ts} +0 -0
- /package/src/memory/{ReferenceIdGenerator.ts → reference-id-generator.ts} +0 -0
- /package/src/memory/{TokenCounter.ts → token-counter.ts} +0 -0
- /package/src/tools/{EntityResolverTool.ts → entity-resolver-tool.ts} +0 -0
- /package/src/utils/{ResponseFormatter.ts → response-formatter.ts} +0 -0
package/dist/esm/index13.js
CHANGED
|
@@ -1,180 +1,289 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
this.messages = [];
|
|
5
|
-
this.systemPrompt = "";
|
|
6
|
-
this.systemPromptTokens = 0;
|
|
7
|
-
if (reserveTokens >= maxTokens) {
|
|
8
|
-
throw new Error("Reserve tokens must be less than max tokens");
|
|
9
|
-
}
|
|
10
|
-
this.maxTokens = maxTokens;
|
|
11
|
-
this.reserveTokens = reserveTokens;
|
|
12
|
-
this.tokenCounter = tokenCounter || new TokenCounter();
|
|
1
|
+
class FieldGuidanceRegistry {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.configurations = [];
|
|
13
4
|
}
|
|
14
5
|
/**
|
|
15
|
-
*
|
|
16
|
-
* @param message - The message to add
|
|
17
|
-
* @returns Result of the add operation including any pruned messages
|
|
6
|
+
* Register field guidance for a specific tool
|
|
18
7
|
*/
|
|
19
|
-
|
|
20
|
-
this.
|
|
21
|
-
this.messages.push(message);
|
|
22
|
-
const currentTokens = this.getCurrentTokenCount();
|
|
23
|
-
const availableTokens = this.maxTokens - this.reserveTokens;
|
|
24
|
-
let prunedMessages = [];
|
|
25
|
-
if (currentTokens > availableTokens) {
|
|
26
|
-
this.messages.pop();
|
|
27
|
-
prunedMessages = this.pruneToFit();
|
|
28
|
-
this.messages.push(message);
|
|
29
|
-
}
|
|
30
|
-
return {
|
|
31
|
-
added: true,
|
|
32
|
-
prunedMessages,
|
|
33
|
-
currentTokenCount: this.getCurrentTokenCount(),
|
|
34
|
-
remainingCapacity: this.getRemainingTokenCapacity()
|
|
35
|
-
};
|
|
8
|
+
registerToolConfiguration(config) {
|
|
9
|
+
this.configurations.push(config);
|
|
36
10
|
}
|
|
37
11
|
/**
|
|
38
|
-
*
|
|
39
|
-
* Removes messages in pairs to maintain conversational flow
|
|
40
|
-
* @returns Array of pruned messages
|
|
12
|
+
* Get field guidance for a specific tool and field
|
|
41
13
|
*/
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
for (let i = 0; i < batchSize; i++) {
|
|
48
|
-
const prunedMessage = this.messages.shift();
|
|
49
|
-
if (prunedMessage) {
|
|
50
|
-
prunedMessages.push(prunedMessage);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
if (prunedMessages.length > 1e3) {
|
|
54
|
-
break;
|
|
14
|
+
getFieldGuidance(toolName, fieldName) {
|
|
15
|
+
for (const config of this.configurations) {
|
|
16
|
+
const matches = typeof config.toolPattern === "string" ? toolName.toLowerCase().includes(config.toolPattern.toLowerCase()) : config.toolPattern.test(toolName);
|
|
17
|
+
if (matches && config.fields[fieldName]) {
|
|
18
|
+
return config.fields[fieldName];
|
|
55
19
|
}
|
|
56
20
|
}
|
|
57
|
-
return
|
|
21
|
+
return null;
|
|
58
22
|
}
|
|
59
23
|
/**
|
|
60
|
-
* Get
|
|
61
|
-
* @returns Current token count
|
|
24
|
+
* Get global guidance for a tool
|
|
62
25
|
*/
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
* @returns Remaining tokens that can be used
|
|
70
|
-
*/
|
|
71
|
-
getRemainingTokenCapacity() {
|
|
72
|
-
return Math.max(0, this.maxTokens - this.getCurrentTokenCount());
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Check if a message can be added without exceeding limits
|
|
76
|
-
* @param message - The message to check
|
|
77
|
-
* @returns True if message can be added within reserve limits
|
|
78
|
-
*/
|
|
79
|
-
canAddMessage(message) {
|
|
80
|
-
const messageTokens = this.tokenCounter.countMessageTokens(message);
|
|
81
|
-
const currentTokens = this.getCurrentTokenCount();
|
|
82
|
-
const wouldExceedReserve = currentTokens + messageTokens > this.maxTokens - this.reserveTokens;
|
|
83
|
-
if (messageTokens > this.maxTokens) {
|
|
84
|
-
return false;
|
|
26
|
+
getGlobalGuidance(toolName) {
|
|
27
|
+
for (const config of this.configurations) {
|
|
28
|
+
const matches = typeof config.toolPattern === "string" ? toolName.toLowerCase().includes(config.toolPattern.toLowerCase()) : config.toolPattern.test(toolName);
|
|
29
|
+
if (matches && config.globalGuidance) {
|
|
30
|
+
return config.globalGuidance;
|
|
31
|
+
}
|
|
85
32
|
}
|
|
86
|
-
return
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Get all messages in the memory window
|
|
90
|
-
* @returns Copy of current messages array
|
|
91
|
-
*/
|
|
92
|
-
getMessages() {
|
|
93
|
-
return [...this.messages];
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Clear all messages from the memory window
|
|
97
|
-
*/
|
|
98
|
-
clear() {
|
|
99
|
-
this.messages = [];
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Set the system prompt and update token calculations
|
|
103
|
-
* @param systemPrompt - The system prompt text
|
|
104
|
-
*/
|
|
105
|
-
setSystemPrompt(systemPrompt) {
|
|
106
|
-
this.systemPrompt = systemPrompt;
|
|
107
|
-
this.systemPromptTokens = this.tokenCounter.estimateSystemPromptTokens(systemPrompt);
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Get the current system prompt
|
|
111
|
-
* @returns Current system prompt
|
|
112
|
-
*/
|
|
113
|
-
getSystemPrompt() {
|
|
114
|
-
return this.systemPrompt;
|
|
33
|
+
return null;
|
|
115
34
|
}
|
|
116
35
|
/**
|
|
117
|
-
*
|
|
118
|
-
* @returns Memory window configuration
|
|
36
|
+
* Validate field value against guidance rules
|
|
119
37
|
*/
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
systemPromptTokens: this.systemPromptTokens
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Update token limits
|
|
131
|
-
* @param maxTokens - New maximum token limit
|
|
132
|
-
* @param reserveTokens - New reserve token amount
|
|
133
|
-
*/
|
|
134
|
-
updateLimits(maxTokens, reserveTokens) {
|
|
135
|
-
if (reserveTokens !== void 0 && reserveTokens >= maxTokens) {
|
|
136
|
-
throw new Error("Reserve tokens must be less than max tokens");
|
|
38
|
+
validateFieldValue(toolName, fieldName, value) {
|
|
39
|
+
const guidance = this.getFieldGuidance(toolName, fieldName);
|
|
40
|
+
const warnings = [];
|
|
41
|
+
const errors = [];
|
|
42
|
+
if (!guidance || typeof value !== "string") {
|
|
43
|
+
return { isValid: true, warnings, errors };
|
|
137
44
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
45
|
+
if (guidance.warnings) {
|
|
46
|
+
for (const warning of guidance.warnings) {
|
|
47
|
+
if (warning.pattern.test(value)) {
|
|
48
|
+
warnings.push(warning.message);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
141
51
|
}
|
|
142
|
-
if (
|
|
143
|
-
|
|
52
|
+
if (guidance.validationRules) {
|
|
53
|
+
const { rejectPatterns, qualityChecks } = guidance.validationRules;
|
|
54
|
+
if (rejectPatterns) {
|
|
55
|
+
for (const reject of rejectPatterns) {
|
|
56
|
+
if (reject.pattern.test(value)) {
|
|
57
|
+
errors.push(`Rejected: ${reject.reason}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (qualityChecks) {
|
|
62
|
+
if (qualityChecks.forbidTechnicalTerms) {
|
|
63
|
+
const lowerValue = value.toLowerCase();
|
|
64
|
+
for (const term of qualityChecks.forbidTechnicalTerms) {
|
|
65
|
+
if (lowerValue.includes(term.toLowerCase())) {
|
|
66
|
+
errors.push(
|
|
67
|
+
`Avoid technical terms like "${term}" in NFT metadata`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (qualityChecks.requireSpecificTerms) {
|
|
73
|
+
const lowerValue = value.toLowerCase();
|
|
74
|
+
const hasRequired = qualityChecks.requireSpecificTerms.some(
|
|
75
|
+
(term) => lowerValue.includes(term.toLowerCase())
|
|
76
|
+
);
|
|
77
|
+
if (!hasRequired) {
|
|
78
|
+
warnings.push(
|
|
79
|
+
`Consider including terms like: ${qualityChecks.requireSpecificTerms.join(
|
|
80
|
+
", "
|
|
81
|
+
)}`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (qualityChecks.minNonTechnicalWords) {
|
|
86
|
+
const words = value.split(/\s+/).filter((word) => word.length > 2);
|
|
87
|
+
if (words.length < qualityChecks.minNonTechnicalWords) {
|
|
88
|
+
warnings.push(
|
|
89
|
+
`Consider providing more descriptive content (at least ${qualityChecks.minNonTechnicalWords} meaningful words)`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
144
94
|
}
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Get statistics about the memory window
|
|
148
|
-
* @returns Memory usage statistics
|
|
149
|
-
*/
|
|
150
|
-
getStats() {
|
|
151
|
-
const currentTokens = this.getCurrentTokenCount();
|
|
152
|
-
const capacity = this.maxTokens;
|
|
153
|
-
const usagePercentage = currentTokens / capacity * 100;
|
|
154
95
|
return {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
reserveTokens: this.reserveTokens,
|
|
159
|
-
systemPromptTokens: this.systemPromptTokens,
|
|
160
|
-
usagePercentage: Math.round(usagePercentage * 100) / 100,
|
|
161
|
-
remainingCapacity: this.getRemainingTokenCapacity(),
|
|
162
|
-
canAcceptMore: this.getRemainingTokenCapacity() > this.reserveTokens
|
|
96
|
+
isValid: errors.length === 0,
|
|
97
|
+
warnings,
|
|
98
|
+
errors
|
|
163
99
|
};
|
|
164
100
|
}
|
|
165
101
|
/**
|
|
166
|
-
*
|
|
102
|
+
* Clear all configurations (useful for testing)
|
|
167
103
|
*/
|
|
168
|
-
|
|
169
|
-
this.
|
|
170
|
-
this.tokenCounter.dispose();
|
|
104
|
+
clear() {
|
|
105
|
+
this.configurations = [];
|
|
171
106
|
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
107
|
+
}
|
|
108
|
+
const fieldGuidanceRegistry = new FieldGuidanceRegistry();
|
|
109
|
+
fieldGuidanceRegistry.registerToolConfiguration({
|
|
110
|
+
toolPattern: /inscribe.*hashinal/i,
|
|
111
|
+
globalGuidance: {
|
|
112
|
+
warnings: [
|
|
113
|
+
"Avoid auto-generating technical metadata like file types or upload sources",
|
|
114
|
+
"Focus on collectible traits that add value to the NFT"
|
|
115
|
+
],
|
|
116
|
+
qualityStandards: [
|
|
117
|
+
"Use meaningful names that describe the artwork or content",
|
|
118
|
+
"Include collectible attributes like rarity, style, or theme",
|
|
119
|
+
"Provide descriptions that tell a story or explain the concept"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
fields: {
|
|
123
|
+
name: {
|
|
124
|
+
suggestions: [
|
|
125
|
+
"Sunset Landscape #42",
|
|
126
|
+
"Digital Abstract Art",
|
|
127
|
+
"Cosmic Dream Series",
|
|
128
|
+
"Portrait Study #5"
|
|
129
|
+
],
|
|
130
|
+
validationRules: {
|
|
131
|
+
rejectPatterns: [
|
|
132
|
+
{
|
|
133
|
+
pattern: /^untitled$/i,
|
|
134
|
+
reason: 'Generic names like "Untitled" are not valuable for NFTs'
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
pattern: /^image|file|upload/i,
|
|
138
|
+
reason: "Avoid technical file references in NFT names"
|
|
139
|
+
}
|
|
140
|
+
],
|
|
141
|
+
qualityChecks: {
|
|
142
|
+
minNonTechnicalWords: 2,
|
|
143
|
+
forbidTechnicalTerms: [
|
|
144
|
+
"MIME",
|
|
145
|
+
"upload",
|
|
146
|
+
"file type",
|
|
147
|
+
"buffer",
|
|
148
|
+
"source"
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
contextualHelpText: "Create a distinctive name that collectors will find appealing and memorable"
|
|
153
|
+
},
|
|
154
|
+
description: {
|
|
155
|
+
suggestions: [
|
|
156
|
+
"A vibrant sunset captured in digital brushstrokes...",
|
|
157
|
+
"Part of the Cosmic Dreams collection, exploring...",
|
|
158
|
+
"This piece represents the intersection of technology and nature..."
|
|
159
|
+
],
|
|
160
|
+
validationRules: {
|
|
161
|
+
rejectPatterns: [
|
|
162
|
+
{
|
|
163
|
+
pattern: /uploaded by|file size|mime type|created from/i,
|
|
164
|
+
reason: "Avoid technical descriptions in NFT metadata"
|
|
165
|
+
}
|
|
166
|
+
],
|
|
167
|
+
qualityChecks: {
|
|
168
|
+
minNonTechnicalWords: 8,
|
|
169
|
+
forbidTechnicalTerms: [
|
|
170
|
+
"uploaded",
|
|
171
|
+
"file size",
|
|
172
|
+
"mime type",
|
|
173
|
+
"user upload",
|
|
174
|
+
"image format",
|
|
175
|
+
"pixel dimensions",
|
|
176
|
+
"file extension"
|
|
177
|
+
],
|
|
178
|
+
requireSpecificTerms: [
|
|
179
|
+
"art",
|
|
180
|
+
"collection",
|
|
181
|
+
"piece",
|
|
182
|
+
"concept",
|
|
183
|
+
"inspired",
|
|
184
|
+
"represents"
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
fieldTypeOverride: "textarea",
|
|
189
|
+
contextualHelpText: "Describe the story, inspiration, or artistic vision behind this NFT"
|
|
190
|
+
},
|
|
191
|
+
creator: {
|
|
192
|
+
suggestions: [
|
|
193
|
+
"0.0.123456 (Hedera Account ID)",
|
|
194
|
+
"ArtistName",
|
|
195
|
+
"StudioBrand",
|
|
196
|
+
"CollectiveDAO"
|
|
197
|
+
],
|
|
198
|
+
contextualHelpText: "Provide the creator's account ID, artist name, or brand identity"
|
|
199
|
+
},
|
|
200
|
+
attributes: {
|
|
201
|
+
predefinedOptions: [
|
|
202
|
+
{
|
|
203
|
+
value: "Rarity",
|
|
204
|
+
label: "Rarity",
|
|
205
|
+
description: "Common, Rare, Epic, Legendary"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
value: "Color",
|
|
209
|
+
label: "Color",
|
|
210
|
+
description: "Primary colors or palette"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
value: "Style",
|
|
214
|
+
label: "Style",
|
|
215
|
+
description: "Abstract, Realistic, Minimalist, etc."
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
value: "Theme",
|
|
219
|
+
label: "Theme",
|
|
220
|
+
description: "Nature, Technology, Fantasy, etc."
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
value: "Series",
|
|
224
|
+
label: "Series",
|
|
225
|
+
description: "Collection or series number"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
value: "Element",
|
|
229
|
+
label: "Element",
|
|
230
|
+
description: "Fire, Water, Earth, Air, etc."
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
value: "Power Level",
|
|
234
|
+
label: "Power Level",
|
|
235
|
+
description: "Numeric strength value"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
value: "Edition",
|
|
239
|
+
label: "Edition",
|
|
240
|
+
description: "Special, Limited, First, etc."
|
|
241
|
+
}
|
|
242
|
+
],
|
|
243
|
+
warnings: [
|
|
244
|
+
{
|
|
245
|
+
pattern: /mime.?type|file.?type|upload.?source/i,
|
|
246
|
+
message: "Technical metadata is not valuable for NFT collectors"
|
|
247
|
+
}
|
|
248
|
+
],
|
|
249
|
+
validationRules: {
|
|
250
|
+
rejectPatterns: [
|
|
251
|
+
{
|
|
252
|
+
pattern: /^(mime.?type|file.?type|source|origin|upload)$/i,
|
|
253
|
+
reason: "Technical attributes are not collectible traits"
|
|
254
|
+
}
|
|
255
|
+
],
|
|
256
|
+
qualityChecks: {
|
|
257
|
+
forbidTechnicalTerms: [
|
|
258
|
+
"MIME Type",
|
|
259
|
+
"File Type",
|
|
260
|
+
"Source",
|
|
261
|
+
"Origin",
|
|
262
|
+
"Upload Source",
|
|
263
|
+
"File Extension",
|
|
264
|
+
"Format"
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
contextualHelpText: "Add traits that make this NFT unique and valuable to collectors"
|
|
269
|
+
},
|
|
270
|
+
type: {
|
|
271
|
+
predefinedOptions: [
|
|
272
|
+
{ value: "Digital Art", label: "Digital Art" },
|
|
273
|
+
{ value: "Photography", label: "Photography" },
|
|
274
|
+
{ value: "Collectible Card", label: "Collectible Card" },
|
|
275
|
+
{ value: "Avatar", label: "Avatar" },
|
|
276
|
+
{ value: "Music", label: "Music" },
|
|
277
|
+
{ value: "Video", label: "Video" },
|
|
278
|
+
{ value: "3D Model", label: "3D Model" },
|
|
279
|
+
{ value: "Generative Art", label: "Generative Art" },
|
|
280
|
+
{ value: "Pixel Art", label: "Pixel Art" }
|
|
281
|
+
],
|
|
282
|
+
contextualHelpText: "Choose the category that best represents your NFT content"
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
177
286
|
export {
|
|
178
|
-
|
|
287
|
+
fieldGuidanceRegistry
|
|
179
288
|
};
|
|
180
289
|
//# sourceMappingURL=index13.js.map
|
package/dist/esm/index13.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index13.js","sources":["../../src/memory/MemoryWindow.ts"],"sourcesContent":["import type { BaseMessage } from '@langchain/core/messages';\nimport { TokenCounter } from './TokenCounter';\n\n/**\n * Result of adding a message to the memory window\n */\nexport interface AddMessageResult {\n /** Whether the message was successfully added */\n added: boolean;\n /** Messages that were pruned to make room */\n prunedMessages: BaseMessage[];\n /** Current token count after operation */\n currentTokenCount: number;\n /** Remaining token capacity */\n remainingCapacity: number;\n}\n\n/**\n * Memory window that manages conversation history with token-based size limits\n * Automatically prunes old messages to stay within token limits while preserving conversational context\n */\nexport class MemoryWindow {\n private messages: BaseMessage[] = [];\n private maxTokens: number;\n private reserveTokens: number;\n private tokenCounter: TokenCounter;\n private systemPrompt: string = '';\n private systemPromptTokens: number = 0;\n\n public static readonly DEFAULT_MAX_TOKENS = 8000;\n public static readonly DEFAULT_RESERVE_TOKENS = 1000;\n public static readonly PRUNING_BATCH_SIZE = 2;\n\n constructor(\n maxTokens: number = MemoryWindow.DEFAULT_MAX_TOKENS,\n reserveTokens: number = MemoryWindow.DEFAULT_RESERVE_TOKENS,\n tokenCounter?: TokenCounter\n ) {\n if (reserveTokens >= maxTokens) {\n throw new Error('Reserve tokens must be less than max tokens');\n }\n\n this.maxTokens = maxTokens;\n this.reserveTokens = reserveTokens;\n this.tokenCounter = tokenCounter || new TokenCounter();\n }\n\n /**\n * Add a message to the memory window, pruning old messages if necessary\n * @param message - The message to add\n * @returns Result of the add operation including any pruned messages\n */\n addMessage(message: BaseMessage): AddMessageResult {\n this.tokenCounter.countMessageTokens(message);\n \n this.messages.push(message);\n \n const currentTokens = this.getCurrentTokenCount();\n const availableTokens = this.maxTokens - this.reserveTokens;\n \n let prunedMessages: BaseMessage[] = [];\n \n if (currentTokens > availableTokens) {\n this.messages.pop();\n \n prunedMessages = this.pruneToFit();\n \n this.messages.push(message);\n }\n\n return {\n added: true,\n prunedMessages,\n currentTokenCount: this.getCurrentTokenCount(),\n remainingCapacity: this.getRemainingTokenCapacity()\n };\n }\n\n /**\n * Prune old messages to fit within token limits\n * Removes messages in pairs to maintain conversational flow\n * @returns Array of pruned messages\n */\n pruneToFit(): BaseMessage[] {\n const prunedMessages: BaseMessage[] = [];\n const targetTokens = this.maxTokens - this.reserveTokens;\n \n while (this.getCurrentTokenCount() > targetTokens && this.messages.length > 0) {\n const batchSize = Math.min(MemoryWindow.PRUNING_BATCH_SIZE, this.messages.length);\n \n for (let i = 0; i < batchSize; i++) {\n const prunedMessage = this.messages.shift();\n if (prunedMessage) {\n prunedMessages.push(prunedMessage);\n }\n }\n \n if (prunedMessages.length > 1000) {\n break;\n }\n }\n\n return prunedMessages;\n }\n\n /**\n * Get current token count including system prompt and messages\n * @returns Current token count\n */\n getCurrentTokenCount(): number {\n const messageTokens = this.tokenCounter.countMessagesTokens(this.messages);\n return this.systemPromptTokens + messageTokens;\n }\n\n /**\n * Get remaining token capacity before hitting the reserve limit\n * @returns Remaining tokens that can be used\n */\n getRemainingTokenCapacity(): number {\n return Math.max(0, this.maxTokens - this.getCurrentTokenCount());\n }\n\n /**\n * Check if a message can be added without exceeding limits\n * @param message - The message to check\n * @returns True if message can be added within reserve limits\n */\n canAddMessage(message: BaseMessage): boolean {\n const messageTokens = this.tokenCounter.countMessageTokens(message);\n const currentTokens = this.getCurrentTokenCount();\n const wouldExceedReserve = (currentTokens + messageTokens) > (this.maxTokens - this.reserveTokens);\n \n if (messageTokens > this.maxTokens) {\n return false;\n }\n \n return !wouldExceedReserve || this.messages.length > 0;\n }\n\n /**\n * Get all messages in the memory window\n * @returns Copy of current messages array\n */\n getMessages(): BaseMessage[] {\n return [...this.messages];\n }\n\n /**\n * Clear all messages from the memory window\n */\n clear(): void {\n this.messages = [];\n }\n\n /**\n * Set the system prompt and update token calculations\n * @param systemPrompt - The system prompt text\n */\n setSystemPrompt(systemPrompt: string): void {\n this.systemPrompt = systemPrompt;\n this.systemPromptTokens = this.tokenCounter.estimateSystemPromptTokens(systemPrompt);\n }\n\n /**\n * Get the current system prompt\n * @returns Current system prompt\n */\n getSystemPrompt(): string {\n return this.systemPrompt;\n }\n\n /**\n * Get current configuration\n * @returns Memory window configuration\n */\n getConfig() {\n return {\n maxTokens: this.maxTokens,\n reserveTokens: this.reserveTokens,\n currentTokens: this.getCurrentTokenCount(),\n messageCount: this.messages.length,\n systemPromptTokens: this.systemPromptTokens\n };\n }\n\n /**\n * Update token limits\n * @param maxTokens - New maximum token limit\n * @param reserveTokens - New reserve token amount\n */\n updateLimits(maxTokens: number, reserveTokens?: number): void {\n if (reserveTokens !== undefined && reserveTokens >= maxTokens) {\n throw new Error('Reserve tokens must be less than max tokens');\n }\n\n this.maxTokens = maxTokens;\n if (reserveTokens !== undefined) {\n this.reserveTokens = reserveTokens;\n }\n\n if (this.getCurrentTokenCount() > (this.maxTokens - this.reserveTokens)) {\n this.pruneToFit();\n }\n }\n\n /**\n * Get statistics about the memory window\n * @returns Memory usage statistics\n */\n getStats() {\n const currentTokens = this.getCurrentTokenCount();\n const capacity = this.maxTokens;\n const usagePercentage = (currentTokens / capacity) * 100;\n \n return {\n totalMessages: this.messages.length,\n currentTokens,\n maxTokens: capacity,\n reserveTokens: this.reserveTokens,\n systemPromptTokens: this.systemPromptTokens,\n usagePercentage: Math.round(usagePercentage * 100) / 100,\n remainingCapacity: this.getRemainingTokenCapacity(),\n canAcceptMore: this.getRemainingTokenCapacity() > this.reserveTokens\n };\n }\n\n /**\n * Clean up resources\n */\n dispose(): void {\n this.clear();\n this.tokenCounter.dispose();\n }\n}"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index13.js","sources":["../../src/forms/field-guidance-registry.ts"],"sourcesContent":["import type { FormFieldType, FieldOption } from './types';\n\n/**\n * Field guidance configuration for providing contextual help and suggestions\n */\nexport interface FieldGuidance {\n /**\n * Suggestions to show as placeholder or examples\n */\n suggestions?: string[];\n\n /**\n * Predefined options for select fields\n */\n predefinedOptions?: FieldOption[];\n\n /**\n * Warning messages for specific patterns to avoid\n */\n warnings?: {\n pattern: RegExp;\n message: string;\n }[];\n\n /**\n * Validation rules specific to the field context\n */\n validationRules?: {\n /**\n * Patterns that should be rejected\n */\n rejectPatterns?: {\n pattern: RegExp;\n reason: string;\n }[];\n\n /**\n * Minimum quality requirements\n */\n qualityChecks?: {\n minNonTechnicalWords?: number;\n requireSpecificTerms?: string[];\n forbidTechnicalTerms?: string[];\n };\n };\n\n /**\n * Field type override for specific contexts\n */\n fieldTypeOverride?: FormFieldType;\n\n /**\n * Help text specific to the tool context\n */\n contextualHelpText?: string;\n}\n\n/**\n * Tool-specific field configurations\n */\nexport interface ToolFieldConfiguration {\n /**\n * Tool name or pattern to match\n */\n toolPattern: string | RegExp;\n\n /**\n * Field-specific guidance\n */\n fields: Record<string, FieldGuidance>;\n\n /**\n * Global guidance for all fields in this tool\n */\n globalGuidance?: {\n /**\n * General warnings to show\n */\n warnings?: string[];\n\n /**\n * Quality standards for this tool\n */\n qualityStandards?: string[];\n };\n}\n\n/**\n * Registry for field guidance configurations\n */\nclass FieldGuidanceRegistry {\n private configurations: ToolFieldConfiguration[] = [];\n\n /**\n * Register field guidance for a specific tool\n */\n registerToolConfiguration(config: ToolFieldConfiguration): void {\n this.configurations.push(config);\n }\n\n /**\n * Get field guidance for a specific tool and field\n */\n getFieldGuidance(toolName: string, fieldName: string): FieldGuidance | null {\n for (const config of this.configurations) {\n const matches =\n typeof config.toolPattern === 'string'\n ? toolName.toLowerCase().includes(config.toolPattern.toLowerCase())\n : config.toolPattern.test(toolName);\n\n if (matches && config.fields[fieldName]) {\n return config.fields[fieldName];\n }\n }\n return null;\n }\n\n /**\n * Get global guidance for a tool\n */\n getGlobalGuidance(\n toolName: string\n ): ToolFieldConfiguration['globalGuidance'] | null {\n for (const config of this.configurations) {\n const matches =\n typeof config.toolPattern === 'string'\n ? toolName.toLowerCase().includes(config.toolPattern.toLowerCase())\n : config.toolPattern.test(toolName);\n\n if (matches && config.globalGuidance) {\n return config.globalGuidance;\n }\n }\n return null;\n }\n\n /**\n * Validate field value against guidance rules\n */\n validateFieldValue(\n toolName: string,\n fieldName: string,\n value: unknown\n ): {\n isValid: boolean;\n warnings: string[];\n errors: string[];\n } {\n const guidance = this.getFieldGuidance(toolName, fieldName);\n const warnings: string[] = [];\n const errors: string[] = [];\n\n if (!guidance || typeof value !== 'string') {\n return { isValid: true, warnings, errors };\n }\n\n if (guidance.warnings) {\n for (const warning of guidance.warnings) {\n if (warning.pattern.test(value)) {\n warnings.push(warning.message);\n }\n }\n }\n\n if (guidance.validationRules) {\n const { rejectPatterns, qualityChecks } = guidance.validationRules;\n\n if (rejectPatterns) {\n for (const reject of rejectPatterns) {\n if (reject.pattern.test(value)) {\n errors.push(`Rejected: ${reject.reason}`);\n }\n }\n }\n\n if (qualityChecks) {\n if (qualityChecks.forbidTechnicalTerms) {\n const lowerValue = value.toLowerCase();\n for (const term of qualityChecks.forbidTechnicalTerms) {\n if (lowerValue.includes(term.toLowerCase())) {\n errors.push(\n `Avoid technical terms like \"${term}\" in NFT metadata`\n );\n }\n }\n }\n\n if (qualityChecks.requireSpecificTerms) {\n const lowerValue = value.toLowerCase();\n const hasRequired = qualityChecks.requireSpecificTerms.some((term) =>\n lowerValue.includes(term.toLowerCase())\n );\n if (!hasRequired) {\n warnings.push(\n `Consider including terms like: ${qualityChecks.requireSpecificTerms.join(\n ', '\n )}`\n );\n }\n }\n\n if (qualityChecks.minNonTechnicalWords) {\n const words = value.split(/\\s+/).filter((word) => word.length > 2);\n if (words.length < qualityChecks.minNonTechnicalWords) {\n warnings.push(\n `Consider providing more descriptive content (at least ${qualityChecks.minNonTechnicalWords} meaningful words)`\n );\n }\n }\n }\n }\n\n return {\n isValid: errors.length === 0,\n warnings,\n errors,\n };\n }\n\n /**\n * Clear all configurations (useful for testing)\n */\n clear(): void {\n this.configurations = [];\n }\n}\n\nexport const fieldGuidanceRegistry = new FieldGuidanceRegistry();\n\nfieldGuidanceRegistry.registerToolConfiguration({\n toolPattern: /inscribe.*hashinal/i,\n globalGuidance: {\n warnings: [\n 'Avoid auto-generating technical metadata like file types or upload sources',\n 'Focus on collectible traits that add value to the NFT',\n ],\n qualityStandards: [\n 'Use meaningful names that describe the artwork or content',\n 'Include collectible attributes like rarity, style, or theme',\n 'Provide descriptions that tell a story or explain the concept',\n ],\n },\n fields: {\n name: {\n suggestions: [\n 'Sunset Landscape #42',\n 'Digital Abstract Art',\n 'Cosmic Dream Series',\n 'Portrait Study #5',\n ],\n validationRules: {\n rejectPatterns: [\n {\n pattern: /^untitled$/i,\n reason: 'Generic names like \"Untitled\" are not valuable for NFTs',\n },\n {\n pattern: /^image|file|upload/i,\n reason: 'Avoid technical file references in NFT names',\n },\n ],\n qualityChecks: {\n minNonTechnicalWords: 2,\n forbidTechnicalTerms: [\n 'MIME',\n 'upload',\n 'file type',\n 'buffer',\n 'source',\n ],\n },\n },\n contextualHelpText:\n 'Create a distinctive name that collectors will find appealing and memorable',\n },\n\n description: {\n suggestions: [\n 'A vibrant sunset captured in digital brushstrokes...',\n 'Part of the Cosmic Dreams collection, exploring...',\n 'This piece represents the intersection of technology and nature...',\n ],\n validationRules: {\n rejectPatterns: [\n {\n pattern: /uploaded by|file size|mime type|created from/i,\n reason: 'Avoid technical descriptions in NFT metadata',\n },\n ],\n qualityChecks: {\n minNonTechnicalWords: 8,\n forbidTechnicalTerms: [\n 'uploaded',\n 'file size',\n 'mime type',\n 'user upload',\n 'image format',\n 'pixel dimensions',\n 'file extension',\n ],\n requireSpecificTerms: [\n 'art',\n 'collection',\n 'piece',\n 'concept',\n 'inspired',\n 'represents',\n ],\n },\n },\n fieldTypeOverride: 'textarea',\n contextualHelpText:\n 'Describe the story, inspiration, or artistic vision behind this NFT',\n },\n\n creator: {\n suggestions: [\n '0.0.123456 (Hedera Account ID)',\n 'ArtistName',\n 'StudioBrand',\n 'CollectiveDAO',\n ],\n contextualHelpText:\n \"Provide the creator's account ID, artist name, or brand identity\",\n },\n\n attributes: {\n predefinedOptions: [\n {\n value: 'Rarity',\n label: 'Rarity',\n description: 'Common, Rare, Epic, Legendary',\n },\n {\n value: 'Color',\n label: 'Color',\n description: 'Primary colors or palette',\n },\n {\n value: 'Style',\n label: 'Style',\n description: 'Abstract, Realistic, Minimalist, etc.',\n },\n {\n value: 'Theme',\n label: 'Theme',\n description: 'Nature, Technology, Fantasy, etc.',\n },\n {\n value: 'Series',\n label: 'Series',\n description: 'Collection or series number',\n },\n {\n value: 'Element',\n label: 'Element',\n description: 'Fire, Water, Earth, Air, etc.',\n },\n {\n value: 'Power Level',\n label: 'Power Level',\n description: 'Numeric strength value',\n },\n {\n value: 'Edition',\n label: 'Edition',\n description: 'Special, Limited, First, etc.',\n },\n ],\n warnings: [\n {\n pattern: /mime.?type|file.?type|upload.?source/i,\n message: 'Technical metadata is not valuable for NFT collectors',\n },\n ],\n validationRules: {\n rejectPatterns: [\n {\n pattern: /^(mime.?type|file.?type|source|origin|upload)$/i,\n reason: 'Technical attributes are not collectible traits',\n },\n ],\n qualityChecks: {\n forbidTechnicalTerms: [\n 'MIME Type',\n 'File Type',\n 'Source',\n 'Origin',\n 'Upload Source',\n 'File Extension',\n 'Format',\n ],\n },\n },\n contextualHelpText:\n 'Add traits that make this NFT unique and valuable to collectors',\n },\n\n type: {\n predefinedOptions: [\n { value: 'Digital Art', label: 'Digital Art' },\n { value: 'Photography', label: 'Photography' },\n { value: 'Collectible Card', label: 'Collectible Card' },\n { value: 'Avatar', label: 'Avatar' },\n { value: 'Music', label: 'Music' },\n { value: 'Video', label: 'Video' },\n { value: '3D Model', label: '3D Model' },\n { value: 'Generative Art', label: 'Generative Art' },\n { value: 'Pixel Art', label: 'Pixel Art' },\n ],\n contextualHelpText:\n 'Choose the category that best represents your NFT content',\n },\n },\n});\n"],"names":[],"mappings":"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"}
|