@hashgraphonline/standards-agent-kit 0.2.162 → 0.2.165

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.
@@ -0,0 +1,630 @@
1
+ import { z } from 'zod';
2
+ import {
3
+ RegistryBrokerClient,
4
+ RegistryBrokerError,
5
+ type RegistryBrokerClientOptions,
6
+ type SearchParams,
7
+ type VectorSearchRequest,
8
+ type AgentRegistrationRequest,
9
+ type RegisterAgentOptions,
10
+ type LedgerChallengeRequest,
11
+ type LedgerVerifyRequest,
12
+ type LedgerCredentialAuthOptions,
13
+ type CreateSessionRequestPayload,
14
+ type SendMessageRequestPayload,
15
+ type CompactHistoryRequestPayload,
16
+ type EncryptionHandshakeSubmissionPayload,
17
+ type StartEncryptedChatSessionOptions,
18
+ type AcceptEncryptedChatSessionOptions,
19
+ type StartConversationOptions,
20
+ type AcceptConversationOptions,
21
+ type ChatHistoryFetchOptions,
22
+ type RegisterEncryptionKeyPayload,
23
+ type DeriveSharedSecretOptions,
24
+ type EncryptCipherEnvelopeOptions,
25
+ type DecryptCipherEnvelopeOptions,
26
+ type EnsureAgentKeyOptions,
27
+ type GenerateEncryptionKeyPairOptions,
28
+ type InitializeAgentClientOptions,
29
+ type ChatHistoryEntry,
30
+ } from '@hashgraphonline/standards-sdk/services/registry-broker';
31
+ import {
32
+ BaseHederaQueryTool,
33
+ type BaseHederaQueryToolParams,
34
+ } from 'hedera-agent-kit';
35
+ import type { RegistryBrokerClientProvider } from './RegistryBrokerClientProvider';
36
+ import { RegistryBrokerConversationStore } from './RegistryBrokerConversationStore';
37
+
38
+ const nonEmptyString = (label: string): z.ZodString =>
39
+ z
40
+ .string({
41
+ required_error: `${label} is required`,
42
+ invalid_type_error: `${label} must be a string`,
43
+ })
44
+ .min(1, `${label} cannot be empty`);
45
+
46
+ const objectLike = <T>(label: string): z.ZodType<T> =>
47
+ z.custom<T>(
48
+ value => typeof value === 'object' && value !== null,
49
+ `${label} must be an object`,
50
+ );
51
+
52
+ const registrySearchParamsSchema: z.ZodType<SearchParams> = z
53
+ .object({
54
+ q: z.string().optional(),
55
+ page: z.number().int().positive().optional(),
56
+ limit: z.number().int().positive().optional(),
57
+ registry: z.string().optional(),
58
+ registries: z.array(z.string()).optional(),
59
+ capabilities: z.array(z.string()).optional(),
60
+ protocols: z.array(z.string()).optional(),
61
+ minTrust: z.number().min(0).max(100).optional(),
62
+ adapters: z.array(z.string()).optional(),
63
+ sortBy: z.string().optional(),
64
+ sortOrder: z.enum(['asc', 'desc']).optional(),
65
+ type: z.string().optional(),
66
+ verified: z.boolean().optional(),
67
+ online: z.boolean().optional(),
68
+ metadata: z
69
+ .record(
70
+ z.array(z.union([z.string(), z.number(), z.boolean()])),
71
+ )
72
+ .optional(),
73
+ })
74
+ .partial();
75
+
76
+ const registryBrokerInputSchema = z.object({
77
+ operation: z.string(),
78
+ payload: z.unknown().optional(),
79
+ });
80
+
81
+ type RegistryBrokerToolInput = z.infer<typeof registryBrokerInputSchema>;
82
+
83
+ type OperationPath = string;
84
+
85
+ type MethodOperationDefinition =
86
+ | { type: 'noArgs'; path: OperationPath }
87
+ | {
88
+ type: 'string';
89
+ path: OperationPath;
90
+ field: string;
91
+ optional?: boolean;
92
+ }
93
+ | { type: 'object'; path: OperationPath; schema: z.ZodTypeAny }
94
+ | {
95
+ type: 'tuple';
96
+ path: OperationPath;
97
+ schema: z.ZodTypeAny;
98
+ mapArgs: (payload: unknown) => unknown[];
99
+ };
100
+
101
+ type CustomOperationDefinition = {
102
+ type: 'custom';
103
+ schema: z.ZodTypeAny;
104
+ handler: (payload: unknown) => Promise<unknown>;
105
+ };
106
+
107
+ type OperationDefinition = MethodOperationDefinition | CustomOperationDefinition;
108
+
109
+ const noArgs = (path: string): MethodOperationDefinition => ({
110
+ type: 'noArgs',
111
+ path,
112
+ });
113
+
114
+ const stringArg = (
115
+ path: string,
116
+ field: string,
117
+ optional = false,
118
+ ): MethodOperationDefinition => ({
119
+ type: 'string',
120
+ path,
121
+ field,
122
+ optional,
123
+ });
124
+
125
+ const objectArg = (
126
+ path: string,
127
+ schema: z.ZodTypeAny,
128
+ ): MethodOperationDefinition => ({
129
+ type: 'object',
130
+ path,
131
+ schema,
132
+ });
133
+
134
+ const tupleArg = (
135
+ path: string,
136
+ schema: z.ZodTypeAny,
137
+ mapArgs: (payload: unknown) => unknown[],
138
+ ): MethodOperationDefinition => ({
139
+ type: 'tuple',
140
+ path,
141
+ schema,
142
+ mapArgs,
143
+ });
144
+
145
+ export class RegistryBrokerOperationTool extends BaseHederaQueryTool<
146
+ typeof registryBrokerInputSchema
147
+ > {
148
+ name = 'registry_broker_operation';
149
+ description =
150
+ 'Invoke registry-broker client methods (search, chat, registry lifecycle, ledger auth, encryption).';
151
+ namespace = 'registry-broker';
152
+ specificInputSchema = registryBrokerInputSchema;
153
+
154
+ constructor(
155
+ params: BaseHederaQueryToolParams & {
156
+ clientProvider: RegistryBrokerClientProvider;
157
+ handleStore: RegistryBrokerConversationStore;
158
+ },
159
+ ) {
160
+ super(params);
161
+ this.clientProvider = params.clientProvider;
162
+ this.handleStore = params.handleStore;
163
+ }
164
+
165
+ private readonly clientProvider: RegistryBrokerClientProvider;
166
+ private readonly handleStore: RegistryBrokerConversationStore;
167
+
168
+ protected override async executeQuery(
169
+ input: RegistryBrokerToolInput,
170
+ ): Promise<{
171
+ success: boolean;
172
+ operation: string;
173
+ result?: unknown;
174
+ error?: string;
175
+ }> {
176
+ try {
177
+ const result = await this.performOperation(input);
178
+ return {
179
+ success: true,
180
+ operation: input.operation,
181
+ result,
182
+ };
183
+ } catch (error) {
184
+ const message =
185
+ error instanceof Error ? error.message : String(error ?? 'unknown error');
186
+ const brokerDetails =
187
+ error instanceof RegistryBrokerError
188
+ ? {
189
+ status: error.status,
190
+ statusText: error.statusText,
191
+ body: error.body,
192
+ }
193
+ : undefined;
194
+ this.logger.error?.(
195
+ `[RegistryBrokerPlugin] Operation "${input.operation}" failed`,
196
+ error,
197
+ );
198
+ return {
199
+ success: false,
200
+ operation: input.operation,
201
+ error: message,
202
+ ...(brokerDetails ? { details: brokerDetails } : {}),
203
+ };
204
+ }
205
+ }
206
+
207
+ private async performOperation(
208
+ input: RegistryBrokerToolInput,
209
+ ): Promise<unknown> {
210
+ if (CONVERSATION_OPERATIONS.has(input.operation)) {
211
+ return this.handleConversationOperation(input);
212
+ }
213
+ if (input.operation === 'initializeAgent') {
214
+ return this.handleInitializeAgent(input.payload);
215
+ }
216
+ const definition = OPERATION_DEFINITIONS[input.operation];
217
+ if (!definition) {
218
+ throw new Error(`Unsupported registry broker operation: ${input.operation}`);
219
+ }
220
+ if (definition.type === 'custom') {
221
+ const parsed = definition.schema.parse(input.payload);
222
+ return definition.handler(parsed);
223
+ }
224
+ const client = await this.clientProvider.getClient();
225
+ const target = this.resolveTarget(client, definition.path);
226
+ if (typeof target !== 'function') {
227
+ throw new Error(`Method "${definition.path}" is unavailable on the client`);
228
+ }
229
+ if (definition.type === 'noArgs') {
230
+ const result = await target.call(client);
231
+ return this.formatResult(input.operation, result);
232
+ }
233
+ if (definition.type === 'string') {
234
+ const schema = z
235
+ .object({
236
+ [definition.field]: definition.optional
237
+ ? z.string().optional()
238
+ : nonEmptyString(definition.field),
239
+ })
240
+ .strict();
241
+ const parsed = schema.parse(
242
+ definition.optional && input.payload === undefined
243
+ ? {}
244
+ : input.payload ?? {},
245
+ );
246
+ const arg = parsed[definition.field];
247
+ const result = await target.call(client, arg);
248
+ return this.formatResult(input.operation, result);
249
+ }
250
+ if (definition.type === 'object') {
251
+ const parsed = definition.schema.parse(
252
+ input.payload ?? ({} as unknown as RegistryBrokerClientOptions),
253
+ );
254
+ const result = await target.call(client, parsed);
255
+ return this.formatResult(input.operation, result);
256
+ }
257
+ if (definition.type === 'tuple') {
258
+ const parsed = definition.schema.parse(input.payload ?? {});
259
+ const args = definition.mapArgs(parsed);
260
+ const result = await target.apply(client, args);
261
+ return this.formatResult(input.operation, result);
262
+ }
263
+ return undefined;
264
+ }
265
+
266
+ private async handleConversationOperation(
267
+ input: RegistryBrokerToolInput,
268
+ ): Promise<unknown> {
269
+ switch (input.operation) {
270
+ case 'conversation.send': {
271
+ const parsed = conversationSendSchema.parse(input.payload ?? {});
272
+ const handle = this.handleStore.get(parsed.handleId);
273
+ return handle.send(parsed.payload);
274
+ }
275
+ case 'conversation.decryptHistoryEntry': {
276
+ const parsed = conversationDecryptSchema.parse(input.payload ?? {});
277
+ const handle = this.handleStore.get(parsed.handleId);
278
+ return handle.decryptHistoryEntry(parsed.entry);
279
+ }
280
+ case 'conversation.release': {
281
+ const parsed = conversationReleaseSchema.parse(input.payload ?? {});
282
+ return this.handleStore.release(parsed.handleId);
283
+ }
284
+ default:
285
+ throw new Error(`Unsupported conversation operation: ${input.operation}`);
286
+ }
287
+ }
288
+
289
+ private async handleInitializeAgent(payload: unknown): Promise<unknown> {
290
+ const parsed = initializeAgentSchema.parse(payload ?? {});
291
+ const result = await RegistryBrokerClient.initializeAgent(parsed);
292
+ return {
293
+ encryption: result.encryption ?? null,
294
+ defaultHeaders: result.client.getDefaultHeaders(),
295
+ };
296
+ }
297
+
298
+ private resolveTarget(
299
+ client: RegistryBrokerClient,
300
+ path: string,
301
+ ): unknown {
302
+ return path.split('.').reduce((acc: unknown, key) => {
303
+ if (acc && typeof acc === 'object') {
304
+ return (acc as Record<string, unknown>)[key];
305
+ }
306
+ return undefined;
307
+ }, client);
308
+ }
309
+
310
+ private formatResult(
311
+ operation: string,
312
+ result: unknown,
313
+ ): unknown {
314
+ if (this.isConversationHandle(result)) {
315
+ const stored = this.handleStore.register(result);
316
+ return {
317
+ handleId: stored.handleId,
318
+ sessionId: stored.sessionId,
319
+ mode: stored.mode,
320
+ summary: stored.summary ?? null,
321
+ };
322
+ }
323
+ if (operation === 'getDefaultHeaders' && typeof result === 'object') {
324
+ return result;
325
+ }
326
+ return result;
327
+ }
328
+
329
+ private isConversationHandle(
330
+ value: unknown,
331
+ ): value is Parameters<
332
+ RegistryBrokerConversationStore['register']
333
+ >[0] {
334
+ if (!value || typeof value !== 'object') {
335
+ return false;
336
+ }
337
+ const candidate = value as Record<string, unknown>;
338
+ return (
339
+ typeof candidate.sessionId === 'string' &&
340
+ typeof candidate.send === 'function' &&
341
+ typeof candidate.decryptHistoryEntry === 'function'
342
+ );
343
+ }
344
+ }
345
+
346
+ const conversationOperations = [
347
+ 'conversation.send',
348
+ 'conversation.decryptHistoryEntry',
349
+ 'conversation.release',
350
+ ] as const;
351
+
352
+ const CONVERSATION_OPERATIONS = new Set<string>(conversationOperations);
353
+
354
+ const conversationSendSchema = z.object({
355
+ handleId: nonEmptyString('handleId'),
356
+ payload: objectLike<Parameters<
357
+ Parameters<RegistryBrokerConversationStore['register']>[0]['send']
358
+ >[0]>('payload'),
359
+ });
360
+
361
+ const conversationDecryptSchema = z.object({
362
+ handleId: nonEmptyString('handleId'),
363
+ entry: objectLike<ChatHistoryEntry>('entry'),
364
+ });
365
+
366
+ const conversationReleaseSchema = z.object({
367
+ handleId: nonEmptyString('handleId'),
368
+ });
369
+
370
+ const vectorSearchSchema =
371
+ objectLike<VectorSearchRequest>('vectorSearchRequest');
372
+
373
+ const registerAgentSchema = z.object({
374
+ payload: objectLike<AgentRegistrationRequest>('registerAgentPayload'),
375
+ options: objectLike<RegisterAgentOptions>('registerAgentOptions').optional(),
376
+ });
377
+
378
+ const updateAgentSchema = z.object({
379
+ uaid: nonEmptyString('uaid'),
380
+ request: objectLike<AgentRegistrationRequest>('request'),
381
+ });
382
+
383
+ const waitForRegistrationSchema = z.object({
384
+ attemptId: nonEmptyString('attemptId'),
385
+ options: objectLike<{
386
+ intervalMs?: number;
387
+ timeoutMs?: number;
388
+ throwOnFailure?: boolean;
389
+ }>('options').optional(),
390
+ });
391
+
392
+ const registryNamespaceSchema = z.object({
393
+ registry: nonEmptyString('registry'),
394
+ namespace: nonEmptyString('namespace'),
395
+ });
396
+
397
+ const ledgerChallengeSchema =
398
+ objectLike<LedgerChallengeRequest>('ledgerChallenge');
399
+
400
+ const ledgerVerifySchema =
401
+ objectLike<LedgerVerifyRequest>('ledgerVerifyRequest');
402
+
403
+ const ledgerAuthSchema =
404
+ objectLike<LedgerCredentialAuthOptions>('ledgerCredentialAuth');
405
+
406
+ const createSessionSchema =
407
+ objectLike<CreateSessionRequestPayload>('createSessionPayload');
408
+
409
+ const sendMessageSchema =
410
+ objectLike<SendMessageRequestPayload>('sendMessagePayload');
411
+
412
+ const chatHistorySchema = z.object({
413
+ sessionId: nonEmptyString('sessionId'),
414
+ options: objectLike<ChatHistoryFetchOptions>('historyOptions').optional(),
415
+ });
416
+
417
+ const submitHandshakeSchema = z.object({
418
+ sessionId: nonEmptyString('sessionId'),
419
+ payload: objectLike<EncryptionHandshakeSubmissionPayload>(
420
+ 'handshakePayload',
421
+ ),
422
+ });
423
+
424
+ const compactHistorySchema =
425
+ objectLike<CompactHistoryRequestPayload>('compactHistoryPayload');
426
+
427
+ const registerKeySchema =
428
+ objectLike<RegisterEncryptionKeyPayload>('registerEncryptionKeyPayload');
429
+
430
+ const deriveSecretSchema =
431
+ objectLike<DeriveSharedSecretOptions>('deriveSharedSecretOptions');
432
+
433
+ const encryptEnvelopeSchema =
434
+ objectLike<EncryptCipherEnvelopeOptions>('encryptCipherEnvelopeOptions');
435
+
436
+ const decryptEnvelopeSchema =
437
+ objectLike<DecryptCipherEnvelopeOptions>('decryptCipherEnvelopeOptions');
438
+
439
+ const ensureAgentKeySchema =
440
+ objectLike<EnsureAgentKeyOptions>('ensureAgentKeyOptions');
441
+
442
+ const generateKeyPairSchema = z
443
+ .object({
444
+ keyType: z.enum(['secp256k1']).optional(),
445
+ envVar: z.string().optional(),
446
+ envPath: z.string().optional(),
447
+ overwrite: z.boolean().optional(),
448
+ })
449
+ .partial()
450
+ .optional();
451
+
452
+ const startChatSchema =
453
+ objectLike<StartChatOptions>('startChatOptions');
454
+
455
+ const startConversationSchema =
456
+ objectLike<StartConversationOptions>('startConversationOptions');
457
+
458
+ const acceptConversationSchema =
459
+ objectLike<AcceptConversationOptions>('acceptConversationOptions');
460
+
461
+ const startEncryptedSessionSchema =
462
+ objectLike<StartEncryptedChatSessionOptions>(
463
+ 'startEncryptedSessionOptions',
464
+ );
465
+
466
+ const acceptEncryptedSessionSchema =
467
+ objectLike<AcceptEncryptedChatSessionOptions>(
468
+ 'acceptEncryptedSessionOptions',
469
+ );
470
+
471
+ const initializeAgentSchema =
472
+ objectLike<InitializeAgentClientOptions>('initializeAgentOptions');
473
+
474
+ const OPERATION_DEFINITIONS: Record<string, OperationDefinition> = {
475
+ stats: noArgs('stats'),
476
+ registries: noArgs('registries'),
477
+ getAdditionalRegistries: noArgs('getAdditionalRegistries'),
478
+ popularSearches: noArgs('popularSearches'),
479
+ adapters: noArgs('adapters'),
480
+ adaptersDetailed: noArgs('adaptersDetailed'),
481
+ listProtocols: noArgs('listProtocols'),
482
+ searchStatus: noArgs('searchStatus'),
483
+ websocketStats: noArgs('websocketStats'),
484
+ metricsSummary: noArgs('metricsSummary'),
485
+ dashboardStats: noArgs('dashboardStats'),
486
+ getX402Minimums: noArgs('getX402Minimums'),
487
+ encryptionReady: noArgs('encryptionReady'),
488
+ getDefaultHeaders: noArgs('getDefaultHeaders'),
489
+ setApiKey: stringArg('setApiKey', 'apiKey', true),
490
+ setLedgerApiKey: stringArg('setLedgerApiKey', 'apiKey', true),
491
+ resolveUaid: stringArg('resolveUaid', 'uaid'),
492
+ validateUaid: stringArg('validateUaid', 'uaid'),
493
+ getUaidConnectionStatus: stringArg(
494
+ 'getUaidConnectionStatus',
495
+ 'uaid',
496
+ ),
497
+ closeUaidConnection: stringArg('closeUaidConnection', 'uaid'),
498
+ facets: stringArg('facets', 'adapter', true),
499
+ search: objectArg('search', registrySearchParamsSchema),
500
+ vectorSearch: objectArg('vectorSearch', vectorSearchSchema),
501
+ registrySearchByNamespace: tupleArg(
502
+ 'registrySearchByNamespace',
503
+ registryNamespaceSchema,
504
+ payload => [payload.registry, payload.namespace],
505
+ ),
506
+ registerAgent: tupleArg(
507
+ 'registerAgent',
508
+ registerAgentSchema,
509
+ payload => [payload.payload, payload.options],
510
+ ),
511
+ getRegistrationQuote: objectArg(
512
+ 'getRegistrationQuote',
513
+ objectLike<AgentRegistrationRequest>('getRegistrationQuotePayload'),
514
+ ),
515
+ updateAgent: tupleArg(
516
+ 'updateAgent',
517
+ updateAgentSchema,
518
+ payload => [payload.uaid, payload.request],
519
+ ),
520
+ getRegistrationProgress: stringArg(
521
+ 'getRegistrationProgress',
522
+ 'attemptId',
523
+ ),
524
+ waitForRegistrationCompletion: tupleArg(
525
+ 'waitForRegistrationCompletion',
526
+ waitForRegistrationSchema,
527
+ payload => [payload.attemptId, payload.options],
528
+ ),
529
+ purchaseCreditsWithHbar: objectArg(
530
+ 'purchaseCreditsWithHbar',
531
+ objectLike('purchaseCreditsWithHbar'),
532
+ ),
533
+ purchaseCreditsWithX402: objectArg(
534
+ 'purchaseCreditsWithX402',
535
+ objectLike('purchaseCreditsWithX402'),
536
+ ),
537
+ buyCreditsWithX402: objectArg(
538
+ 'buyCreditsWithX402',
539
+ objectLike('buyCreditsWithX402'),
540
+ ),
541
+ createLedgerChallenge: objectArg(
542
+ 'createLedgerChallenge',
543
+ ledgerChallengeSchema,
544
+ ),
545
+ verifyLedgerChallenge: objectArg(
546
+ 'verifyLedgerChallenge',
547
+ ledgerVerifySchema,
548
+ ),
549
+ authenticateWithLedger: objectArg(
550
+ 'authenticateWithLedger',
551
+ ledgerAuthSchema,
552
+ ),
553
+ authenticateWithLedgerCredentials: objectArg(
554
+ 'authenticateWithLedgerCredentials',
555
+ ledgerAuthSchema,
556
+ ),
557
+ detectProtocol: objectArg('detectProtocol', objectLike('detectProtocol')),
558
+ setDefaultHeader: tupleArg(
559
+ 'setDefaultHeader',
560
+ z.object({
561
+ name: nonEmptyString('name'),
562
+ value: z.string().optional(),
563
+ }),
564
+ payload => [payload.name, payload.value],
565
+ ),
566
+ 'chat.start': objectArg('chat.start', startChatSchema),
567
+ 'chat.createSession': objectArg('chat.createSession', createSessionSchema),
568
+ 'chat.sendMessage': objectArg('chat.sendMessage', sendMessageSchema),
569
+ 'chat.endSession': stringArg('chat.endSession', 'sessionId'),
570
+ 'chat.getHistory': tupleArg('chat.getHistory', chatHistorySchema, payload => [
571
+ payload.sessionId,
572
+ payload.options,
573
+ ]),
574
+ 'chat.compactHistory': objectArg(
575
+ 'chat.compactHistory',
576
+ compactHistorySchema,
577
+ ),
578
+ 'chat.getEncryptionStatus': stringArg(
579
+ 'chat.getEncryptionStatus',
580
+ 'sessionId',
581
+ ),
582
+ 'chat.submitEncryptionHandshake': tupleArg(
583
+ 'chat.submitEncryptionHandshake',
584
+ submitHandshakeSchema,
585
+ payload => [payload.sessionId, payload.payload],
586
+ ),
587
+ 'chat.createEncryptedSession': objectArg(
588
+ 'chat.createEncryptedSession',
589
+ startEncryptedSessionSchema,
590
+ ),
591
+ 'chat.acceptEncryptedSession': objectArg(
592
+ 'chat.acceptEncryptedSession',
593
+ acceptEncryptedSessionSchema,
594
+ ),
595
+ 'chat.startConversation': objectArg(
596
+ 'chat.startConversation',
597
+ startConversationSchema,
598
+ ),
599
+ 'chat.acceptConversation': objectArg(
600
+ 'chat.acceptConversation',
601
+ acceptConversationSchema,
602
+ ),
603
+ 'encryption.registerKey': objectArg(
604
+ 'encryption.registerKey',
605
+ registerKeySchema,
606
+ ),
607
+ 'encryption.generateEphemeralKeyPair': noArgs(
608
+ 'encryption.generateEphemeralKeyPair',
609
+ ),
610
+ 'encryption.deriveSharedSecret': objectArg(
611
+ 'encryption.deriveSharedSecret',
612
+ deriveSecretSchema,
613
+ ),
614
+ 'encryption.encryptCipherEnvelope': objectArg(
615
+ 'encryption.encryptCipherEnvelope',
616
+ encryptEnvelopeSchema,
617
+ ),
618
+ 'encryption.decryptCipherEnvelope': objectArg(
619
+ 'encryption.decryptCipherEnvelope',
620
+ decryptEnvelopeSchema,
621
+ ),
622
+ 'encryption.ensureAgentKey': objectArg(
623
+ 'encryption.ensureAgentKey',
624
+ ensureAgentKeySchema,
625
+ ),
626
+ generateEncryptionKeyPair: objectArg(
627
+ 'generateEncryptionKeyPair',
628
+ generateKeyPairSchema,
629
+ ),
630
+ };
@@ -0,0 +1,63 @@
1
+ import {
2
+ BasePlugin,
3
+ type GenericPluginContext,
4
+ type HederaAgentKit,
5
+ type HederaTool,
6
+ } from 'hedera-agent-kit';
7
+ import { RegistryBrokerClientProvider } from './RegistryBrokerClientProvider';
8
+ import type { RegistryBrokerPluginConfiguration } from './RegistryBrokerClientProvider';
9
+ import { RegistryBrokerConversationStore } from './RegistryBrokerConversationStore';
10
+ import { RegistryBrokerOperationTool } from './RegistryBrokerOperationTool';
11
+
12
+ export interface RegistryBrokerPluginContext extends GenericPluginContext {
13
+ config: GenericPluginContext['config'] & {
14
+ registryBroker?: RegistryBrokerPluginConfiguration;
15
+ };
16
+ }
17
+
18
+ export class RegistryBrokerPlugin extends BasePlugin<RegistryBrokerPluginContext> {
19
+ id = 'registry-broker';
20
+ name = 'Registry Broker Plugin';
21
+ description =
22
+ 'Expose RegistryBrokerClient operations to Hedera Agent Kit tools for discovery, chat, registration, and ledger auth.';
23
+ version = '0.1.0';
24
+ author = 'Hashgraph Online';
25
+
26
+ private tools: HederaTool[] = [];
27
+ private clientProvider?: RegistryBrokerClientProvider;
28
+ private readonly handleStore = new RegistryBrokerConversationStore();
29
+
30
+ override async initialize(
31
+ context: RegistryBrokerPluginContext,
32
+ ): Promise<void> {
33
+ await super.initialize(context);
34
+ const hederaKit = context.config.hederaKit as HederaAgentKit | undefined;
35
+ if (!hederaKit) {
36
+ this.context.logger.warn(
37
+ '[RegistryBrokerPlugin] HederaAgentKit not available; plugin initialization skipped.',
38
+ );
39
+ this.tools = [];
40
+ return;
41
+ }
42
+
43
+ const provider = new RegistryBrokerClientProvider(
44
+ context.config.registryBroker,
45
+ this.context.logger,
46
+ );
47
+ this.clientProvider = provider;
48
+
49
+ const tool = new RegistryBrokerOperationTool({
50
+ hederaKit,
51
+ logger: this.context.logger,
52
+ clientProvider: provider,
53
+ handleStore: this.handleStore,
54
+ });
55
+
56
+ this.tools = [tool];
57
+ this.context.logger.info?.('[RegistryBrokerPlugin] Initialized.');
58
+ }
59
+
60
+ override getTools(): HederaTool[] {
61
+ return this.tools;
62
+ }
63
+ }