@@ -29,7 +29,7 @@ import { MCP } from "@/mcp"
|
||||
import { Todo } from "@/session/todo"
|
||||
import { z } from "zod"
|
||||
import { LoadAPIKeyError } from "ai"
|
||||
import type { OpencodeClient } from "@opencode-ai/sdk"
|
||||
import type { OpencodeClient } from "@opencode-ai/sdk/v2"
|
||||
|
||||
export namespace ACP {
|
||||
const log = Log.create({ service: "acp-agent" })
|
||||
@@ -68,7 +68,7 @@ export namespace ACP {
|
||||
{ optionId: "always", kind: "allow_always", name: "Always allow" },
|
||||
{ optionId: "reject", kind: "reject_once", name: "Reject" },
|
||||
]
|
||||
this.config.sdk.event.subscribe({ query: { directory } }).then(async (events) => {
|
||||
this.config.sdk.event.subscribe({ directory }).then(async (events) => {
|
||||
for await (const event of events.stream) {
|
||||
switch (event.type) {
|
||||
case "permission.updated":
|
||||
@@ -93,32 +93,29 @@ export namespace ACP {
|
||||
permissionID: permission.id,
|
||||
sessionID: permission.sessionID,
|
||||
})
|
||||
await this.config.sdk.postSessionIdPermissionsPermissionId({
|
||||
path: { id: permission.sessionID, permissionID: permission.id },
|
||||
body: {
|
||||
response: "reject",
|
||||
},
|
||||
query: { directory },
|
||||
await this.config.sdk.permission.respond({
|
||||
sessionID: permission.sessionID,
|
||||
permissionID: permission.id,
|
||||
response: "reject",
|
||||
directory,
|
||||
})
|
||||
return
|
||||
})
|
||||
if (!res) return
|
||||
if (res.outcome.outcome !== "selected") {
|
||||
await this.config.sdk.postSessionIdPermissionsPermissionId({
|
||||
path: { id: permission.sessionID, permissionID: permission.id },
|
||||
body: {
|
||||
response: "reject",
|
||||
},
|
||||
query: { directory },
|
||||
await this.config.sdk.permission.respond({
|
||||
sessionID: permission.sessionID,
|
||||
permissionID: permission.id,
|
||||
response: "reject",
|
||||
directory,
|
||||
})
|
||||
return
|
||||
}
|
||||
await this.config.sdk.postSessionIdPermissionsPermissionId({
|
||||
path: { id: permission.sessionID, permissionID: permission.id },
|
||||
body: {
|
||||
response: res.outcome.optionId as "once" | "always" | "reject",
|
||||
},
|
||||
query: { directory },
|
||||
await this.config.sdk.permission.respond({
|
||||
sessionID: permission.sessionID,
|
||||
permissionID: permission.id,
|
||||
response: res.outcome.optionId as "once" | "always" | "reject",
|
||||
directory,
|
||||
})
|
||||
} catch (err) {
|
||||
log.error("unexpected error when handling permission", { error: err })
|
||||
@@ -133,14 +130,14 @@ export namespace ACP {
|
||||
const { part } = props
|
||||
|
||||
const message = await this.config.sdk.session
|
||||
.message({
|
||||
throwOnError: true,
|
||||
path: {
|
||||
id: part.sessionID,
|
||||
.message(
|
||||
{
|
||||
sessionID: part.sessionID,
|
||||
messageID: part.messageID,
|
||||
directory,
|
||||
},
|
||||
query: { directory },
|
||||
})
|
||||
{ throwOnError: true },
|
||||
)
|
||||
.then((x) => x.data)
|
||||
.catch((err) => {
|
||||
log.error("unexpected error when fetching message", { error: err })
|
||||
@@ -420,9 +417,7 @@ export namespace ACP {
|
||||
const model = await defaultModel(this.config, directory)
|
||||
const sessionId = params.sessionId
|
||||
|
||||
const providers = await this.sdk.config
|
||||
.providers({ throwOnError: true, query: { directory } })
|
||||
.then((x) => x.data.providers)
|
||||
const providers = await this.sdk.config.providers({ directory }).then((x) => x.data!.providers)
|
||||
const entries = providers.sort((a, b) => {
|
||||
const nameA = a.name.toLowerCase()
|
||||
const nameB = b.name.toLowerCase()
|
||||
@@ -439,22 +434,22 @@ export namespace ACP {
|
||||
})
|
||||
|
||||
const agents = await this.config.sdk.app
|
||||
.agents({
|
||||
throwOnError: true,
|
||||
query: {
|
||||
.agents(
|
||||
{
|
||||
directory,
|
||||
},
|
||||
})
|
||||
.then((resp) => resp.data)
|
||||
{ throwOnError: true },
|
||||
)
|
||||
.then((resp) => resp.data!)
|
||||
|
||||
const commands = await this.config.sdk.command
|
||||
.list({
|
||||
throwOnError: true,
|
||||
query: {
|
||||
.list(
|
||||
{
|
||||
directory,
|
||||
},
|
||||
})
|
||||
.then((resp) => resp.data)
|
||||
{ throwOnError: true },
|
||||
)
|
||||
.then((resp) => resp.data!)
|
||||
|
||||
const availableCommands = commands.map((command) => ({
|
||||
name: command.name,
|
||||
@@ -503,14 +498,14 @@ export namespace ACP {
|
||||
await Promise.all(
|
||||
Object.entries(mcpServers).map(async ([key, mcp]) => {
|
||||
await this.sdk.mcp
|
||||
.add({
|
||||
throwOnError: true,
|
||||
query: { directory },
|
||||
body: {
|
||||
.add(
|
||||
{
|
||||
directory,
|
||||
name: key,
|
||||
config: mcp,
|
||||
},
|
||||
})
|
||||
{ throwOnError: true },
|
||||
)
|
||||
.catch((error) => {
|
||||
log.error("failed to add mcp server", { name: key, error })
|
||||
})
|
||||
@@ -559,7 +554,7 @@ export namespace ACP {
|
||||
async setSessionMode(params: SetSessionModeRequest): Promise<SetSessionModeResponse | void> {
|
||||
this.sessionManager.get(params.sessionId)
|
||||
await this.config.sdk.app
|
||||
.agents({ throwOnError: true })
|
||||
.agents({}, { throwOnError: true })
|
||||
.then((x) => x.data)
|
||||
.then((agent) => {
|
||||
if (!agent) throw new Error(`Agent not found: ${params.modeId}`)
|
||||
@@ -651,50 +646,42 @@ export namespace ACP {
|
||||
|
||||
if (!cmd) {
|
||||
await this.sdk.session.prompt({
|
||||
path: { id: sessionID },
|
||||
body: {
|
||||
model: {
|
||||
providerID: model.providerID,
|
||||
modelID: model.modelID,
|
||||
},
|
||||
parts,
|
||||
agent,
|
||||
},
|
||||
query: {
|
||||
directory,
|
||||
sessionID,
|
||||
model: {
|
||||
providerID: model.providerID,
|
||||
modelID: model.modelID,
|
||||
},
|
||||
parts,
|
||||
agent,
|
||||
directory,
|
||||
})
|
||||
return done
|
||||
}
|
||||
|
||||
const command = await this.config.sdk.command
|
||||
.list({ throwOnError: true, query: { directory } })
|
||||
.then((x) => x.data.find((c) => c.name === cmd.name))
|
||||
.list({ directory }, { throwOnError: true })
|
||||
.then((x) => x.data!.find((c) => c.name === cmd.name))
|
||||
if (command) {
|
||||
await this.sdk.session.command({
|
||||
path: { id: sessionID },
|
||||
body: {
|
||||
command: command.name,
|
||||
arguments: cmd.args,
|
||||
model: model.providerID + "/" + model.modelID,
|
||||
agent,
|
||||
},
|
||||
query: {
|
||||
directory,
|
||||
},
|
||||
sessionID,
|
||||
command: command.name,
|
||||
arguments: cmd.args,
|
||||
model: model.providerID + "/" + model.modelID,
|
||||
agent,
|
||||
directory,
|
||||
})
|
||||
return done
|
||||
}
|
||||
|
||||
switch (cmd.name) {
|
||||
case "compact":
|
||||
await this.config.sdk.session.summarize({
|
||||
path: { id: sessionID },
|
||||
throwOnError: true,
|
||||
query: {
|
||||
await this.config.sdk.session.summarize(
|
||||
{
|
||||
sessionID,
|
||||
directory,
|
||||
},
|
||||
})
|
||||
{ throwOnError: true },
|
||||
)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -703,13 +690,13 @@ export namespace ACP {
|
||||
|
||||
async cancel(params: CancelNotification) {
|
||||
const session = this.sessionManager.get(params.sessionId)
|
||||
await this.config.sdk.session.abort({
|
||||
path: { id: params.sessionId },
|
||||
throwOnError: true,
|
||||
query: {
|
||||
await this.config.sdk.session.abort(
|
||||
{
|
||||
sessionID: params.sessionId,
|
||||
directory: session.cwd,
|
||||
},
|
||||
})
|
||||
{ throwOnError: true },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -766,10 +753,10 @@ export namespace ACP {
|
||||
if (configured) return configured
|
||||
|
||||
const model = await sdk.config
|
||||
.get({ throwOnError: true, query: { directory: cwd } })
|
||||
.get({ directory: cwd }, { throwOnError: true })
|
||||
.then((resp) => {
|
||||
const cfg = resp.data
|
||||
if (!cfg.model) return undefined
|
||||
if (!cfg || !cfg.model) return undefined
|
||||
const parsed = Provider.parseModel(cfg.model)
|
||||
return {
|
||||
providerID: parsed.providerID,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { RequestError, type McpServer } from "@agentclientprotocol/sdk"
|
||||
import type { ACPSessionState } from "./types"
|
||||
import { Log } from "@/util/log"
|
||||
import type { OpencodeClient } from "@opencode-ai/sdk"
|
||||
import type { OpencodeClient } from "@opencode-ai/sdk/v2"
|
||||
|
||||
const log = Log.create({ service: "acp-session-manager" })
|
||||
|
||||
@@ -15,16 +15,14 @@ export class ACPSessionManager {
|
||||
|
||||
async create(cwd: string, mcpServers: McpServer[], model?: ACPSessionState["model"]): Promise<ACPSessionState> {
|
||||
const session = await this.sdk.session
|
||||
.create({
|
||||
body: {
|
||||
.create(
|
||||
{
|
||||
title: `ACP Session ${crypto.randomUUID()}`,
|
||||
},
|
||||
query: {
|
||||
directory: cwd,
|
||||
},
|
||||
throwOnError: true,
|
||||
})
|
||||
.then((x) => x.data)
|
||||
{ throwOnError: true },
|
||||
)
|
||||
.then((x) => x.data!)
|
||||
|
||||
const sessionId = session.id
|
||||
const resolvedModel = model
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { McpServer } from "@agentclientprotocol/sdk"
|
||||
import type { OpencodeClient } from "@opencode-ai/sdk"
|
||||
import type { OpencodeClient } from "@opencode-ai/sdk/v2"
|
||||
|
||||
export interface ACPSessionState {
|
||||
id: string
|
||||
|
||||
@@ -4,7 +4,7 @@ import { cmd } from "./cmd"
|
||||
import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"
|
||||
import { ACP } from "@/acp/agent"
|
||||
import { Server } from "@/server/server"
|
||||
import { createOpencodeClient } from "@opencode-ai/sdk"
|
||||
import { createOpencodeClient } from "@opencode-ai/sdk/v2"
|
||||
|
||||
const log = Log.create({ service: "acp-command" })
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { bootstrap } from "../bootstrap"
|
||||
import { Command } from "../../command"
|
||||
import { EOL } from "os"
|
||||
import { select } from "@clack/prompts"
|
||||
import { createOpencodeClient, type OpencodeClient } from "@opencode-ai/sdk"
|
||||
import { createOpencodeClient, type OpencodeClient } from "@opencode-ai/sdk/v2"
|
||||
import { Server } from "../../server/server"
|
||||
import { Provider } from "../../provider/provider"
|
||||
|
||||
@@ -212,9 +212,10 @@ export const RunCommand = cmd({
|
||||
initialValue: "once",
|
||||
}).catch(() => "reject")
|
||||
const response = (result.toString().includes("cancel") ? "reject" : result) as "once" | "always" | "reject"
|
||||
await sdk.postSessionIdPermissionsPermissionId({
|
||||
path: { id: sessionID, permissionID: permission.id },
|
||||
body: { response },
|
||||
await sdk.permission.respond({
|
||||
sessionID,
|
||||
permissionID: permission.id,
|
||||
response,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -222,23 +223,19 @@ export const RunCommand = cmd({
|
||||
|
||||
if (args.command) {
|
||||
await sdk.session.command({
|
||||
path: { id: sessionID },
|
||||
body: {
|
||||
agent: args.agent || "build",
|
||||
model: args.model,
|
||||
command: args.command,
|
||||
arguments: message,
|
||||
},
|
||||
sessionID,
|
||||
agent: args.agent || "build",
|
||||
model: args.model,
|
||||
command: args.command,
|
||||
arguments: message,
|
||||
})
|
||||
} else {
|
||||
const modelParam = args.model ? Provider.parseModel(args.model) : undefined
|
||||
await sdk.session.prompt({
|
||||
path: { id: sessionID },
|
||||
body: {
|
||||
agent: args.agent || "build",
|
||||
model: modelParam,
|
||||
parts: [...fileParts, { type: "text", text: message }],
|
||||
},
|
||||
sessionID,
|
||||
agent: args.agent || "build",
|
||||
model: modelParam,
|
||||
parts: [...fileParts, { type: "text", text: message }],
|
||||
})
|
||||
}
|
||||
|
||||
@@ -263,7 +260,7 @@ export const RunCommand = cmd({
|
||||
: args.title
|
||||
: undefined
|
||||
|
||||
const result = await sdk.session.create({ body: title ? { title } : {} })
|
||||
const result = await sdk.session.create(title ? { title } : {})
|
||||
return result.data?.id
|
||||
})()
|
||||
|
||||
@@ -274,7 +271,7 @@ export const RunCommand = cmd({
|
||||
|
||||
const cfgResult = await sdk.config.get()
|
||||
if (cfgResult.data && (cfgResult.data.share === "auto" || Flag.OPENCODE_AUTO_SHARE || args.share)) {
|
||||
const shareResult = await sdk.session.share({ path: { id: sessionID } }).catch((error) => {
|
||||
const shareResult = await sdk.session.share({ sessionID }).catch((error) => {
|
||||
if (error instanceof Error && error.message.includes("disabled")) {
|
||||
UI.println(UI.Style.TEXT_DANGER_BOLD + "! " + error.message)
|
||||
}
|
||||
@@ -315,7 +312,7 @@ export const RunCommand = cmd({
|
||||
: args.title
|
||||
: undefined
|
||||
|
||||
const result = await sdk.session.create({ body: title ? { title } : {} })
|
||||
const result = await sdk.session.create(title ? { title } : {})
|
||||
return result.data?.id
|
||||
})()
|
||||
|
||||
@@ -327,7 +324,7 @@ export const RunCommand = cmd({
|
||||
|
||||
const cfgResult = await sdk.config.get()
|
||||
if (cfgResult.data && (cfgResult.data.share === "auto" || Flag.OPENCODE_AUTO_SHARE || args.share)) {
|
||||
const shareResult = await sdk.session.share({ path: { id: sessionID } }).catch((error) => {
|
||||
const shareResult = await sdk.session.share({ sessionID }).catch((error) => {
|
||||
if (error instanceof Error && error.message.includes("disabled")) {
|
||||
UI.println(UI.Style.TEXT_DANGER_BOLD + "! " + error.message)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from "solid-js"
|
||||
import { useKeyboard } from "@opentui/solid"
|
||||
import { useKeybind } from "@tui/context/keybind"
|
||||
import type { KeybindsConfig } from "@opencode-ai/sdk"
|
||||
import type { KeybindsConfig } from "@opencode-ai/sdk/v2"
|
||||
|
||||
type Context = ReturnType<typeof init>
|
||||
const ctx = createContext<Context>()
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useSDK } from "../context/sdk"
|
||||
import { DialogPrompt } from "../ui/dialog-prompt"
|
||||
import { useTheme } from "../context/theme"
|
||||
import { TextAttributes } from "@opentui/core"
|
||||
import type { ProviderAuthAuthorization } from "@opencode-ai/sdk"
|
||||
import type { ProviderAuthAuthorization } from "@opencode-ai/sdk/v2"
|
||||
import { DialogModel } from "./dialog-model"
|
||||
|
||||
const PROVIDER_PRIORITY: Record<string, number> = {
|
||||
@@ -64,12 +64,8 @@ export function createDialogProviderOptions() {
|
||||
const method = methods[index]
|
||||
if (method.type === "oauth") {
|
||||
const result = await sdk.client.provider.oauth.authorize({
|
||||
path: {
|
||||
id: provider.id,
|
||||
},
|
||||
body: {
|
||||
method: index,
|
||||
},
|
||||
providerID: provider.id,
|
||||
method: index,
|
||||
})
|
||||
if (result.data?.method === "code") {
|
||||
dialog.replace(() => (
|
||||
@@ -111,12 +107,8 @@ function AutoMethod(props: AutoMethodProps) {
|
||||
|
||||
onMount(async () => {
|
||||
const result = await sdk.client.provider.oauth.callback({
|
||||
path: {
|
||||
id: props.providerID,
|
||||
},
|
||||
body: {
|
||||
method: props.index,
|
||||
},
|
||||
providerID: props.providerID,
|
||||
method: props.index,
|
||||
})
|
||||
if (result.error) {
|
||||
dialog.clear()
|
||||
@@ -161,13 +153,9 @@ function CodeMethod(props: CodeMethodProps) {
|
||||
placeholder="Authorization code"
|
||||
onConfirm={async (value) => {
|
||||
const { error } = await sdk.client.provider.oauth.callback({
|
||||
path: {
|
||||
id: props.providerID,
|
||||
},
|
||||
body: {
|
||||
method: props.index,
|
||||
code: value,
|
||||
},
|
||||
providerID: props.providerID,
|
||||
method: props.index,
|
||||
code: value,
|
||||
})
|
||||
if (!error) {
|
||||
await sdk.client.instance.dispose()
|
||||
@@ -219,10 +207,8 @@ function ApiMethod(props: ApiMethodProps) {
|
||||
onConfirm={async (value) => {
|
||||
if (!value) return
|
||||
sdk.client.auth.set({
|
||||
path: {
|
||||
id: props.providerID,
|
||||
},
|
||||
body: {
|
||||
providerID: props.providerID,
|
||||
auth: {
|
||||
type: "api",
|
||||
key: value,
|
||||
},
|
||||
|
||||
@@ -74,9 +74,7 @@ export function DialogSessionList() {
|
||||
onTrigger: async (option) => {
|
||||
if (toDelete() === option.value) {
|
||||
sdk.client.session.delete({
|
||||
path: {
|
||||
id: option.value,
|
||||
},
|
||||
sessionID: option.value,
|
||||
})
|
||||
setToDelete(undefined)
|
||||
// dialog.clear()
|
||||
|
||||
@@ -20,12 +20,8 @@ export function DialogSessionRename(props: DialogSessionRenameProps) {
|
||||
value={session()?.title}
|
||||
onConfirm={(value) => {
|
||||
sdk.client.session.update({
|
||||
path: {
|
||||
id: props.session,
|
||||
},
|
||||
body: {
|
||||
title: value,
|
||||
},
|
||||
sessionID: props.session,
|
||||
title: value,
|
||||
})
|
||||
dialog.clear()
|
||||
}}
|
||||
|
||||
@@ -16,9 +16,7 @@ export function DialogTag(props: { onSelect?: (value: string) => void }) {
|
||||
() => [store.filter],
|
||||
async () => {
|
||||
const result = await sdk.client.find.files({
|
||||
query: {
|
||||
query: store.filter,
|
||||
},
|
||||
query: store.filter,
|
||||
})
|
||||
if (result.error) return []
|
||||
const sliced = (result.data ?? []).slice(0, 5)
|
||||
|
||||
@@ -140,9 +140,7 @@ export function Autocomplete(props: {
|
||||
|
||||
// Get files from SDK
|
||||
const result = await sdk.client.find.files({
|
||||
query: {
|
||||
query: query ?? "",
|
||||
},
|
||||
query: query ?? "",
|
||||
})
|
||||
|
||||
const options: AutocompleteOption[] = []
|
||||
|
||||
@@ -5,7 +5,7 @@ import { createStore, produce } from "solid-js/store"
|
||||
import { clone } from "remeda"
|
||||
import { createSimpleContext } from "../../context/helper"
|
||||
import { appendFile, writeFile } from "fs/promises"
|
||||
import type { AgentPart, FilePart, TextPart } from "@opencode-ai/sdk"
|
||||
import type { AgentPart, FilePart, TextPart } from "@opencode-ai/sdk/v2"
|
||||
|
||||
export type PromptInfo = {
|
||||
input: string
|
||||
|
||||
@@ -17,7 +17,7 @@ import { useRenderer } from "@opentui/solid"
|
||||
import { Editor } from "@tui/util/editor"
|
||||
import { useExit } from "../../context/exit"
|
||||
import { Clipboard } from "../../util/clipboard"
|
||||
import type { FilePart } from "@opencode-ai/sdk"
|
||||
import type { FilePart } from "@opencode-ai/sdk/v2"
|
||||
import { TuiEvent } from "../../event"
|
||||
import { iife } from "@/util/iife"
|
||||
import { Locale } from "@/util/locale"
|
||||
@@ -170,9 +170,7 @@ export function Prompt(props: PromptProps) {
|
||||
|
||||
if (store.interrupt >= 2) {
|
||||
sdk.client.session.abort({
|
||||
path: {
|
||||
id: props.sessionID,
|
||||
},
|
||||
sessionID: props.sessionID,
|
||||
})
|
||||
setStore("interrupt", 0)
|
||||
}
|
||||
@@ -447,17 +445,13 @@ export function Prompt(props: PromptProps) {
|
||||
|
||||
if (store.mode === "shell") {
|
||||
sdk.client.session.shell({
|
||||
path: {
|
||||
id: sessionID,
|
||||
},
|
||||
body: {
|
||||
agent: local.agent.current().name,
|
||||
model: {
|
||||
providerID: selectedModel.providerID,
|
||||
modelID: selectedModel.modelID,
|
||||
},
|
||||
command: inputText,
|
||||
sessionID,
|
||||
agent: local.agent.current().name,
|
||||
model: {
|
||||
providerID: selectedModel.providerID,
|
||||
modelID: selectedModel.modelID,
|
||||
},
|
||||
command: inputText,
|
||||
})
|
||||
setStore("mode", "normal")
|
||||
} else if (
|
||||
@@ -470,39 +464,31 @@ export function Prompt(props: PromptProps) {
|
||||
) {
|
||||
let [command, ...args] = inputText.split(" ")
|
||||
sdk.client.session.command({
|
||||
path: {
|
||||
id: sessionID,
|
||||
},
|
||||
body: {
|
||||
command: command.slice(1),
|
||||
arguments: args.join(" "),
|
||||
agent: local.agent.current().name,
|
||||
model: `${selectedModel.providerID}/${selectedModel.modelID}`,
|
||||
messageID,
|
||||
},
|
||||
sessionID,
|
||||
command: command.slice(1),
|
||||
arguments: args.join(" "),
|
||||
agent: local.agent.current().name,
|
||||
model: `${selectedModel.providerID}/${selectedModel.modelID}`,
|
||||
messageID,
|
||||
})
|
||||
} else {
|
||||
sdk.client.session.prompt({
|
||||
path: {
|
||||
id: sessionID,
|
||||
},
|
||||
body: {
|
||||
...selectedModel,
|
||||
messageID,
|
||||
agent: local.agent.current().name,
|
||||
model: selectedModel,
|
||||
parts: [
|
||||
{
|
||||
id: Identifier.ascending("part"),
|
||||
type: "text",
|
||||
text: inputText,
|
||||
},
|
||||
...nonTextParts.map((x) => ({
|
||||
id: Identifier.ascending("part"),
|
||||
...x,
|
||||
})),
|
||||
],
|
||||
},
|
||||
sessionID,
|
||||
...selectedModel,
|
||||
messageID,
|
||||
agent: local.agent.current().name,
|
||||
model: selectedModel,
|
||||
parts: [
|
||||
{
|
||||
id: Identifier.ascending("part"),
|
||||
type: "text",
|
||||
text: inputText,
|
||||
},
|
||||
...nonTextParts.map((x) => ({
|
||||
id: Identifier.ascending("part"),
|
||||
...x,
|
||||
})),
|
||||
],
|
||||
})
|
||||
}
|
||||
history.append(store.prompt)
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createMemo } from "solid-js"
|
||||
import { useSync } from "@tui/context/sync"
|
||||
import { Keybind } from "@/util/keybind"
|
||||
import { pipe, mapValues } from "remeda"
|
||||
import type { KeybindsConfig } from "@opencode-ai/sdk"
|
||||
import type { KeybindsConfig } from "@opencode-ai/sdk/v2"
|
||||
import type { ParsedKey, Renderable } from "@opentui/core"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { useKeyboard, useRenderer } from "@opentui/solid"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createOpencodeClient, type Event } from "@opencode-ai/sdk"
|
||||
import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2"
|
||||
import { createSimpleContext } from "./helper"
|
||||
import { createGlobalEmitter } from "@solid-primitives/event-bus"
|
||||
import { batch, onCleanup, onMount } from "solid-js"
|
||||
@@ -20,9 +20,12 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
||||
onMount(async () => {
|
||||
while (true) {
|
||||
if (abort.signal.aborted) break
|
||||
const events = await sdk.event.subscribe({
|
||||
signal: abort.signal,
|
||||
})
|
||||
const events = await sdk.event.subscribe(
|
||||
{},
|
||||
{
|
||||
signal: abort.signal,
|
||||
},
|
||||
)
|
||||
let queue: Event[] = []
|
||||
let timer: Timer | undefined
|
||||
let last = 0
|
||||
|
||||
@@ -15,7 +15,7 @@ import type {
|
||||
ProviderListResponse,
|
||||
ProviderAuthMethod,
|
||||
VcsInfo,
|
||||
} from "@opencode-ai/sdk"
|
||||
} from "@opencode-ai/sdk/v2"
|
||||
import { createStore, produce, reconcile } from "solid-js/store"
|
||||
import { useSDK } from "@tui/context/sdk"
|
||||
import { Binary } from "@opencode-ai/util/binary"
|
||||
@@ -255,19 +255,19 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
async function bootstrap() {
|
||||
// blocking
|
||||
await Promise.all([
|
||||
sdk.client.config.providers({ throwOnError: true }).then((x) => {
|
||||
sdk.client.config.providers({}, { throwOnError: true }).then((x) => {
|
||||
batch(() => {
|
||||
setStore("provider", x.data!.providers)
|
||||
setStore("provider_default", x.data!.default)
|
||||
})
|
||||
}),
|
||||
sdk.client.provider.list({ throwOnError: true }).then((x) => {
|
||||
sdk.client.provider.list({}, { throwOnError: true }).then((x) => {
|
||||
batch(() => {
|
||||
setStore("provider_next", x.data!)
|
||||
})
|
||||
}),
|
||||
sdk.client.app.agents({ throwOnError: true }).then((x) => setStore("agent", x.data ?? [])),
|
||||
sdk.client.config.get({ throwOnError: true }).then((x) => setStore("config", x.data!)),
|
||||
sdk.client.app.agents({}, { throwOnError: true }).then((x) => setStore("agent", x.data ?? [])),
|
||||
sdk.client.config.get({}, { throwOnError: true }).then((x) => setStore("config", x.data!)),
|
||||
])
|
||||
.then(() => {
|
||||
if (store.status !== "complete") setStore("status", "partial")
|
||||
@@ -333,10 +333,10 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
async sync(sessionID: string) {
|
||||
if (fullSyncedSessions.has(sessionID)) return
|
||||
const [session, messages, todo, diff] = await Promise.all([
|
||||
sdk.client.session.get({ path: { id: sessionID }, throwOnError: true }),
|
||||
sdk.client.session.messages({ path: { id: sessionID }, query: { limit: 100 } }),
|
||||
sdk.client.session.todo({ path: { id: sessionID } }),
|
||||
sdk.client.session.diff({ path: { id: sessionID } }),
|
||||
sdk.client.session.get({ sessionID }, { throwOnError: true }),
|
||||
sdk.client.session.messages({ sessionID, limit: 100 }),
|
||||
sdk.client.session.todo({ sessionID }),
|
||||
sdk.client.session.diff({ sessionID }),
|
||||
])
|
||||
setStore(
|
||||
produce((draft) => {
|
||||
|
||||
@@ -29,12 +29,8 @@ export function DialogMessage(props: {
|
||||
if (!msg) return
|
||||
|
||||
sdk.client.session.revert({
|
||||
path: {
|
||||
id: props.sessionID,
|
||||
},
|
||||
body: {
|
||||
messageID: msg.id,
|
||||
},
|
||||
sessionID: props.sessionID,
|
||||
messageID: msg.id,
|
||||
})
|
||||
|
||||
if (props.setPrompt) {
|
||||
@@ -81,12 +77,8 @@ export function DialogMessage(props: {
|
||||
description: "create a new session",
|
||||
onSelect: async (dialog) => {
|
||||
const result = await sdk.client.session.fork({
|
||||
path: {
|
||||
id: props.sessionID,
|
||||
},
|
||||
body: {
|
||||
messageID: props.messageID,
|
||||
},
|
||||
sessionID: props.sessionID,
|
||||
messageID: props.messageID,
|
||||
})
|
||||
route.navigate({
|
||||
sessionID: result.data!.id,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createMemo, onMount } from "solid-js"
|
||||
import { useSync } from "@tui/context/sync"
|
||||
import { DialogSelect, type DialogSelectOption } from "@tui/ui/dialog-select"
|
||||
import type { TextPart } from "@opencode-ai/sdk"
|
||||
import type { TextPart } from "@opencode-ai/sdk/v2"
|
||||
import { Locale } from "@/util/locale"
|
||||
import { DialogMessage } from "./dialog-message"
|
||||
import { useDialog } from "../../ui/dialog"
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useSync } from "@tui/context/sync"
|
||||
import { pipe, sumBy } from "remeda"
|
||||
import { useTheme } from "@tui/context/theme"
|
||||
import { SplitBorder, EmptyBorder } from "@tui/component/border"
|
||||
import type { AssistantMessage, Session } from "@opencode-ai/sdk"
|
||||
import type { AssistantMessage, Session } from "@opencode-ai/sdk/v2"
|
||||
import { useDirectory } from "../../context/directory"
|
||||
import { useKeybind } from "../../context/keybind"
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
type ScrollAcceleration,
|
||||
} from "@opentui/core"
|
||||
import { Prompt, type PromptRef } from "@tui/component/prompt"
|
||||
import type { AssistantMessage, Part, ToolPart, UserMessage, TextPart, ReasoningPart } from "@opencode-ai/sdk"
|
||||
import type { AssistantMessage, Part, ToolPart, UserMessage, TextPart, ReasoningPart } from "@opencode-ai/sdk/v2"
|
||||
import { useLocal } from "@tui/context/local"
|
||||
import { Locale } from "@/util/locale"
|
||||
import type { Tool } from "@/tool/tool"
|
||||
@@ -150,7 +150,8 @@ export function Session() {
|
||||
.then(() => {
|
||||
if (scroll) scroll.scrollBy(100_000)
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((e) => {
|
||||
console.error(e)
|
||||
toast.show({
|
||||
message: `Session not found: ${route.sessionID}`,
|
||||
variant: "error",
|
||||
@@ -202,14 +203,10 @@ export function Session() {
|
||||
return
|
||||
})
|
||||
if (response) {
|
||||
sdk.client.postSessionIdPermissionsPermissionId({
|
||||
path: {
|
||||
permissionID: first.id,
|
||||
id: route.sessionID,
|
||||
},
|
||||
body: {
|
||||
response: response,
|
||||
},
|
||||
sdk.client.permission.respond({
|
||||
permissionID: first.id,
|
||||
sessionID: route.sessionID,
|
||||
response: response,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -254,9 +251,7 @@ export function Session() {
|
||||
onSelect: async (dialog: any) => {
|
||||
await sdk.client.session
|
||||
.share({
|
||||
path: {
|
||||
id: route.sessionID,
|
||||
},
|
||||
sessionID: route.sessionID,
|
||||
})
|
||||
.then((res) =>
|
||||
Clipboard.copy(res.data!.share!.url).catch(() =>
|
||||
@@ -314,13 +309,9 @@ export function Session() {
|
||||
return
|
||||
}
|
||||
sdk.client.session.summarize({
|
||||
path: {
|
||||
id: route.sessionID,
|
||||
},
|
||||
body: {
|
||||
modelID: selectedModel.modelID,
|
||||
providerID: selectedModel.providerID,
|
||||
},
|
||||
sessionID: route.sessionID,
|
||||
modelID: selectedModel.modelID,
|
||||
providerID: selectedModel.providerID,
|
||||
})
|
||||
dialog.clear()
|
||||
},
|
||||
@@ -333,9 +324,7 @@ export function Session() {
|
||||
category: "Session",
|
||||
onSelect: (dialog) => {
|
||||
sdk.client.session.unshare({
|
||||
path: {
|
||||
id: route.sessionID,
|
||||
},
|
||||
sessionID: route.sessionID,
|
||||
})
|
||||
dialog.clear()
|
||||
},
|
||||
@@ -347,18 +336,14 @@ export function Session() {
|
||||
category: "Session",
|
||||
onSelect: async (dialog) => {
|
||||
const status = sync.data.session_status[route.sessionID]
|
||||
if (status?.type !== "idle") await sdk.client.session.abort({ path: { id: route.sessionID } }).catch(() => {})
|
||||
if (status?.type !== "idle") await sdk.client.session.abort({ sessionID: route.sessionID }).catch(() => {})
|
||||
const revert = session().revert?.messageID
|
||||
const message = messages().findLast((x) => (!revert || x.id < revert) && x.role === "user")
|
||||
if (!message) return
|
||||
sdk.client.session
|
||||
.revert({
|
||||
path: {
|
||||
id: route.sessionID,
|
||||
},
|
||||
body: {
|
||||
messageID: message.id,
|
||||
},
|
||||
sessionID: route.sessionID,
|
||||
messageID: message.id,
|
||||
})
|
||||
.then(() => {
|
||||
toBottom()
|
||||
@@ -392,20 +377,14 @@ export function Session() {
|
||||
const message = messages().find((x) => x.role === "user" && x.id > messageID)
|
||||
if (!message) {
|
||||
sdk.client.session.unrevert({
|
||||
path: {
|
||||
id: route.sessionID,
|
||||
},
|
||||
sessionID: route.sessionID,
|
||||
})
|
||||
prompt.set({ input: "", parts: [] })
|
||||
return
|
||||
}
|
||||
sdk.client.session.revert({
|
||||
path: {
|
||||
id: route.sessionID,
|
||||
},
|
||||
body: {
|
||||
messageID: message.id,
|
||||
},
|
||||
sessionID: route.sessionID,
|
||||
messageID: message.id,
|
||||
})
|
||||
},
|
||||
},
|
||||
@@ -1066,7 +1045,7 @@ function UserMessage(props: {
|
||||
</box>
|
||||
</Show>
|
||||
<text fg={theme.textMuted}>
|
||||
{ctx.usernameVisible() ? `${sync.data.config.username ?? "You"}` : "You"}
|
||||
{ctx.usernameVisible() ? `${sync.data.config.username ?? "You "}` : "You "}
|
||||
<Show
|
||||
when={queued()}
|
||||
fallback={
|
||||
|
||||
@@ -4,7 +4,7 @@ import { createStore } from "solid-js/store"
|
||||
import { useTheme } from "../../context/theme"
|
||||
import { Locale } from "@/util/locale"
|
||||
import path from "path"
|
||||
import type { AssistantMessage } from "@opencode-ai/sdk"
|
||||
import type { AssistantMessage } from "@opencode-ai/sdk/v2"
|
||||
import { Global } from "@/global"
|
||||
import { Installation } from "@/installation"
|
||||
import { useKeybind } from "../../context/keybind"
|
||||
|
||||
@@ -61,10 +61,14 @@ export namespace Plugin {
|
||||
for (const hook of await state().then((x) => x.hooks)) {
|
||||
const fn = hook[name]
|
||||
if (!fn) continue
|
||||
// @ts-expect-error if you feel adventurous, please fix the typing, make sure to bump the try-counter if you
|
||||
// give up.
|
||||
// try-counter: 2
|
||||
await fn(input, output)
|
||||
try {
|
||||
// @ts-expect-error if you feel adventurous, please fix the typing, make sure to bump the try-counter if you
|
||||
// give up.
|
||||
// try-counter: 2
|
||||
await fn(input, output)
|
||||
} catch (e) {
|
||||
log.error("failed to trigger hook", { name, error: e })
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ export namespace Server {
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/pty/:id",
|
||||
"/pty/:ptyID",
|
||||
describeRoute({
|
||||
description: "Get PTY session info",
|
||||
operationId: "pty.get",
|
||||
@@ -225,9 +225,9 @@ export namespace Server {
|
||||
...errors(404),
|
||||
},
|
||||
}),
|
||||
validator("param", z.object({ id: z.string() })),
|
||||
validator("param", z.object({ ptyID: z.string() })),
|
||||
async (c) => {
|
||||
const info = Pty.get(c.req.valid("param").id)
|
||||
const info = Pty.get(c.req.valid("param").ptyID)
|
||||
if (!info) {
|
||||
throw new Storage.NotFoundError({ message: "Session not found" })
|
||||
}
|
||||
@@ -235,7 +235,7 @@ export namespace Server {
|
||||
},
|
||||
)
|
||||
.put(
|
||||
"/pty/:id",
|
||||
"/pty/:ptyID",
|
||||
describeRoute({
|
||||
description: "Update PTY session",
|
||||
operationId: "pty.update",
|
||||
@@ -251,15 +251,15 @@ export namespace Server {
|
||||
...errors(400),
|
||||
},
|
||||
}),
|
||||
validator("param", z.object({ id: z.string() })),
|
||||
validator("param", z.object({ ptyID: z.string() })),
|
||||
validator("json", Pty.UpdateInput),
|
||||
async (c) => {
|
||||
const info = await Pty.update(c.req.valid("param").id, c.req.valid("json"))
|
||||
const info = await Pty.update(c.req.valid("param").ptyID, c.req.valid("json"))
|
||||
return c.json(info)
|
||||
},
|
||||
)
|
||||
.delete(
|
||||
"/pty/:id",
|
||||
"/pty/:ptyID",
|
||||
describeRoute({
|
||||
description: "Remove a PTY session",
|
||||
operationId: "pty.remove",
|
||||
@@ -275,14 +275,14 @@ export namespace Server {
|
||||
...errors(404),
|
||||
},
|
||||
}),
|
||||
validator("param", z.object({ id: z.string() })),
|
||||
validator("param", z.object({ ptyID: z.string() })),
|
||||
async (c) => {
|
||||
await Pty.remove(c.req.valid("param").id)
|
||||
await Pty.remove(c.req.valid("param").ptyID)
|
||||
return c.json(true)
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/pty/:id/connect",
|
||||
"/pty/:ptyID/connect",
|
||||
describeRoute({
|
||||
description: "Connect to a PTY session",
|
||||
operationId: "pty.connect",
|
||||
@@ -298,9 +298,9 @@ export namespace Server {
|
||||
...errors(404),
|
||||
},
|
||||
}),
|
||||
validator("param", z.object({ id: z.string() })),
|
||||
validator("param", z.object({ ptyID: z.string() })),
|
||||
upgradeWebSocket((c) => {
|
||||
const id = c.req.param("id")
|
||||
const id = c.req.param("ptyID")
|
||||
let handler: ReturnType<typeof Pty.connect>
|
||||
if (!Pty.get(id)) throw new Error("Session not found")
|
||||
return {
|
||||
@@ -557,7 +557,7 @@ export namespace Server {
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/session/:id",
|
||||
"/session/:sessionID",
|
||||
describeRoute({
|
||||
description: "Get session",
|
||||
operationId: "session.get",
|
||||
@@ -576,17 +576,18 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: Session.get.schema,
|
||||
sessionID: Session.get.schema,
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
log.info("SEARCH", { url: c.req.url })
|
||||
const session = await Session.get(sessionID)
|
||||
return c.json(session)
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/session/:id/children",
|
||||
"/session/:sessionID/children",
|
||||
describeRoute({
|
||||
description: "Get a session's children",
|
||||
operationId: "session.children",
|
||||
@@ -605,17 +606,17 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: Session.children.schema,
|
||||
sessionID: Session.children.schema,
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const session = await Session.children(sessionID)
|
||||
return c.json(session)
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/session/:id/todo",
|
||||
"/session/:sessionID/todo",
|
||||
describeRoute({
|
||||
description: "Get the todo list for a session",
|
||||
operationId: "session.todo",
|
||||
@@ -634,11 +635,11 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
sessionID: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const todos = await Todo.get(sessionID)
|
||||
return c.json(todos)
|
||||
},
|
||||
@@ -668,7 +669,7 @@ export namespace Server {
|
||||
},
|
||||
)
|
||||
.delete(
|
||||
"/session/:id",
|
||||
"/session/:sessionID",
|
||||
describeRoute({
|
||||
description: "Delete a session and all its data",
|
||||
operationId: "session.delete",
|
||||
@@ -687,11 +688,11 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: Session.remove.schema,
|
||||
sessionID: Session.remove.schema,
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
await Session.remove(sessionID)
|
||||
await Bus.publish(TuiEvent.CommandExecute, {
|
||||
command: "session.list",
|
||||
@@ -700,7 +701,7 @@ export namespace Server {
|
||||
},
|
||||
)
|
||||
.patch(
|
||||
"/session/:id",
|
||||
"/session/:sessionID",
|
||||
describeRoute({
|
||||
description: "Update session properties",
|
||||
operationId: "session.update",
|
||||
@@ -719,7 +720,7 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
sessionID: z.string(),
|
||||
}),
|
||||
),
|
||||
validator(
|
||||
@@ -729,7 +730,7 @@ export namespace Server {
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const updates = c.req.valid("json")
|
||||
|
||||
const updatedSession = await Session.update(sessionID, (session) => {
|
||||
@@ -742,7 +743,7 @@ export namespace Server {
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/init",
|
||||
"/session/:sessionID/init",
|
||||
describeRoute({
|
||||
description: "Analyze the app and create an AGENTS.md file",
|
||||
operationId: "session.init",
|
||||
@@ -761,19 +762,19 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
sessionID: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
validator("json", Session.initialize.schema.omit({ sessionID: true })),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const body = c.req.valid("json")
|
||||
await Session.initialize({ ...body, sessionID })
|
||||
return c.json(true)
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/fork",
|
||||
"/session/:sessionID/fork",
|
||||
describeRoute({
|
||||
description: "Fork an existing session at a specific message",
|
||||
operationId: "session.fork",
|
||||
@@ -791,19 +792,19 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: Session.fork.schema.shape.sessionID,
|
||||
sessionID: Session.fork.schema.shape.sessionID,
|
||||
}),
|
||||
),
|
||||
validator("json", Session.fork.schema.omit({ sessionID: true })),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const body = c.req.valid("json")
|
||||
const result = await Session.fork({ ...body, sessionID })
|
||||
return c.json(result)
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/abort",
|
||||
"/session/:sessionID/abort",
|
||||
describeRoute({
|
||||
description: "Abort a session",
|
||||
operationId: "session.abort",
|
||||
@@ -822,16 +823,16 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
sessionID: z.string(),
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
SessionPrompt.cancel(c.req.valid("param").id)
|
||||
SessionPrompt.cancel(c.req.valid("param").sessionID)
|
||||
return c.json(true)
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/share",
|
||||
"/session/:sessionID/share",
|
||||
describeRoute({
|
||||
description: "Share a session",
|
||||
operationId: "session.share",
|
||||
@@ -850,18 +851,18 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
sessionID: z.string(),
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
await Session.share(id)
|
||||
const session = await Session.get(id)
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
await Session.share(sessionID)
|
||||
const session = await Session.get(sessionID)
|
||||
return c.json(session)
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/session/:id/diff",
|
||||
"/session/:sessionID/diff",
|
||||
describeRoute({
|
||||
description: "Get the diff that resulted from this user message",
|
||||
operationId: "session.diff",
|
||||
@@ -879,7 +880,7 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: SessionSummary.diff.schema.shape.sessionID,
|
||||
sessionID: SessionSummary.diff.schema.shape.sessionID,
|
||||
}),
|
||||
),
|
||||
validator(
|
||||
@@ -892,14 +893,14 @@ export namespace Server {
|
||||
const query = c.req.valid("query")
|
||||
const params = c.req.valid("param")
|
||||
const result = await SessionSummary.diff({
|
||||
sessionID: params.id,
|
||||
sessionID: params.sessionID,
|
||||
messageID: query.messageID,
|
||||
})
|
||||
return c.json(result)
|
||||
},
|
||||
)
|
||||
.delete(
|
||||
"/session/:id/share",
|
||||
"/session/:sessionID/share",
|
||||
describeRoute({
|
||||
description: "Unshare the session",
|
||||
operationId: "session.unshare",
|
||||
@@ -918,18 +919,18 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: Session.unshare.schema,
|
||||
sessionID: Session.unshare.schema,
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
await Session.unshare(id)
|
||||
const session = await Session.get(id)
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
await Session.unshare(sessionID)
|
||||
const session = await Session.get(sessionID)
|
||||
return c.json(session)
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/summarize",
|
||||
"/session/:sessionID/summarize",
|
||||
describeRoute({
|
||||
description: "Summarize the session",
|
||||
operationId: "session.summarize",
|
||||
@@ -948,7 +949,7 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
sessionID: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
validator(
|
||||
@@ -959,9 +960,9 @@ export namespace Server {
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const body = c.req.valid("json")
|
||||
const msgs = await Session.messages({ sessionID: id })
|
||||
const msgs = await Session.messages({ sessionID })
|
||||
let currentAgent = "build"
|
||||
for (let i = msgs.length - 1; i >= 0; i--) {
|
||||
const info = msgs[i].info
|
||||
@@ -971,7 +972,7 @@ export namespace Server {
|
||||
}
|
||||
}
|
||||
await SessionCompaction.create({
|
||||
sessionID: id,
|
||||
sessionID,
|
||||
agent: currentAgent,
|
||||
model: {
|
||||
providerID: body.providerID,
|
||||
@@ -979,12 +980,12 @@ export namespace Server {
|
||||
},
|
||||
auto: false,
|
||||
})
|
||||
await SessionPrompt.loop(id)
|
||||
await SessionPrompt.loop(sessionID)
|
||||
return c.json(true)
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/session/:id/message",
|
||||
"/session/:sessionID/message",
|
||||
describeRoute({
|
||||
description: "List messages for a session",
|
||||
operationId: "session.messages",
|
||||
@@ -1003,7 +1004,7 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
sessionID: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
validator(
|
||||
@@ -1015,14 +1016,14 @@ export namespace Server {
|
||||
async (c) => {
|
||||
const query = c.req.valid("query")
|
||||
const messages = await Session.messages({
|
||||
sessionID: c.req.valid("param").id,
|
||||
sessionID: c.req.valid("param").sessionID,
|
||||
limit: query.limit,
|
||||
})
|
||||
return c.json(messages)
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/session/:id/diff",
|
||||
"/session/:sessionID/diff",
|
||||
describeRoute({
|
||||
description: "Get the diff for this session",
|
||||
operationId: "session.diff",
|
||||
@@ -1041,16 +1042,16 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
sessionID: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const diff = await Session.diff(c.req.valid("param").id)
|
||||
const diff = await Session.diff(c.req.valid("param").sessionID)
|
||||
return c.json(diff)
|
||||
},
|
||||
)
|
||||
.get(
|
||||
"/session/:id/message/:messageID",
|
||||
"/session/:sessionID/message/:messageID",
|
||||
describeRoute({
|
||||
description: "Get a message from a session",
|
||||
operationId: "session.message",
|
||||
@@ -1074,21 +1075,21 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
sessionID: z.string().meta({ description: "Session ID" }),
|
||||
messageID: z.string().meta({ description: "Message ID" }),
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const params = c.req.valid("param")
|
||||
const message = await MessageV2.get({
|
||||
sessionID: params.id,
|
||||
sessionID: params.sessionID,
|
||||
messageID: params.messageID,
|
||||
})
|
||||
return c.json(message)
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/message",
|
||||
"/session/:sessionID/message",
|
||||
describeRoute({
|
||||
description: "Create and send a new message to a session",
|
||||
operationId: "session.prompt",
|
||||
@@ -1112,7 +1113,7 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
sessionID: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
validator("json", SessionPrompt.PromptInput.omit({ sessionID: true })),
|
||||
@@ -1120,7 +1121,7 @@ export namespace Server {
|
||||
c.status(200)
|
||||
c.header("Content-Type", "application/json")
|
||||
return stream(c, async (stream) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const body = c.req.valid("json")
|
||||
const msg = await SessionPrompt.prompt({ ...body, sessionID })
|
||||
stream.write(JSON.stringify(msg))
|
||||
@@ -1128,7 +1129,7 @@ export namespace Server {
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/prompt_async",
|
||||
"/session/:sessionID/prompt_async",
|
||||
describeRoute({
|
||||
description: "Create and send a new message to a session, start if needed and return immediately",
|
||||
operationId: "session.prompt_async",
|
||||
@@ -1142,7 +1143,7 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
sessionID: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
validator("json", SessionPrompt.PromptInput.omit({ sessionID: true })),
|
||||
@@ -1150,14 +1151,14 @@ export namespace Server {
|
||||
c.status(204)
|
||||
c.header("Content-Type", "application/json")
|
||||
return stream(c, async () => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const body = c.req.valid("json")
|
||||
SessionPrompt.prompt({ ...body, sessionID })
|
||||
})
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/command",
|
||||
"/session/:sessionID/command",
|
||||
describeRoute({
|
||||
description: "Send a new command to a session",
|
||||
operationId: "session.command",
|
||||
@@ -1181,19 +1182,19 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
sessionID: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
validator("json", SessionPrompt.CommandInput.omit({ sessionID: true })),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const body = c.req.valid("json")
|
||||
const msg = await SessionPrompt.command({ ...body, sessionID })
|
||||
return c.json(msg)
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/shell",
|
||||
"/session/:sessionID/shell",
|
||||
describeRoute({
|
||||
description: "Run a shell command",
|
||||
operationId: "session.shell",
|
||||
@@ -1212,19 +1213,19 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
sessionID: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
validator("json", SessionPrompt.ShellInput.omit({ sessionID: true })),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const body = c.req.valid("json")
|
||||
const msg = await SessionPrompt.shell({ ...body, sessionID })
|
||||
return c.json(msg)
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/revert",
|
||||
"/session/:sessionID/revert",
|
||||
describeRoute({
|
||||
description: "Revert a message",
|
||||
operationId: "session.revert",
|
||||
@@ -1243,22 +1244,22 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
sessionID: z.string(),
|
||||
}),
|
||||
),
|
||||
validator("json", SessionRevert.RevertInput.omit({ sessionID: true })),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
log.info("revert", c.req.valid("json"))
|
||||
const session = await SessionRevert.revert({
|
||||
sessionID: id,
|
||||
sessionID,
|
||||
...c.req.valid("json"),
|
||||
})
|
||||
return c.json(session)
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/unrevert",
|
||||
"/session/:sessionID/unrevert",
|
||||
describeRoute({
|
||||
description: "Restore all reverted messages",
|
||||
operationId: "session.unrevert",
|
||||
@@ -1277,19 +1278,20 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
sessionID: z.string(),
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
const session = await SessionRevert.unrevert({ sessionID: id })
|
||||
const sessionID = c.req.valid("param").sessionID
|
||||
const session = await SessionRevert.unrevert({ sessionID })
|
||||
return c.json(session)
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/session/:id/permissions/:permissionID",
|
||||
"/session/:sessionID/permissions/:permissionID",
|
||||
describeRoute({
|
||||
description: "Respond to a permission request",
|
||||
operationId: "permission.respond",
|
||||
responses: {
|
||||
200: {
|
||||
description: "Permission processed successfully",
|
||||
@@ -1305,17 +1307,17 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
sessionID: z.string(),
|
||||
permissionID: z.string(),
|
||||
}),
|
||||
),
|
||||
validator("json", z.object({ response: Permission.Response })),
|
||||
async (c) => {
|
||||
const params = c.req.valid("param")
|
||||
const id = params.id
|
||||
const sessionID = params.sessionID
|
||||
const permissionID = params.permissionID
|
||||
Permission.respond({
|
||||
sessionID: id,
|
||||
sessionID,
|
||||
permissionID,
|
||||
response: c.req.valid("json").response,
|
||||
})
|
||||
@@ -1429,7 +1431,7 @@ export namespace Server {
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/provider/:id/oauth/authorize",
|
||||
"/provider/:providerID/oauth/authorize",
|
||||
describeRoute({
|
||||
description: "Authorize a provider using OAuth",
|
||||
operationId: "provider.oauth.authorize",
|
||||
@@ -1448,7 +1450,7 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Provider ID" }),
|
||||
providerID: z.string().meta({ description: "Provider ID" }),
|
||||
}),
|
||||
),
|
||||
validator(
|
||||
@@ -1458,17 +1460,17 @@ export namespace Server {
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
const providerID = c.req.valid("param").providerID
|
||||
const { method } = c.req.valid("json")
|
||||
const result = await ProviderAuth.authorize({
|
||||
providerID: id,
|
||||
providerID,
|
||||
method,
|
||||
})
|
||||
return c.json(result)
|
||||
},
|
||||
)
|
||||
.post(
|
||||
"/provider/:id/oauth/callback",
|
||||
"/provider/:providerID/oauth/callback",
|
||||
describeRoute({
|
||||
description: "Handle OAuth callback for a provider",
|
||||
operationId: "provider.oauth.callback",
|
||||
@@ -1487,7 +1489,7 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().meta({ description: "Provider ID" }),
|
||||
providerID: z.string().meta({ description: "Provider ID" }),
|
||||
}),
|
||||
),
|
||||
validator(
|
||||
@@ -1498,10 +1500,10 @@ export namespace Server {
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
const providerID = c.req.valid("param").providerID
|
||||
const { method, code } = c.req.valid("json")
|
||||
await ProviderAuth.callback({
|
||||
providerID: id,
|
||||
providerID,
|
||||
method,
|
||||
code,
|
||||
})
|
||||
@@ -2215,7 +2217,7 @@ export namespace Server {
|
||||
)
|
||||
.route("/tui/control", TuiRoute)
|
||||
.put(
|
||||
"/auth/:id",
|
||||
"/auth/:providerID",
|
||||
describeRoute({
|
||||
description: "Set authentication credentials",
|
||||
operationId: "auth.set",
|
||||
@@ -2234,14 +2236,14 @@ export namespace Server {
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
providerID: z.string(),
|
||||
}),
|
||||
),
|
||||
validator("json", Auth.Info),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
const providerID = c.req.valid("param").providerID
|
||||
const info = c.req.valid("json")
|
||||
await Auth.set(id, info)
|
||||
await Auth.set(providerID, info)
|
||||
return c.json(true)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Session } from "@/session"
|
||||
import { MessageV2 } from "@/session/message-v2"
|
||||
import { Storage } from "@/storage/storage"
|
||||
import { Log } from "@/util/log"
|
||||
import type * as SDK from "@opencode-ai/sdk"
|
||||
import type * as SDK from "@opencode-ai/sdk/v2"
|
||||
|
||||
export namespace ShareNext {
|
||||
const log = Log.create({ service: "share-next" })
|
||||
|
||||
Reference in New Issue
Block a user