task loop

This commit is contained in:
锦恢 2025-06-19 14:20:18 +08:00
parent 1b3418f15b
commit e6d1f1205a
3 changed files with 188 additions and 38 deletions

View File

@ -1,6 +1,6 @@
/* eslint-disable */ /* eslint-disable */
import { ref, type Ref } from "vue"; import { ref, type Ref } from "vue";
import { type ToolCall, type ChatStorage, getToolSchema, MessageState, type ChatMessage } from "../chat-box/chat"; import { type ToolCall, type ChatStorage, getToolSchema, MessageState, type ChatMessage, type ChatSetting, type EnableToolItem } from "../chat-box/chat";
import { useMessageBridge, MessageBridge, createMessageBridge } from "@/api/message-bridge"; import { useMessageBridge, MessageBridge, createMessageBridge } from "@/api/message-bridge";
import type { OpenAI } from 'openai'; import type { OpenAI } from 'openai';
import { llmManager, llms, type BasicLlmDescription } from "@/views/setting/llm"; import { llmManager, llms, type BasicLlmDescription } from "@/views/setting/llm";
@ -737,4 +737,40 @@ export class TaskLoop {
} }
} }
} }
public async createStorage(settings?: ChatSetting): Promise<ChatStorage> {
let {
enableXmlWrapper = false,
systemPrompt = '',
temperature = 0.6,
contextLength = 100,
parallelToolCalls = true,
enableWebSearch = false,
enableTools = undefined,
} = settings || {};
if (enableTools === undefined) {
// 默认缺省的情况下使用全部工具
const tools = await this.listTools();
enableTools = tools.map(tool => ({
...tool,
enabled: true
})) as EnableToolItem[];
}
const _settings = {
enableXmlWrapper,
systemPrompt,
temperature,
contextLength,
parallelToolCalls,
enableTools,
enableWebSearch
} as ChatSetting;
return {
messages: [],
settings: _settings
}
}
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "openmcp-sdk", "name": "openmcp-sdk",
"version": "0.0.7", "version": "0.0.8",
"description": "openmcp-sdk", "description": "openmcp-sdk",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"

View File

