Files
orca/src/renderer/src/lib/launch-ai-vault-session.ts
T
38e82b4fff Fix AI Vault scanning for runtime hosts (#7631)
* Fix AI Vault runtime host scanning

* fix runtime ai vault response validation

* test runtime ai vault validation more loosely

* fix(ai-vault): harden runtime host scanning

Co-authored-by: Orca <help@stably.ai>

* fix(ai-vault): resume runtime host sessions

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-08 11:20:26 -07:00

87 lines
3.1 KiB
TypeScript

import { useAppStore } from '@/store'
import { reconcileTabOrder } from '@/components/tab-bar/reconcile-order'
import { tuiAgentToAgentKind } from '@/lib/telemetry'
import { getRuntimeEnvironmentIdForWorktree } from '@/lib/worktree-runtime-owner'
import {
createWebRuntimeSessionTerminal,
isWebRuntimeSessionActive
} from '@/runtime/web-runtime-session'
import type { AiVaultAgent } from '../../../shared/ai-vault-types'
import type { SleepingAgentLaunchConfig } from '../../../shared/agent-session-resume'
import type { TabSplitDirection } from '@/store/slices/tabs'
export type LaunchAiVaultSessionInNewTabResult =
| { tabId: string; groupId?: string }
| { tabId: null; groupId?: string; runtimeLaunch: Promise<boolean> }
export function launchAiVaultSessionInNewTab(args: {
agent: AiVaultAgent
worktreeId: string
command: string
env?: Record<string, string>
launchConfig?: SleepingAgentLaunchConfig
targetGroupId?: string
splitDirection?: TabSplitDirection
}): LaunchAiVaultSessionInNewTabResult {
const store = useAppStore.getState()
let targetGroupId = args.targetGroupId
const runtimeEnvironmentId = getRuntimeEnvironmentIdForWorktree(store, args.worktreeId)
if (isWebRuntimeSessionActive(runtimeEnvironmentId)) {
const runtimeLaunch = createWebRuntimeSessionTerminal({
worktreeId: args.worktreeId,
environmentId: runtimeEnvironmentId,
...(targetGroupId ? { targetGroupId } : {}),
command: args.command,
...(args.env ? { env: args.env } : {}),
...(args.launchConfig ? { launchConfig: args.launchConfig } : {}),
launchAgent: args.agent,
activate: true
}).then((created) => {
if (created) {
useAppStore.getState().setActiveTabType('terminal')
}
return created
})
return {
tabId: null,
...(targetGroupId ? { groupId: targetGroupId } : {}),
runtimeLaunch
}
}
if (args.splitDirection && targetGroupId) {
targetGroupId =
store.createEmptySplitGroup(args.worktreeId, targetGroupId, args.splitDirection) ??
targetGroupId
}
const tab = store.createTab(args.worktreeId, targetGroupId)
store.queueTabStartupCommand(tab.id, {
command: args.command,
...(args.env ? { env: args.env } : {}),
...(args.launchConfig ? { launchConfig: args.launchConfig, launchAgent: args.agent } : {}),
telemetry: {
agent_kind: tuiAgentToAgentKind(args.agent),
launch_source: 'sidebar',
request_kind: 'resume'
}
})
store.setActiveTabType('terminal')
const fresh = useAppStore.getState()
const termIds = (fresh.tabsByWorktree[args.worktreeId] ?? []).map((t) => t.id)
const editorIds = fresh.openFiles.filter((f) => f.worktreeId === args.worktreeId).map((f) => f.id)
const browserIds = (fresh.browserTabsByWorktree?.[args.worktreeId] ?? []).map((t) => t.id)
const base = reconcileTabOrder(
fresh.tabBarOrderByWorktree[args.worktreeId],
termIds,
editorIds,
browserIds
)
const order = base.filter((id) => id !== tab.id)
order.push(tab.id)
fresh.setTabBarOrder(args.worktreeId, order)
return { tabId: tab.id, groupId: targetGroupId }
}