@hashgraphonline/conversational-agent 0.2.104 → 0.2.105
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/README.md +64 -27
- package/cli/dist/CLIApp.d.ts +3 -1
- package/cli/dist/CLIApp.d.ts.map +1 -0
- package/cli/dist/CLIApp.js +6 -5
- package/cli/dist/CLIApp.js.map +1 -0
- package/cli/dist/app.d.ts +3 -1
- package/cli/dist/app.d.ts.map +1 -0
- package/cli/dist/app.js +2 -1
- package/cli/dist/app.js.map +1 -0
- package/cli/dist/cli.d.ts +1 -0
- package/cli/dist/cli.d.ts.map +1 -0
- package/cli/dist/cli.js +39 -3
- package/cli/dist/cli.js.map +1 -0
- package/cli/dist/components/ChatScreen.d.ts +9 -3
- package/cli/dist/components/ChatScreen.d.ts.map +1 -0
- package/cli/dist/components/ChatScreen.js +4 -3
- package/cli/dist/components/ChatScreen.js.map +1 -0
- package/cli/dist/components/LoadingScreen.d.ts +1 -0
- package/cli/dist/components/LoadingScreen.d.ts.map +1 -0
- package/cli/dist/components/LoadingScreen.js +2 -1
- package/cli/dist/components/LoadingScreen.js.map +1 -0
- package/cli/dist/components/MCPConfigScreen.d.ts +2 -2
- package/cli/dist/components/MCPConfigScreen.d.ts.map +1 -0
- package/cli/dist/components/MCPConfigScreen.js +77 -59
- package/cli/dist/components/MCPConfigScreen.js.map +1 -0
- package/cli/dist/components/ScreenRouter.d.ts +1 -0
- package/cli/dist/components/ScreenRouter.d.ts.map +1 -0
- package/cli/dist/components/ScreenRouter.js +6 -5
- package/cli/dist/components/ScreenRouter.js.map +1 -0
- package/cli/dist/components/SetupScreen.d.ts +1 -0
- package/cli/dist/components/SetupScreen.d.ts.map +1 -0
- package/cli/dist/components/SetupScreen.js +28 -26
- package/cli/dist/components/SetupScreen.js.map +1 -0
- package/cli/dist/components/StatusBadge.d.ts +4 -1
- package/cli/dist/components/StatusBadge.d.ts.map +1 -0
- package/cli/dist/components/StatusBadge.js +18 -22
- package/cli/dist/components/StatusBadge.js.map +1 -0
- package/cli/dist/components/TerminalWindow.d.ts +1 -0
- package/cli/dist/components/TerminalWindow.d.ts.map +1 -0
- package/cli/dist/components/TerminalWindow.js +2 -7
- package/cli/dist/components/TerminalWindow.js.map +1 -0
- package/cli/dist/components/WelcomeScreen.d.ts +1 -0
- package/cli/dist/components/WelcomeScreen.d.ts.map +1 -0
- package/cli/dist/components/WelcomeScreen.js +15 -15
- package/cli/dist/components/WelcomeScreen.js.map +1 -0
- package/cli/dist/headless-runner.d.ts +17 -0
- package/cli/dist/headless-runner.d.ts.map +1 -0
- package/cli/dist/headless-runner.js +128 -0
- package/cli/dist/headless-runner.js.map +1 -0
- package/cli/dist/hooks/useInitializeAgent.d.ts +4 -4
- package/cli/dist/hooks/useInitializeAgent.d.ts.map +1 -0
- package/cli/dist/hooks/useInitializeAgent.js +1 -0
- package/cli/dist/hooks/useInitializeAgent.js.map +1 -0
- package/cli/dist/hooks/useStableState.d.ts +2 -2
- package/cli/dist/hooks/useStableState.d.ts.map +1 -0
- package/cli/dist/hooks/useStableState.js +1 -0
- package/cli/dist/hooks/useStableState.js.map +1 -0
- package/cli/dist/managers/AgentManager.d.ts +3 -2
- package/cli/dist/managers/AgentManager.d.ts.map +1 -0
- package/cli/dist/managers/AgentManager.js +8 -6
- package/cli/dist/managers/AgentManager.js.map +1 -0
- package/cli/dist/managers/ConfigManager.d.ts +3 -2
- package/cli/dist/managers/ConfigManager.d.ts.map +1 -0
- package/cli/dist/managers/ConfigManager.js +23 -8
- package/cli/dist/managers/ConfigManager.js.map +1 -0
- package/cli/dist/types.d.ts +22 -1
- package/cli/dist/types.d.ts.map +1 -0
- package/cli/dist/types.js +15 -0
- package/cli/dist/types.js.map +1 -0
- package/dist/cjs/config/system-message.d.ts +1 -1
- package/dist/cjs/conversational-agent.d.ts +30 -2
- package/dist/cjs/core/tool-registry.d.ts +29 -0
- package/dist/cjs/forms/field-guidance-registry.d.ts +33 -0
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/mcp/types.d.ts +14 -3
- package/dist/cjs/plugins/index.d.ts +1 -0
- package/dist/cjs/plugins/inscribe/InscribePlugin.d.ts +1 -0
- package/dist/cjs/plugins/web-browser/WebBrowserPlugin.d.ts +14 -0
- package/dist/cjs/runtime/wallet-bridge.d.ts +26 -0
- package/dist/cjs/services/attachment-processor.d.ts +1 -2
- package/dist/cjs/services/content-store-manager.d.ts +1 -1
- package/dist/cjs/services/formatters/types.d.ts +3 -1
- package/dist/cjs/services/index.d.ts +1 -1
- package/dist/cjs/signers/browser-signer.d.ts +32 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index10.js +13 -5
- package/dist/esm/index10.js.map +1 -1
- package/dist/esm/index13.js +157 -179
- package/dist/esm/index13.js.map +1 -1
- package/dist/esm/index15.js +9 -4
- package/dist/esm/index15.js.map +1 -1
- package/dist/esm/index18.js.map +1 -1
- package/dist/esm/index2.js +25 -27
- package/dist/esm/index2.js.map +1 -1
- package/dist/esm/index21.js +1 -1
- package/dist/esm/index21.js.map +1 -1
- package/dist/esm/index23.js +3 -3
- package/dist/esm/index24.js.map +1 -1
- package/dist/esm/index26.js.map +1 -1
- package/dist/esm/index3.js.map +1 -1
- package/dist/esm/index30.js.map +1 -1
- package/dist/esm/index31.js +6 -3
- package/dist/esm/index31.js.map +1 -1
- package/dist/esm/index33.js +5 -5
- package/dist/esm/index33.js.map +1 -1
- package/dist/esm/index36.js +8 -45
- package/dist/esm/index36.js.map +1 -1
- package/dist/esm/index37.js +41 -102
- package/dist/esm/index37.js.map +1 -1
- package/dist/esm/index38.js +107 -21
- package/dist/esm/index38.js.map +1 -1
- package/dist/esm/index39.js +63 -24
- package/dist/esm/index39.js.map +1 -1
- package/dist/esm/index4.js +43 -0
- package/dist/esm/index4.js.map +1 -1
- package/dist/esm/index40.js +78 -11
- package/dist/esm/index40.js.map +1 -1
- package/dist/esm/index41.js +21 -5
- package/dist/esm/index41.js.map +1 -1
- package/dist/esm/index42.js +5 -255
- package/dist/esm/index42.js.map +1 -1
- package/dist/esm/index43.js +12 -184
- package/dist/esm/index43.js.map +1 -1
- package/dist/esm/index44.js +322 -7
- package/dist/esm/index44.js.map +1 -1
- package/dist/esm/index45.js +174 -82
- package/dist/esm/index45.js.map +1 -1
- package/dist/esm/index46.js +30 -0
- package/dist/esm/index46.js.map +1 -0
- package/dist/esm/index47.js +10 -0
- package/dist/esm/index47.js.map +1 -0
- package/dist/esm/index48.js +98 -0
- package/dist/esm/index48.js.map +1 -0
- package/dist/esm/index5.js +2 -2
- package/dist/esm/index6.js +189 -29
- package/dist/esm/index6.js.map +1 -1
- package/dist/types/config/system-message.d.ts +1 -1
- package/dist/types/conversational-agent.d.ts +30 -2
- package/dist/types/core/tool-registry.d.ts +29 -0
- package/dist/types/forms/field-guidance-registry.d.ts +33 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/mcp/types.d.ts +14 -3
- package/dist/types/plugins/index.d.ts +1 -0
- package/dist/types/plugins/inscribe/InscribePlugin.d.ts +1 -0
- package/dist/types/plugins/web-browser/WebBrowserPlugin.d.ts +14 -0
- package/dist/types/runtime/wallet-bridge.d.ts +26 -0
- package/dist/types/services/attachment-processor.d.ts +1 -2
- package/dist/types/services/content-store-manager.d.ts +1 -1
- package/dist/types/services/formatters/types.d.ts +3 -1
- package/dist/types/services/index.d.ts +1 -1
- package/dist/types/signers/browser-signer.d.ts +32 -0
- package/package.json +16 -11
- package/src/config/system-message.ts +3 -3
- package/src/conversational-agent.ts +318 -45
- package/src/core/tool-registry.ts +85 -0
- package/src/forms/field-guidance-registry.ts +213 -188
- package/src/forms/form-generator.ts +28 -12
- package/src/index.ts +1 -0
- package/src/langchain/form-aware-agent-executor.ts +6 -6
- package/src/langchain/langchain-agent.ts +1 -1
- package/src/mcp/mcp-client-manager.ts +12 -5
- package/src/mcp/types.ts +15 -3
- package/src/memory/content-storage.ts +19 -6
- package/src/memory/smart-memory-manager.ts +0 -1
- package/src/plugins/hbar/AccountBuilder.ts +16 -16
- package/src/plugins/hcs-10/HCS10Plugin.ts +38 -38
- package/src/plugins/hcs-2/HCS2Plugin.ts +2 -2
- package/src/plugins/index.ts +2 -1
- package/src/plugins/inscribe/InscribePlugin.ts +46 -2
- package/src/plugins/web-browser/WebBrowserPlugin.ts +128 -0
- package/src/runtime/wallet-bridge.ts +46 -0
- package/src/services/attachment-processor.ts +1 -1
- package/src/services/content-store-manager.ts +1 -1
- package/src/services/formatters/types.ts +3 -1
- package/src/services/index.ts +1 -1
- package/src/signers/browser-signer.ts +111 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FormFieldType, FieldOption } from './types';
|
|
2
|
+
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Field guidance configuration for providing contextual help and suggestions
|
|
@@ -90,6 +91,19 @@ export interface ToolFieldConfiguration {
|
|
|
90
91
|
*/
|
|
91
92
|
class FieldGuidanceRegistry {
|
|
92
93
|
private configurations: ToolFieldConfiguration[] = [];
|
|
94
|
+
private providers: Array<{
|
|
95
|
+
id: string;
|
|
96
|
+
priority: number;
|
|
97
|
+
pattern: string | RegExp;
|
|
98
|
+
provider: FieldGuidanceProvider;
|
|
99
|
+
order: number;
|
|
100
|
+
}> = [];
|
|
101
|
+
private registerOrderCounter = 0;
|
|
102
|
+
private logger: Logger;
|
|
103
|
+
|
|
104
|
+
constructor() {
|
|
105
|
+
this.logger = new Logger({ module: 'FieldGuidanceRegistry' });
|
|
106
|
+
}
|
|
93
107
|
|
|
94
108
|
/**
|
|
95
109
|
* Register field guidance for a specific tool
|
|
@@ -98,10 +112,55 @@ class FieldGuidanceRegistry {
|
|
|
98
112
|
this.configurations.push(config);
|
|
99
113
|
}
|
|
100
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Register a provider for dynamic field/global guidance
|
|
117
|
+
*/
|
|
118
|
+
registerToolProvider(
|
|
119
|
+
toolPattern: string | RegExp,
|
|
120
|
+
provider: FieldGuidanceProvider,
|
|
121
|
+
options?: { id?: string; priority?: number }
|
|
122
|
+
): string {
|
|
123
|
+
const id = options?.id ?? `provider-${this.providers.length + 1}`;
|
|
124
|
+
const priority = options?.priority ?? 0;
|
|
125
|
+
if (this.providers.some((p) => p.id === id)) {
|
|
126
|
+
this.logger.error('Duplicate provider id', { id });
|
|
127
|
+
throw new Error('DUPLICATE_PROVIDER_ID');
|
|
128
|
+
}
|
|
129
|
+
this.providers.push({
|
|
130
|
+
id,
|
|
131
|
+
priority,
|
|
132
|
+
pattern: toolPattern,
|
|
133
|
+
provider,
|
|
134
|
+
order: this.registerOrderCounter++,
|
|
135
|
+
});
|
|
136
|
+
return id;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Unregister a provider by id */
|
|
140
|
+
unregisterProvider(id: string): void {
|
|
141
|
+
this.providers = this.providers.filter((p) => p.id !== id);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** List registered providers */
|
|
145
|
+
listProviders(): Array<{
|
|
146
|
+
id: string;
|
|
147
|
+
priority: number;
|
|
148
|
+
pattern: string | RegExp;
|
|
149
|
+
}> {
|
|
150
|
+
return this.providers.map(({ id, priority, pattern }) => ({
|
|
151
|
+
id,
|
|
152
|
+
priority,
|
|
153
|
+
pattern,
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
|
|
101
157
|
/**
|
|
102
158
|
* Get field guidance for a specific tool and field
|
|
103
159
|
*/
|
|
104
160
|
getFieldGuidance(toolName: string, fieldName: string): FieldGuidance | null {
|
|
161
|
+
if (process.env.CA_FORM_GUIDANCE_ENABLED === 'false') {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
105
164
|
for (const config of this.configurations) {
|
|
106
165
|
const matches =
|
|
107
166
|
typeof config.toolPattern === 'string'
|
|
@@ -109,8 +168,31 @@ class FieldGuidanceRegistry {
|
|
|
109
168
|
: config.toolPattern.test(toolName);
|
|
110
169
|
|
|
111
170
|
if (matches && config.fields[fieldName]) {
|
|
112
|
-
|
|
171
|
+
const staticGuidance = config.fields[fieldName];
|
|
172
|
+
const providers = this.pickMatchingProviders(toolName);
|
|
173
|
+
if (providers.length === 0) return staticGuidance;
|
|
174
|
+
let merged: FieldGuidance = { ...staticGuidance };
|
|
175
|
+
for (const p of [...providers].reverse()) {
|
|
176
|
+
const fromProvider = this.safeGetFieldGuidance(
|
|
177
|
+
p,
|
|
178
|
+
fieldName,
|
|
179
|
+
toolName
|
|
180
|
+
);
|
|
181
|
+
if (fromProvider) {
|
|
182
|
+
merged = this.mergeGuidance(merged, fromProvider);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return merged;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const providers = this.pickMatchingProviders(toolName);
|
|
189
|
+
if (providers.length > 0) {
|
|
190
|
+
let merged: FieldGuidance = {};
|
|
191
|
+
for (const p of [...providers].reverse()) {
|
|
192
|
+
const g = this.safeGetFieldGuidance(p, fieldName, toolName);
|
|
193
|
+
if (g) merged = this.mergeGuidance(merged, g);
|
|
113
194
|
}
|
|
195
|
+
return Object.keys(merged).length > 0 ? merged : null;
|
|
114
196
|
}
|
|
115
197
|
return null;
|
|
116
198
|
}
|
|
@@ -121,6 +203,9 @@ class FieldGuidanceRegistry {
|
|
|
121
203
|
getGlobalGuidance(
|
|
122
204
|
toolName: string
|
|
123
205
|
): ToolFieldConfiguration['globalGuidance'] | null {
|
|
206
|
+
if (process.env.CA_FORM_GUIDANCE_ENABLED === 'false') {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
124
209
|
for (const config of this.configurations) {
|
|
125
210
|
const matches =
|
|
126
211
|
typeof config.toolPattern === 'string'
|
|
@@ -128,9 +213,42 @@ class FieldGuidanceRegistry {
|
|
|
128
213
|
: config.toolPattern.test(toolName);
|
|
129
214
|
|
|
130
215
|
if (matches && config.globalGuidance) {
|
|
131
|
-
|
|
216
|
+
const base = config.globalGuidance;
|
|
217
|
+
const providers = this.pickMatchingProviders(toolName);
|
|
218
|
+
if (providers.length === 0) return base;
|
|
219
|
+
let mergedWarnings: string[] | undefined = base.warnings;
|
|
220
|
+
let mergedQuality: string[] | undefined = base.qualityStandards;
|
|
221
|
+
for (const p of [...providers].reverse()) {
|
|
222
|
+
const fromProvider = this.safeGetGlobalGuidance(p, toolName);
|
|
223
|
+
if (fromProvider) {
|
|
224
|
+
mergedWarnings = fromProvider.warnings ?? mergedWarnings;
|
|
225
|
+
mergedQuality = fromProvider.qualityStandards ?? mergedQuality;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const result: NonNullable<ToolFieldConfiguration['globalGuidance']> =
|
|
229
|
+
{};
|
|
230
|
+
if (mergedWarnings !== undefined) result.warnings = mergedWarnings;
|
|
231
|
+
if (mergedQuality !== undefined)
|
|
232
|
+
result.qualityStandards = mergedQuality;
|
|
233
|
+
return result;
|
|
132
234
|
}
|
|
133
235
|
}
|
|
236
|
+
const providers = this.pickMatchingProviders(toolName);
|
|
237
|
+
if (providers.length > 0) {
|
|
238
|
+
let mergedWarnings: string[] | undefined;
|
|
239
|
+
let mergedQuality: string[] | undefined;
|
|
240
|
+
for (const p of [...providers].reverse()) {
|
|
241
|
+
const g = this.safeGetGlobalGuidance(p, toolName);
|
|
242
|
+
if (g) {
|
|
243
|
+
mergedWarnings = g.warnings ?? mergedWarnings;
|
|
244
|
+
mergedQuality = g.qualityStandards ?? mergedQuality;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const result: NonNullable<ToolFieldConfiguration['globalGuidance']> = {};
|
|
248
|
+
if (mergedWarnings !== undefined) result.warnings = mergedWarnings;
|
|
249
|
+
if (mergedQuality !== undefined) result.qualityStandards = mergedQuality;
|
|
250
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
251
|
+
}
|
|
134
252
|
return null;
|
|
135
253
|
}
|
|
136
254
|
|
|
@@ -222,194 +340,101 @@ class FieldGuidanceRegistry {
|
|
|
222
340
|
*/
|
|
223
341
|
clear(): void {
|
|
224
342
|
this.configurations = [];
|
|
343
|
+
this.providers = [];
|
|
344
|
+
this.registerOrderCounter = 0;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/** Choose matching provider by priority then last-in wins */
|
|
348
|
+
private pickMatchingProviders(toolName: string): Array<{
|
|
349
|
+
id: string;
|
|
350
|
+
provider: FieldGuidanceProvider;
|
|
351
|
+
priority: number;
|
|
352
|
+
order: number;
|
|
353
|
+
}> {
|
|
354
|
+
const matches = this.providers.filter((p) =>
|
|
355
|
+
typeof p.pattern === 'string'
|
|
356
|
+
? toolName.toLowerCase().includes((p.pattern as string).toLowerCase())
|
|
357
|
+
: (p.pattern as RegExp).test(toolName)
|
|
358
|
+
);
|
|
359
|
+
const sorted = matches.sort((a, b) => {
|
|
360
|
+
if (b.priority !== a.priority) return b.priority - a.priority;
|
|
361
|
+
return b.order - a.order; // last-in wins when equal priority
|
|
362
|
+
});
|
|
363
|
+
return sorted.map((m) => ({
|
|
364
|
+
id: m.id,
|
|
365
|
+
provider: m.provider,
|
|
366
|
+
priority: m.priority,
|
|
367
|
+
order: m.order,
|
|
368
|
+
}));
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
private safeGetFieldGuidance(
|
|
372
|
+
winner: { id: string; provider: FieldGuidanceProvider },
|
|
373
|
+
fieldName: string,
|
|
374
|
+
toolName: string
|
|
375
|
+
): FieldGuidance | null {
|
|
376
|
+
try {
|
|
377
|
+
return winner.provider.getFieldGuidance(fieldName, { toolName }) ?? null;
|
|
378
|
+
} catch (err) {
|
|
379
|
+
this.logger.warn('Provider getFieldGuidance failed', {
|
|
380
|
+
id: winner.id,
|
|
381
|
+
err,
|
|
382
|
+
});
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
private safeGetGlobalGuidance(
|
|
388
|
+
winner: { id: string; provider: FieldGuidanceProvider },
|
|
389
|
+
toolName: string
|
|
390
|
+
): ToolFieldConfiguration['globalGuidance'] | null {
|
|
391
|
+
try {
|
|
392
|
+
return winner.provider.getGlobalGuidance?.(toolName) ?? null;
|
|
393
|
+
} catch (err) {
|
|
394
|
+
this.logger.warn('Provider getGlobalGuidance failed', {
|
|
395
|
+
id: winner.id,
|
|
396
|
+
err,
|
|
397
|
+
});
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
private mergeGuidance(
|
|
403
|
+
base: FieldGuidance,
|
|
404
|
+
over: FieldGuidance
|
|
405
|
+
): FieldGuidance {
|
|
406
|
+
const out: FieldGuidance = {};
|
|
407
|
+
const suggestions = over.suggestions ?? base.suggestions;
|
|
408
|
+
if (suggestions !== undefined) out.suggestions = suggestions;
|
|
409
|
+
const predefinedOptions = over.predefinedOptions ?? base.predefinedOptions;
|
|
410
|
+
if (predefinedOptions !== undefined)
|
|
411
|
+
out.predefinedOptions = predefinedOptions;
|
|
412
|
+
const warnings = over.warnings ?? base.warnings;
|
|
413
|
+
if (warnings !== undefined) out.warnings = warnings;
|
|
414
|
+
const validationRules = over.validationRules ?? base.validationRules;
|
|
415
|
+
if (validationRules !== undefined) out.validationRules = validationRules;
|
|
416
|
+
const fieldTypeOverride = over.fieldTypeOverride ?? base.fieldTypeOverride;
|
|
417
|
+
if (fieldTypeOverride !== undefined)
|
|
418
|
+
out.fieldTypeOverride = fieldTypeOverride;
|
|
419
|
+
const contextualHelpText =
|
|
420
|
+
over.contextualHelpText ?? base.contextualHelpText;
|
|
421
|
+
if (contextualHelpText !== undefined)
|
|
422
|
+
out.contextualHelpText = contextualHelpText;
|
|
423
|
+
return out;
|
|
225
424
|
}
|
|
226
425
|
}
|
|
227
426
|
|
|
228
427
|
export const fieldGuidanceRegistry = new FieldGuidanceRegistry();
|
|
229
428
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
},
|
|
243
|
-
fields: {
|
|
244
|
-
name: {
|
|
245
|
-
suggestions: [
|
|
246
|
-
'Sunset Landscape #42',
|
|
247
|
-
'Digital Abstract Art',
|
|
248
|
-
'Cosmic Dream Series',
|
|
249
|
-
'Portrait Study #5',
|
|
250
|
-
],
|
|
251
|
-
validationRules: {
|
|
252
|
-
rejectPatterns: [
|
|
253
|
-
{
|
|
254
|
-
pattern: /^untitled$/i,
|
|
255
|
-
reason: 'Generic names like "Untitled" are not valuable for NFTs',
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
pattern: /^image|file|upload/i,
|
|
259
|
-
reason: 'Avoid technical file references in NFT names',
|
|
260
|
-
},
|
|
261
|
-
],
|
|
262
|
-
qualityChecks: {
|
|
263
|
-
minNonTechnicalWords: 2,
|
|
264
|
-
forbidTechnicalTerms: [
|
|
265
|
-
'MIME',
|
|
266
|
-
'upload',
|
|
267
|
-
'file type',
|
|
268
|
-
'buffer',
|
|
269
|
-
'source',
|
|
270
|
-
],
|
|
271
|
-
},
|
|
272
|
-
},
|
|
273
|
-
contextualHelpText:
|
|
274
|
-
'Create a distinctive name that collectors will find appealing and memorable',
|
|
275
|
-
},
|
|
276
|
-
|
|
277
|
-
description: {
|
|
278
|
-
suggestions: [
|
|
279
|
-
'A vibrant sunset captured in digital brushstrokes...',
|
|
280
|
-
'Part of the Cosmic Dreams collection, exploring...',
|
|
281
|
-
'This piece represents the intersection of technology and nature...',
|
|
282
|
-
],
|
|
283
|
-
validationRules: {
|
|
284
|
-
rejectPatterns: [
|
|
285
|
-
{
|
|
286
|
-
pattern: /uploaded by|file size|mime type|created from/i,
|
|
287
|
-
reason: 'Avoid technical descriptions in NFT metadata',
|
|
288
|
-
},
|
|
289
|
-
],
|
|
290
|
-
qualityChecks: {
|
|
291
|
-
minNonTechnicalWords: 8,
|
|
292
|
-
forbidTechnicalTerms: [
|
|
293
|
-
'uploaded',
|
|
294
|
-
'file size',
|
|
295
|
-
'mime type',
|
|
296
|
-
'user upload',
|
|
297
|
-
'image format',
|
|
298
|
-
'pixel dimensions',
|
|
299
|
-
'file extension',
|
|
300
|
-
],
|
|
301
|
-
requireSpecificTerms: [
|
|
302
|
-
'art',
|
|
303
|
-
'collection',
|
|
304
|
-
'piece',
|
|
305
|
-
'concept',
|
|
306
|
-
'inspired',
|
|
307
|
-
'represents',
|
|
308
|
-
],
|
|
309
|
-
},
|
|
310
|
-
},
|
|
311
|
-
fieldTypeOverride: 'textarea',
|
|
312
|
-
contextualHelpText:
|
|
313
|
-
'Describe the story, inspiration, or artistic vision behind this NFT',
|
|
314
|
-
},
|
|
315
|
-
|
|
316
|
-
creator: {
|
|
317
|
-
suggestions: [
|
|
318
|
-
'0.0.123456 (Hedera Account ID)',
|
|
319
|
-
'ArtistName',
|
|
320
|
-
'StudioBrand',
|
|
321
|
-
'CollectiveDAO',
|
|
322
|
-
],
|
|
323
|
-
contextualHelpText:
|
|
324
|
-
"Provide the creator's account ID, artist name, or brand identity",
|
|
325
|
-
},
|
|
326
|
-
|
|
327
|
-
attributes: {
|
|
328
|
-
predefinedOptions: [
|
|
329
|
-
{
|
|
330
|
-
value: 'Rarity',
|
|
331
|
-
label: 'Rarity',
|
|
332
|
-
description: 'Common, Rare, Epic, Legendary',
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
value: 'Color',
|
|
336
|
-
label: 'Color',
|
|
337
|
-
description: 'Primary colors or palette',
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
value: 'Style',
|
|
341
|
-
label: 'Style',
|
|
342
|
-
description: 'Abstract, Realistic, Minimalist, etc.',
|
|
343
|
-
},
|
|
344
|
-
{
|
|
345
|
-
value: 'Theme',
|
|
346
|
-
label: 'Theme',
|
|
347
|
-
description: 'Nature, Technology, Fantasy, etc.',
|
|
348
|
-
},
|
|
349
|
-
{
|
|
350
|
-
value: 'Series',
|
|
351
|
-
label: 'Series',
|
|
352
|
-
description: 'Collection or series number',
|
|
353
|
-
},
|
|
354
|
-
{
|
|
355
|
-
value: 'Element',
|
|
356
|
-
label: 'Element',
|
|
357
|
-
description: 'Fire, Water, Earth, Air, etc.',
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
value: 'Power Level',
|
|
361
|
-
label: 'Power Level',
|
|
362
|
-
description: 'Numeric strength value',
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
value: 'Edition',
|
|
366
|
-
label: 'Edition',
|
|
367
|
-
description: 'Special, Limited, First, etc.',
|
|
368
|
-
},
|
|
369
|
-
],
|
|
370
|
-
warnings: [
|
|
371
|
-
{
|
|
372
|
-
pattern: /mime.?type|file.?type|upload.?source/i,
|
|
373
|
-
message: 'Technical metadata is not valuable for NFT collectors',
|
|
374
|
-
},
|
|
375
|
-
],
|
|
376
|
-
validationRules: {
|
|
377
|
-
rejectPatterns: [
|
|
378
|
-
{
|
|
379
|
-
pattern: /^(mime.?type|file.?type|source|origin|upload)$/i,
|
|
380
|
-
reason: 'Technical attributes are not collectible traits',
|
|
381
|
-
},
|
|
382
|
-
],
|
|
383
|
-
qualityChecks: {
|
|
384
|
-
forbidTechnicalTerms: [
|
|
385
|
-
'MIME Type',
|
|
386
|
-
'File Type',
|
|
387
|
-
'Source',
|
|
388
|
-
'Origin',
|
|
389
|
-
'Upload Source',
|
|
390
|
-
'File Extension',
|
|
391
|
-
'Format',
|
|
392
|
-
],
|
|
393
|
-
},
|
|
394
|
-
},
|
|
395
|
-
contextualHelpText:
|
|
396
|
-
'Add traits that make this NFT unique and valuable to collectors',
|
|
397
|
-
},
|
|
398
|
-
|
|
399
|
-
type: {
|
|
400
|
-
predefinedOptions: [
|
|
401
|
-
{ value: 'Digital Art', label: 'Digital Art' },
|
|
402
|
-
{ value: 'Photography', label: 'Photography' },
|
|
403
|
-
{ value: 'Collectible Card', label: 'Collectible Card' },
|
|
404
|
-
{ value: 'Avatar', label: 'Avatar' },
|
|
405
|
-
{ value: 'Music', label: 'Music' },
|
|
406
|
-
{ value: 'Video', label: 'Video' },
|
|
407
|
-
{ value: '3D Model', label: '3D Model' },
|
|
408
|
-
{ value: 'Generative Art', label: 'Generative Art' },
|
|
409
|
-
{ value: 'Pixel Art', label: 'Pixel Art' },
|
|
410
|
-
],
|
|
411
|
-
contextualHelpText:
|
|
412
|
-
'Choose the category that best represents your NFT content',
|
|
413
|
-
},
|
|
414
|
-
},
|
|
415
|
-
});
|
|
429
|
+
/**
|
|
430
|
+
* Provider interface (optional, for dynamic guidance)
|
|
431
|
+
*/
|
|
432
|
+
export interface FieldGuidanceProvider {
|
|
433
|
+
getFieldGuidance(
|
|
434
|
+
fieldName: string,
|
|
435
|
+
ctx: { toolName: string }
|
|
436
|
+
): FieldGuidance | null;
|
|
437
|
+
getGlobalGuidance?(
|
|
438
|
+
toolName: string
|
|
439
|
+
): ToolFieldConfiguration['globalGuidance'] | null;
|
|
440
|
+
}
|
|
@@ -187,11 +187,17 @@ export class FormGenerator {
|
|
|
187
187
|
);
|
|
188
188
|
|
|
189
189
|
const globalGuidance = fieldGuidanceRegistry.getGlobalGuidance(toolName);
|
|
190
|
-
let description = this.generateFormDescription(
|
|
191
|
-
|
|
190
|
+
let description = this.generateFormDescription(
|
|
191
|
+
toolName,
|
|
192
|
+
missingFields.size
|
|
193
|
+
);
|
|
194
|
+
|
|
192
195
|
if (globalGuidance?.qualityStandards) {
|
|
193
|
-
description +=
|
|
194
|
-
|
|
196
|
+
description +=
|
|
197
|
+
'\n\nQuality Guidelines:\n' +
|
|
198
|
+
globalGuidance.qualityStandards
|
|
199
|
+
.map((standard) => `• ${standard}`)
|
|
200
|
+
.join('\n');
|
|
195
201
|
}
|
|
196
202
|
|
|
197
203
|
return {
|
|
@@ -203,7 +209,7 @@ export class FormGenerator {
|
|
|
203
209
|
metadata: {
|
|
204
210
|
toolName,
|
|
205
211
|
missingFieldCount: missingFields.size,
|
|
206
|
-
globalGuidance
|
|
212
|
+
globalGuidance,
|
|
207
213
|
},
|
|
208
214
|
};
|
|
209
215
|
}
|
|
@@ -453,8 +459,10 @@ export class FormGenerator {
|
|
|
453
459
|
): FormField {
|
|
454
460
|
const type = this.mapFieldType(renderConfig?.fieldType, schema, fieldPath);
|
|
455
461
|
const isRequired = this.isFieldRequired(schema, fieldPath || fieldName);
|
|
456
|
-
|
|
457
|
-
const guidance = toolName
|
|
462
|
+
|
|
463
|
+
const guidance = toolName
|
|
464
|
+
? fieldGuidanceRegistry.getFieldGuidance(toolName, fieldName)
|
|
465
|
+
: null;
|
|
458
466
|
const finalType = guidance?.fieldTypeOverride || type;
|
|
459
467
|
|
|
460
468
|
const field: FormField = {
|
|
@@ -474,7 +482,10 @@ export class FormGenerator {
|
|
|
474
482
|
}
|
|
475
483
|
|
|
476
484
|
if (guidance.predefinedOptions) {
|
|
477
|
-
field.options = [
|
|
485
|
+
field.options = [
|
|
486
|
+
...(field.options || []),
|
|
487
|
+
...guidance.predefinedOptions,
|
|
488
|
+
];
|
|
478
489
|
}
|
|
479
490
|
|
|
480
491
|
if (guidance.contextualHelpText) {
|
|
@@ -482,7 +493,7 @@ export class FormGenerator {
|
|
|
482
493
|
}
|
|
483
494
|
|
|
484
495
|
if (guidance.warnings) {
|
|
485
|
-
field.warnings = guidance.warnings.map(w => w.message);
|
|
496
|
+
field.warnings = guidance.warnings.map((w) => w.message);
|
|
486
497
|
}
|
|
487
498
|
|
|
488
499
|
if (guidance.validationRules) {
|
|
@@ -491,7 +502,7 @@ export class FormGenerator {
|
|
|
491
502
|
field.contextualGuidance = {
|
|
492
503
|
qualityStandards: [],
|
|
493
504
|
examples: guidance.suggestions || [],
|
|
494
|
-
avoidPatterns: qualityChecks.forbidTechnicalTerms || []
|
|
505
|
+
avoidPatterns: qualityChecks.forbidTechnicalTerms || [],
|
|
495
506
|
};
|
|
496
507
|
|
|
497
508
|
if (qualityChecks.minNonTechnicalWords) {
|
|
@@ -502,7 +513,9 @@ export class FormGenerator {
|
|
|
502
513
|
|
|
503
514
|
if (qualityChecks.forbidTechnicalTerms) {
|
|
504
515
|
field.contextualGuidance.qualityStandards?.push(
|
|
505
|
-
`Avoid technical terms like: ${qualityChecks.forbidTechnicalTerms.join(
|
|
516
|
+
`Avoid technical terms like: ${qualityChecks.forbidTechnicalTerms.join(
|
|
517
|
+
', '
|
|
518
|
+
)}`
|
|
506
519
|
);
|
|
507
520
|
}
|
|
508
521
|
}
|
|
@@ -817,7 +830,10 @@ export class FormGenerator {
|
|
|
817
830
|
zodSchema: z.ZodObject<z.ZodRawShape>,
|
|
818
831
|
partialInput?: Record<string, unknown>,
|
|
819
832
|
missingFields?: Set<string>
|
|
820
|
-
): {
|
|
833
|
+
): {
|
|
834
|
+
jsonSchema: Record<string, unknown>;
|
|
835
|
+
uiSchema: Record<string, unknown>;
|
|
836
|
+
} {
|
|
821
837
|
const fullJsonSchema = zodToJsonSchema(zodSchema, {
|
|
822
838
|
target: 'jsonSchema7',
|
|
823
839
|
});
|
package/src/index.ts
CHANGED
|
@@ -979,9 +979,11 @@ export class FormAwareAgentExecutor extends AgentExecutor {
|
|
|
979
979
|
'🔗 HASHLINK DETECTED: Processing HashLink response separately to preserve metadata'
|
|
980
980
|
);
|
|
981
981
|
|
|
982
|
+
const parsedRecord = parsed as Record<string, unknown>;
|
|
982
983
|
responseMetadata = {
|
|
983
984
|
...responseMetadata,
|
|
984
|
-
hashLinkBlock:
|
|
985
|
+
hashLinkBlock: parsedRecord.hashLinkBlock,
|
|
986
|
+
...parsedRecord,
|
|
985
987
|
};
|
|
986
988
|
|
|
987
989
|
formattedOutput = ResponseFormatter.formatHashLinkResponse(parsed);
|
|
@@ -1003,6 +1005,7 @@ export class FormAwareAgentExecutor extends AgentExecutor {
|
|
|
1003
1005
|
responseMetadata = {
|
|
1004
1006
|
...responseMetadata,
|
|
1005
1007
|
hashLinkBlock: (parsed as Record<string, unknown>).hashLinkBlock,
|
|
1008
|
+
...parsed,
|
|
1006
1009
|
};
|
|
1007
1010
|
}
|
|
1008
1011
|
} else {
|
|
@@ -1240,6 +1243,7 @@ Please fill out the form below to continue.`;
|
|
|
1240
1243
|
}));
|
|
1241
1244
|
}
|
|
1242
1245
|
|
|
1246
|
+
|
|
1243
1247
|
/**
|
|
1244
1248
|
* Processes HashLink block responses from tools
|
|
1245
1249
|
*/
|
|
@@ -1251,11 +1255,7 @@ Please fill out the form below to continue.`;
|
|
|
1251
1255
|
|
|
1252
1256
|
if (toolResponse.hashLinkBlock) {
|
|
1253
1257
|
hashLinkBlock = toolResponse.hashLinkBlock;
|
|
1254
|
-
} else if (
|
|
1255
|
-
toolResponse.success &&
|
|
1256
|
-
toolResponse.inscription &&
|
|
1257
|
-
toolResponse.hashLinkBlock
|
|
1258
|
-
) {
|
|
1258
|
+
} else if (toolResponse.success && toolResponse.hashLinkBlock) {
|
|
1259
1259
|
hashLinkBlock = toolResponse.hashLinkBlock;
|
|
1260
1260
|
}
|
|
1261
1261
|
|
|
@@ -819,7 +819,7 @@ export class LangChainAgent extends BaseAgent {
|
|
|
819
819
|
if (args.metaOptions && typeof args.metaOptions === 'object') {
|
|
820
820
|
const metaOptions = args.metaOptions as Record<string, unknown>;
|
|
821
821
|
if (metaOptions.transactionMemo) {
|
|
822
|
-
|
|
822
|
+
this.logger.warn(
|
|
823
823
|
'🚨 WORKAROUND: Stripping transactionMemo from hedera-hts-mint-nft to avoid bug',
|
|
824
824
|
{ originalMemo: metaOptions.transactionMemo }
|
|
825
825
|
);
|
|
@@ -56,10 +56,17 @@ export class MCPClientManager {
|
|
|
56
56
|
this.clients.set(config.name, client);
|
|
57
57
|
|
|
58
58
|
const toolsResponse = await client.listTools();
|
|
59
|
-
const toolsWithServer: MCPToolInfo[] = toolsResponse.tools.map(tool =>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
const toolsWithServer: MCPToolInfo[] = toolsResponse.tools.map((tool: unknown) => {
|
|
60
|
+
const t = tool as { description?: string } & Record<string, unknown>;
|
|
61
|
+
const { description, ...rest } = t;
|
|
62
|
+
const base = description !== undefined && typeof description === 'string'
|
|
63
|
+
? { ...rest, description }
|
|
64
|
+
: { ...rest };
|
|
65
|
+
return {
|
|
66
|
+
...(base as Omit<MCPToolInfo, 'serverName'>),
|
|
67
|
+
serverName: config.name,
|
|
68
|
+
} as MCPToolInfo;
|
|
69
|
+
});
|
|
63
70
|
|
|
64
71
|
this.tools.set(config.name, toolsWithServer);
|
|
65
72
|
this.logger.info(`Connected to MCP server ${config.name} with ${toolsWithServer.length} tools`);
|
|
@@ -205,4 +212,4 @@ export class MCPClientManager {
|
|
|
205
212
|
}
|
|
206
213
|
return this.contentProcessor.analyzeResponse(response);
|
|
207
214
|
}
|
|
208
|
-
}
|
|
215
|
+
}
|
package/src/mcp/types.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Minimal MCP Tool shape used internally to avoid external type dependency resolution issues.
|
|
3
|
+
* Aligns with MCP tool metadata returned by listTools.
|
|
4
|
+
*/
|
|
5
|
+
export interface BaseMCPTool {
|
|
6
|
+
name: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
/**
|
|
9
|
+
* JSON Schema describing input parameters for the tool.
|
|
10
|
+
* Kept as unknown and validated/converted at the boundary.
|
|
11
|
+
*/
|
|
12
|
+
inputSchema?: unknown;
|
|
13
|
+
}
|
|
2
14
|
|
|
3
15
|
export interface MCPServerConfig {
|
|
4
16
|
name: string;
|
|
@@ -17,7 +29,7 @@ export interface MCPServerConfig {
|
|
|
17
29
|
toolDescriptions?: Record<string, string>;
|
|
18
30
|
}
|
|
19
31
|
|
|
20
|
-
export interface MCPToolInfo extends
|
|
32
|
+
export interface MCPToolInfo extends BaseMCPTool {
|
|
21
33
|
serverName: string;
|
|
22
34
|
}
|
|
23
35
|
|
|
@@ -26,4 +38,4 @@ export interface MCPConnectionStatus {
|
|
|
26
38
|
connected: boolean;
|
|
27
39
|
error?: string;
|
|
28
40
|
tools: MCPToolInfo[];
|
|
29
|
-
}
|
|
41
|
+
}
|