Unify TUI slash commands and harden tool inventory responses
This commit is contained in:
+88
-15
@@ -1,5 +1,5 @@
|
||||
import type { Command } from 'commander';
|
||||
import type { Config, ModelConfig, ModelProvider } from '../config/index.js';
|
||||
import type { Config, CouncilsConfig, ModelConfig, ModelProvider } from '../config/index.js';
|
||||
import { loadConfigSafe, getConfigPath } from './shared.js';
|
||||
import { existsSync, mkdirSync, readFileSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
@@ -110,12 +110,14 @@ export function registerTuiCommand(program: Command): void {
|
||||
createGtasksTools,
|
||||
createAgentsListTool,
|
||||
createAgentDelegateTool,
|
||||
createCouncilRunTool,
|
||||
} = await import('../tools/index.js');
|
||||
const { HookEngine } = await import('../hooks/index.js');
|
||||
const { Lifecycle } = await import('../daemon/lifecycle.js');
|
||||
const { initTools } = await import('../daemon/tools.js');
|
||||
const { createModelRouter } = await import('../daemon/index.js');
|
||||
const { AgentConfigRegistry } = await import('../agents/index.js');
|
||||
const { loadCouncilScaffoldSafe } = await import('../councils/scaffold.js');
|
||||
|
||||
const dataDir = process.env.FLYNN_DATA_DIR ?? resolve(homedir(), '.local/share/flynn');
|
||||
mkdirSync(dataDir, { recursive: true });
|
||||
@@ -182,25 +184,39 @@ export function registerTuiCommand(program: Command): void {
|
||||
|
||||
const agentConfigRegistry = new AgentConfigRegistry();
|
||||
agentConfigRegistry.loadFromConfig(config.agent_configs);
|
||||
const delegateRunner = {
|
||||
async delegate(request: {
|
||||
tier: 'fast' | 'default' | 'complex' | 'local';
|
||||
systemPrompt: string;
|
||||
message: string;
|
||||
maxTokens?: number;
|
||||
}) {
|
||||
const response = await modelRouter.chat({
|
||||
messages: [{ role: 'user', content: request.message }],
|
||||
system: request.systemPrompt,
|
||||
maxTokens: request.maxTokens,
|
||||
}, request.tier);
|
||||
return {
|
||||
content: response.content,
|
||||
usage: response.usage,
|
||||
tier: request.tier,
|
||||
};
|
||||
},
|
||||
};
|
||||
if (agentConfigRegistry.list().length > 0) {
|
||||
toolRegistry.register(createAgentsListTool(agentConfigRegistry));
|
||||
toolRegistry.register(createAgentDelegateTool({
|
||||
registry: agentConfigRegistry,
|
||||
orchestrator: {
|
||||
async delegate(request) {
|
||||
const response = await modelRouter.chat({
|
||||
messages: [{ role: 'user', content: request.message }],
|
||||
system: request.systemPrompt,
|
||||
maxTokens: request.maxTokens,
|
||||
}, request.tier);
|
||||
return {
|
||||
content: response.content,
|
||||
usage: response.usage,
|
||||
tier: request.tier,
|
||||
};
|
||||
},
|
||||
},
|
||||
orchestrator: delegateRunner,
|
||||
}));
|
||||
if (config.councils?.enabled) {
|
||||
toolRegistry.register(createCouncilRunTool({
|
||||
registry: agentConfigRegistry,
|
||||
orchestrator: delegateRunner,
|
||||
config: config.councils as CouncilsConfig,
|
||||
scaffold: loadCouncilScaffoldSafe(config.councils.scaffold_path),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
const session = sessionManager.getSession('tui', 'local');
|
||||
@@ -296,6 +312,54 @@ export function registerTuiCommand(program: Command): void {
|
||||
return `Unknown transfer target: ${target}. Supported targets: tui, telegram`;
|
||||
};
|
||||
|
||||
const listAvailableTools = (): string => {
|
||||
const names = toolRegistry.filteredList().map((tool) => tool.name).sort();
|
||||
return [
|
||||
`Available tools (${names.length}):`,
|
||||
...names.map((name) => `- ${name}`),
|
||||
].join('\n');
|
||||
};
|
||||
|
||||
const delegateToResearchAgent = async (task: string): Promise<string> => {
|
||||
const message = task.trim();
|
||||
if (!message) {
|
||||
return 'Usage: /research <question or task>';
|
||||
}
|
||||
const agentConfig = agentConfigRegistry.get('research');
|
||||
if (!agentConfig) {
|
||||
return 'Agent "research" not found. Configure agent_configs.research first.';
|
||||
}
|
||||
const tier = agentConfig.modelTier ?? 'default';
|
||||
const systemPrompt = agentConfig.systemPrompt
|
||||
?? 'You are a research sub-agent. Produce concise, source-grounded findings.';
|
||||
const result = await delegateRunner.delegate({
|
||||
tier,
|
||||
systemPrompt,
|
||||
message,
|
||||
maxTokens: 4096,
|
||||
});
|
||||
return `[Agent: research | Tier: ${result.tier} | Tokens: ${result.usage.inputTokens}+${result.usage.outputTokens}]\n\n${result.content}`;
|
||||
};
|
||||
|
||||
const runCouncilTask = async (task: string): Promise<string> => {
|
||||
const message = task.trim();
|
||||
if (!message) {
|
||||
return 'Usage: /council <question or task>';
|
||||
}
|
||||
if (!config.councils?.enabled) {
|
||||
return 'Councils are disabled. Set councils.enabled: true in config.';
|
||||
}
|
||||
const tool = toolRegistry.get('council.run');
|
||||
if (!tool) {
|
||||
return 'Council tool is not registered. Verify councils config and restart Flynn.';
|
||||
}
|
||||
const result = await tool.execute({ task: message });
|
||||
if (!result.success) {
|
||||
return `Council run failed: ${result.error ?? 'unknown error'}`;
|
||||
}
|
||||
return result.output;
|
||||
};
|
||||
|
||||
if (opts.fullscreen) {
|
||||
await startFullscreenTui({
|
||||
session,
|
||||
@@ -311,6 +375,9 @@ export function registerTuiCommand(program: Command): void {
|
||||
modelProviderConfigs,
|
||||
contextThresholdPct: config.compaction.threshold_pct,
|
||||
onTransfer: transferSessionToTarget,
|
||||
onTools: listAvailableTools,
|
||||
onResearch: delegateToResearchAgent,
|
||||
onCouncil: runCouncilTask,
|
||||
onExit: () => {
|
||||
void cleanup();
|
||||
},
|
||||
@@ -326,6 +393,9 @@ export function registerTuiCommand(program: Command): void {
|
||||
agent,
|
||||
hookEngine,
|
||||
pairingManager,
|
||||
onTools: listAvailableTools,
|
||||
onResearch: delegateToResearchAgent,
|
||||
onCouncil: runCouncilTask,
|
||||
localProviders: config.models.local_providers,
|
||||
modelProviderConfigs,
|
||||
contextThresholdPct: config.compaction.threshold_pct,
|
||||
@@ -357,6 +427,9 @@ export function registerTuiCommand(program: Command): void {
|
||||
modelProviderConfigs,
|
||||
contextThresholdPct: config.compaction.threshold_pct,
|
||||
onTransfer: transferSessionToTarget,
|
||||
onTools: listAvailableTools,
|
||||
onResearch: delegateToResearchAgent,
|
||||
onCouncil: runCouncilTask,
|
||||
onExit: () => {
|
||||
void cleanup();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user