mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
feat: support opencode
This commit is contained in:
@@ -312,7 +312,7 @@ export function HappyComposer(props: {
|
||||
|
||||
useEffect(() => {
|
||||
const handleGlobalKeyDown = (e: globalThis.KeyboardEvent) => {
|
||||
if (e.key === 'm' && (e.metaKey || e.ctrlKey) && onModelModeChange && agentFlavor !== 'codex' && agentFlavor !== 'gemini') {
|
||||
if (e.key === 'm' && (e.metaKey || e.ctrlKey) && onModelModeChange && agentFlavor !== 'codex' && agentFlavor !== 'gemini' && agentFlavor !== 'opencode') {
|
||||
e.preventDefault()
|
||||
const currentIndex = MODEL_MODES.indexOf(modelMode as typeof MODEL_MODES[number])
|
||||
const nextIndex = (currentIndex + 1) % MODEL_MODES.length
|
||||
@@ -386,7 +386,7 @@ export function HappyComposer(props: {
|
||||
}, [onModelModeChange, controlsDisabled, haptic])
|
||||
|
||||
const showPermissionSettings = Boolean(onPermissionModeChange && permissionModeOptions.length > 0)
|
||||
const showModelSettings = Boolean(onModelModeChange && agentFlavor !== 'codex' && agentFlavor !== 'gemini')
|
||||
const showModelSettings = Boolean(onModelModeChange && agentFlavor !== 'codex' && agentFlavor !== 'gemini' && agentFlavor !== 'opencode')
|
||||
const showSettingsButton = Boolean(showPermissionSettings || showModelSettings)
|
||||
const showAbortButton = true
|
||||
const voiceEnabled = Boolean(onVoiceToggle)
|
||||
|
||||
@@ -14,7 +14,7 @@ export function AgentSelector(props: {
|
||||
{t('newSession.agent')}
|
||||
</label>
|
||||
<div className="flex gap-3">
|
||||
{(['claude', 'codex', 'gemini'] as const).map((agentType) => (
|
||||
{(['claude', 'codex', 'gemini', 'opencode'] as const).map((agentType) => (
|
||||
<label
|
||||
key={agentType}
|
||||
className="flex items-center gap-1.5 cursor-pointer"
|
||||
|
||||
@@ -10,6 +10,9 @@ export function ModelSelector(props: {
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const options = MODEL_OPTIONS[props.agent]
|
||||
if (options.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-1.5 px-3 py-3">
|
||||
|
||||
@@ -195,11 +195,12 @@ export function NewSession(props: {
|
||||
|
||||
setError(null)
|
||||
try {
|
||||
const resolvedModel = model !== 'auto' && agent !== 'opencode' ? model : undefined
|
||||
const result = await spawnSession({
|
||||
machineId,
|
||||
directory: directory.trim(),
|
||||
agent,
|
||||
model: model !== 'auto' ? model : undefined,
|
||||
model: resolvedModel,
|
||||
yolo: yoloMode,
|
||||
sessionType,
|
||||
worktreeName: sessionType === 'worktree' ? (worktreeName.trim() || undefined) : undefined
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type AgentType = 'claude' | 'codex' | 'gemini'
|
||||
export type AgentType = 'claude' | 'codex' | 'gemini' | 'opencode'
|
||||
export type SessionType = 'simple' | 'worktree'
|
||||
|
||||
export const MODEL_OPTIONS: Record<AgentType, { value: string; label: string }[]> = {
|
||||
@@ -20,4 +20,5 @@ export const MODEL_OPTIONS: Record<AgentType, { value: string; label: string }[]
|
||||
{ value: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro' },
|
||||
{ value: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash' },
|
||||
],
|
||||
opencode: [],
|
||||
}
|
||||
|
||||
@@ -33,8 +33,10 @@ function isToolAllowedForSession(toolName: string, toolInput: unknown, allowedTo
|
||||
function isCodexSession(metadata: SessionMetadataSummary | null, toolName: string): boolean {
|
||||
return metadata?.flavor === 'codex'
|
||||
|| metadata?.flavor === 'gemini'
|
||||
|| metadata?.flavor === 'opencode'
|
||||
|| toolName.startsWith('Codex')
|
||||
|| toolName.startsWith('Gemini')
|
||||
|| toolName.startsWith('OpenCode')
|
||||
}
|
||||
|
||||
function formatPermissionSummary(permission: ToolPermission, toolName: string, toolInput: unknown, codex: boolean, t: (key: string) => string): string {
|
||||
|
||||
Reference in New Issue
Block a user