Skip to content
中文

tool ​

SUPPORT · function · Runtime value

Instantiate a tool definition class; schema and authorization stay with existing defineTool. Bind an existing host method as the tool's execute callback. A model-only tool method provides its synchronous resolver.

Import ​

ts
import { tool } from '@jangts/agent-core/support/decorators';
js
import { tool } from '@jangts/agent-core/support/decorators';

Other public entry points:@jangts/agent-core/support/decorators.

Definition ​

Type parameters ​

Type parameterConstraintDefault type
Input—any
Output—any
App—any

Overload 1 ​

ts
tool<Input = any, Output = any, App = any>(id: string, options?: DecorationOptions): ClassDecoration<WithoutIntent<ToolDefinition<Input, Output, App> | ModelTool<Input, Output, App>>>

Instantiate a tool definition class; schema and authorization stay with existing defineTool.

Type parameterConstraintDefault type
Input—any
Output—any
App—any
ParameterTypePassingDescription
idstringRequired—
optionsDecorationOptions | undefinedOptional—

Optional shapes of Parameter options: choose one shape; required fields for each branch are listed separately.

Branch 1

undefined

Branch 2
FieldTypeRequiredDescription
nsstring | readonly string[] | undefinedOptionalRead-only. See the type definition and usage context.

Returns: ClassDecoration<(Omit<ToolDefinition<Input, Output, App>, "asIntent"> & { readonly asIntent?: never; }) \| (Omit<ModelTool<Input, Output, App>, "asIntent"> & { readonly asIntent?: never; })>.

Overload 2 ​

ts
tool<Input = unknown, Output = unknown, App = any>(id: string, options: MethodOptions<Omit<ToolDefinition<Input, Output, App>, "asIntent">, "execute">): MethodDecoration<ToolDefinition<Input, Output, App>["execute"]>

Bind an existing host method as the tool's execute callback.

Type parameterConstraintDefault type
Input—unknown
Output—unknown
App—any
ParameterTypePassingDescription
idstringRequired—
optionsMethodOptions<Omit<ToolDefinition<Input, Output, App>, "asIntent">, "execute">Required—
Fields of options
FieldTypeRequiredDescription
descriptionstringRequiredRead-only. Model-visible explanation of when to call the tool.
resolve((input: Input, context: Readonly<{ stageId: string; }>) => ToolProposal) | undefinedOptionalRead-only. See the type definition and usage context.
inputSchemaSchemaAdapter<Input>RequiredRead-only. Schema applied to raw model arguments before authorize and execute.
activeToolCondition<App> | undefinedOptionalRead-only. Omitted means active. Authorization remains a separate execution boundary.
kindstringRequiredRead-only. Declared grouping used by registries and documentation; not an authorization boundary.
authorize(input: Input, context: OperationContext<App>) => MaybePromise<void>RequiredHost permission check. Runs before execution and may be asynchronous.
debugSteps((result: Output, context: import("../debug.js").NodeReportingContext) => void) | undefinedOptionalOptional result hook; writes through context.createSubFlowLogger() are recorded immediately.
parseOutput(value: unknown) => OutputRequiredValidates untrusted output (for example a cached replay) before it is returned.
nsstring | readonly string[] | undefinedOptionalRead-only. See the type definition and usage context.

Returns: MethodDecoration<(input: Input, context: OperationContext<App> & NodeReportingContext) => MaybePromise<Output>>.

Overload 3 ​

ts
tool<Input = unknown, Output = Input, App = any>(id: string, options: MethodOptions<Omit<ModelTool<Input, Output, App>, "asIntent">, "resolve">): MethodDecoration<ModelTool<Input, Output, App>["resolve"]>

A model-only tool method provides its synchronous resolver.

Type parameterConstraintDefault type
Input—unknown
Output—Input
App—any
ParameterTypePassingDescription
idstringRequired—
optionsMethodOptions<Omit<ModelTool<Input, Output, App>, "asIntent">, "resolve">Required—
Fields of options
FieldTypeRequiredDescription
descriptionstringRequiredRead-only. Model-visible description explaining when the capability applies.
inputSchemaSchemaAdapter<Input>RequiredRead-only. Schema describing the arguments; must be an object schema.
activeToolCondition<App> | undefinedOptionalRead-only. Omitted means active. Authorization remains a separate execution boundary.
nsstring | readonly string[] | undefinedOptionalRead-only. See the type definition and usage context.

Returns: MethodDecoration<(input: Input, context: Readonly<{ stageId: string; }>) => Output>.

Examples ​

A class owns configuration and private helpers without manual construction ​

Beginner · TypeScript 标准装饰器

