Agent Catalog: generate the tool menu from real registrations
Tool, scope, and host tool menus are projected from the real catalogs instead of maintaining a separate tool list for prompts.
defineAgentCatalog accepts structured ports. goalIds/goals/scopes read from real registrations; tools provides values, has, supportsGoal, and describe; currentTask returns the task already accepted for this run as { goalId, scopeId }, or undefined.
modelCatalog(app) returns availableGoalIds, availableGoals, availableScopes, and availableTools. restrictToTask defaults to true, limiting the menu to that tool and its scopes once a task is accepted; set it to false to keep the full menu. goalDelegates combines tool delegates with host tool invocation.id. Runtime availability is still determined by the App ports, and the menu does not replace execution authorization.
Progressive examples for the same business case
Project existing tools and scopes into a model menu
Beginner · Node.js
import { IntentRegistry, ScopeRegistry, defineAgentCatalog } from '@jangts/agent-core/kits/domains';
const tools = IntentRegistry.create([{ id: 'explain', description: '解释接口', delegates: ['reply'], asIntent: true }]);
const scopes = ScopeRegistry.create([{ id: 'sdk', description: 'SDK 资料', category: 'knowledge', goalIds: ['explain'] }]);
const catalog = defineAgentCatalog({
goalIds: () => tools.ids(), goals: ids => tools.describe(ids), scopes: ids => scopes.describe(ids), currentTask: () => undefined,
tools: { values: () => [], has: () => false, supportsGoal: () => true, describe: () => [] },
});
console.log(catalog.modelCatalog(undefined));import { IntentRegistry, ScopeRegistry, defineAgentCatalog } from '@jangts/agent-core/kits/domains';
const tools = IntentRegistry.create([{ id: 'explain', description: '解释接口', delegates: ['reply'], asIntent: true }]);
const scopes = ScopeRegistry.create([{ id: 'sdk', description: 'SDK 资料', category: 'knowledge', goalIds: ['explain'] }]);
const catalog = defineAgentCatalog({
goalIds: () => tools.ids(), goals: ids => tools.describe(ids), scopes: ids => scopes.describe(ids), currentTask: () => undefined,
tools: { values: () => [], has: () => false, supportsGoal: () => true, describe: () => [] },
});
console.log(catalog.modelCatalog(undefined));Connect the same menu to actual tool declarations and the current task
Configuration · Node.js
The tools here are a structured projection port; a real application should connect directly to the corresponding methods of the real tool registry to avoid parallel maintenance.
import { IntentRegistry, ScopeRegistry, defineAgentCatalog } from '@jangts/agent-core/kits/domains';
const goals = IntentRegistry.create([{ id: 'explain', description: '解释接口', delegates: ['reply'], asIntent: true }]);
const scopes = ScopeRegistry.create([{ id: 'sdk', description: 'SDK 资料', category: 'knowledge', goalIds: ['explain'], toolIds: ['read-source'] }]);
const tools = [{ id: 'read-source', kind: 'read', description: '读取允许的说明资料', audience: 'model', effect: 'read', goalIds: ['explain'], lifecycle: { id: 'read' } }];
type App = { current?: { goalId: string; scopeId: string } };
const catalog = defineAgentCatalog<App, string, ReturnType<typeof goals.describe>[number], ReturnType<typeof scopes.describe>[number]>({
goalIds: () => goals.ids(), goals: ids => goals.describe(ids), scopes: ids => scopes.describe(ids), currentTask: app => app.current,
tools: { values: () => tools, has: id => tools.some(tool => tool.id === id), supportsGoal: () => true, describe: audience => tools.filter(tool => !audience || tool.audience === audience) },
});
console.log(catalog.modelCatalog({ current: { goalId: 'explain', scopeId: 'sdk' } }));import { IntentRegistry, ScopeRegistry, defineAgentCatalog } from '@jangts/agent-core/kits/domains';
const goals = IntentRegistry.create([{ id: 'explain', description: '解释接口', delegates: ['reply'], asIntent: true }]);
const scopes = ScopeRegistry.create([{ id: 'sdk', description: 'SDK 资料', category: 'knowledge', goalIds: ['explain'], toolIds: ['read-source'] }]);
const tools = [{ id: 'read-source', kind: 'read', description: '读取允许的说明资料', audience: 'model', effect: 'read', goalIds: ['explain'], lifecycle: { id: 'read' } }];
const catalog = defineAgentCatalog({
goalIds: () => goals.ids(), goals: ids => goals.describe(ids), scopes: ids => scopes.describe(ids), currentTask: app => app.current,
tools: { values: () => tools, has: id => tools.some(tool => tool.id === id), supportsGoal: () => true, describe: audience => tools.filter(tool => !audience || tool.audience === audience) },
});
console.log(catalog.modelCatalog({ current: { goalId: 'explain', scopeId: 'sdk' } }));