upgrade taskloop

This commit is contained in:
锦恢 2025-06-20 15:49:54 +08:00
parent f59e27b569
commit 50510ae647
5 changed files with 68 additions and 11 deletions

View File

@ -159,3 +159,13 @@ npm run build:plugin
``` ```
Then just press F5, いただきます (Let's begin) Then just press F5, いただきます (Let's begin)
---
## CI Pipeline
✅ npm run build
✅ npm run build:task-loop
✅ openmcp-client UT
✅ openmcp-sdk UT
✅ vscode extension UT

View File

@ -64,7 +64,7 @@ export class TaskLoop {
constructor( constructor(
private readonly taskOptions: TaskLoopOptions = { private readonly taskOptions: TaskLoopOptions = {
maxEpochs: 20, maxEpochs: 50,
maxJsonParseRetry: 3, maxJsonParseRetry: 3,
adapter: undefined, adapter: undefined,
verbose: 0 verbose: 0
@ -513,7 +513,7 @@ export class TaskLoop {
let jsonParseErrorRetryCount = 0; let jsonParseErrorRetryCount = 0;
const { const {
maxEpochs = 20, maxEpochs = 50,
verbose = 0 verbose = 0
} = this.taskOptions || {}; } = this.taskOptions || {};

View File

@ -37,6 +37,8 @@
"open": "^10.1.2", "open": "^10.1.2",
"ws": "^8.18.1", "ws": "^8.18.1",
"cli-table3": "^0.6.5", "cli-table3": "^0.6.5",
"https-proxy-agent": "^7.0.6" "https-proxy-agent": "^7.0.6",
"pino": "^9.6.0",
"pino-pretty": "^13.0.0"
} }
} }

View File

@ -189,7 +189,13 @@ export interface OmAgentConfiguration {
} }
} }
import { MessageState, type ChatMessage, type ChatSetting, type TaskLoop, type TextMessage } from '../../task-loop.js'; export interface DefaultLLM {
baseURL: string;
apiToken?: string;
model: string;
}
import { MessageState, TaskLoopOptions, type ChatMessage, type ChatSetting, type TaskLoop, type TextMessage } from '../../task-loop.js';
export function UserMessage(content: string): TextMessage { export function UserMessage(content: string): TextMessage {
return { return {
@ -218,8 +224,9 @@ export function AssistantMessage(content: string): TextMessage {
} }
export class OmAgent { export class OmAgent {
public _adapter: TaskLoopAdapter; private _adapter: TaskLoopAdapter;
public _loop?: TaskLoop; private _loop?: TaskLoop;
private _defaultLLM?: DefaultLLM;
constructor() { constructor() {
this._adapter = new TaskLoopAdapter(); this._adapter = new TaskLoopAdapter();
@ -257,6 +264,10 @@ export class OmAgent {
public loadMcpConfig(configPath: string) { public loadMcpConfig(configPath: string) {
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as OmAgentConfiguration; const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as OmAgentConfiguration;
const { mcpServers, defaultLLM } = config; const { mcpServers, defaultLLM } = config;
// set default llm
this.setDefaultLLM(defaultLLM);
for (const key in mcpServers) { for (const key in mcpServers) {
const mcpConfig = mcpServers[key]; const mcpConfig = mcpServers[key];
if ('command' in mcpConfig) { if ('command' in mcpConfig) {
@ -284,28 +295,48 @@ export class OmAgent {
} }
} }
public async getLoop() { private async getLoop(loopOption?: TaskLoopOptions) {
if (this._loop) { if (this._loop) {
return this._loop; return this._loop;
} }
const {
verbose = 1,
maxEpochs = 50,
maxJsonParseRetry = 3,
} = loopOption || {}
const adapter = this._adapter; const adapter = this._adapter;
const { TaskLoop } = await import('../../task-loop.js'); const { TaskLoop } = await import('../../task-loop.js');
this._loop = new TaskLoop({ adapter, verbose: 1 }); this._loop = new TaskLoop({ adapter, verbose, maxEpochs, maxJsonParseRetry });
return this._loop; return this._loop;
} }
public setDefaultLLM(option: DefaultLLM) {
this._defaultLLM = option;
}
public async start( public async start(
messages: ChatMessage[] | string, messages: ChatMessage[] | string,
settings?: ChatSetting settings?: ChatSetting & Partial<TaskLoopOptions>
) { ) {
if (messages.length === 0) { if (messages.length === 0) {
throw new Error('messages is empty'); throw new Error('messages is empty');
} }
const loop = await this.getLoop(); // detach taskloop option from settings and set default value
const {
maxEpochs = 50,
maxJsonParseRetry = 3,
verbose = 1
} = settings || {};
const loop = await this.getLoop({ maxEpochs, maxJsonParseRetry, verbose });
const storage = await loop.createStorage(settings); const storage = await loop.createStorage(settings);
// set input message
// user can invoke [UserMessage("CONTENT")] to make messages quickly
// or use string directly
let userMessage: string; let userMessage: string;
if (typeof messages === 'string') { if (typeof messages === 'string') {
userMessage = messages; userMessage = messages;
@ -318,6 +349,20 @@ export class OmAgent {
} }
} }
// select correct llm config
// user can set llm config via omagent.setDefaultLLM()
// or write "defaultLLM" in mcpconfig.json to specify
if (this._defaultLLM) {
loop.setLlmConfig({
baseUrl: this._defaultLLM.baseURL,
userToken: this._defaultLLM.apiToken,
userModel: this._defaultLLM.model,
});
} else {
// throw error to user and give the suggestion
throw new Error('default LLM is not set, please set it via omagent.setDefaultLLM() or write "defaultLLM" in mcpconfig.json');
}
return await loop.start(storage, userMessage); return await loop.start(storage, userMessage);
} }
} }

View File

@ -1,4 +1,4 @@
export { routeMessage } from './common/router.js'; export { routeMessage } from './common/router.js';
export { VSCodeWebViewLike, TaskLoopAdapter, OmAgent, OmAgentConfiguration } from './hook/adapter.js'; export { VSCodeWebViewLike, TaskLoopAdapter, OmAgent, OmAgentConfiguration, UserMessage, AssistantMessage } from './hook/adapter.js';
export { setVscodeWorkspace, setRunningCWD } from './hook/setting.js'; export { setVscodeWorkspace, setRunningCWD } from './hook/setting.js';
export { clientMap } from './mcp/connect.service.js'; export { clientMap } from './mcp/connect.service.js';