feat(agent): skill invocation — load and execute skills from catalog (#128) (#143)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful

Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #143.
This commit is contained in:
2026-03-15 18:36:58 +00:00
committed by jason.woltje
parent 54b821d8bd
commit 3bb401641e
5 changed files with 263 additions and 4 deletions

View File

@@ -14,6 +14,7 @@ import { EmbeddingService } from '../memory/embedding.service.js';
import { CoordService } from '../coord/coord.service.js';
import { ProviderService } from './provider.service.js';
import { McpClientService } from '../mcp-client/mcp-client.service.js';
import { SkillLoaderService } from './skill-loader.service.js';
import { createBrainTools } from './tools/brain-tools.js';
import { createCoordTools } from './tools/coord-tools.js';
import { createMemoryTools } from './tools/memory-tools.js';
@@ -38,6 +39,8 @@ export interface AgentSession {
createdAt: number;
promptCount: number;
channels: Set<string>;
/** System prompt additions injected from enabled prompt-type skills. */
skillPromptAdditions: string[];
}
@Injectable()
@@ -55,6 +58,7 @@ export class AgentService implements OnModuleDestroy {
@Inject(EmbeddingService) private readonly embeddingService: EmbeddingService,
@Inject(CoordService) private readonly coordService: CoordService,
@Inject(McpClientService) private readonly mcpClientService: McpClientService,
@Inject(SkillLoaderService) private readonly skillLoaderService: SkillLoaderService,
) {
const fileBaseDir = process.env['AGENT_FILE_SANDBOX_DIR'] ?? process.cwd();
const gitDefaultCwd = process.env['AGENT_GIT_CWD'] ?? process.cwd();
@@ -98,9 +102,21 @@ export class AgentService implements OnModuleDestroy {
`Creating agent session: ${sessionId} (provider=${providerName}, model=${modelId})`,
);
// Load skill tools from the catalog
const { metaTools: skillMetaTools, promptAdditions } =
await this.skillLoaderService.loadForSession();
if (skillMetaTools.length > 0) {
this.logger.log(`Attaching ${skillMetaTools.length} skill tool(s) to session ${sessionId}`);
}
if (promptAdditions.length > 0) {
this.logger.log(
`Injecting ${promptAdditions.length} skill prompt addition(s) into session ${sessionId}`,
);
}
// Combine static tools with dynamically discovered MCP client tools
const mcpTools = this.mcpClientService.getToolDefinitions();
const allCustomTools = [...this.customTools, ...mcpTools];
const allCustomTools = [...this.customTools, ...skillMetaTools, ...mcpTools];
if (mcpTools.length > 0) {
this.logger.log(`Attaching ${mcpTools.length} MCP client tool(s) to session ${sessionId}`);
}
@@ -145,6 +161,7 @@ export class AgentService implements OnModuleDestroy {
createdAt: Date.now(),
promptCount: 0,
channels: new Set(),
skillPromptAdditions: promptAdditions,
};
this.sessions.set(sessionId, session);