@ -4,20 +4,13 @@ import type { OpenAI } from 'openai';
export type ChatCompletionChunk = OpenAI.Chat.Completions.ChatCompletionChunk; export type ChatCompletionChunk = OpenAI.Chat.Completions.ChatCompletionChunk;
export type ChatCompletionCreateParamsBase = OpenAI.Chat.Completions.ChatCompletionCreateParams & { id?: string }; export type ChatCompletionCreateParamsBase = OpenAI.Chat.Completions.ChatCompletionCreateParams & { id?: string };
export interface TaskLoopOptions { interface SchemaProperty {
maxEpochs?: number;
maxJsonParseRetry?: number;
adapter?: any;
verbose?: 0 | 1 | 2 | 3;
}
export interface SchemaProperty {
title: string; title: string;
type: string; type: string;
description?: string; description?: string;
} }
export interface InputSchema { interface InputSchema {
type: string; type: string;
properties: Record<string, SchemaProperty>; properties: Record<string, SchemaProperty>;
required?: string[]; required?: string[];
@ -25,7 +18,7 @@ export interface InputSchema {
$defs?: any; $defs?: any;
} }
export interface ToolItem { interface ToolItem {
name: string; name: string;
description: string; description: string;
inputSchema: InputSchema; inputSchema: InputSchema;
@ -33,6 +26,50 @@ export interface ToolItem {
anyOf?: any; anyOf?: any;
} }
interface IExtraInfo {
created: number,
state: MessageState,
serverName: string,
usage?: ChatCompletionChunk['usage'];
enableXmlWrapper: boolean;
[key: string]: any;
}
interface ToolMessage {
role: 'tool';
index: number;
content: ToolCallContent[];
tool_call_id?: string
name?: string // 工具名称,当 role 为 tool
tool_calls?: ToolCall[],
extraInfo: IExtraInfo
}
interface TextMessage {
role: 'user' | 'assistant' | 'system';
content: string;
tool_call_id?: string
name?: string // 工具名称,当 role 为 tool
tool_calls?: ToolCall[],
extraInfo: IExtraInfo
}
export type ChatMessage = ToolMessage | TextMessage;
interface ChatStorage {
messages: ChatMessage[]
settings: ChatSetting
}
interface EnableToolItem {
name: string;
description: string;
enabled: boolean;
inputSchema: InputSchema;
}
export type Ref<T> = { export type Ref<T> = {
value: T; value: T;
}; };
@ -80,68 +117,132 @@ export interface IDoConversationResult {
stop: boolean; stop: boolean;
} }
export interface TaskLoopOptions {
/**
* The maximum number of epochs (conversation rounds) to perform.
*/
maxEpochs?: number;
/**
* The maximum number of retries allowed when parsing JSON responses fails.
*/
maxJsonParseRetry?: number;
/**
* A custom adapter that can be used to modify behavior or integrate with different environments.
*/
adapter?: any;
/**
* Verbosity level for logging:
* 0 - Silent, 1 - Errors only, 2 - Warnings and errors, 3 - Full debug output.
*/
verbose?: 0 | 1 | 2 | 3;
}
interface ChatSetting {
/**
* Index of the selected language model from a list of available models.
*/
modelIndex: number;
/**
* System-level prompt used to guide the behavior of the assistant.
*/
systemPrompt: string;
/**
* List of tools that are enabled and available during the chat.
*/
enableTools: EnableToolItem[];
/**
* Sampling temperature for generating responses.
* Higher values (e.g., 0.8) make output more random; lower values (e.g., 0.2) make it more focused and deterministic.
*/
temperature: number;
/**
* Whether web search is enabled for enhancing responses with real-time information.
*/
enableWebSearch: boolean;
/**
* Maximum length of the conversation context to keep.
*/
contextLength: number;
/**
* Whether multiple tools can be called in parallel within a single message.
*/
parallelToolCalls: boolean;
/**
* Whether to wrap tool call responses in XML format.
*/
enableXmlWrapper: boolean;
}
/** /**
* @description * @description
*/ */
export class TaskLoop { export class TaskLoop {
private streamingContent;
private streamingToolCalls;
private readonly taskOptions;
private bridge;
private currentChatId;
private onError;
private onChunk;
private onDone;
private onToolCalled;
private onEpoch;
private completionUsage;
private llmConfig;
constructor(taskOptions?: TaskLoopOptions); constructor(taskOptions?: TaskLoopOptions);
private handleChunkDeltaContent;
private handleChunkDeltaToolCalls; /**
private handleChunkUsage; * @description make chat data
private doConversation; * @param tabStorage
*/
makeChatData(tabStorage: any): ChatCompletionCreateParamsBase | undefined; makeChatData(tabStorage: any): ChatCompletionCreateParamsBase | undefined;
/**
* @description stop the task loop
*/
abort(): void; abort(): void;
/** /**
* @description error * @description Register a callback function triggered on error
* @param handler * @param handler
*/ */
registerOnError(handler: (msg: IErrorMssage) => void): void; registerOnError(handler: (msg: IErrorMssage) => void): void;
/**
* @description Register a callback function triggered on chunk
* @param handler
*/
registerOnChunk(handler: (chunk: ChatCompletionChunk) => void): void; registerOnChunk(handler: (chunk: ChatCompletionChunk) => void): void;
/** /**
* @description chat.completion * @description Register a callback function triggered at the beginning of each epoch
* @param handler * @param handler
*/ */
registerOnDone(handler: () => void): void; registerOnDone(handler: () => void): void;
/** /**
* @description epoch * @description Register a callback function triggered at the beginning of each epoch
* @param handler * @param handler
*/ */
registerOnEpoch(handler: () => void): void; registerOnEpoch(handler: () => void): void;
/** /**
* @description toolcall * @description Registers a callback function that is triggered when a tool call is completed. This method allows you to intercept and modify the output of the tool call.
* @param handler * @param handler
*/ */
registerOnToolCalled(handler: (toolCallResult: ToolCallResult) => ToolCallResult): void; registerOnToolCalled(handler: (toolCallResult: ToolCallResult) => ToolCallResult): void;
/** /**
* @description toolcall * @description Register a callback triggered after tool call finishes. You can intercept and modify the output.
* @param handler * @param handler
*/ */
registerOnToolCall(handler: (toolCall: ToolCall) => ToolCall): void; registerOnToolCall(handler: (toolCall: ToolCall) => ToolCall): void;
/** /**
* @description LLM * @description Get current LLM configuration
*/ */
getLlmConfig(): any; getLlmConfig(): any;
/** /**
* @description LLM nodejs * @description Set the current LLM configuration, for Node.js environment
* @param config * @param config
* @example * @example
* setLlmConfig({ * setLlmConfig({
@ -154,11 +255,19 @@ export class TaskLoop {
setLlmConfig(config: any): void; setLlmConfig(config: any): void;
/** /**
* @description epoch * @description Set proxy server
* @param maxEpochs * @param maxEpochs
*/ */
setMaxEpochs(maxEpochs: number): void; setMaxEpochs(maxEpochs: number): void;
/**
* @description bind streaming content and tool calls
*/
bindStreaming(content: Ref<string>, toolCalls: Ref<ToolCall[]>): void; bindStreaming(content: Ref<string>, toolCalls: Ref<ToolCall[]>): void;
/**
* @description not finish
*/
connectToService(): Promise<void>; connectToService(): Promise<void>;
/** /**
@ -168,14 +277,19 @@ export class TaskLoop {
setProxyServer(proxyServer: string): void; setProxyServer(proxyServer: string): void;
/** /**
* @description * @description Get all available tool list
*/ */
listTools(): Promise<ToolItem[]>; listTools(): Promise<ToolItem[]>;
/** /**
* @description DOM * @description Start the loop and asynchronously update the DOM
*/ */
start(tabStorage: any, userMessage: string): Promise<void>; start(tabStorage: any, userMessage: string): Promise<void>;
/**
* @description Create single conversation context
*/
createStorage(settings?: ChatSetting): Promise<ChatStorage>;
} }
export declare const getToolSchema: any; export declare const getToolSchema: any;