fix-issue
Aiden Cline 2025-12-01 17:57:07 -06:00
parent 0acefd5c08
commit 2b4da9e274
5 changed files with 94 additions and 20 deletions

View File

@ -11,6 +11,16 @@
},
},
},
"disabled_providers": [
"openai",
"google",
"perplexity",
"openrouter",
"opencode",
// "anthropic",
"azure",
"github-copilot",
],
"mcp": {
"exa": {
"type": "remote",

View File

@ -188,6 +188,7 @@ function App() {
})
let continued = false
let providerPrompted = false
createEffect(() => {
if (continued || sync.status !== "complete" || !args.continue) return
const match = sync.data.session.at(0)?.id
@ -197,6 +198,22 @@ function App() {
}
})
createEffect(() => {
if (sync.status !== "complete") return
if (sync.data.provider.length > 0) {
providerPrompted = false
return
}
if (providerPrompted) return
providerPrompted = true
toast.show({
variant: "warning",
message: "Connect a provider to start using OpenCode",
duration: 4000,
})
dialog.replace(() => <DialogProviderList />)
})
command.register(() => [
{
title: "Switch session",
@ -367,8 +384,9 @@ function App() {
])
createEffect(() => {
const providerID = local.model.current().providerID
if (providerID === "openrouter" && !kv.get("openrouter_warning", false)) {
const currentModel = local.model.current()
if (!currentModel) return
if (currentModel.providerID === "openrouter" && !kv.get("openrouter_warning", false)) {
untrack(() => {
DialogAlert.show(
dialog,

View File

@ -22,6 +22,9 @@ import { TuiEvent } from "../../event"
import { iife } from "@/util/iife"
import { Locale } from "@/util/locale"
import { createColors, createFrames } from "../../ui/spinner.ts"
import { useDialog } from "@tui/ui/dialog"
import { DialogProvider as DialogProviderConnect } from "../dialog-provider"
import { useToast } from "../../ui/toast"
export type PromptProps = {
sessionID?: string
@ -50,12 +53,25 @@ export function Prompt(props: PromptProps) {
const sdk = useSDK()
const route = useRoute()
const sync = useSync()
const dialog = useDialog()
const toast = useToast()
const status = createMemo(() => sync.data.session_status[props.sessionID ?? ""] ?? { type: "idle" })
const history = usePromptHistory()
const command = useCommandDialog()
const renderer = useRenderer()
const { theme, syntax } = useTheme()
function promptModelWarning() {
toast.show({
variant: "warning",
message: "Connect a provider to send prompts",
duration: 3000,
})
if (sync.data.provider.length === 0) {
dialog.replace(() => <DialogProviderConnect />)
}
}
const textareaKeybindings = createMemo(() => {
const newlineBindings = keybind.all.input_newline || []
const submitBindings = keybind.all.input_submit || []
@ -388,6 +404,11 @@ export function Prompt(props: PromptProps) {
if (props.disabled) return
if (autocomplete.visible) return
if (!store.prompt.input) return
const selectedModel = local.model.current()
if (!selectedModel) {
promptModelWarning()
return
}
const sessionID = props.sessionID
? props.sessionID
: await (async () => {
@ -424,8 +445,8 @@ export function Prompt(props: PromptProps) {
body: {
agent: local.agent.current().name,
model: {
providerID: local.model.current().providerID,
modelID: local.model.current().modelID,
providerID: selectedModel.providerID,
modelID: selectedModel.modelID,
},
command: inputText,
},
@ -448,7 +469,7 @@ export function Prompt(props: PromptProps) {
command: command.slice(1),
arguments: args.join(" "),
agent: local.agent.current().name,
model: `${local.model.current().providerID}/${local.model.current().modelID}`,
model: `${selectedModel.providerID}/${selectedModel.modelID}`,
messageID,
},
})
@ -458,10 +479,10 @@ export function Prompt(props: PromptProps) {
id: sessionID,
},
body: {
...local.model.current(),
...selectedModel,
messageID,
agent: local.agent.current().name,
model: local.model.current(),
model: selectedModel,
parts: [
{
id: Identifier.ascending("part"),

View File

@ -175,8 +175,13 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
return item
}
}
const provider = sync.data.provider[0]
const model = sync.data.provider_default[provider.id] ?? Object.values(provider.models)[0].id
if (!provider) return undefined
const defaultModel = sync.data.provider_default[provider.id]
const firstModel = Object.values(provider.models)[0]
const model = defaultModel ?? firstModel?.id
if (!model) return undefined
return {
providerID: provider.id,
modelID: model,
@ -185,11 +190,13 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
const currentModel = createMemo(() => {
const a = agent.current()
return getFirstValidModel(
() => modelStore.model[a.name],
() => a.model,
fallbackModel,
)!
return (
getFirstValidModel(
() => modelStore.model[a.name],
() => a.model,
fallbackModel,
) ?? undefined
)
})
return {
@ -205,11 +212,17 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
},
parsed: createMemo(() => {
const value = currentModel()
const provider = sync.data.provider.find((x) => x.id === value.providerID)!
const model = provider.models[value.modelID]
if (!value) {
return {
provider: "Connect a provider",
model: "No provider selected",
}
}
const provider = sync.data.provider.find((x) => x.id === value.providerID)
const info = provider?.models[value.modelID]
return {
provider: provider.name ?? value.providerID,
model: model.name ?? value.modelID,
provider: provider?.name ?? value.providerID,
model: info?.name ?? value.modelID,
}
}),
cycle(direction: 1 | -1) {
@ -236,7 +249,10 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
return
}
const current = currentModel()
let index = favorites.findIndex((x) => x.providerID === current.providerID && x.modelID === current.modelID)
let index = -1
if (current) {
index = favorites.findIndex((x) => x.providerID === current.providerID && x.modelID === current.modelID)
}
if (index === -1) {
index = direction === 1 ? 0 : favorites.length - 1
} else {

View File

@ -269,13 +269,22 @@ export function Session() {
keybind: "session_compact",
category: "Session",
onSelect: (dialog) => {
const selectedModel = local.model.current()
if (!selectedModel) {
toast.show({
variant: "warning",
message: "Connect a provider to summarize this session",
duration: 3000,
})
return
}
sdk.client.session.summarize({
path: {
id: route.sessionID,
},
body: {
modelID: local.model.current().modelID,
providerID: local.model.current().providerID,
modelID: selectedModel.modelID,
providerID: selectedModel.providerID,
},
})
dialog.clear()