1- // @ts -nocheck -- frozen migration capsule; do not refactor against current Junior internals.
2- /* eslint-disable no-unused-vars */
3-
4- // packages/junior/src/cli/upgrade/migrations/agent-turn-session-actor.ts
51import { THREAD_STATE_TTL_MS } from "chat" ;
2+ import type {
3+ MigrationRedisV1 ,
4+ MigrationStateV1 ,
5+ MigrationV1 ,
6+ } from "@sentry/junior-migrations" ;
7+ import {
8+ isRecord ,
9+ migrationRedisKey ,
10+ toOptionalString ,
11+ } from "@sentry/junior/migration-helpers/v1" ;
612
7- // packages/junior/src/chat/coerce.ts
8- function toOptionalString ( value ) {
9- return typeof value === "string" && value . trim ( ) ? value : void 0 ;
10- }
11- function isRecord ( value ) {
12- return typeof value === "object" && value !== null ;
13- }
13+ type StateAdapter = MigrationStateV1 ;
14+ type RedisStateAdapter = { getClient ( ) : MigrationRedisV1 } ;
15+ type MigrationContext = {
16+ io ?: { info ( message : string ) : void } ;
17+ redisStateAdapter ?: RedisStateAdapter ;
18+ stateAdapter : StateAdapter ;
19+ } ;
20+ type MigrationResult = {
21+ existing : number ;
22+ migrated : number ;
23+ missing : number ;
24+ scanned : number ;
25+ } ;
1426
15- // migration:config
16- function getChatConfig ( ) {
17- const databaseUrl = process . env . DATABASE_URL ;
18- if ( ! databaseUrl ) throw new Error ( "DATABASE_URL is required" ) ;
19- const configured = process . env . JUNIOR_DATABASE_DRIVER ;
20- const url = new URL ( databaseUrl ) ;
21- const driver =
22- configured === "postgres" || configured === "neon"
23- ? configured
24- : url . hostname === "localhost" || url . hostname === "127.0.0.1"
25- ? "postgres"
26- : "neon" ;
27- return {
28- bot : { modelContextWindowTokens : void 0 } ,
29- sql : { databaseUrl, driver } ,
30- state : {
31- keyPrefix : process . env . JUNIOR_STATE_KEY_PREFIX ?. trim ( ) || void 0 ,
32- adapter : process . env . REDIS_URL ? "redis" : "memory" ,
33- redisUrl : process . env . REDIS_URL ,
34- } ,
35- } ;
27+ const AGENT_TURN_SESSION_PREFIX = "junior:agent_turn_session" ;
28+ const AGENT_TURN_SESSION_INDEX_KEY = `${ AGENT_TURN_SESSION_PREFIX } :index` ;
29+ const AGENT_TURN_SESSION_INDEX_MAX_LENGTH = 5_000 ;
30+ const REDIS_SCAN_COUNT = 500 ;
31+
32+ type RedisCommandClient = {
33+ sendCommand < T = unknown > ( args : readonly string [ ] ) : Promise < T > ;
34+ } ;
35+
36+ interface MigratedValue {
37+ changed : boolean ;
38+ value : unknown ;
3639}
3740
38- // packages/junior/src/cli/upgrade/migrations/agent-turn-session-actor.ts
39- var AGENT_TURN_SESSION_PREFIX = "junior:agent_turn_session" ;
40- var AGENT_TURN_SESSION_INDEX_KEY = `${ AGENT_TURN_SESSION_PREFIX } :index` ;
41- var AGENT_TURN_SESSION_INDEX_MAX_LENGTH = 5e3 ;
42- var REDIS_SCAN_COUNT = 500 ;
43- function conversationIndexKey ( conversationId ) {
41+ function conversationIndexKey ( conversationId : string ) : string {
4442 return `${ AGENT_TURN_SESSION_PREFIX } :conversation:${ conversationId } :index` ;
4543}
46- function sessionRecordKey ( conversationId , sessionId ) {
44+
45+ function sessionRecordKey ( conversationId : string , sessionId : string ) : string {
4746 return `${ AGENT_TURN_SESSION_PREFIX } :${ conversationId } :${ sessionId } ` ;
4847}
49- function logicalConversationIndexPrefix ( ) {
50- const prefix = getChatConfig ( ) . state . keyPrefix ;
51- return [
52- ...( prefix ? [ prefix ] : [ ] ) ,
53- `${ AGENT_TURN_SESSION_PREFIX } :conversation:` ,
54- ] . join ( ":" ) ;
48+
49+ function logicalConversationIndexPrefix ( ) : string {
50+ return migrationRedisKey ( `${ AGENT_TURN_SESSION_PREFIX } :conversation:` ) ;
5551}
56- function conversationIdFromRedisListKey ( key ) {
52+
53+ function conversationIdFromRedisListKey ( key : string ) : string | undefined {
5754 const marker = `:list:${ logicalConversationIndexPrefix ( ) } ` ;
5855 const markerIndex = key . indexOf ( marker ) ;
5956 if ( markerIndex < 0 || ! key . endsWith ( ":index" ) ) {
60- return void 0 ;
57+ return undefined ;
6158 }
6259 return toOptionalString (
6360 key . slice ( markerIndex + marker . length , - ":index" . length ) ,
6461 ) ;
6562}
66- async function discoverRedisConversationIds ( redisStateAdapter ) {
67- const client = redisStateAdapter ?. getClient ( ) ;
63+
64+ async function discoverRedisConversationIds (
65+ redisStateAdapter : RedisStateAdapter | undefined ,
66+ ) : Promise < string [ ] > {
67+ const client = redisStateAdapter ?. getClient ( ) as
68+ | RedisCommandClient
69+ | undefined ;
6870 if ( ! client ) {
6971 return [ ] ;
7072 }
71- const conversationIds = /* @__PURE__ */ new Set ( ) ;
73+
74+ const conversationIds = new Set < string > ( ) ;
7275 const match = `*:list:${ logicalConversationIndexPrefix ( ) } *:index` ;
7376 let cursor = "0" ;
7477 do {
75- const reply = await client . sendCommand ( [
78+ const reply = await client . sendCommand < unknown > ( [
7679 "SCAN" ,
7780 cursor ,
7881 "MATCH" ,
@@ -101,41 +104,55 @@ async function discoverRedisConversationIds(redisStateAdapter) {
101104 }
102105 }
103106 } while ( cursor !== "0" ) ;
107+
104108 return [ ...conversationIds ] ;
105109}
106- function migrateRequesterToActor ( value ) {
107- if ( ! isRecord ( value ) || value . requester === void 0 ) {
110+
111+ function migrateRequesterToActor ( value : unknown ) : MigratedValue {
112+ if ( ! isRecord ( value ) || value . requester === undefined ) {
108113 return { changed : false , value } ;
109114 }
115+
110116 const { requester, ...record } = value ;
111117 return {
112118 changed : true ,
113119 value : {
114120 ...record ,
115- ...( record . actor === void 0 ? { actor : requester } : { } ) ,
121+ ...( record . actor === undefined ? { actor : requester } : { } ) ,
116122 } ,
117123 } ;
118124}
119- async function rewriteList ( args ) {
125+
126+ async function rewriteList ( args : {
127+ key : string ;
128+ maxLength ?: number ;
129+ stateAdapter : StateAdapter ;
130+ } ) : Promise < { migrated : number ; values : unknown [ ] } > {
120131 const values = await args . stateAdapter . getList ( args . key ) ;
121132 const migrated = values . map ( migrateRequesterToActor ) ;
122133 const changed = migrated . filter ( ( entry ) => entry . changed ) . length ;
123134 if ( changed === 0 ) {
124135 return { migrated : 0 , values } ;
125136 }
137+
126138 await args . stateAdapter . delete ( args . key ) ;
127139 for ( const entry of migrated ) {
128140 await args . stateAdapter . appendToList ( args . key , entry . value , {
129- ...( args . maxLength !== void 0 ? { maxLength : args . maxLength } : { } ) ,
141+ ...( args . maxLength !== undefined ? { maxLength : args . maxLength } : { } ) ,
130142 ttlMs : THREAD_STATE_TTL_MS ,
131143 } ) ;
132144 }
133145 return { migrated : changed , values : migrated . map ( ( entry ) => entry . value ) } ;
134146}
135- async function migrateSessionRecord ( args ) {
147+
148+ async function migrateSessionRecord ( args : {
149+ conversationId : string ;
150+ sessionId : string ;
151+ stateAdapter : StateAdapter ;
152+ } ) : Promise < "existing" | "migrated" | "missing" > {
136153 const key = sessionRecordKey ( args . conversationId , args . sessionId ) ;
137- const existing = await args . stateAdapter . get ( key ) ;
138- if ( existing === void 0 ) {
154+ const existing = await args . stateAdapter . get < unknown > ( key ) ;
155+ if ( existing === undefined ) {
139156 return "missing" ;
140157 }
141158 const migrated = migrateRequesterToActor ( existing ) ;
@@ -145,8 +162,12 @@ async function migrateSessionRecord(args) {
145162 await args . stateAdapter . set ( key , migrated . value , THREAD_STATE_TTL_MS ) ;
146163 return "migrated" ;
147164}
148- async function migrateAgentTurnSessionActor ( context ) {
149- const result = {
165+
166+ /** Rewrite retained turn-session requester fields to actor fields. */
167+ export async function migrateAgentTurnSessionActor (
168+ context : MigrationContext ,
169+ ) : Promise < MigrationResult > {
170+ const result : MigrationResult = {
150171 existing : 0 ,
151172 migrated : 0 ,
152173 missing : 0 ,
@@ -159,8 +180,9 @@ async function migrateAgentTurnSessionActor(context) {
159180 } ) ;
160181 result . scanned += global . values . length ;
161182 result . migrated += global . migrated ;
162- const conversations = /* @__PURE__ */ new Set ( ) ;
163- const sessions = /* @__PURE__ */ new Set ( ) ;
183+
184+ const conversations = new Set < string > ( ) ;
185+ const sessions = new Set < string > ( ) ;
164186 for ( const conversationId of await discoverRedisConversationIds (
165187 context . redisStateAdapter ,
166188 ) ) {
@@ -177,9 +199,10 @@ async function migrateAgentTurnSessionActor(context) {
177199 }
178200 conversations . add ( conversationId ) ;
179201 if ( sessionId ) {
180- sessions . add ( `${ conversationId } \0 ${ sessionId } ` ) ;
202+ sessions . add ( `${ conversationId } \u0000 ${ sessionId } ` ) ;
181203 }
182204 }
205+
183206 for ( const conversationId of conversations ) {
184207 const conversation = await rewriteList ( {
185208 key : conversationIndexKey ( conversationId ) ,
@@ -193,12 +216,13 @@ async function migrateAgentTurnSessionActor(context) {
193216 }
194217 const sessionId = toOptionalString ( value . sessionId ) ;
195218 if ( sessionId ) {
196- sessions . add ( `${ conversationId } \0 ${ sessionId } ` ) ;
219+ sessions . add ( `${ conversationId } \u0000 ${ sessionId } ` ) ;
197220 }
198221 }
199222 }
223+
200224 for ( const session of sessions ) {
201- const separator = session . indexOf ( "\0 " ) ;
225+ const separator = session . indexOf ( "\u0000 " ) ;
202226 const conversationId = session . slice ( 0 , separator ) ;
203227 const sessionId = session . slice ( separator + 1 ) ;
204228 result . scanned += 1 ;
@@ -215,24 +239,20 @@ async function migrateAgentTurnSessionActor(context) {
215239 result . missing += 1 ;
216240 }
217241 }
242+
218243 return result ;
219244}
220245
221- // ../../../../../../private/tmp/0004_agent_turn_session_actor-entry.ts
222- var migration = {
246+ const migration = {
223247 apiVersion : 1 ,
224248 async up ( context ) {
225249 return await migrateAgentTurnSessionActor ( {
226250 stateAdapter : context . state ,
227- redisStateAdapter : context . redis
228- ? { getClient : ( ) => ( { sendCommand : context . redis . sendCommand } ) }
229- : void 0 ,
230- io : { info : context . log } ,
251+ ...( context . redis
252+ ? { redisStateAdapter : { getClient : ( ) => context . redis ! } }
253+ : { } ) ,
231254 } ) ;
232255 } ,
233- } ;
234- var agent_turn_session_actor_entry_default = migration ;
235- export {
236- agent_turn_session_actor_entry_default as default ,
237- migrateAgentTurnSessionActor ,
238- } ;
256+ } satisfies MigrationV1 ;
257+
258+ export default migration ;
0 commit comments