Skip to content
中文

ToolCatalog ​

SUPPORT · interface · Type contract

Frozen tool catalog with model tools and per-request binding.

Import ​

ts
import type { ToolCatalog } from '@jangts/agent-core/support';
js
/** @typedef {import('@jangts/agent-core/support').ToolCatalog} ToolCatalog */

Other public entry points:@jangts/agent-core/types, @jangts/agent-core/structs, @jangts/agent-core/support.

Definition ​

ts
interface ToolCatalog<App, Tool>

Extends or implements: ReadonlyCatalog<ToolCatalogEntry<App, Tool>>.

Type parameters ​

Type parameterConstraintDefault type
App——
ToolToolDefinition<unknown, unknown, App>ToolDefinition<unknown, unknown, App>

Field structure ​

FieldTypeRequiredDescription
toolsToolModelView<App>RequiredRead-only. See the type definition and usage context.
select<const Ids extends readonly string[]>(ids: Ids, context?: App) => ToolCatalog<App, SelectedTools<Tool, Ids[number]>>RequiredNarrows the catalog while preserving declaration order; throws for unknown ids.
withIntent(context: App) => ToolCatalog<App, Tool>RequiredActive tools advertising demand-discovery use; descriptions are view-local.
bind(request: { app: App; execution?: ExecutionOptions; errors?: Pick<ToolRegistryPorts, "unavailable" | "errorCode">; }) => ToolRuntime<Tool, App>RequiredBinds the catalog to one App request and returns an invocable runtime.
definitionsreadonly Readonly<ToolCatalogEntry<App, Tool>>[]RequiredRead-only. Definitions in registration order; each entry is frozen by the implementation.
ids() => readonly string[]RequiredIds in the same order as definitions.
values() => IterableIterator<Readonly<ToolCatalogEntry<App, Tool>>>RequiredSee the type definition and usage context.
entries() => IterableIterator<readonly [string, Readonly<ToolCatalogEntry<App, Tool>>]>RequiredSee the type definition and usage context.
has(id: string) => booleanRequiredSee the type definition and usage context.
get(id: string) => Readonly<ToolCatalogEntry<App, Tool>> | undefinedRequiredReturns the definition or undefined; the caller decides whether absence is an error.
require(id: string) => Readonly<ToolCatalogEntry<App, Tool>>RequiredReturns the definition or throws; use when the id is a required reference.

Member index ​

MemberPurpose
selectNarrows the catalog while preserving declaration order; throws for unknown ids.
withIntentActive tools advertising demand-discovery use; descriptions are view-local.
bindBinds the catalog to one App request and returns an invocable runtime.
idsIds in the same order as definitions.
valuesSee the overload below for full inputs and outputs.
entriesSee the overload below for full inputs and outputs.
hasSee the overload below for full inputs and outputs.
getReturns the definition or undefined; the caller decides whether absence is an error.
requireReturns the definition or throws; use when the id is a required reference.

Member details ​

select ​

Narrows the catalog while preserving declaration order; throws for unknown ids.

ts
ToolCatalog.select<const Ids extends readonly string[]>(ids: Ids, context?: App): ToolCatalog<App, SelectedTools<Tool, Ids[number]>>

Narrows the catalog while preserving declaration order; throws for unknown ids.

Type parameterConstraintDefault type
Idsreadonly string[]—
ParameterTypePassingDescription
idsIdsRequired—
contextApp | undefinedOptional—

Returns: ToolCatalog<App, SelectedTools<Tool, Ids[number]>>.

