| ... | @@ -15,12 +15,12 @@ import type { EnvironmentThread, EnvironmentThreadShell } from "./models.ts"; | ... | @@ -15,12 +15,12 @@ import type { EnvironmentThread, EnvironmentThreadShell } from "./models.ts"; |
| 15 | import { scopeThread } from "./models.ts"; | 15 | import { scopeThread } from "./models.ts"; |
| 16 | import { EMPTY_ENVIRONMENT_THREAD_STATE, type EnvironmentThreadState } from "./threads.ts"; | 16 | import { EMPTY_ENVIRONMENT_THREAD_STATE, type EnvironmentThreadState } from "./threads.ts"; |
| 17 | import { parseThreadKey, threadKey } from "./entities.ts"; | 17 | import { parseThreadKey, threadKey } from "./entities.ts"; |
| | 18 | import { THREAD_STATE_IDLE_TTL_MS } from "./threadRetention.ts"; |
| 18 | | 19 | |
| 19 | const EMPTY_MESSAGES: ReadonlyArray<OrchestrationMessage> = Object.freeze([]); | 20 | const EMPTY_MESSAGES: ReadonlyArray<OrchestrationMessage> = Object.freeze([]); |
| 20 | const EMPTY_ACTIVITIES: ReadonlyArray<OrchestrationThreadActivity> = Object.freeze([]); | 21 | const EMPTY_ACTIVITIES: ReadonlyArray<OrchestrationThreadActivity> = Object.freeze([]); |
| 21 | const EMPTY_PROPOSED_PLANS: ReadonlyArray<OrchestrationProposedPlan> = Object.freeze([]); | 22 | const EMPTY_PROPOSED_PLANS: ReadonlyArray<OrchestrationProposedPlan> = Object.freeze([]); |
| 22 | const EMPTY_CHECKPOINTS: ReadonlyArray<OrchestrationCheckpointSummary> = Object.freeze([]); | 23 | const EMPTY_CHECKPOINTS: ReadonlyArray<OrchestrationCheckpointSummary> = Object.freeze([]); |
| 23 | const THREAD_DETAIL_IDLE_TTL_MS = 5 * 60_000; | | |
| 24 | | 24 | |
| 25 | /** | 25 | /** |
| 26 | * Combine detail-only collections with the shell's authoritative thread metadata. | 26 | * Combine detail-only collections with the shell's authoritative thread metadata. |
| ... | @@ -75,7 +75,7 @@ export function createEnvironmentThreadDetailAtoms<E>( | ... | @@ -75,7 +75,7 @@ export function createEnvironmentThreadDetailAtoms<E>( |
| 75 | () => EMPTY_ENVIRONMENT_THREAD_STATE, | 75 | () => EMPTY_ENVIRONMENT_THREAD_STATE, |
| 76 | ), | 76 | ), |
| 77 | ).pipe( | 77 | ).pipe( |
| 78 | Atom.setIdleTTL(THREAD_DETAIL_IDLE_TTL_MS), | 78 | Atom.setIdleTTL(THREAD_STATE_IDLE_TTL_MS), |
| 79 | Atom.withLabel(`environment-thread-state-value:${key}`), | 79 | Atom.withLabel(`environment-thread-state-value:${key}`), |
| 80 | ); | 80 | ); |
| 81 | }); | 81 | }); |
| ... | @@ -93,21 +93,21 @@ export function createEnvironmentThreadDetailAtoms<E>( | ... | @@ -93,21 +93,21 @@ export function createEnvironmentThreadDetailAtoms<E>( |
| 93 | previousValue = source === null ? null : scopeThread(ref.environmentId, source); | 93 | previousValue = source === null ? null : scopeThread(ref.environmentId, source); |
| 94 | return previousValue; | 94 | return previousValue; |
| 95 | }).pipe( | 95 | }).pipe( |
| 96 | Atom.setIdleTTL(THREAD_DETAIL_IDLE_TTL_MS), | 96 | Atom.setIdleTTL(THREAD_STATE_IDLE_TTL_MS), |
| 97 | Atom.withLabel(`environment-thread-detail:${key}`), | 97 | Atom.withLabel(`environment-thread-detail:${key}`), |
| 98 | ); | 98 | ); |
| 99 | }); | 99 | }); |
| 100 | | 100 | |
| 101 | const threadStatusAtomFamily = Atom.family((key: string) => | 101 | const threadStatusAtomFamily = Atom.family((key: string) => |
| 102 | Atom.make((get) => get(threadStateValueAtomFamily(key)).status).pipe( | 102 | Atom.make((get) => get(threadStateValueAtomFamily(key)).status).pipe( |
| 103 | Atom.setIdleTTL(THREAD_DETAIL_IDLE_TTL_MS), | 103 | Atom.setIdleTTL(THREAD_STATE_IDLE_TTL_MS), |
| 104 | Atom.withLabel(`environment-thread-status:${key}`), | 104 | Atom.withLabel(`environment-thread-status:${key}`), |
| 105 | ), | 105 | ), |
| 106 | ); | 106 | ); |
| 107 | | 107 | |
| 108 | const threadErrorAtomFamily = Atom.family((key: string) => | 108 | const threadErrorAtomFamily = Atom.family((key: string) => |
| 109 | Atom.make((get) => Option.getOrNull(get(threadStateValueAtomFamily(key)).error)).pipe( | 109 | Atom.make((get) => Option.getOrNull(get(threadStateValueAtomFamily(key)).error)).pipe( |
| 110 | Atom.setIdleTTL(THREAD_DETAIL_IDLE_TTL_MS), | 110 | Atom.setIdleTTL(THREAD_STATE_IDLE_TTL_MS), |
| 111 | Atom.withLabel(`environment-thread-error:${key}`), | 111 | Atom.withLabel(`environment-thread-error:${key}`), |
| 112 | ), | 112 | ), |
| 113 | ); | 113 | ); |
| ... | @@ -117,7 +117,7 @@ export function createEnvironmentThreadDetailAtoms<E>( | ... | @@ -117,7 +117,7 @@ export function createEnvironmentThreadDetailAtoms<E>( |
| 117 | (get): ReadonlyArray<OrchestrationMessage> => | 117 | (get): ReadonlyArray<OrchestrationMessage> => |
| 118 | get(threadDetailAtomFamily(key))?.messages ?? EMPTY_MESSAGES, | 118 | get(threadDetailAtomFamily(key))?.messages ?? EMPTY_MESSAGES, |
| 119 | ).pipe( | 119 | ).pipe( |
| 120 | Atom.setIdleTTL(THREAD_DETAIL_IDLE_TTL_MS), | 120 | Atom.setIdleTTL(THREAD_STATE_IDLE_TTL_MS), |
| 121 | Atom.withLabel(`environment-thread-messages:${key}`), | 121 | Atom.withLabel(`environment-thread-messages:${key}`), |
| 122 | ), | 122 | ), |
| 123 | ); | 123 | ); |
| ... | @@ -127,7 +127,7 @@ export function createEnvironmentThreadDetailAtoms<E>( | ... | @@ -127,7 +127,7 @@ export function createEnvironmentThreadDetailAtoms<E>( |
| 127 | (get): ReadonlyArray<OrchestrationThreadActivity> => | 127 | (get): ReadonlyArray<OrchestrationThreadActivity> => |
| 128 | get(threadDetailAtomFamily(key))?.activities ?? EMPTY_ACTIVITIES, | 128 | get(threadDetailAtomFamily(key))?.activities ?? EMPTY_ACTIVITIES, |
| 129 | ).pipe( | 129 | ).pipe( |
| 130 | Atom.setIdleTTL(THREAD_DETAIL_IDLE_TTL_MS), | 130 | Atom.setIdleTTL(THREAD_STATE_IDLE_TTL_MS), |
| 131 | Atom.withLabel(`environment-thread-activities:${key}`), | 131 | Atom.withLabel(`environment-thread-activities:${key}`), |
| 132 | ), | 132 | ), |
| 133 | ); | 133 | ); |
| ... | @@ -137,7 +137,7 @@ export function createEnvironmentThreadDetailAtoms<E>( | ... | @@ -137,7 +137,7 @@ export function createEnvironmentThreadDetailAtoms<E>( |
| 137 | (get): ReadonlyArray<OrchestrationProposedPlan> => | 137 | (get): ReadonlyArray<OrchestrationProposedPlan> => |
| 138 | get(threadDetailAtomFamily(key))?.proposedPlans ?? EMPTY_PROPOSED_PLANS, | 138 | get(threadDetailAtomFamily(key))?.proposedPlans ?? EMPTY_PROPOSED_PLANS, |
| 139 | ).pipe( | 139 | ).pipe( |
| 140 | Atom.setIdleTTL(THREAD_DETAIL_IDLE_TTL_MS), | 140 | Atom.setIdleTTL(THREAD_STATE_IDLE_TTL_MS), |
| 141 | Atom.withLabel(`environment-thread-proposed-plans:${key}`), | 141 | Atom.withLabel(`environment-thread-proposed-plans:${key}`), |
| 142 | ), | 142 | ), |
| 143 | ); | 143 | ); |
| ... | @@ -147,7 +147,7 @@ export function createEnvironmentThreadDetailAtoms<E>( | ... | @@ -147,7 +147,7 @@ export function createEnvironmentThreadDetailAtoms<E>( |
| 147 | (get): ReadonlyArray<OrchestrationCheckpointSummary> => | 147 | (get): ReadonlyArray<OrchestrationCheckpointSummary> => |
| 148 | get(threadDetailAtomFamily(key))?.checkpoints ?? EMPTY_CHECKPOINTS, | 148 | get(threadDetailAtomFamily(key))?.checkpoints ?? EMPTY_CHECKPOINTS, |
| 149 | ).pipe( | 149 | ).pipe( |
| 150 | Atom.setIdleTTL(THREAD_DETAIL_IDLE_TTL_MS), | 150 | Atom.setIdleTTL(THREAD_STATE_IDLE_TTL_MS), |
| 151 | Atom.withLabel(`environment-thread-checkpoints:${key}`), | 151 | Atom.withLabel(`environment-thread-checkpoints:${key}`), |
| 152 | ), | 152 | ), |
| 153 | ); | 153 | ); |
| ... | @@ -156,7 +156,7 @@ export function createEnvironmentThreadDetailAtoms<E>( | ... | @@ -156,7 +156,7 @@ export function createEnvironmentThreadDetailAtoms<E>( |
| 156 | Atom.make( | 156 | Atom.make( |
| 157 | (get): OrchestrationSession | null => get(threadDetailAtomFamily(key))?.session ?? null, | 157 | (get): OrchestrationSession | null => get(threadDetailAtomFamily(key))?.session ?? null, |
| 158 | ).pipe( | 158 | ).pipe( |
| 159 | Atom.setIdleTTL(THREAD_DETAIL_IDLE_TTL_MS), | 159 | Atom.setIdleTTL(THREAD_STATE_IDLE_TTL_MS), |
| 160 | Atom.withLabel(`environment-thread-session:${key}`), | 160 | Atom.withLabel(`environment-thread-session:${key}`), |
| 161 | ), | 161 | ), |
| 162 | ); | 162 | ); |
| ... | @@ -165,7 +165,7 @@ export function createEnvironmentThreadDetailAtoms<E>( | ... | @@ -165,7 +165,7 @@ export function createEnvironmentThreadDetailAtoms<E>( |
| 165 | Atom.make( | 165 | Atom.make( |
| 166 | (get): OrchestrationLatestTurn | null => get(threadDetailAtomFamily(key))?.latestTurn ?? null, | 166 | (get): OrchestrationLatestTurn | null => get(threadDetailAtomFamily(key))?.latestTurn ?? null, |
| 167 | ).pipe( | 167 | ).pipe( |
| 168 | Atom.setIdleTTL(THREAD_DETAIL_IDLE_TTL_MS), | 168 | Atom.setIdleTTL(THREAD_STATE_IDLE_TTL_MS), |
| 169 | Atom.withLabel(`environment-thread-latest-turn:${key}`), | 169 | Atom.withLabel(`environment-thread-latest-turn:${key}`), |
| 170 | ), | 170 | ), |
| 171 | ); | 171 | ); |