feat(core): add command, intent, and routing primitives
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import type { CommandDefinition, CommandResult } from '../types.js';
|
||||
import type { CommandRegistry } from '../registry.js';
|
||||
|
||||
function notAvailable(label: string): CommandResult {
|
||||
return {
|
||||
handled: true,
|
||||
text: `${label} is not available in this session.`,
|
||||
};
|
||||
}
|
||||
|
||||
export function createHelpCommand(registry: CommandRegistry): CommandDefinition {
|
||||
return {
|
||||
name: 'help',
|
||||
description: 'Show available commands',
|
||||
execute: async () => {
|
||||
const lines = ['Available commands:'];
|
||||
for (const command of registry.list()) {
|
||||
const aliases = command.aliases && command.aliases.length > 0
|
||||
? ` (aliases: ${command.aliases.map(alias => `/${alias}`).join(', ')})`
|
||||
: '';
|
||||
lines.push(`- /${command.name}: ${command.description}${aliases}`);
|
||||
}
|
||||
return {
|
||||
handled: true,
|
||||
text: lines.join('\n'),
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function createStatusCommand(): CommandDefinition {
|
||||
return {
|
||||
name: 'status',
|
||||
description: 'Show current status',
|
||||
execute: async (_args, ctx) => {
|
||||
if (!ctx.services?.getStatus) {
|
||||
return {
|
||||
handled: true,
|
||||
text: 'Flynn is running.',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
handled: true,
|
||||
text: await ctx.services.getStatus(),
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function createUsageCommand(): CommandDefinition {
|
||||
return {
|
||||
name: 'usage',
|
||||
description: 'Show token usage',
|
||||
execute: async (_args, ctx) => {
|
||||
if (!ctx.services?.getUsage) {
|
||||
return notAvailable('Usage command');
|
||||
}
|
||||
|
||||
return {
|
||||
handled: true,
|
||||
text: await ctx.services.getUsage(),
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function createModelCommand(): CommandDefinition {
|
||||
return {
|
||||
name: 'model',
|
||||
description: 'Show or change model tier',
|
||||
execute: async (args, ctx) => {
|
||||
if (args.length === 0) {
|
||||
if (!ctx.services?.getModel) {
|
||||
return notAvailable('Model command');
|
||||
}
|
||||
return {
|
||||
handled: true,
|
||||
text: await ctx.services.getModel(),
|
||||
};
|
||||
}
|
||||
|
||||
if (!ctx.services?.setModel) {
|
||||
return notAvailable('Model command');
|
||||
}
|
||||
|
||||
return {
|
||||
handled: true,
|
||||
text: await ctx.services.setModel(args[0]),
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function createCompactCommand(): CommandDefinition {
|
||||
return {
|
||||
name: 'compact',
|
||||
description: 'Compact conversation context',
|
||||
execute: async (_args, ctx) => {
|
||||
if (!ctx.services?.compact) {
|
||||
return notAvailable('Compact command');
|
||||
}
|
||||
|
||||
return {
|
||||
handled: true,
|
||||
text: await ctx.services.compact(),
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function createResetCommand(): CommandDefinition {
|
||||
return {
|
||||
name: 'reset',
|
||||
description: 'Reset current session',
|
||||
execute: async (_args, ctx) => {
|
||||
if (!ctx.services?.reset) {
|
||||
return notAvailable('Reset command');
|
||||
}
|
||||
|
||||
return {
|
||||
handled: true,
|
||||
text: await ctx.services.reset(),
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function registerBuiltinCommands(registry: CommandRegistry): void {
|
||||
registry.register(createHelpCommand(registry));
|
||||
registry.register(createStatusCommand());
|
||||
registry.register(createUsageCommand());
|
||||
registry.register(createModelCommand());
|
||||
registry.register(createCompactCommand());
|
||||
registry.register(createResetCommand());
|
||||
}
|
||||
Reference in New Issue
Block a user