Return value structure
FieldTypeRequiredDescription
toolsToolModelView<App>RequiredRead-only. See the type definition and usage context.
select<const Ids extends readonly string[]>(ids: Ids, context?: App) => ToolCatalog<App, SelectedTools<SelectedTools<Tool, Ids[number]>, Ids[number]>>RequiredNarrows the catalog while preserving declaration order; throws for unknown ids.
withIntent(context: App) => ToolCatalog<App, SelectedTools<Tool, Ids[number]>>RequiredActive tools advertising demand-discovery use; descriptions are view-local.
bind(request: { app: App; execution?: ExecutionOptions; errors?: Pick<ToolRegistryPorts, "unavailable" | "errorCode">; }) => ToolRuntime<SelectedTools<Tool, Ids[number]>, App>RequiredBinds the catalog to one App request and returns an invocable runtime.
definitionsreadonly Readonly<ToolCatalogEntry<App, SelectedTools<Tool, Ids[number]>>>[]RequiredRead-only. Definitions in registration order; each entry is frozen by the implementation.
ids() => readonly string[]RequiredIds in the same order as definitions.
values() => IterableIterator<Readonly<ToolCatalogEntry<App, SelectedTools<Tool, Ids[number]>>>>RequiredSee the type definition and usage context.
entries() => IterableIterator<readonly [string, Readonly<ToolCatalogEntry<App, SelectedTools<Tool, Ids[number]>>>]>RequiredSee the type definition and usage context.
has(id: string) => booleanRequiredSee the type definition and usage context.
get(id: string) => Readonly<ToolCatalogEntry<App, SelectedTools<Tool, Ids[number]>>> | undefinedRequiredReturns the definition or undefined; the caller decides whether absence is an error.
require(id: string) => Readonly<ToolCatalogEntry<App, SelectedTools<Tool, Ids[number]>>>RequiredReturns the definition or throws; use when the id is a required reference.

withIntent ​

Active tools advertising demand-discovery use; descriptions are view-local.

ts
ToolCatalog.withIntent(context: App): ToolCatalog<App, Tool>

Active tools advertising demand-discovery use; descriptions are view-local.

ParameterTypePassingDescription
contextAppRequired—

Returns: ToolCatalog<App, Tool>.

Return value structure
FieldTypeRequiredDescription
toolsToolModelView<App>RequiredRead-only. See the type definition and usage context.
select<const Ids extends readonly string[]>(ids: Ids, context?: App) => ToolCatalog<App, SelectedTools<Tool, Ids[number]>>RequiredNarrows the catalog while preserving declaration order; throws for unknown ids.
withIntent(context: App) => ToolCatalog<App, Tool>RequiredActive tools advertising demand-discovery use; descriptions are view-local.
bind(request: { app: App; execution?: ExecutionOptions; errors?: Pick<ToolRegistryPorts, "unavailable" | "errorCode">; }) => ToolRuntime<Tool, App>RequiredBinds the catalog to one App request and returns an invocable runtime.
definitionsreadonly Readonly<ToolCatalogEntry<App, Tool>>[]RequiredRead-only. Definitions in registration order; each entry is frozen by the implementation.
ids() => readonly string[]RequiredIds in the same order as definitions.
values() => IterableIterator<Readonly<ToolCatalogEntry<App, Tool>>>RequiredSee the type definition and usage context.
entries() => IterableIterator<readonly [string, Readonly<ToolCatalogEntry<App, Tool>>]>RequiredSee the type definition and usage context.
has(id: string) => booleanRequiredSee the type definition and usage context.
get(id: string) => Readonly<ToolCatalogEntry<App, Tool>> | undefinedRequiredReturns the definition or undefined; the caller decides whether absence is an error.
require(id: string) => Readonly<ToolCatalogEntry<App, Tool>>RequiredReturns the definition or throws; use when the id is a required reference.

bind ​

Binds the catalog to one App request and returns an invocable runtime.

ts
ToolCatalog.bind(request: { app: App; execution?: ExecutionOptions; errors?: Pick<ToolRegistryPorts, "unavailable" | "errorCode">; }): ToolRuntime<Tool, App>

Binds the catalog to one App request and returns an invocable runtime.

ParameterTypePassingDescription
request{ app: App; execution?: ExecutionOptions; errors?: Pick<ToolRegistryPorts, "unavailable" | "errorCode">; }Required—
Fields of request
FieldTypeRequiredDescription
appAppRequiredSee the type definition and usage context.
executionExecutionOptions | undefinedOptionalSee the type definition and usage context.
errorsPick<ToolRegistryPorts, "unavailable" | "errorCode"> | undefinedOptionalSee the type definition and usage context.

Returns: ToolRuntime<Tool, App>.

Return value structure
FieldTypeRequiredDescription
toolsToolModelView<App>RequiredRead-only. The catalog's model tools, shared with the catalog instance.
eventsreadonly ToolExecutionEvent<string>[]RequiredRead-only. Execution events recorded by this runtime so far, in occurrence order.
invokeSync{ <const Id extends Tool["id"]>(request: ToolInvocationRequest<Id>): ToolResult<ToolOutput<Tool, Id>>; (request: ToolInvocationRequest): ToolResult<unknown>; }RequiredSynchronous invocation; rejects tools declared as asynchronous.
invoke{ <const Id extends Tool["id"]>(request: ToolInvocationRequest<Id>): Promise<ToolResult<ToolOutput<Tool, Id>>>; (request: ToolInvocationRequest): Promise<ToolResult<unknown>>; }RequiredAsynchronous invocation; still bounded by the bound execution signal and errors.

