feat: default locale Russian, geo determines language for other countries
- localization-svc: defaultLocale ru, resolveLocale only by geo - web-svc: DEFAULT_LOCALE ru, layout lang=ru, embeddedTranslations fallback ru - countryToLocale: default ru when no country or unknown country Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
106
services/master-agents-svc/src/lib/agent/master.ts
Normal file
106
services/master-agents-svc/src/lib/agent/master.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import type { BaseLLM } from '../models/base/llm.js';
|
||||
import type { Message } from '../types.js';
|
||||
import { getTools, getTool, getToolSchemasForLLM } from '../tools/registry.js';
|
||||
import type { AgentContext } from '../tools/types.js';
|
||||
import { MASTER_SYSTEM_PROMPT } from '../prompts/master.js';
|
||||
|
||||
export type MasterAgentInput = {
|
||||
task: string;
|
||||
chatHistory?: [string, string][];
|
||||
context: AgentContext;
|
||||
maxSteps?: number;
|
||||
};
|
||||
|
||||
export type MasterAgentOutput = {
|
||||
content: string;
|
||||
steps: number;
|
||||
}
|
||||
|
||||
export async function runMasterAgent(
|
||||
llm: BaseLLM,
|
||||
input: MasterAgentInput,
|
||||
): Promise<MasterAgentOutput> {
|
||||
const maxSteps = input.maxSteps ?? 15;
|
||||
const tools = getTools();
|
||||
const toolSchemas = getToolSchemasForLLM();
|
||||
|
||||
const historyStr =
|
||||
input.chatHistory?.length
|
||||
? input.chatHistory
|
||||
.slice(-6)
|
||||
.map(([role, content]) => `${role === 'human' ? 'User' : 'Assistant'}: ${content}`)
|
||||
.join('\n')
|
||||
: '';
|
||||
|
||||
const userContent = historyStr
|
||||
? `<recent_conversation>\n${historyStr}\n</recent_conversation>\n\n<current_task>\n${input.task}\n</current_task>`
|
||||
: input.task;
|
||||
|
||||
const messages: Message[] = [
|
||||
{ role: 'system', content: MASTER_SYSTEM_PROMPT },
|
||||
{ role: 'user', content: userContent },
|
||||
];
|
||||
|
||||
let steps = 0;
|
||||
|
||||
while (steps < maxSteps) {
|
||||
steps += 1;
|
||||
|
||||
const result = await llm.generateText({
|
||||
messages,
|
||||
tools: toolSchemas,
|
||||
});
|
||||
|
||||
if (result.toolCalls.length === 0) {
|
||||
return {
|
||||
content: result.content.trim() || 'Нет ответа.',
|
||||
steps,
|
||||
};
|
||||
}
|
||||
|
||||
messages.push({
|
||||
role: 'assistant',
|
||||
content: result.content,
|
||||
tool_calls: result.toolCalls,
|
||||
});
|
||||
|
||||
for (const tc of result.toolCalls) {
|
||||
const tool = getTool(tc.name);
|
||||
if (!tool) {
|
||||
messages.push({
|
||||
role: 'tool',
|
||||
id: tc.id,
|
||||
name: tc.name,
|
||||
content: JSON.stringify({ error: `Unknown tool: ${tc.name}` }),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
let toolResult: string;
|
||||
try {
|
||||
toolResult = await tool.execute(tc.arguments, input.context);
|
||||
} catch (err) {
|
||||
toolResult = JSON.stringify({
|
||||
error: err instanceof Error ? err.message : String(err),
|
||||
});
|
||||
}
|
||||
|
||||
messages.push({
|
||||
role: 'tool',
|
||||
id: tc.id,
|
||||
name: tc.name,
|
||||
content: toolResult.length > 12000 ? toolResult.slice(0, 12000) + '\n...[truncated]' : toolResult,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const finalResult = await llm.generateText({
|
||||
messages,
|
||||
tools: [],
|
||||
});
|
||||
|
||||
return {
|
||||
content: finalResult.content.trim() || 'Достигнут лимит шагов. Попробуйте уточнить запрос.',
|
||||
steps,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user