ts
import { AgentCoreEngine, defineWorkflow } from '@jangts/agent-core';
import type { WorkflowNode } from '@jangts/agent-core';
import { node, nodePool } from '@jangts/agent-core/support/decorators';
import type { Node } from '@jangts/agent-core/support/decorators';
type State = { text: string; answer?: string };
@node<State, string>('greet', { ns: 'greeting' })
class Greeting implements Node<State, string> {
  readonly description = '生成问候';
  readonly routes = [{ complete: (state: Readonly<State>) => state.answer! }];
  #prefix = '你好,';
  run(state: Readonly<State>) { return { answer: this._format(state.text) }; }
  private _format(text: string) { return this.#prefix + text.trim(); }
}
const flow = defineWorkflow<State, string>({ id: 'greeting', nodes: nodePool.getAll('greeting') });
console.log(await new AgentCoreEngine({ workflow: flow }).run({ text: '访客' }));
js
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { AgentCoreEngine, defineWorkflow } from '@jangts/agent-core';
import { node, nodePool } from '@jangts/agent-core/support/decorators';
let Greeting = class Greeting {
    description = '生成问候';
    routes = [{ complete: (state) => state.answer }];
    #prefix = '你好,';
    run(state) { return { answer: this._format(state.text) }; }
    _format(text) { return this.#prefix + text.trim(); }
};
Greeting = __decorate([
    node('greet', { ns: 'greeting' })
], Greeting);
const flow = defineWorkflow({ id: 'greeting', nodes: nodePool.getAll('greeting') });
console.log(await new AgentCoreEngine({ workflow: flow }).run({ text: '访客' }));

Keep a service method name and bind its original host automatically ​

Configuration · TypeScript 标准装饰器

ts
import type { WorkflowNode } from '@jangts/agent-core';
import { node, nodePool } from '@jangts/agent-core/support/decorators';
type State = { text: string; answer?: string };
class GreetingService {
  constructor(private readonly prefix: string) {}
  @node<State, string>('reply', { ns: 'service',
    description: '调用现有服务',
    routes: [{ complete: (state: Readonly<State>) => state.answer! }],
  })
  answer(state: Readonly<State>) { return { answer: this.prefix + state.text }; }
}
const service = new GreetingService('你好,');
const definition = nodePool.get<WorkflowNode<State, string>>('reply', 'service')!;
console.log(definition === nodePool.get('reply', 'service'));
js
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { node, nodePool } from '@jangts/agent-core/support/decorators';
class GreetingService {
    prefix;
    constructor(prefix) {
        this.prefix = prefix;
    }
    answer(state) { return { answer: this.prefix + state.text }; }
}
__decorate([
    node('reply', { ns: 'service',
        description: '调用现有服务',
        routes: [{ complete: (state) => state.answer }],
    })
], GreetingService.prototype, "answer", null);
const service = new GreetingService('你好,');
const definition = nodePool.get('reply', 'service');
console.log(definition === nodePool.get('reply', 'service'));

Tool classes preserve original authorization and result checks ​

Extension · TypeScript 标准装饰器

ts
import { Support } from '@jangts/agent-core';
import type { ToolDefinition } from '@jangts/agent-core';
import { tool, toolPool } from '@jangts/agent-core/support/decorators';
import type { Tool } from '@jangts/agent-core/support/decorators';
type Input = { text: string };
@tool<Input, string, undefined>('echo', { ns: 'echo' })
class Echo implements Tool<Input, string, undefined> {
  readonly kind = 'read';
  readonly description = '回显文本';
  readonly inputSchema = {
    jsonSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] },
    parse(value: unknown): Input {
      if (!value || typeof value !== 'object' || !('text' in value) || typeof value.text !== 'string') throw new TypeError('text');
      return { text: value.text };
    },
  };
  authorize(): void {}
  execute(input: Input) { return this._format(input.text); }
  private _format(text: string) { return text.trim(); }
  parseOutput(value: unknown): string {
    if (typeof value !== 'string') throw new TypeError('string');
    return value;
  }
}
const runtime = Support.defineToolCatalog<undefined>(toolPool.getAll<ToolDefinition<Input, string, undefined>>('echo')).bind({ app: undefined });
console.log((await runtime.invoke({ toolId: 'echo', input: { text: 'hello' } })).value);
js
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { Support } from '@jangts/agent-core';
import { tool, toolPool } from '@jangts/agent-core/support/decorators';
let Echo = class Echo {
    kind = 'read';
    description = '回显文本';
    inputSchema = {
        jsonSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] },
        parse(value) {
            if (!value || typeof value !== 'object' || !('text' in value) || typeof value.text !== 'string')
                throw new TypeError('text');
            return { text: value.text };
        },
    };
    authorize() { }
    execute(input) { return this._format(input.text); }
    _format(text) { return text.trim(); }
    parseOutput(value) {
        if (typeof value !== 'string')
            throw new TypeError('string');
        return value;
    }
};
Echo = __decorate([
    tool('echo', { ns: 'echo' })
], Echo);
const runtime = Support.defineToolCatalog(toolPool.getAll('echo')).bind({ app: undefined });
console.log((await runtime.invoke({ toolId: 'echo', input: { text: 'hello' } })).value);

API reference, usage examples and developer guides.