more explorations
This commit is contained in:
@@ -2,7 +2,6 @@ import { BusEvent } from "@/bus/bus-event"
|
||||
import { Bus } from "@/bus"
|
||||
import { Session } from "."
|
||||
import { SessionID, MessageID, PartID } from "./schema"
|
||||
import { Instance } from "../project/instance"
|
||||
import { Provider } from "../provider/provider"
|
||||
import { MessageV2 } from "./message-v2"
|
||||
import z from "zod"
|
||||
@@ -219,7 +218,6 @@ When constructing the summary, try to stick to this template:
|
||||
const prompt = compacting.prompt ?? [defaultPrompt, ...compacting.context].join("\n\n")
|
||||
const msgs = structuredClone(messages)
|
||||
yield* plugin.trigger("experimental.chat.messages.transform", {}, { messages: msgs })
|
||||
const modelMessages = yield* MessageV2.toModelMessagesEffect(msgs, model, { stripMedia: true })
|
||||
const ctx = yield* InstanceState.context
|
||||
const msg: MessageV2.Assistant = {
|
||||
id: MessageID.ascending(),
|
||||
@@ -261,10 +259,29 @@ When constructing the summary, try to stick to this template:
|
||||
tools: {},
|
||||
system: [],
|
||||
messages: [
|
||||
...modelMessages,
|
||||
...msgs,
|
||||
{
|
||||
role: "user",
|
||||
content: [{ type: "text", text: prompt }],
|
||||
info: {
|
||||
role: "user",
|
||||
sessionID: input.sessionID,
|
||||
id: MessageID.ascending(),
|
||||
time: { created: Date.now() },
|
||||
agent: agent.name,
|
||||
model: {
|
||||
modelID: model.id,
|
||||
providerID: model.providerID,
|
||||
},
|
||||
},
|
||||
parts: [
|
||||
{
|
||||
type: "text",
|
||||
text: prompt,
|
||||
sessionID: input.sessionID,
|
||||
messageID: MessageID.ascending(),
|
||||
id: PartID.ascending(),
|
||||
synthetic: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
model,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Provider } from "@/provider/provider"
|
||||
import { Log } from "@/util/log"
|
||||
import { Cause, Effect, Layer, Record, ServiceMap } from "effect"
|
||||
import * as Queue from "effect/Queue"
|
||||
import { Effect, Layer, Record, ServiceMap } from "effect"
|
||||
import * as Stream from "effect/Stream"
|
||||
import { streamText, wrapLanguageModel, type ModelMessage, type Tool, tool, jsonSchema } from "ai"
|
||||
import { mergeDeep, pipe } from "remeda"
|
||||
@@ -10,13 +9,14 @@ import { ProviderTransform } from "@/provider/transform"
|
||||
import { Config } from "@/config/config"
|
||||
import { Instance } from "@/project/instance"
|
||||
import type { Agent } from "@/agent/agent"
|
||||
import type { MessageV2 } from "./message-v2"
|
||||
import { MessageV2 } from "./message-v2"
|
||||
import { Plugin } from "@/plugin"
|
||||
import { SystemPrompt } from "./system"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { Permission } from "@/permission"
|
||||
import { Auth } from "@/auth"
|
||||
import { Installation } from "@/installation"
|
||||
import { iife } from "@/util/iife"
|
||||
|
||||
export namespace LLM {
|
||||
const log = Log.create({ service: "llm" })
|
||||
@@ -30,7 +30,7 @@ export namespace LLM {
|
||||
agent: Agent.Info
|
||||
permission?: Permission.Ruleset
|
||||
system: string[]
|
||||
messages: ModelMessage[]
|
||||
messages: MessageV2.WithParts[]
|
||||
small?: boolean
|
||||
tools: Record<string, Tool>
|
||||
retries?: number
|
||||
@@ -146,19 +146,18 @@ export namespace LLM {
|
||||
}
|
||||
|
||||
const isWorkflow = language instanceof GitLabWorkflowLanguageModel
|
||||
const messages = isOpenaiOauth
|
||||
? input.messages
|
||||
: isWorkflow
|
||||
? input.messages
|
||||
: [
|
||||
...system.map(
|
||||
(x): ModelMessage => ({
|
||||
role: "system",
|
||||
content: x,
|
||||
}),
|
||||
),
|
||||
...input.messages,
|
||||
]
|
||||
const messages = await iife(async () => {
|
||||
if (isOpenaiOauth || isWorkflow) return MessageV2.toModelMessages(input.messages, input.model)
|
||||
return [
|
||||
...system.map(
|
||||
(x): ModelMessage => ({
|
||||
role: "system",
|
||||
content: x,
|
||||
}),
|
||||
),
|
||||
...(await MessageV2.toModelMessages(input.messages, input.model)),
|
||||
]
|
||||
})
|
||||
|
||||
const params = await Plugin.trigger(
|
||||
"chat.params",
|
||||
@@ -198,7 +197,7 @@ export namespace LLM {
|
||||
? undefined
|
||||
: ProviderTransform.maxOutputTokens(input.model)
|
||||
|
||||
const tools = await resolveTools(input)
|
||||
const tools = resolveTools(input)
|
||||
|
||||
// LiteLLM and some Anthropic proxies require the tools parameter to be present
|
||||
// when message history contains tool calls, even if no tools are being used.
|
||||
@@ -242,7 +241,7 @@ export namespace LLM {
|
||||
try {
|
||||
const result = await t.execute!(JSON.parse(argsJson), {
|
||||
toolCallId: _requestID,
|
||||
messages: input.messages,
|
||||
messages: [],
|
||||
abortSignal: input.abort,
|
||||
})
|
||||
const output = typeof result === "string" ? result : (result?.output ?? JSON.stringify(result))
|
||||
@@ -346,13 +345,7 @@ export namespace LLM {
|
||||
|
||||
// Check if messages contain any tool-call content
|
||||
// Used to determine if a dummy tool should be added for LiteLLM proxy compatibility
|
||||
export function hasToolCalls(messages: ModelMessage[]): boolean {
|
||||
for (const msg of messages) {
|
||||
if (!Array.isArray(msg.content)) continue
|
||||
for (const part of msg.content) {
|
||||
if (part.type === "tool-call" || part.type === "tool-result") return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
export function hasToolCalls(messages: MessageV2.WithParts[]): boolean {
|
||||
return messages.some((msg) => msg.parts.some((part) => part.type === "tool"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,5 +77,6 @@ export function createOpencodeClient(config?: Config & { directory?: string; exp
|
||||
workspace: config?.experimental_workspaceID,
|
||||
}),
|
||||
)
|
||||
return new OpencodeClient({ client })
|
||||
const result = new OpencodeClient({ client })
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { Part, UserMessage } from "./client.js"
|
||||
|
||||
export const message = {
|
||||
user(input: Omit<UserMessage, "role" | "time" | "id"> & { parts: Omit<Part, "id" | "sessionID" | "messageID">[] }): {
|
||||
info: UserMessage
|
||||
parts: Part[]
|
||||
} {
|
||||
const { parts, ...rest } = input
|
||||
|
||||
const info: UserMessage = {
|
||||
...rest,
|
||||
id: "asdasd",
|
||||
time: {
|
||||
created: Date.now(),
|
||||
},
|
||||
role: "user",
|
||||
}
|
||||
|
||||
return {
|
||||
info,
|
||||
parts: input.parts.map(
|
||||
(part) =>
|
||||
({
|
||||
...part,
|
||||
id: "asdasd",
|
||||
messageID: info.id,
|
||||
sessionID: info.sessionID,
|
||||
}) as Part,
|
||||
),
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -5,6 +5,9 @@ import { createOpencodeClient } from "./client.js"
|
||||
import { createOpencodeServer } from "./server.js"
|
||||
import type { ServerOptions } from "./server.js"
|
||||
|
||||
export * as data from "./data.js"
|
||||
import * as data from "./data.js"
|
||||
|
||||
export async function createOpencode(options?: ServerOptions) {
|
||||
const server = await createOpencodeServer({
|
||||
...options,
|
||||
|
||||
Reference in New Issue
Block a user