wip
parent
0acefd5c08
commit
2b4da9e274
|
|
@ -11,6 +11,16 @@
|
|||
},
|
||||
},
|
||||
},
|
||||
"disabled_providers": [
|
||||
"openai",
|
||||
"google",
|
||||
"perplexity",
|
||||
"openrouter",
|
||||
"opencode",
|
||||
// "anthropic",
|
||||
"azure",
|
||||
"github-copilot",
|
||||
],
|
||||
"mcp": {
|
||||
"exa": {
|
||||
"type": "remote",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue