mirror of
https://github.com/stablyai/orca.git
synced 2026-11-04 19:17:28 +00:00
refactor(native-chat): the status summary's broadcast equality gets its own module
The status feed crossed the file-size limit once the summary gained the main agent's turn outcome beside the child views. Which summary changes reach every session list now lives in structured-agent-session-status-summary-equality.ts.
This commit is contained in:
@@ -10,28 +10,24 @@
|
||||
// each chat is reopened. Restart is the one boundary that forgets, and restoring readable sessions
|
||||
// republishes them.
|
||||
|
||||
import { agentProviderSessionsEqual } from '../../../shared/agent-session-resume'
|
||||
import type { AgentSessionRecord } from '../../../shared/agent-session-record'
|
||||
import { normalizeOptionalField } from '../../../shared/agent-status-field-normalization'
|
||||
import { isAgentStatusHeldOpenByChildWork } from '../../../shared/agent-lead-status-fold'
|
||||
import { AGENT_MODEL_MAX_LENGTH } from '../../../shared/agent-status-types'
|
||||
import {
|
||||
agentSessionBackgroundTasksEqual,
|
||||
type AgentSessionStatusEvent,
|
||||
type AgentSessionStatusSummary
|
||||
import type {
|
||||
AgentSessionStatusEvent,
|
||||
AgentSessionStatusSummary
|
||||
} from '../../../shared/agent-session-wire'
|
||||
import type { AgentChildWorkEvidence } from '../../../shared/agent-status-child-work-evidence'
|
||||
import type { AgentChildWorkView } from '../../../shared/agent-status-child-work-view'
|
||||
import { projectStructuredAgentSessionStatusState } from '../../../shared/structured-agent-session-projection'
|
||||
import { structuredAgentSessionAgentStatus } from '../../../shared/structured-agent-session-agent-status'
|
||||
import type { AgentSessionJournal } from '../agent-session-journal/journal-store'
|
||||
import type { StructuredAgentSessionProviderChild } from './structured-agent-session-host-types'
|
||||
import { structuredAgentSessionProviderSessionMetadata } from './structured-agent-session-history-result'
|
||||
import {
|
||||
newestRootTurnId,
|
||||
structuredStatusChildrenEqual,
|
||||
structuredStatusChildWork
|
||||
} from './structured-agent-session-status-child-work'
|
||||
import { structuredStatusSummariesEqual } from './structured-agent-session-status-summary-equality'
|
||||
import {
|
||||
StructuredAgentSessionStatusOwnership,
|
||||
type StructuredAgentSessionStatusSink
|
||||
@@ -70,48 +66,6 @@ export type StructuredAgentSessionStatusFeedDeps = {
|
||||
onAgentStarted?: (sessionId: string) => void
|
||||
}
|
||||
|
||||
function summariesEqual(a: AgentSessionStatusSummary, b: AgentSessionStatusSummary): boolean {
|
||||
return (
|
||||
a.workspaceId === b.workspaceId &&
|
||||
a.agent === b.agent &&
|
||||
a.status === b.status &&
|
||||
a.hostExecutionOwned === b.hostExecutionOwned &&
|
||||
a.hostExecutionPhase === b.hostExecutionPhase &&
|
||||
a.hostExecutionChild?.generation === b.hostExecutionChild?.generation &&
|
||||
a.hostExecutionChild?.fence === b.hostExecutionChild?.fence &&
|
||||
a.rewindBlockedReason === b.rewindBlockedReason &&
|
||||
// A moved state clock changes ranking; row activity alone, including a subagent's, does not.
|
||||
// An idle state the journal cannot date still republishes, since readers date it by `updatedAt`,
|
||||
// and so does one live child work holds open: readers take each publish as its evidence.
|
||||
a.statusStartedAt === b.statusStartedAt &&
|
||||
(a.status !== 'idle' ||
|
||||
a.updatedAt === b.updatedAt ||
|
||||
(a.statusStartedAt !== undefined && !isIdleHeldOpenByChildWork(b))) &&
|
||||
a.latestPrompt === b.latestPrompt &&
|
||||
a.model === b.model &&
|
||||
a.toolName === b.toolName &&
|
||||
a.toolInput === b.toolInput &&
|
||||
a.lastAssistantMessage === b.lastAssistantMessage &&
|
||||
a.turnOutcome === b.turnOutcome &&
|
||||
structuredStatusChildrenEqual(a.children, b.children) &&
|
||||
agentSessionBackgroundTasksEqual(a.backgroundTasks, b.backgroundTasks) &&
|
||||
agentProviderSessionsEqual(undefined, a.providerSession, b.providerSession)
|
||||
)
|
||||
}
|
||||
|
||||
function isIdleHeldOpenByChildWork(summary: AgentSessionStatusSummary): boolean {
|
||||
return (
|
||||
summary.status === 'idle' &&
|
||||
isAgentStatusHeldOpenByChildWork(
|
||||
structuredAgentSessionAgentStatus({
|
||||
status: summary.status,
|
||||
backgroundTasks: summary.backgroundTasks,
|
||||
turnOutcome: summary.turnOutcome
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Wire the host's own deps into a feed; keeps the host at one call site.
|
||||
* `deps` is a thunk because the host builds the feed in a field initializer,
|
||||
* before its constructor parameters are assigned. */
|
||||
@@ -250,7 +204,7 @@ export class StructuredAgentSessionStatusFeed {
|
||||
this.retireSettledChildrenOnNewTurn(sessionId, session, projection.rootTurnId)
|
||||
const summary = this.summaryFor(sessionId, session, source, record, projection.state)
|
||||
const previous = this.published.get(sessionId)
|
||||
if (previous && summariesEqual(previous, summary)) {
|
||||
if (previous && structuredStatusSummariesEqual(previous, summary)) {
|
||||
if (!this.ownership.matchesLocation(sessionId, session.params.location)) {
|
||||
this.sink(summary, session.params.location)
|
||||
}
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// Which status-summary changes reach every session list. The summary is broadcast to remote
|
||||
// subscribers too, so only a change a session list shows may re-send it.
|
||||
|
||||
import { agentProviderSessionsEqual } from '../../../shared/agent-session-resume'
|
||||
import {
|
||||
agentSessionBackgroundTasksEqual,
|
||||
type AgentSessionStatusSummary
|
||||
} from '../../../shared/agent-session-wire'
|
||||
import { isAgentStatusHeldOpenByChildWork } from '../../../shared/agent-lead-status-fold'
|
||||
import { structuredAgentSessionAgentStatus } from '../../../shared/structured-agent-session-agent-status'
|
||||
import { structuredStatusChildrenEqual } from './structured-agent-session-status-child-work'
|
||||
|
||||
export function structuredStatusSummariesEqual(
|
||||
a: AgentSessionStatusSummary,
|
||||
b: AgentSessionStatusSummary
|
||||
): boolean {
|
||||
return (
|
||||
a.workspaceId === b.workspaceId &&
|
||||
a.agent === b.agent &&
|
||||
a.status === b.status &&
|
||||
a.hostExecutionOwned === b.hostExecutionOwned &&
|
||||
a.hostExecutionPhase === b.hostExecutionPhase &&
|
||||
a.hostExecutionChild?.generation === b.hostExecutionChild?.generation &&
|
||||
a.hostExecutionChild?.fence === b.hostExecutionChild?.fence &&
|
||||
a.rewindBlockedReason === b.rewindBlockedReason &&
|
||||
// A moved state clock changes ranking; row activity alone, including a subagent's, does not.
|
||||
// An idle state the journal cannot date still republishes, since readers date it by `updatedAt`,
|
||||
// and so does one live child work holds open: readers take each publish as its evidence.
|
||||
a.statusStartedAt === b.statusStartedAt &&
|
||||
(a.status !== 'idle' ||
|
||||
a.updatedAt === b.updatedAt ||
|
||||
(a.statusStartedAt !== undefined && !isIdleHeldOpenByChildWork(b))) &&
|
||||
a.latestPrompt === b.latestPrompt &&
|
||||
a.model === b.model &&
|
||||
a.toolName === b.toolName &&
|
||||
a.toolInput === b.toolInput &&
|
||||
a.lastAssistantMessage === b.lastAssistantMessage &&
|
||||
a.turnOutcome === b.turnOutcome &&
|
||||
agentSessionBackgroundTasksEqual(a.backgroundTasks, b.backgroundTasks) &&
|
||||
structuredStatusChildrenEqual(a.children, b.children) &&
|
||||
agentProviderSessionsEqual(undefined, a.providerSession, b.providerSession)
|
||||
)
|
||||
}
|
||||
|
||||
/** Held open by the host's child records, read the way every row reads them. */
|
||||
function isIdleHeldOpenByChildWork(summary: AgentSessionStatusSummary): boolean {
|
||||
return (
|
||||
summary.status === 'idle' &&
|
||||
isAgentStatusHeldOpenByChildWork(
|
||||
structuredAgentSessionAgentStatus({
|
||||
status: summary.status,
|
||||
childWork: summary.children ?? summary.backgroundTasks,
|
||||
turnOutcome: summary.turnOutcome
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user