chore: format code

This commit is contained in:
GitHub Action
2025-11-08 01:59:02 +00:00
parent 16357e8041
commit 34ff87d504
182 changed files with 940 additions and 3646 deletions

View File

@@ -30,17 +30,12 @@ export namespace SessionCompaction {
),
}
export function isOverflow(input: {
tokens: MessageV2.Assistant["tokens"]
model: ModelsDev.Model
}) {
export function isOverflow(input: { tokens: MessageV2.Assistant["tokens"]; model: ModelsDev.Model }) {
if (Flag.OPENCODE_DISABLE_AUTOCOMPACT) return false
const context = input.model.limit.context
if (context === 0) return false
const count = input.tokens.input + input.tokens.cache.read + input.tokens.output
const output =
Math.min(input.model.limit.output, SessionPrompt.OUTPUT_TOKEN_MAX) ||
SessionPrompt.OUTPUT_TOKEN_MAX
const output = Math.min(input.model.limit.output, SessionPrompt.OUTPUT_TOKEN_MAX) || SessionPrompt.OUTPUT_TOKEN_MAX
const usable = context - output
return count > usable
}
@@ -92,15 +87,9 @@ export namespace SessionCompaction {
}
}
export async function run(input: {
sessionID: string
providerID: string
modelID: string
signal?: AbortSignal
}) {
export async function run(input: { sessionID: string; providerID: string; modelID: string; signal?: AbortSignal }) {
if (!input.signal) SessionLock.assertUnlocked(input.sessionID)
await using lock =
input.signal === undefined ? SessionLock.acquire({ sessionID: input.sessionID }) : undefined
await using lock = input.signal === undefined ? SessionLock.acquire({ sessionID: input.sessionID }) : undefined
const signal = input.signal ?? lock!.signal
await Session.update(input.sessionID, (draft) => {
@@ -160,11 +149,7 @@ export namespace SessionCompaction {
// set to 0, we handle loop
maxRetries: 0,
model: model.language,
providerOptions: ProviderTransform.providerOptions(
model.npm,
model.providerID,
model.info.options,
),
providerOptions: ProviderTransform.providerOptions(model.npm, model.providerID, model.info.options),
headers: model.info.headers,
abortSignal: signal,
onError(error) {
@@ -244,11 +229,7 @@ export namespace SessionCompaction {
error: e,
})
const error = MessageV2.fromError(e, { providerID: input.providerID })
if (
retries.count < retries.max &&
MessageV2.APIError.isInstance(error) &&
error.data.isRetryable
) {
if (retries.count < retries.max && MessageV2.APIError.isInstance(error) && error.data.isRetryable) {
shouldRetry = true
await Session.updatePart({
id: Identifier.ascending("part"),
@@ -287,9 +268,7 @@ export namespace SessionCompaction {
})
if (result.shouldRetry) {
for (let retry = 1; retry < maxRetries; retry++) {
const lastRetryPart = result.parts.findLast(
(p): p is MessageV2.RetryPart => p.type === "retry",
)
const lastRetryPart = result.parts.findLast((p): p is MessageV2.RetryPart => p.type === "retry")
if (lastRetryPart) {
const delayMs = SessionRetry.getRetryDelayInMs(lastRetryPart.error, retry)
@@ -338,9 +317,7 @@ export namespace SessionCompaction {
if (
!msg.error ||
(MessageV2.AbortedError.isInstance(msg.error) &&
result.parts.some(
(part): part is MessageV2.TextPart => part.type === "text" && part.text.length > 0,
))
result.parts.some((part): part is MessageV2.TextPart => part.type === "text" && part.text.length > 0))
) {
msg.summary = true
Bus.publish(Event.Compacted, {

View File

@@ -172,12 +172,7 @@ export namespace Session {
})
})
export async function createNext(input: {
id?: string
title?: string
parentID?: string
directory: string
}) {
export async function createNext(input: { id?: string; title?: string; parentID?: string; directory: string }) {
const result: Info = {
id: Identifier.descending("session", input.id),
version: Installation.VERSION,
@@ -400,9 +395,7 @@ export namespace Session {
.add(new Decimal(tokens.input).mul(input.model.cost?.input ?? 0).div(1_000_000))
.add(new Decimal(tokens.output).mul(input.model.cost?.output ?? 0).div(1_000_000))
.add(new Decimal(tokens.cache.read).mul(input.model.cost?.cache_read ?? 0).div(1_000_000))
.add(
new Decimal(tokens.cache.write).mul(input.model.cost?.cache_write ?? 0).div(1_000_000),
)
.add(new Decimal(tokens.cache.write).mul(input.model.cost?.cache_write ?? 0).div(1_000_000))
.toNumber(),
tokens,
}

View File

@@ -2,13 +2,7 @@ import z from "zod"
import { Bus } from "../bus"
import { NamedError } from "../util/error"
import { Message } from "./message"
import {
APICallError,
convertToModelMessages,
LoadAPIKeyError,
type ModelMessage,
type UIMessage,
} from "ai"
import { APICallError, convertToModelMessages, LoadAPIKeyError, type ModelMessage, type UIMessage } from "ai"
import { Identifier } from "../id/id"
import { LSP } from "../lsp"
import { Snapshot } from "@/snapshot"
@@ -17,10 +11,7 @@ import { Storage } from "@/storage/storage"
export namespace MessageV2 {
export const OutputLengthError = NamedError.create("MessageOutputLengthError", z.object({}))
export const AbortedError = NamedError.create(
"MessageAbortedError",
z.object({ message: z.string() }),
)
export const AbortedError = NamedError.create("MessageAbortedError", z.object({ message: z.string() }))
export const AuthError = NamedError.create(
"ProviderAuthError",
z.object({
@@ -253,12 +244,7 @@ export namespace MessageV2 {
export type ToolStateError = z.infer<typeof ToolStateError>
export const ToolState = z
.discriminatedUnion("status", [
ToolStatePending,
ToolStateRunning,
ToolStateCompleted,
ToolStateError,
])
.discriminatedUnion("status", [ToolStatePending, ToolStateRunning, ToolStateCompleted, ToolStateError])
.meta({
ref: "ToolState",
})
@@ -454,8 +440,7 @@ export namespace MessageV2 {
}
}
const { title, time, ...metadata } =
v1.metadata.tool[part.toolInvocation.toolCallId] ?? {}
const { title, time, ...metadata } = v1.metadata.tool[part.toolInvocation.toolCallId] ?? {}
if (part.toolInvocation.state === "call") {
return {
status: "running",
@@ -556,11 +541,7 @@ export namespace MessageV2 {
},
]
// text/plain and directory files are converted into text parts, ignore them
if (
part.type === "file" &&
part.mime !== "text/plain" &&
part.mime !== "application/x-directory"
)
if (part.type === "file" && part.mime !== "text/plain" && part.mime !== "application/x-directory")
return [
{
type: "file",
@@ -619,9 +600,7 @@ export namespace MessageV2 {
state: "output-available",
toolCallId: part.callID,
input: part.state.input,
output: part.state.time.compacted
? "[Old tool result content cleared]"
: part.state.output,
output: part.state.time.compacted ? "[Old tool result content cleared]" : part.state.output,
callProviderMetadata: part.metadata,
},
]

View File

@@ -51,11 +51,9 @@ export namespace Message {
})
export type ToolResult = z.infer<typeof ToolResult>
export const ToolInvocation = z
.discriminatedUnion("state", [ToolCall, ToolPartialCall, ToolResult])
.meta({
ref: "ToolInvocation",
})
export const ToolInvocation = z.discriminatedUnion("state", [ToolCall, ToolPartialCall, ToolResult]).meta({
ref: "ToolInvocation",
})
export type ToolInvocation = z.infer<typeof ToolInvocation>
export const TextPart = z
@@ -124,14 +122,7 @@ export namespace Message {
export type StepStartPart = z.infer<typeof StepStartPart>
export const MessagePart = z
.discriminatedUnion("type", [
TextPart,
ReasoningPart,
ToolInvocationPart,
SourceUrlPart,
FilePart,
StepStartPart,
])
.discriminatedUnion("type", [TextPart, ReasoningPart, ToolInvocationPart, SourceUrlPart, FilePart, StepStartPart])
.meta({
ref: "MessagePart",
})
@@ -149,11 +140,7 @@ export namespace Message {
completed: z.number().optional(),
}),
error: z
.discriminatedUnion("name", [
AuthError.Schema,
NamedError.Unknown.Schema,
OutputLengthError.Schema,
])
.discriminatedUnion("name", [AuthError.Schema, NamedError.Unknown.Schema, OutputLengthError.Schema])
.optional(),
sessionID: z.string(),
tool: z.record(

View File

@@ -301,11 +301,7 @@ export namespace SessionPrompt {
OUTPUT_TOKEN_MAX,
),
abortSignal: abort.signal,
providerOptions: ProviderTransform.providerOptions(
model.npm,
model.providerID,
params.options,
),
providerOptions: ProviderTransform.providerOptions(model.npm, model.providerID, params.options),
stopWhen: stepCountIs(1),
temperature: params.temperature,
topP: params.topP,
@@ -340,11 +336,7 @@ export namespace SessionPrompt {
async transformParams(args) {
if (args.type === "stream") {
// @ts-expect-error
args.params.prompt = ProviderTransform.message(
args.params.prompt,
model.providerID,
model.modelID,
)
args.params.prompt = ProviderTransform.message(args.params.prompt, model.providerID, model.modelID)
}
return args.params
},
@@ -362,9 +354,7 @@ export namespace SessionPrompt {
})
if (result.shouldRetry) {
for (let retry = 1; retry < maxRetries; retry++) {
const lastRetryPart = result.parts.findLast(
(p): p is MessageV2.RetryPart => p.type === "retry",
)
const lastRetryPart = result.parts.findLast((p): p is MessageV2.RetryPart => p.type === "retry")
if (lastRetryPart) {
const delayMs = SessionRetry.getRetryDelayInMs(lastRetryPart.error, retry)
@@ -529,11 +519,7 @@ export namespace SessionPrompt {
)
for (const item of await ToolRegistry.tools(input.providerID, input.modelID)) {
if (Wildcard.all(item.id, enabledTools) === false) continue
const schema = ProviderTransform.schema(
input.providerID,
input.modelID,
z.toJSONSchema(item.parameters),
)
const schema = ProviderTransform.schema(input.providerID, input.modelID, z.toJSONSchema(item.parameters))
tools[item.id] = tool({
id: item.id as any,
description: item.description,
@@ -853,9 +839,7 @@ export namespace SessionPrompt {
messageID: info.id,
sessionID: input.sessionID,
type: "file",
url:
`data:${part.mime};base64,` +
Buffer.from(await file.bytes()).toString("base64"),
url: `data:${part.mime};base64,` + Buffer.from(await file.bytes()).toString("base64"),
mime: part.mime,
filename: part.filename!,
source: part.source,
@@ -929,9 +913,7 @@ export namespace SessionPrompt {
synthetic: true,
})
}
const wasPlan = input.messages.some(
(msg) => msg.info.role === "assistant" && msg.info.mode === "plan",
)
const wasPlan = input.messages.some((msg) => msg.info.role === "assistant" && msg.info.mode === "plan")
if (wasPlan && input.agent.name === "build") {
userMessage.parts.push({
id: Identifier.ascending("part"),
@@ -1010,10 +992,7 @@ export namespace SessionPrompt {
partFromToolCall(toolCallID: string) {
return toolcalls[toolCallID]
},
async process(
stream: StreamTextResult<Record<string, AITool>, never>,
retries: { count: number; max: number },
) {
async process(stream: StreamTextResult<Record<string, AITool>, never>, retries: { count: number; max: number }) {
log.info("process")
if (!assistantMsg) throw new Error("call next() first before processing")
let shouldRetry = false
@@ -1169,10 +1148,7 @@ export namespace SessionPrompt {
status: "error",
input: value.input,
error: (value.error as any).toString(),
metadata:
value.error instanceof Permission.RejectedError
? value.error.metadata
: undefined,
metadata: value.error instanceof Permission.RejectedError ? value.error.metadata : undefined,
time: {
start: match.state.time.start,
end: Date.now(),
@@ -1296,11 +1272,7 @@ export namespace SessionPrompt {
error: e,
})
const error = MessageV2.fromError(e, { providerID: input.providerID })
if (
retries.count < retries.max &&
MessageV2.APIError.isInstance(error) &&
error.data.isRetryable
) {
if (retries.count < retries.max && MessageV2.APIError.isInstance(error) && error.data.isRetryable) {
shouldRetry = true
await Session.updatePart({
id: Identifier.ascending("part"),
@@ -1323,11 +1295,7 @@ export namespace SessionPrompt {
}
const p = await MessageV2.parts(assistantMsg.id)
for (const part of p) {
if (
part.type === "tool" &&
part.state.status !== "completed" &&
part.state.status !== "error"
) {
if (part.type === "tool" && part.state.status !== "completed" && part.state.status !== "error") {
await Session.updatePart({
...part,
state: {
@@ -1822,13 +1790,11 @@ export namespace SessionPrompt {
if (input.session.parentID) return
if (!Session.isDefaultTitle(input.session.title)) return
const isFirst =
input.history.filter(
(m) => m.info.role === "user" && !m.parts.every((p) => "synthetic" in p && p.synthetic),
).length === 1
input.history.filter((m) => m.info.role === "user" && !m.parts.every((p) => "synthetic" in p && p.synthetic))
.length === 1
if (!isFirst) return
const small =
(await Provider.getSmallModel(input.providerID)) ??
(await Provider.getModel(input.providerID, input.modelID))
(await Provider.getSmallModel(input.providerID)) ?? (await Provider.getModel(input.providerID, input.modelID))
const options = {
...ProviderTransform.options(small.providerID, small.modelID, input.session.id),
...small.info.options,

View File

@@ -45,9 +45,7 @@ export namespace SessionRevert {
if (!revert) {
if ((msg.info.id === input.messageID && !input.partID) || part.id === input.partID) {
// if no useful parts left in message, same as reverting whole message
const partID = remaining.some((item) => ["text", "tool"].includes(item.type))
? input.partID
: undefined
const partID = remaining.some((item) => ["text", "tool"].includes(item.type)) ? input.partID : undefined
revert = {
messageID: !partID && lastUser ? lastUser.id : msg.info.id,
partID,

View File

@@ -60,9 +60,7 @@ export namespace SessionSummary {
async function summarizeMessage(input: { messageID: string; messages: MessageV2.WithParts[] }) {
const messages = input.messages.filter(
(m) =>
m.info.id === input.messageID ||
(m.info.role === "assistant" && m.info.parentID === input.messageID),
(m) => m.info.id === input.messageID || (m.info.role === "assistant" && m.info.parentID === input.messageID),
)
const msgWithParts = messages.find((m) => m.info.id === input.messageID)!
const userMsg = msgWithParts.info as MessageV2.User
@@ -73,14 +71,11 @@ export namespace SessionSummary {
}
await Session.updateMessage(userMsg)
const assistantMsg = messages.find((m) => m.info.role === "assistant")!
.info as MessageV2.Assistant
const assistantMsg = messages.find((m) => m.info.role === "assistant")!.info as MessageV2.Assistant
const small = await Provider.getSmallModel(assistantMsg.providerID)
if (!small) return
const textPart = msgWithParts.parts.find(
(p) => p.type === "text" && !p.synthetic,
) as MessageV2.TextPart
const textPart = msgWithParts.parts.find((p) => p.type === "text" && !p.synthetic) as MessageV2.TextPart
if (textPart && !userMsg.summary?.title) {
const result = await generateText({
maxOutputTokens: small.info.reasoning ? 1500 : 20,
@@ -113,8 +108,7 @@ export namespace SessionSummary {
if (
messages.some(
(m) =>
m.info.role === "assistant" &&
m.parts.some((p) => p.type === "step-finish" && p.reason !== "tool-calls"),
m.info.role === "assistant" && m.parts.some((p) => p.type === "step-finish" && p.reason !== "tool-calls"),
)
) {
let summary = messages

View File

@@ -24,8 +24,7 @@ export namespace SystemPrompt {
export function provider(modelID: string) {
if (modelID.includes("gpt-5")) return [PROMPT_CODEX]
if (modelID.includes("gpt-") || modelID.includes("o1") || modelID.includes("o3"))
return [PROMPT_BEAST]
if (modelID.includes("gpt-") || modelID.includes("o1") || modelID.includes("o3")) return [PROMPT_BEAST]
if (modelID.includes("gemini-")) return [PROMPT_GEMINI]
if (modelID.includes("claude")) return [PROMPT_ANTHROPIC]
return [PROMPT_ANTHROPIC_WITHOUT_TODO]
@@ -100,11 +99,7 @@ export namespace SystemPrompt {
}),
).catch(() => [])
} else {
matches = await Filesystem.globUp(
instruction,
Instance.directory,
Instance.worktree,
).catch(() => [])
matches = await Filesystem.globUp(instruction, Instance.directory, Instance.worktree).catch(() => [])
}
matches.forEach((path) => paths.add(path))
}

View File

@@ -6,9 +6,7 @@ export namespace Todo {
export const Info = z
.object({
content: z.string().describe("Brief description of the task"),
status: z
.string()
.describe("Current status of the task: pending, in_progress, completed, cancelled"),
status: z.string().describe("Current status of the task: pending, in_progress, completed, cancelled"),
priority: z.string().describe("Priority level of the task: high, medium, low"),
id: z.string().describe("Unique identifier for the todo item"),
})