mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-25 17:54:34 +08:00
- Replace @mariozechner/pi-ai and pi-agent-core with @earendil-works scope - Adapt to AgentTool.execute() params type change (Record → unknown) - Migrate Agent constructor to use initialState for systemPrompt/tools/messages - Update onPayload callback signature to include model parameter - Filter finalMessages with isPiMessage() for new AgentMessage union type - Use state.errorMessage instead of deprecated state.error Co-authored-by: Cursor <cursoragent@cursor.com>
84 lines
3.1 KiB
TypeScript
84 lines
3.1 KiB
TypeScript
/**
|
|
* 共享工具适配器
|
|
*
|
|
* 将 @openchatlab/tools 的 ToolDefinition 转换为 Electron 的 ToolRegistryEntry。
|
|
* Electron 端使用 WorkerDataProvider 替代 Server 端的 CoreDataProvider。
|
|
*/
|
|
|
|
import type { ToolDefinition, ToolExecutionContext } from '@openchatlab/tools'
|
|
import type { AgentTool, AgentToolResult } from '@openchatlab/node-runtime'
|
|
import { batchSegmentWithFrequency } from '@openchatlab/node-runtime'
|
|
import type { ToolContext, ToolRegistryEntry, ToolCategory } from './types'
|
|
import { WorkerDataProvider } from './worker-data-provider'
|
|
import { t as i18nT } from '../../i18n'
|
|
|
|
interface AdaptOptions {
|
|
category: ToolCategory
|
|
truncationStrategy?: 'keep_first' | 'keep_last'
|
|
}
|
|
|
|
function buildExecutionContext(ctx: ToolContext): ToolExecutionContext {
|
|
return {
|
|
dataProvider: new WorkerDataProvider(ctx.sessionId),
|
|
sessionId: ctx.sessionId,
|
|
locale: ctx.locale,
|
|
timeFilter: ctx.timeFilter,
|
|
searchContextBefore: ctx.searchContextBefore,
|
|
searchContextAfter: ctx.searchContextAfter,
|
|
maxMessagesLimit: ctx.maxMessagesLimit,
|
|
segmentText: (texts, locale, options) => batchSegmentWithFrequency(texts, locale as any, options as any),
|
|
translateTemplate: (key: string) => {
|
|
const translated = i18nT(key)
|
|
return translated !== key ? translated : undefined
|
|
},
|
|
}
|
|
}
|
|
|
|
export function adaptSharedTool(tool: ToolDefinition, options: AdaptOptions): ToolRegistryEntry {
|
|
return {
|
|
name: tool.name,
|
|
category: options.category,
|
|
truncationStrategy: options.truncationStrategy ?? tool.truncationStrategy,
|
|
factory(context: ToolContext): AgentTool<any> {
|
|
const schema = {
|
|
type: 'object' as const,
|
|
properties: { ...tool.inputSchema.properties },
|
|
required: tool.inputSchema.required ?? [],
|
|
}
|
|
|
|
return {
|
|
name: tool.name,
|
|
label: tool.name,
|
|
description: `ai.tools.${tool.name}.desc`,
|
|
parameters: schema as any,
|
|
async execute(_toolCallId: string, params: unknown): Promise<AgentToolResult<unknown>> {
|
|
const toolParams = (params && typeof params === 'object' ? params : {}) as Record<string, unknown>
|
|
const execCtx = buildExecutionContext(context)
|
|
try {
|
|
const result = await tool.handler(toolParams, execCtx)
|
|
|
|
if (result.rawMessages && result.rawMessages.length > 0) {
|
|
const baseData = (typeof result.data === 'object' && result.data !== null ? result.data : {}) as Record<
|
|
string,
|
|
unknown
|
|
>
|
|
return {
|
|
content: [{ type: 'text', text: result.content }],
|
|
details: { ...baseData, rawMessages: result.rawMessages },
|
|
}
|
|
}
|
|
|
|
return {
|
|
content: [{ type: 'text', text: result.content }],
|
|
details: result.data ?? null,
|
|
}
|
|
} catch (error) {
|
|
const msg = error instanceof Error ? error.message : String(error)
|
|
return { content: [{ type: 'text', text: `Error: ${msg}` }], details: null }
|
|
}
|
|
},
|
|
}
|
|
},
|
|
}
|
|
}
|