ids ​

Ids in the same order as definitions.

ts
ToolCatalog.ids(): readonly string[]

Ids in the same order as definitions.

No call parameters.

Returns: readonly string[].

values ​

ts
ToolCatalog.values(): IterableIterator<Readonly<ToolCatalogEntry<App, Tool>>>

No call parameters.

Returns: IterableIterator<Readonly<ToolCatalogEntry<App, Tool>>>.

entries ​

ts
ToolCatalog.entries(): IterableIterator<readonly [string, Readonly<ToolCatalogEntry<App, Tool>>]>

No call parameters.

Returns: IterableIterator<readonly [string, Readonly<ToolCatalogEntry<App, Tool>>]>.

has ​

ts
ToolCatalog.has(id: string): boolean
ParameterTypePassingDescription
idstringRequired—

Returns: boolean.

get ​

Returns the definition or undefined; the caller decides whether absence is an error.

ts
ToolCatalog.get(id: string): Readonly<ToolCatalogEntry<App, Tool>> | undefined

Returns the definition or undefined; the caller decides whether absence is an error.

ParameterTypePassingDescription
idstringRequired—

Returns: Readonly<ToolCatalogEntry<App, Tool>> \| undefined.

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

Branch 1

undefined

Branch 2
FieldTypeRequiredDescription
idToolCatalogEntry<App, Tool>["id"]RequiredRead-only. Stable id; also the name the model calls.
descriptionToolCatalogEntry<App, Tool>["description"]RequiredRead-only. Model-visible explanation of when to call the tool.
resolveToolCatalogEntry<App, Tool>["resolve"] | undefinedOptionalRead-only. See the type definition and usage context.
inputSchemaToolCatalogEntry<App, Tool>["inputSchema"]RequiredRead-only. Schema applied to raw model arguments before authorize and execute.
activeToolCatalogEntry<App, Tool>["active"] | undefinedOptionalRead-only. Omitted means active. Authorization remains a separate execution boundary.
asIntentToolCatalogEntry<App, Tool>["asIntent"] | undefinedOptionalRead-only. Omitted means this tool is not advertised by withIntent().
kindToolCatalogEntry<App, Tool>["kind"]RequiredRead-only. Declared grouping used by registries and documentation; not an authorization boundary.
authorizeToolCatalogEntry<App, Tool>["authorize"]RequiredHost permission check. Runs before execution and may be asynchronous.
executeToolCatalogEntry<App, Tool>["execute"]RequiredExecutes the already-authorized input; must not repeat authorization decisions.
debugStepsToolCatalogEntry<App, Tool>["debugSteps"] | undefinedOptionalOptional result hook; writes through context.createSubFlowLogger() are recorded immediately.
parseOutputToolCatalogEntry<App, Tool>["parseOutput"]RequiredValidates untrusted output (for example a cached replay) before it is returned.

require ​

Returns the definition or throws; use when the id is a required reference.

ts
ToolCatalog.require(id: string): Readonly<ToolCatalogEntry<App, Tool>>

Returns the definition or throws; use when the id is a required reference.

ParameterTypePassingDescription
idstringRequired—

Returns: Readonly<ToolCatalogEntry<App, Tool>>.

Return value structure
FieldTypeRequiredDescription
idToolCatalogEntry<App, Tool>["id"]RequiredRead-only. Stable id; also the name the model calls.
descriptionToolCatalogEntry<App, Tool>["description"]RequiredRead-only. Model-visible explanation of when to call the tool.
resolveToolCatalogEntry<App, Tool>["resolve"] | undefinedOptionalRead-only. See the type definition and usage context.
inputSchemaToolCatalogEntry<App, Tool>["inputSchema"]RequiredRead-only. Schema applied to raw model arguments before authorize and execute.
activeToolCatalogEntry<App, Tool>["active"] | undefinedOptionalRead-only. Omitted means active. Authorization remains a separate execution boundary.
asIntentToolCatalogEntry<App, Tool>["asIntent"] | undefinedOptionalRead-only. Omitted means this tool is not advertised by withIntent().
kindToolCatalogEntry<App, Tool>["kind"]RequiredRead-only. Declared grouping used by registries and documentation; not an authorization boundary.
authorizeToolCatalogEntry<App, Tool>["authorize"]RequiredHost permission check. Runs before execution and may be asynchronous.
executeToolCatalogEntry<App, Tool>["execute"]RequiredExecutes the already-authorized input; must not repeat authorization decisions.
debugStepsToolCatalogEntry<App, Tool>["debugSteps"] | undefinedOptionalOptional result hook; writes through context.createSubFlowLogger() are recorded immediately.
parseOutputToolCatalogEntry<App, Tool>["parseOutput"]RequiredValidates untrusted output (for example a cached replay) before it is returned.

