diff --git a/packages/core/src/tools/tools.test.ts b/packages/core/src/tools/tools.test.ts index edbc487160..9b200d6f38 100644 --- a/packages/core/src/tools/tools.test.ts +++ b/packages/core/src/tools/tools.test.ts @@ -6,6 +6,7 @@ import { describe, it, expect, vi } from 'vitest'; import { + BaseToolInvocation, DeclarativeTool, hasCycleInSchema, Kind, @@ -272,3 +273,55 @@ describe('Tools Read-Only property', () => { expect(searcher.isReadOnly).toBe(true); }); }); + +describe('toJSON serialization', () => { + it('DeclarativeTool.toJSON should return essential metadata', () => { + const bus = createMockMessageBus(); + class MyTool extends DeclarativeTool { + build(_params: object): ToolInvocation { + throw new Error('Not implemented'); + } + } + const tool = new MyTool( + 'name', + 'display', + 'desc', + Kind.Read, + { type: 'object' }, + bus, + ); + const json = tool.toJSON(); + + expect(json).toEqual({ + name: 'name', + displayName: 'display', + description: 'desc', + kind: Kind.Read, + parameterSchema: { type: 'object' }, + }); + // Ensure messageBus is NOT included in serialization + expect(Object.keys(json)).not.toContain('messageBus'); + expect(JSON.stringify(tool)).toContain('"name":"name"'); + expect(JSON.stringify(tool)).not.toContain('messageBus'); + }); + + it('BaseToolInvocation.toJSON should return only params', () => { + const bus = createMockMessageBus(); + const params = { foo: 'bar' }; + class MyInvocation extends BaseToolInvocation { + getDescription() { + return 'desc'; + } + async execute() { + return { llmContent: '', returnDisplay: '' }; + } + } + const invocation = new MyInvocation(params, bus, 'tool'); + const json = invocation.toJSON(); + + expect(json).toEqual({ params }); + // Ensure messageBus is NOT included in serialization + expect(Object.keys(json)).not.toContain('messageBus'); + expect(JSON.stringify(invocation)).toBe('{"params":{"foo":"bar"}}'); + }); +}); diff --git a/packages/core/src/tools/tools.ts b/packages/core/src/tools/tools.ts index 6b22f7a3e3..23e88b608b 100644 --- a/packages/core/src/tools/tools.ts +++ b/packages/core/src/tools/tools.ts @@ -379,6 +379,12 @@ export abstract class BaseToolInvocation< updateOutput?: (output: ToolLiveOutput) => void, options?: ExecuteOptions, ): Promise; + + toJSON() { + return { + params: this.params, + }; + } } /** @@ -498,6 +504,16 @@ export abstract class DeclarativeTool< return cloned; } + toJSON() { + return { + name: this.name, + displayName: this.displayName, + description: this.description, + kind: this.kind, + parameterSchema: this.parameterSchema, + }; + } + get isReadOnly(): boolean { return READ_ONLY_KINDS.includes(this.kind); }