mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
* Chat renames are saved as the chat's name, so Session History shows them after the tab closes Renaming a native chat tab only changed that window's tab. Session History, phones and other windows read the host's saved name, so the rename vanished from History once the tab closed or Orca restarted. A rename now goes to the host that owns the chat (agentSession.rename) and is saved as the chat's one name, the field History, tabs, sidebars and phones already read. The record remembers that the user chose it, so automatic naming never replaces it. A window's pre-upgrade tab rename is uploaded once and only fills a name Orca chose. Hosts without the new capability keep the old tab-only rename. Every native agent's History row now shows the chat's name once it has one. * Keep saved chat names consistent across readers and reconnects * Carry qualified chat names into cached readers * Reuse the history recorder context across platforms * Use recorded chat ownership for legacy name transfer * Transfer legacy chat names only from known catalog ownership * Correct recorder path matching and History subscription order * Require complete evidence for bridged parity exclusions * Preserve sparse array lengths in complete recording comparisons * Initialize History observation before loading workspace context * Integrate measured History recordings and scoped parity evidence * fix chat naming retries and certify both replay modes * fix ambiguous chat rename labels after navigation * preserve chat rename intent across tab updates * type dashboard snapshot fixtures without assertions * fix: align chat name observation with store contracts * test: update chat name consumer fixtures * test: distinguish sender naming metadata from status * Preserve saved Activity chat names across tab focus * Clarify Activity tab projection identity * Remove package-manager lockfile churn from main merge * Refresh automatic chat names after clearing context * fix(runtime): validate tab property edits before saving chat names * Preserve naming eligibility and refresh cleared chat titles * Fix checked naming projection types and logging metadata * Supply context floor in status-feed journal fixtures * fix: refresh History ownership after conversation clear * fix: commit History request identity before refresh effects * Fix History scan scope typing and integration test placement * test: cover saved chat name reader contracts * fix: bound chat naming work through generation settlement * Remove duplicate History name-transition refresh * Restore cache option in tab History test * Consolidate naming test imports * test: align naming fixtures with checked contracts * test: name the discovery child fixture contract * test: initialize writable child fixture streams * test: account for ownership head and key reads
105 lines
4.3 KiB
TypeScript
105 lines
4.3 KiB
TypeScript
import { agentSessionCurrentContextRows } from '../../shared/agent-session-context-clear'
|
|
import { LOCAL_EXECUTION_HOST_ID, type ExecutionHostId } from '../../shared/execution-host'
|
|
import type { CommitMessageAgentEnvironmentResolvers } from '../text-generation/commit-message-agent-environment'
|
|
import type { StructuredChatNamingDeps } from '../native-chat/structured-chat-naming'
|
|
import type { StructuredAgentSessionLogger } from '../native-chat/agent-session-wire/structured-agent-session-logger'
|
|
import { getStructuredAgentSessionHost } from '../native-chat/agent-session-wire/structured-agent-session-registry'
|
|
import { firstStructuredChatNamingPrompt } from '../../shared/structured-chat-naming-eligibility'
|
|
import { firstStructuredAgentSessionPrompt } from '../../shared/structured-agent-session-first-prompt'
|
|
import { LOCAL_COMMIT_MESSAGE_HOST_KEY } from '../../shared/commit-message-host-key'
|
|
import {
|
|
generateConversationNameFromContext,
|
|
resolveTextGenerationParams
|
|
} from '../text-generation/commit-message-text-generation'
|
|
import { resolveGenerationTarget } from '../agent-hooks/first-work-generation-target'
|
|
|
|
type StructuredChatNamingRuntime = {
|
|
resolveWorkspace: (
|
|
workspaceId: string
|
|
) => Promise<{ path: string; executionHostId: ExecutionHostId }>
|
|
getAgentEnvResolvers: () => CommitMessageAgentEnvironmentResolvers | undefined
|
|
workerTaskTitle: StructuredChatNamingDeps['workerTaskTitle']
|
|
retitleOpenTab: StructuredChatNamingDeps['onNamed']
|
|
}
|
|
|
|
export function structuredChatNamingDeps(
|
|
getStore: () => {
|
|
getSettings: () => Parameters<typeof resolveTextGenerationParams>[0] &
|
|
ReturnType<StructuredChatNamingDeps['getSettings']>
|
|
},
|
|
runtime: StructuredChatNamingRuntime,
|
|
logger: StructuredAgentSessionLogger
|
|
): StructuredChatNamingDeps {
|
|
return {
|
|
getStore: () => getStructuredAgentSessionHost()?.deps.store ?? null,
|
|
getSettings: () => getStore().getSettings(),
|
|
readFirstPrompt: async (sessionId, hostStartedAt) => {
|
|
const host = getStructuredAgentSessionHost()
|
|
return host
|
|
? firstStructuredChatNamingPrompt(await host.journalSnapshot(sessionId), hostStartedAt)
|
|
: ''
|
|
},
|
|
readJournalFirstPrompt: async (sessionId) => {
|
|
const host = getStructuredAgentSessionHost()
|
|
return host
|
|
? firstStructuredAgentSessionPrompt(
|
|
agentSessionCurrentContextRows((await host.journalSnapshot(sessionId)).items).items
|
|
)
|
|
: ''
|
|
},
|
|
workerTaskTitle: runtime.workerTaskTitle,
|
|
generate: async (record, firstPrompt, shouldExecute) => {
|
|
// Unsupported execution contexts keep the seed regardless of native naming settings.
|
|
if (record.location.wslDistro !== null) {
|
|
return null
|
|
}
|
|
const workspace = await runtime.resolveWorkspace(record.location.workspaceId)
|
|
if (workspace.executionHostId !== LOCAL_EXECUTION_HOST_ID) {
|
|
return null
|
|
}
|
|
const settings = resolveTextGenerationParams(
|
|
getStore().getSettings(),
|
|
LOCAL_COMMIT_MESSAGE_HOST_KEY,
|
|
'conversationName',
|
|
null
|
|
)
|
|
const log = { scope: 'conversation-name', sessionId: record.sessionId }
|
|
if (!settings.ok) {
|
|
logger.warn(settings.error, log)
|
|
return { error: settings.error }
|
|
}
|
|
const target = await resolveGenerationTarget(workspace.path, settings.params.agentId, runtime)
|
|
if (!target) {
|
|
const error = 'No chat-name agent can run in this workspace.'
|
|
logger.warn(error, log)
|
|
return { error }
|
|
}
|
|
const result = await generateConversationNameFromContext(
|
|
{ firstPrompt },
|
|
settings.params,
|
|
target,
|
|
shouldExecute
|
|
)
|
|
if (result.success) {
|
|
return { name: result.name }
|
|
}
|
|
logger.warn(result.error, log)
|
|
return result.canceled ? null : { error: result.error, failureOutput: result.failureOutput }
|
|
},
|
|
onNamed: (workspaceId, sessionId) => {
|
|
try {
|
|
// Lists that show the chat without its tab, a closed one too, learn the name from the feed.
|
|
getStructuredAgentSessionHost()?.publishConversationName(sessionId)
|
|
} catch (error) {
|
|
logger.warn('Chat name publication failed', {
|
|
scope: 'conversation-name',
|
|
sessionId,
|
|
error
|
|
})
|
|
}
|
|
runtime.retitleOpenTab(workspaceId, sessionId)
|
|
},
|
|
logger
|
|
}
|
|
}
|