Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b30705c42 | ||
|
|
1f8d396b76 | ||
|
|
3752bb9717 | ||
|
|
16d66c209d | ||
|
|
6506e48c54 | ||
|
|
f0e8b7c29b | ||
|
|
a00b49d65b | ||
|
|
b1589be4ba |
@@ -77,3 +77,4 @@
|
||||
| 2025-09-10 | 307,287 (+7,251) | 233,435 (+3,647) | 540,722 (+10,898) |
|
||||
| 2025-09-11 | 314,083 (+6,796) | 237,356 (+3,921) | 551,439 (+10,717) |
|
||||
| 2025-09-12 | 321,046 (+6,963) | 240,728 (+3,372) | 561,774 (+10,335) |
|
||||
| 2025-09-13 | 324,894 (+3,848) | 245,539 (+4,811) | 570,433 (+8,659) |
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"dev:remote": "VITE_AUTH_URL=https://auth.dev.opencode.ai bun sst shell --stage=dev bun dev",
|
||||
"build": "vinxi build && ../../packages/opencode/script/schema.ts ./.output/public/config.json",
|
||||
"start": "vinxi start",
|
||||
"version": "0.7.9"
|
||||
"version": "0.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ibm/plex": "6.4.1",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode/cloud-core",
|
||||
"version": "0.7.9",
|
||||
"version": "0.8.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode/cloud-function",
|
||||
"version": "0.7.9",
|
||||
"version": "0.8.0",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode/cloud-scripts",
|
||||
"version": "0.7.9",
|
||||
"version": "0.8.0",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode/function",
|
||||
"version": "0.7.9",
|
||||
"version": "0.8.0",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "0.7.9",
|
||||
"version": "0.8.0",
|
||||
"name": "opencode",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
|
||||
@@ -123,14 +123,15 @@ export const TuiCommand = cmd({
|
||||
const file = Bun.file(binary)
|
||||
if (!(await file.exists())) {
|
||||
await Bun.write(file, tui, { mode: 0o755 })
|
||||
await fs.chmod(binary, 0o755)
|
||||
if (process.platform !== "win32") await fs.chmod(binary, 0o755)
|
||||
}
|
||||
cmd = [binary]
|
||||
}
|
||||
if (!tui) {
|
||||
const dir = Bun.fileURLToPath(new URL("../../../../tui/cmd/opencode", import.meta.url))
|
||||
await $`go build -o ./dist/tui ./main.go`.cwd(dir)
|
||||
cmd = [path.join(dir, "dist/tui")]
|
||||
let binaryName = `./dist/tui${process.platform === "win32" ? ".exe" : ""}`
|
||||
await $`go build -o ${binaryName} ./main.go`.cwd(dir)
|
||||
cmd = [path.join(dir, binaryName)]
|
||||
}
|
||||
Log.Default.info("tui", {
|
||||
cmd,
|
||||
|
||||
@@ -10,6 +10,7 @@ export namespace Command {
|
||||
agent: z.string().optional(),
|
||||
model: z.string().optional(),
|
||||
template: z.string(),
|
||||
subtask: z.boolean().optional(),
|
||||
})
|
||||
.openapi({
|
||||
ref: "Command",
|
||||
@@ -28,6 +29,7 @@ export namespace Command {
|
||||
model: command.model,
|
||||
description: command.description,
|
||||
template: command.template,
|
||||
subtask: command.subtask,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -244,6 +244,7 @@ export namespace Config {
|
||||
description: z.string().optional(),
|
||||
agent: z.string().optional(),
|
||||
model: z.string().optional(),
|
||||
subtask: z.boolean().optional(),
|
||||
})
|
||||
export type Command = z.infer<typeof Command>
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ export namespace Flag {
|
||||
export const OPENCODE_DISABLE_DEFAULT_PLUGINS = truthy("OPENCODE_DISABLE_DEFAULT_PLUGINS")
|
||||
export const OPENCODE_DISABLE_LSP_DOWNLOAD = truthy("OPENCODE_DISABLE_LSP_DOWNLOAD")
|
||||
export const OPENCODE_ENABLE_EXPERIMENTAL_MODELS = truthy("OPENCODE_ENABLE_EXPERIMENTAL_MODELS")
|
||||
export const OPENCODE_DISABLE_AUTOCOMPACT = truthy("OPENCODE_DISABLE_AUTOCOMPACT")
|
||||
|
||||
function truthy(key: string) {
|
||||
const value = process.env[key]?.toLowerCase()
|
||||
|
||||
@@ -10,6 +10,7 @@ import { Bus } from "../bus"
|
||||
import z from "zod"
|
||||
import type { ModelsDev } from "../provider/models"
|
||||
import { SessionPrompt } from "./prompt"
|
||||
import { Flag } from "../flag/flag"
|
||||
|
||||
export namespace SessionCompaction {
|
||||
export const Event = {
|
||||
@@ -22,9 +23,12 @@ export namespace SessionCompaction {
|
||||
}
|
||||
|
||||
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 usable = input.model.limit.context - output
|
||||
const usable = context - output
|
||||
return count > usable
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import { MCP } from "../mcp"
|
||||
import { LSP } from "../lsp"
|
||||
import { ReadTool } from "../tool/read"
|
||||
import { ListTool } from "../tool/ls"
|
||||
import { TaskTool } from "../tool/task"
|
||||
import { FileTime } from "../file/time"
|
||||
import { Permission } from "../permission"
|
||||
import { Snapshot } from "../snapshot"
|
||||
@@ -278,7 +279,11 @@ export namespace SessionPrompt {
|
||||
content: x,
|
||||
}),
|
||||
),
|
||||
...MessageV2.toModelMessage(msgs.filter((m) => !(m.info.role === "assistant" && m.info.error))),
|
||||
...MessageV2.toModelMessage(
|
||||
msgs.filter(
|
||||
(m) => !(m.info.role === "assistant" && m.info.error && !MessageV2.AbortedError.isInstance(m.info.error)),
|
||||
),
|
||||
),
|
||||
],
|
||||
tools: model.info.tool_call === false ? undefined : tools,
|
||||
model: wrapLanguageModel({
|
||||
@@ -1311,7 +1316,7 @@ export namespace SessionPrompt {
|
||||
export async function command(input: CommandInput) {
|
||||
log.info("command", input)
|
||||
const command = await Command.get(input.command)
|
||||
const agent = command.agent ?? input.agent ?? "build"
|
||||
const agentName = command.agent ?? input.agent ?? "build"
|
||||
|
||||
let template = command.template.replace("$ARGUMENTS", input.arguments)
|
||||
|
||||
@@ -1381,22 +1386,134 @@ export namespace SessionPrompt {
|
||||
return Provider.parseModel(command.model)
|
||||
}
|
||||
if (command.agent) {
|
||||
const agent = await Agent.get(command.agent)
|
||||
if (agent.model) {
|
||||
return agent.model
|
||||
const cmdAgent = await Agent.get(command.agent)
|
||||
if (cmdAgent.model) {
|
||||
return cmdAgent.model
|
||||
}
|
||||
}
|
||||
if (input.model) {
|
||||
return Provider.parseModel(input.model)
|
||||
}
|
||||
return undefined
|
||||
return await Provider.defaultModel()
|
||||
})()
|
||||
|
||||
const agent = await Agent.get(agentName)
|
||||
if (agent.mode === "subagent" || command.subtask) {
|
||||
using abort = lock(input.sessionID)
|
||||
|
||||
const userMsg: MessageV2.User = {
|
||||
id: Identifier.ascending("message"),
|
||||
sessionID: input.sessionID,
|
||||
time: {
|
||||
created: Date.now(),
|
||||
},
|
||||
role: "user",
|
||||
}
|
||||
await Session.updateMessage(userMsg)
|
||||
const userPart: MessageV2.Part = {
|
||||
type: "text",
|
||||
id: Identifier.ascending("part"),
|
||||
messageID: userMsg.id,
|
||||
sessionID: input.sessionID,
|
||||
text: "The following tool was executed by the user",
|
||||
synthetic: true,
|
||||
}
|
||||
await Session.updatePart(userPart)
|
||||
|
||||
const assistantMsg: MessageV2.Assistant = {
|
||||
id: Identifier.ascending("message"),
|
||||
sessionID: input.sessionID,
|
||||
system: [],
|
||||
mode: agentName,
|
||||
cost: 0,
|
||||
path: {
|
||||
cwd: Instance.directory,
|
||||
root: Instance.worktree,
|
||||
},
|
||||
time: {
|
||||
created: Date.now(),
|
||||
},
|
||||
role: "assistant",
|
||||
tokens: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
reasoning: 0,
|
||||
cache: { read: 0, write: 0 },
|
||||
},
|
||||
modelID: model.modelID,
|
||||
providerID: model.providerID,
|
||||
}
|
||||
await Session.updateMessage(assistantMsg)
|
||||
|
||||
const args = {
|
||||
description: "Consulting " + agent.name,
|
||||
subagent_type: agent.name,
|
||||
prompt: template,
|
||||
}
|
||||
const toolPart: MessageV2.ToolPart = {
|
||||
type: "tool",
|
||||
id: Identifier.ascending("part"),
|
||||
messageID: assistantMsg.id,
|
||||
sessionID: input.sessionID,
|
||||
tool: "task",
|
||||
callID: ulid(),
|
||||
state: {
|
||||
status: "running",
|
||||
time: {
|
||||
start: Date.now(),
|
||||
},
|
||||
input: {
|
||||
description: args.description,
|
||||
subagent_type: args.subagent_type,
|
||||
// truncate prompt to preserve context
|
||||
prompt: args.prompt.length > 100 ? args.prompt.substring(0, 97) + "..." : args.prompt,
|
||||
},
|
||||
},
|
||||
}
|
||||
await Session.updatePart(toolPart)
|
||||
|
||||
const result = await TaskTool.init().then((t) =>
|
||||
t.execute(args, {
|
||||
sessionID: input.sessionID,
|
||||
abort: abort.signal,
|
||||
agent: agent.name,
|
||||
messageID: assistantMsg.id,
|
||||
extra: {},
|
||||
metadata: async (metadata) => {
|
||||
if (toolPart.state.status === "running") {
|
||||
toolPart.state.metadata = metadata.metadata
|
||||
toolPart.state.title = metadata.title
|
||||
await Session.updatePart(toolPart)
|
||||
}
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
assistantMsg.time.completed = Date.now()
|
||||
await Session.updateMessage(assistantMsg)
|
||||
if (toolPart.state.status === "running") {
|
||||
toolPart.state = {
|
||||
status: "completed",
|
||||
time: {
|
||||
...toolPart.state.time,
|
||||
end: Date.now(),
|
||||
},
|
||||
input: toolPart.state.input,
|
||||
title: "",
|
||||
metadata: result.metadata,
|
||||
output: result.output,
|
||||
}
|
||||
await Session.updatePart(toolPart)
|
||||
}
|
||||
|
||||
return { info: assistantMsg, parts: [toolPart] }
|
||||
}
|
||||
|
||||
return prompt({
|
||||
sessionID: input.sessionID,
|
||||
messageID: input.messageID,
|
||||
model,
|
||||
agent,
|
||||
agent: agentName,
|
||||
parts,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "0.7.9",
|
||||
"version": "0.8.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/sdk",
|
||||
"version": "0.7.9",
|
||||
"version": "0.8.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit"
|
||||
|
||||
@@ -29,6 +29,9 @@ export type Event =
|
||||
| ({
|
||||
type: "message.part.removed"
|
||||
} & EventMessagePartRemoved)
|
||||
| ({
|
||||
type: "session.compacted"
|
||||
} & EventSessionCompacted)
|
||||
| ({
|
||||
type: "permission.updated"
|
||||
} & EventPermissionUpdated)
|
||||
@@ -38,21 +41,18 @@ export type Event =
|
||||
| ({
|
||||
type: "file.edited"
|
||||
} & EventFileEdited)
|
||||
| ({
|
||||
type: "session.idle"
|
||||
} & EventSessionIdle)
|
||||
| ({
|
||||
type: "session.updated"
|
||||
} & EventSessionUpdated)
|
||||
| ({
|
||||
type: "session.deleted"
|
||||
} & EventSessionDeleted)
|
||||
| ({
|
||||
type: "session.idle"
|
||||
} & EventSessionIdle)
|
||||
| ({
|
||||
type: "session.error"
|
||||
} & EventSessionError)
|
||||
| ({
|
||||
type: "session.compacted"
|
||||
} & EventSessionCompacted)
|
||||
| ({
|
||||
type: "server.connected"
|
||||
} & EventServerConnected)
|
||||
@@ -425,6 +425,13 @@ export type EventMessagePartRemoved = {
|
||||
}
|
||||
}
|
||||
|
||||
export type EventSessionCompacted = {
|
||||
type: "session.compacted"
|
||||
properties: {
|
||||
sessionID: string
|
||||
}
|
||||
}
|
||||
|
||||
export type EventPermissionUpdated = {
|
||||
type: "permission.updated"
|
||||
properties: Permission
|
||||
@@ -462,6 +469,13 @@ export type EventFileEdited = {
|
||||
}
|
||||
}
|
||||
|
||||
export type EventSessionIdle = {
|
||||
type: "session.idle"
|
||||
properties: {
|
||||
sessionID: string
|
||||
}
|
||||
}
|
||||
|
||||
export type EventSessionUpdated = {
|
||||
type: "session.updated"
|
||||
properties: {
|
||||
@@ -499,13 +513,6 @@ export type EventSessionDeleted = {
|
||||
}
|
||||
}
|
||||
|
||||
export type EventSessionIdle = {
|
||||
type: "session.idle"
|
||||
properties: {
|
||||
sessionID: string
|
||||
}
|
||||
}
|
||||
|
||||
export type EventSessionError = {
|
||||
type: "session.error"
|
||||
properties: {
|
||||
@@ -526,13 +533,6 @@ export type EventSessionError = {
|
||||
}
|
||||
}
|
||||
|
||||
export type EventSessionCompacted = {
|
||||
type: "session.compacted"
|
||||
properties: {
|
||||
sessionID: string
|
||||
}
|
||||
}
|
||||
|
||||
export type EventServerConnected = {
|
||||
type: "server.connected"
|
||||
properties: {
|
||||
@@ -571,6 +571,7 @@ export type Config = {
|
||||
description?: string
|
||||
agent?: string
|
||||
model?: string
|
||||
subtask?: boolean
|
||||
}
|
||||
}
|
||||
plugin?: Array<string>
|
||||
@@ -1156,6 +1157,7 @@ export type Command = {
|
||||
agent?: string
|
||||
model?: string
|
||||
template: string
|
||||
subtask?: boolean
|
||||
}
|
||||
|
||||
export type Symbol = {
|
||||
|
||||
@@ -899,7 +899,6 @@ func (m *messagesComponent) renderHeader() string {
|
||||
}
|
||||
tokens = (usage.Input +
|
||||
usage.Cache.Write +
|
||||
usage.Cache.Read +
|
||||
usage.Output +
|
||||
usage.Reasoning)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@opencode/web",
|
||||
"type": "module",
|
||||
"version": "0.7.9",
|
||||
"version": "0.8.0",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"dev:remote": "sst shell --stage=dev --target=Web astro dev",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "opencode",
|
||||
"displayName": "opencode",
|
||||
"description": "opencode for VS Code",
|
||||
"version": "0.7.9",
|
||||
"version": "0.8.0",
|
||||
"publisher": "sst-dev",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
Reference in New Issue
Block a user