Examples ​

Define and use a read-only tool ​

Beginner · Node.js

ts
import { Support } from '@jangts/agent-core';
const inputSchema = Support.defineSchema({
  jsonSchema: { type: 'object', properties: {}, additionalProperties: false },
  parse(value: unknown) {
    if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).length) throw new TypeError('需要空对象');
    return {};
  },
});
const catalog = Support.defineToolCatalog([{ id: 'get_status', kind: 'read', description: '读取服务状态', inputSchema,
  authorize() {},
  execute() { return '服务运行正常'; },
  parseOutput(value: unknown) { if (typeof value !== 'string') throw new TypeError('需要字符串'); return value; },
}]);
const tools = catalog.bind({ app: undefined });
console.log((await tools.invoke({ toolId: 'get_status', input: {} })).value);
console.log(catalog.tools.ids());
js
import { Support } from '@jangts/agent-core';
const inputSchema = Support.defineSchema({
    jsonSchema: { type: 'object', properties: {}, additionalProperties: false },
    parse(value) {
        if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).length)
            throw new TypeError('需要空对象');
        return {};
    },
});
const catalog = Support.defineToolCatalog([{ id: 'get_status', kind: 'read', description: '读取服务状态', inputSchema,
        authorize() { },
        execute() { return '服务运行正常'; },
        parseOutput(value) { if (typeof value !== 'string')
            throw new TypeError('需要字符串'); return value; },
    }]);
const tools = catalog.bind({ app: undefined });
console.log((await tools.invoke({ toolId: 'get_status', input: {} })).value);
console.log(catalog.tools.ids());

Keep the list and add this request's permissions and service dependencies ​

Configuration · Node.js

ts
import { Support } from '@jangts/agent-core';
import type { OperationContext } from '@jangts/agent-core/types';
type App = { allowed: boolean; readStatus(): Promise<string> };
const inputSchema = Support.defineSchema({
  jsonSchema: { type: 'object', properties: {}, additionalProperties: false },
  parse(value: unknown) {
    if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).length) throw new TypeError('需要空对象');
    return {};
  },
});
const catalog = Support.defineToolCatalog<App>([{ id: 'get_status', kind: 'read', description: '读取状态', inputSchema,
  authorize(_input: {}, { app }: OperationContext<App>) { if (!app.allowed) throw new Error('当前请求没有读取权限'); },
  execute(_input: {}, { app }: OperationContext<App>) { return app.readStatus(); },
  parseOutput(value: unknown) { if (typeof value !== 'string') throw new TypeError('需要字符串'); return value; },
}]);
const tools = catalog.bind({ app: { allowed: true, readStatus: async () => '服务运行正常' },
  execution: { signal: AbortSignal.timeout(10000) },
});
console.log((await tools.invoke({ toolId: 'get_status', input: {} })).value);
js
import { Support } from '@jangts/agent-core';
const inputSchema = Support.defineSchema({
    jsonSchema: { type: 'object', properties: {}, additionalProperties: false },
    parse(value) {
        if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).length)
            throw new TypeError('需要空对象');
        return {};
    },
});
const catalog = Support.defineToolCatalog([{ id: 'get_status', kind: 'read', description: '读取状态', inputSchema,
        authorize(_input, { app }) { if (!app.allowed)
            throw new Error('当前请求没有读取权限'); },
        execute(_input, { app }) { return app.readStatus(); },
        parseOutput(value) { if (typeof value !== 'string')
            throw new TypeError('需要字符串'); return value; },
    }]);
const tools = catalog.bind({ app: { allowed: true, readStatus: async () => '服务运行正常' },
    execution: { signal: AbortSignal.timeout(10000) },
});
console.log((await tools.invoke({ toolId: 'get_status', input: {} })).value);

API reference, usage examples and developer guides.