Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

97 lines
3.0 KiB
TypeScript

import {
selectPlanTurnDismissed,
selectSessionMessages,
selectWorkspaceAgentConsumerSessions,
type AgentActivitySession,
type AgentActivityTurn
} from "@tutti-os/agent-activity-core";
import { latestPlanTurnId } from "./planImplementationPresentation";
type AgentSessionEngineSnapshot = Parameters<
typeof selectWorkspaceAgentConsumerSessions
>[0];
/**
* Shared predicate for the synthesized plan-implementation wait. Durable
* approval / question / exit-plan waits already ride pendingInteractions;
* this predicate is the matching cross-surface fact for plan confirmation so
* rail, conversation list, and attention do not each invent a private rule.
*
* Capability rules match the detail composer: an explicit `false` fails closed,
* but a missing capabilities record stays open so a settled plan turn can still
* surface waiting while composer options are the only advertised source.
*/
export function consumerAwaitingPlanImplementation(input: {
capabilities: AgentActivitySession["capabilities"] | null | undefined;
dismissed: boolean;
latestTurn: AgentActivityTurn | null | undefined;
messages: readonly {
turnId?: string | null;
occurredAtUnixMs?: number | null;
createdAtUnixMs?: number | null;
seq?: number | null;
payload?: Record<string, unknown> | null;
}[];
}): boolean {
const latestTurn = input.latestTurn;
if (
!latestTurn ||
latestTurn.phase !== "settled" ||
latestTurn.outcome !== "completed" ||
input.dismissed ||
!sessionAllowsPlanImplementation(input.capabilities)
) {
return false;
}
return latestPlanTurnId(input.messages) === latestTurn.turnId;
}
function sessionAllowsPlanImplementation(
capabilities: AgentActivitySession["capabilities"] | null | undefined
): boolean {
if (!capabilities) {
return true;
}
return (
capabilities.planImplementation === true && capabilities.planMode === true
);
}
export function selectRootAgentSessionIdsAwaitingPlanImplementation(
state: AgentSessionEngineSnapshot
): readonly string[] {
const sessionIds: string[] = [];
for (const consumer of selectWorkspaceAgentConsumerSessions(state)) {
const sessionId = consumer.session.agentSessionId;
if (
!consumerAwaitingPlanImplementation({
capabilities: consumer.session.capabilities,
dismissed: selectPlanTurnDismissed(
state,
sessionId,
consumer.latestTurn?.turnId
),
latestTurn: consumer.latestTurn,
messages: sessionMessagesForPlanDetection(state, consumer.session)
})
) {
continue;
}
sessionIds.push(sessionId);
}
return sessionIds;
}
function sessionMessagesForPlanDetection(
state: AgentSessionEngineSnapshot,
session: Pick<AgentActivitySession, "agentSessionId" | "providerSessionId">
) {
for (const id of [session.agentSessionId, session.providerSessionId]) {
const messages = selectSessionMessages(state, id);
if (messages.length > 0) {
return messages;
}
}
return [];
}