mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
123 lines
3.2 KiB
TypeScript
123 lines
3.2 KiB
TypeScript
import type { ChatToolCall } from "@/store/chat"
|
|
|
|
function parseLegacyToolFeedbackContent(
|
|
content: string,
|
|
): ChatToolCall[] | undefined {
|
|
const trimmed = content.trim()
|
|
const match = /^🔧\s+`([^`]+)`(?:\n([\s\S]*))?$/.exec(trimmed)
|
|
if (!match) {
|
|
return undefined
|
|
}
|
|
|
|
const toolName = match[1]?.trim() ?? ""
|
|
const body = match[2]?.trim() ?? ""
|
|
const codeFence = /```(?:json)?\n([\s\S]*?)\n```/m.exec(body)
|
|
const argumentsText = codeFence?.[1]?.trim() ?? ""
|
|
const explanation = body.replace(/```(?:json)?\n[\s\S]*?\n```/gm, "").trim()
|
|
|
|
return [
|
|
{
|
|
type: "function",
|
|
function: {
|
|
name: toolName,
|
|
...(argumentsText ? { arguments: argumentsText } : {}),
|
|
},
|
|
...(explanation
|
|
? {
|
|
extraContent: {
|
|
toolFeedbackExplanation: explanation,
|
|
},
|
|
}
|
|
: {}),
|
|
},
|
|
]
|
|
}
|
|
|
|
export function parseToolCallsValue(raw: unknown): ChatToolCall[] | undefined {
|
|
if (!Array.isArray(raw)) {
|
|
return undefined
|
|
}
|
|
|
|
const toolCalls: ChatToolCall[] = []
|
|
for (const item of raw) {
|
|
if (!item || typeof item !== "object") {
|
|
continue
|
|
}
|
|
|
|
const toolCall = item as Record<string, unknown>
|
|
const rawFunction =
|
|
toolCall.function && typeof toolCall.function === "object"
|
|
? (toolCall.function as Record<string, unknown>)
|
|
: null
|
|
const rawExtraContent =
|
|
toolCall.extra_content && typeof toolCall.extra_content === "object"
|
|
? (toolCall.extra_content as Record<string, unknown>)
|
|
: null
|
|
|
|
const nextToolCall: ChatToolCall = {
|
|
...(typeof toolCall.id === "string" ? { id: toolCall.id } : {}),
|
|
...(typeof toolCall.type === "string" ? { type: toolCall.type } : {}),
|
|
}
|
|
|
|
if (rawFunction) {
|
|
const name =
|
|
typeof rawFunction.name === "string" ? rawFunction.name : undefined
|
|
const argumentsText =
|
|
typeof rawFunction.arguments === "string"
|
|
? rawFunction.arguments
|
|
: undefined
|
|
|
|
if (name || argumentsText) {
|
|
nextToolCall.function = {
|
|
...(name ? { name } : {}),
|
|
...(argumentsText ? { arguments: argumentsText } : {}),
|
|
}
|
|
}
|
|
}
|
|
|
|
if (rawExtraContent) {
|
|
const toolFeedbackExplanation =
|
|
typeof rawExtraContent.tool_feedback_explanation === "string"
|
|
? rawExtraContent.tool_feedback_explanation
|
|
: undefined
|
|
|
|
if (toolFeedbackExplanation) {
|
|
nextToolCall.extraContent = {
|
|
toolFeedbackExplanation,
|
|
}
|
|
}
|
|
}
|
|
|
|
if (
|
|
nextToolCall.id ||
|
|
nextToolCall.type ||
|
|
nextToolCall.function ||
|
|
nextToolCall.extraContent
|
|
) {
|
|
toolCalls.push(nextToolCall)
|
|
}
|
|
}
|
|
|
|
return toolCalls.length > 0 ? toolCalls : undefined
|
|
}
|
|
|
|
export function parseToolCallsFromContent(
|
|
content: string,
|
|
): ChatToolCall[] | undefined {
|
|
return parseLegacyToolFeedbackContent(content)
|
|
}
|
|
|
|
export function toolCallsSignature(toolCalls?: ChatToolCall[]): string {
|
|
return (toolCalls ?? [])
|
|
.map((toolCall) =>
|
|
[
|
|
toolCall.id ?? "",
|
|
toolCall.type ?? "",
|
|
toolCall.function?.name ?? "",
|
|
toolCall.function?.arguments ?? "",
|
|
toolCall.extraContent?.toolFeedbackExplanation ?? "",
|
|
].join("\u0001"),
|
|
)
|
|
.join("\u0002")
|
|
}
|