Agents
Extras for @di-framework/ai. Agent Skills (SKILL.md, graduated disclosure) with filesystem, HITL questions, todos, optional web / memory / task, and opt-in Write/Edit/Bash.
This is a TypeScript counterpart of spring-ai-agent-utils. Skills run in your process. It is not Anthropic’s hosted Skills API.
Prefer builders: SkillsAgent.builder(), SkillsToolbox.builder(), SkillsTool.builder(). Free-function aliases remain. Skills stay in this package — configureAi/@Agent on AI are unchanged.
Features
Progressive disclosure: discovery embeds
name+description; activation loads the fullSKILL.mdbody and base directory.Builder-first:
SkillsAgent.builder()for aChatAgent,SkillsToolbox.builder()to attach tools,SkillsTool.builder()forSkillonly.YAML front matter: maps, lists, scalars,
|/>blocks;allowed-tools,license,compatibility,metadata.Jailed file tools:
Read,ListDirectory,Glob,Grep, opt-inWrite/Edit/Bash.Agent extras:
TodoWrite, optionalAskUserQuestion, web fetch/search, file memory, nestedTask.Enforcement: after a skill with
allowed-toolsactivates, other tools are gated; file tools jail to workspace ∪ that skill.Discovery: directories, single files, in-memory skills, npm packages, or neutral defaults at
.agents/skillsand~/.agents/skills.Plugins: discover and validate
.agents/pluginsbundles (plugin.json, nested skills, rules,mcp_config.json, hooks) without auto-wiring agents or MCP.Project policy: hierarchical
AGENTS.mdinstructions and root.aiignoreenforcement with inspectable provenance and diagnostics.Repository operations: read-only agent-configuration audits plus deterministic, dry-run-first neutral migration plans and explicit execution.
Installation
Peer: @di-framework/ai and @di-framework/core (required for decorator DX; builders work with both installed as shown above).
Quick start
Attach the toolbox to an existing client:
The ai-skills example has scripted tests (no API key) and a live bun start path that reviews fixtures/sample-user.ts with OpenAiChatModel (process.env.OPENAI_API_KEY).
The ai-plugins example validates the published @di-framework/plugin package, expands ${pluginDir} in mcp_config.json, and electively starts its stdio MCP (no API keys for local tools such as di_scaffold_provider).
Skill folders
A skill is a folder with a SKILL.md file (YAML front matter + instructions). Optional scripts/, references/, and other files stay on disk until the model reads them.
name and description must satisfy agentskills.io rules. On disk, the folder name must match name. Invalid loaded skills fail closed.
Builders
Factory | Builds | When to use |
|---|---|---|
|
| Usual entry |
| Toolbox ( | Existing |
|
| Tests, or when you already have file tools |
.of(options) matches the older options-object APIs. Aliases: createSkillsAgent, createSkillsToolbox, skillsToolbox, skillsTool.
Shared toolbox methods
These exist on both SkillsAgent.builder() and SkillsToolbox.builder().
Method | Effect |
|---|---|
| Load |
| Load one |
| In-memory skills |
| npm package or path ( |
| Supplement or replace the neutral automatic roots |
| Default cwd / search root (also an allowed file root) |
| Override the user root used for |
| Extra sandbox roots |
| Opt-in |
| Enforce root |
| Supply discovery policy and observe content-free suppressions |
| Approve or reject each |
|
|
|
|
| Long-term memory tools ( |
| Nested |
| Pass |
| Keep all skill dirs allowed after activate |
| Customize the |
Agent-only methods
system, instructionDiscovery, chatModel, chatClient, extraTools, advisors, conversationMemory, defaultConversationId, defaultOptions, clientBuilderOptions.
build() returns ChatAgent. buildBundle() also returns the toolbox and inspectable repository instruction result.
Tools
Included by default | Opt-in |
|---|---|
|
|
File tools are limited to workspace ∪ skill folders (and extras). After a skill with allowed-tools activates, other tools are denied by name.
Bash jails cwd only. It is not a container: the process can still use the network or cd elsewhere. Prefer a container for untrusted skills. Use confirmShell when a human should approve commands.
WebSearch needs BRAVE_API_KEY or .web({ braveApiKey }). Task subagents do not get AskUserQuestion or nested Task.
Discovery
The automatic roots are <workspace>/.agents/skills and ~/.agents/skills. In the default merge mode, explicit directories and packages precede the workspace and user defaults. Use sourceMode('replace') to use only explicit directories and packages. Duplicate skill names are deterministic: the first definition wins, and the toolbox exposes source and duplicate diagnostics.
addPackage('@scope/pack') resolves the package from the workspace, then uses package.json#skills or falls back to .agents/skills and skills under the package root. No vendor-specific path is loaded implicitly.
Repository instructions and ignore policy share the same boundary-safe source model. See Agent configuration for source provenance, catalog validation, AGENTS.md hierarchy, .aiignore discovery/direct modes, security precedence, typed repository audits, and plan-before-apply migration from vendor-specific layouts into neutral paths.
Large catalogs
Normal discovery places every skill name and description in the Skill tool. For catalogs above the default threshold of 50, generate a semantic index during the application build:
Or call the same package implementation programmatically:
This writes .di-framework/skills-index.json. Enable fail-closed retrieval with .semanticDiscovery() on SkillsAgent.builder() or SkillsToolbox.builder(). The default index is also detected automatically when present.
The default indexer uses the optional @huggingface/transformers peer. Install it only for large-catalog indexing (bun add @huggingface/[email protected]); small catalogs and custom embedders do not need it. Transformers.js tokenizes each exact SKILL.md into overlapping model-token chunks and embeds them locally with a pinned quantized BGE model. Runtime ranks skills using chunk cosine scores and sends only the top 10 names/descriptions to the chat model. Chunks and vectors do not enter the prompt; the full body remains lazy until activation. At or below the threshold, Transformers.js is not initialized and normal discovery remains active.
Very large catalogs can reuse the same SkillVectorSearch contract with SkillSearchRepository and SkillSearchIndexer over a SkillSearchConnection. SkillSearchConnection.fromVectorStore(new BunSqliteVectorStore({ ... })) stores float32 embeddings and builds a portable HNSW graph above the exact-scan limit; fromStorageAdapter accepts @di-framework/repo adapters. JSONL exact cosine stays the default discovery artifact.
Decorator DX
Thin decorators store catalog / retrieval / index metadata and apply helpers feed the same builders. Prefer builders for most apps; use decorators when you want DI-style declarations. Decorators never build indexes, load Transformers.js, or hide async work.
Helpers: skillsToolboxOptionsFrom, skillsToolboxBuilderFrom/skillsToolboxFrom, skillsAgentBuilderFrom/skillsAgentFrom, skillsIndexBuilderFrom. Pass chatModel, custom SkillEmbedder, and stores as overrides — they are not stored on decorator metadata. Stack @Skills, @SemanticSkillDiscovery, and @Skill on one class; merge multiple catalog classes yourself. Terminal use goes through di-framework skills index; package APIs remain independent of command-line arguments and output.
Skill-only and MCP
skillsToolboxAsMcp returns descriptor + handler pairs from @di-framework/ai toolCallbackAsMcpTool.
Plugins
Plugins are filesystem bundles under .agents/plugins/<id>/ (and ~/.agents/plugins/<id>/):
SkillsAgent/SkillsToolbox do not load plugins by themselves. Use the plugin APIs to discover and validate bundles, then wire pieces electively.
Automatic (discovery only)
Defaults are <workspace>/.agents/plugins then ~/.agents/plugins. Explicit directories/packages and sourceMode work like skill sources. A package that publishes plugin.json at its own root (for example @di-framework/plugin) resolves as a single-plugin source. Nested skills/ are validated with the skill catalog rules when you validate a plugin catalog.
Automatic here means where plugins are found, not that agents consume them.
Programmatic
AgentPlugin exposes skillsDirectory, mcpConfig, rules, and hooks. This package does not start MCP servers or run hooks.
Elective (opt into an agent)
Validate the catalog, pass each plugin’s skills/ root into skill discovery, and append rule markdown to system context:
MCP is elective the same way: read plugin.mcpConfig.mcpServers and register those entries with your MCP client (expand ${pluginDir} when present). Hooks stay data until you interpret hooks.json.
See the ai-plugins example for official @di-framework/plugin discovery plus elective MCP wiring.
Related
SkillsAgent on kube — guest filesystem, model transport, and tool requirements before a complete agent deployment
AI — chat, tools, RAG, MCP, and agents (
@di-framework/ai)Agent configuration — neutral sources, validation, instructions, plugins, and
.aiignore