@@ -8,6 +8,8 @@ import { ClaudeClient, formatCostEstimate } from "./claude-client.ts";
88import { OpenAIClient } from "./openai-client.ts" ;
99import { BatchDeminifyClient } from "./batch-client.ts" ;
1010import type { BatchStatus } from "./batch-client.ts" ;
11+ import { OpenAIBatchClient } from "./openai-batch.ts" ;
12+ import type { OpenAIBatchStatus } from "./openai-batch.ts" ;
1113import {
1214 saveBatchState ,
1315 loadBatchState ,
@@ -77,6 +79,7 @@ export class Deminifier {
7779 private config : DeminifyConfig ;
7880 private client : ClaudeClient | OpenAIClient ;
7981 private batchClient : BatchDeminifyClient | null ;
82+ private openAIBatchClient : OpenAIBatchClient | null ;
8083 private cache : DeminifyCache | null ;
8184 private stats : DeminifyStats ;
8285
@@ -86,10 +89,12 @@ export class Deminifier {
8689 // Select client based on provider
8790 if ( config . provider === "openai" ) {
8891 this . client = new OpenAIClient ( config ) ;
89- this . batchClient = null ; // OpenAI doesn't have equivalent batch API
92+ this . batchClient = null ;
93+ this . openAIBatchClient = new OpenAIBatchClient ( config ) ;
9094 } else {
9195 this . client = new ClaudeClient ( config ) ;
9296 this . batchClient = new BatchDeminifyClient ( config ) ;
97+ this . openAIBatchClient = null ;
9398 }
9499
95100 this . cache = config . cacheEnabled
@@ -418,7 +423,13 @@ export class Deminifier {
418423
419424 const result = await processor . processAll ( source , graph , {
420425 // maxBatchTokens computed from model context limit if not specified
426+ < << << << Updated upstream
421427 ...( options ?. maxBatchTokens !== undefined ? { maxBatchTokens : options . maxBatchTokens } : { } ) ,
428+ | || || || Stash base
429+ maxBatchTokens : options ?. maxBatchTokens ,
430+ = === ===
431+ ...( options ?. maxBatchTokens !== undefined && { maxBatchTokens : options . maxBatchTokens } ) ,
432+ > >>> >>> Stashed changes
422433 verbose : this . config . verbose ,
423434 onProgress : ( progress ) => {
424435 const progressUpdate : DeminifyProgress = {
@@ -470,11 +481,13 @@ export class Deminifier {
470481 fileContext : FileContext ,
471482 options : DeminifyFileOptions
472483 ) : Promise < string > {
473- // Batch mode only available for Anthropic
474- if ( ! this . batchClient ) {
475- throw new Error (
476- "Batch mode is only available with Anthropic provider. Use --provider anthropic or remove --batch flag."
477- ) ;
484+ // Check that we have a batch client for the provider
485+ const isOpenAI = this . config . provider === "openai" ;
486+ if ( isOpenAI && ! this . openAIBatchClient ) {
487+ throw new Error ( "OpenAI batch client not initialized" ) ;
488+ }
489+ if ( ! isOpenAI && ! this . batchClient ) {
490+ throw new Error ( "Anthropic batch client not initialized" ) ;
478491 }
479492
480493 const fileName = options . fileName ?? "unknown.js" ;
@@ -520,9 +533,16 @@ export class Deminifier {
520533 contexts . set ( func . id , context ) ;
521534 }
522535
523- // Create batch
524- console . log ( "Submitting batch to Anthropic API..." ) ;
525- const batchId = await this . batchClient . createBatch ( contexts ) ;
536+ // Create batch using the appropriate client
537+ const providerName = isOpenAI ? "OpenAI" : "Anthropic" ;
538+ console . log ( `Submitting batch to ${ providerName } API...` ) ;
539+
540+ let batchId : string ;
541+ if ( isOpenAI ) {
542+ batchId = await this . openAIBatchClient ! . createBatch ( contexts ) ;
543+ } else {
544+ batchId = await this . batchClient ! . createBatch ( contexts ) ;
545+ }
526546
527547 // Save state for resume (includes projectId for isolation in shared environments)
528548 await saveBatchState (
@@ -542,27 +562,57 @@ export class Deminifier {
542562 console . log ( `\nBatch submitted: ${ batchId } ` ) ;
543563 console . log ( "Waiting for results (typically 30-60 minutes)...\n" ) ;
544564
545- // Poll for completion
546- await this . batchClient . waitForCompletion ( batchId , {
547- onStatusUpdate : ( status ) => {
548- options . onBatchStatus ?.( status ) ;
549- if ( ! options . onBatchStatus ) {
550- // Default console output
551- const pct =
552- status . total > 0
553- ? Math . round ( ( status . succeeded / status . total ) * 100 )
554- : 0 ;
555- process . stdout . write (
556- `\r Progress: ${ status . succeeded } /${ status . total } (${ pct } %) | Errors: ${ status . errored } `
557- ) ;
558- }
559- } ,
560- } ) ;
565+ // Poll for completion using the appropriate client
566+ if ( isOpenAI ) {
567+ await this . openAIBatchClient ! . waitForCompletion ( batchId , {
568+ onStatusUpdate : ( status : OpenAIBatchStatus ) => {
569+ // Convert to common format for callback
570+ const commonStatus : BatchStatus = {
571+ batchId : status . batchId ,
572+ status : status . status === "completed" ? "ended" : "in_progress" ,
573+ total : status . total ,
574+ succeeded : status . completed ,
575+ errored : status . failed ,
576+ processing : status . total - status . completed - status . failed ,
577+ } ;
578+ options . onBatchStatus ?.( commonStatus ) ;
579+ if ( ! options . onBatchStatus ) {
580+ const pct =
581+ status . total > 0
582+ ? Math . round ( ( status . completed / status . total ) * 100 )
583+ : 0 ;
584+ process . stdout . write (
585+ `\r Progress: ${ status . completed } /${ status . total } (${ pct } %) | Errors: ${ status . failed } `
586+ ) ;
587+ }
588+ } ,
589+ } ) ;
590+ } else {
591+ await this . batchClient ! . waitForCompletion ( batchId , {
592+ onStatusUpdate : ( status ) => {
593+ options . onBatchStatus ?.( status ) ;
594+ if ( ! options . onBatchStatus ) {
595+ const pct =
596+ status . total > 0
597+ ? Math . round ( ( status . succeeded / status . total ) * 100 )
598+ : 0 ;
599+ process . stdout . write (
600+ `\r Progress: ${ status . succeeded } /${ status . total } (${ pct } %) | Errors: ${ status . errored } `
601+ ) ;
602+ }
603+ } ,
604+ } ) ;
605+ }
561606
562607 console . log ( "\n\nBatch complete! Retrieving results..." ) ;
563608
564- // Get results
565- const results = await this . batchClient . getResults ( batchId , contexts ) ;
609+ // Get results using the appropriate client
610+ let results : Map < string , DeminifyResult > ;
611+ if ( isOpenAI ) {
612+ results = await this . openAIBatchClient ! . getResults ( batchId , contexts ) ;
613+ } else {
614+ results = await this . batchClient ! . getResults ( batchId , contexts ) ;
615+ }
566616
567617 console . log ( `Retrieved ${ results . size } results` ) ;
568618
@@ -610,8 +660,12 @@ export class Deminifier {
610660 batchId : string ,
611661 options : DeminifyFileOptions
612662 ) : Promise < string > {
613- if ( ! this . batchClient ) {
614- throw new Error ( "Batch mode is only available with Anthropic provider." ) ;
663+ const isOpenAI = this . config . provider === "openai" ;
664+ if ( isOpenAI && ! this . openAIBatchClient ) {
665+ throw new Error ( "OpenAI batch client not initialized" ) ;
666+ }
667+ if ( ! isOpenAI && ! this . batchClient ) {
668+ throw new Error ( "Anthropic batch client not initialized" ) ;
615669 }
616670
617671 // Rebuild contexts
@@ -626,33 +680,74 @@ export class Deminifier {
626680 contexts . set ( func . id , context ) ;
627681 }
628682
629- // Check batch status
630- const status = await this . batchClient . getBatchStatus ( batchId ) ;
631-
632- if ( status . status === "in_progress" ) {
633- console . log (
634- `Batch still processing: ${ status . succeeded } /${ status . total } complete`
635- ) ;
636- console . log ( "Waiting for completion...\n" ) ;
683+ // Check batch status using appropriate client
684+ if ( isOpenAI ) {
685+ const status = await this . openAIBatchClient ! . getBatchStatus ( batchId ) ;
686+
687+ if (
688+ status . status === "in_progress" ||
689+ status . status === "validating" ||
690+ status . status === "finalizing"
691+ ) {
692+ console . log (
693+ `Batch still processing: ${ status . completed } /${ status . total } complete`
694+ ) ;
695+ console . log ( "Waiting for completion...\n" ) ;
696+
697+ await this . openAIBatchClient ! . waitForCompletion ( batchId , {
698+ onStatusUpdate : ( s : OpenAIBatchStatus ) => {
699+ const commonStatus : BatchStatus = {
700+ batchId : s . batchId ,
701+ status : s . status === "completed" ? "ended" : "in_progress" ,
702+ total : s . total ,
703+ succeeded : s . completed ,
704+ errored : s . failed ,
705+ processing : s . total - s . completed - s . failed ,
706+ } ;
707+ options . onBatchStatus ?.( commonStatus ) ;
708+ if ( ! options . onBatchStatus ) {
709+ const pct =
710+ s . total > 0 ? Math . round ( ( s . completed / s . total ) * 100 ) : 0 ;
711+ process . stdout . write (
712+ `\r Progress: ${ s . completed } /${ s . total } (${ pct } %) | Errors: ${ s . failed } `
713+ ) ;
714+ }
715+ } ,
716+ } ) ;
717+ }
718+ } else {
719+ const status = await this . batchClient ! . getBatchStatus ( batchId ) ;
637720
638- await this . batchClient . waitForCompletion ( batchId , {
639- onStatusUpdate : ( s ) => {
640- options . onBatchStatus ?.( s ) ;
641- if ( ! options . onBatchStatus ) {
642- const pct =
643- s . total > 0 ? Math . round ( ( s . succeeded / s . total ) * 100 ) : 0 ;
644- process . stdout . write (
645- `\r Progress: ${ s . succeeded } /${ s . total } (${ pct } %) | Errors: ${ s . errored } `
646- ) ;
647- }
648- } ,
649- } ) ;
721+ if ( status . status === "in_progress" ) {
722+ console . log (
723+ `Batch still processing: ${ status . succeeded } /${ status . total } complete`
724+ ) ;
725+ console . log ( "Waiting for completion...\n" ) ;
726+
727+ await this . batchClient ! . waitForCompletion ( batchId , {
728+ onStatusUpdate : ( s ) => {
729+ options . onBatchStatus ?.( s ) ;
730+ if ( ! options . onBatchStatus ) {
731+ const pct =
732+ s . total > 0 ? Math . round ( ( s . succeeded / s . total ) * 100 ) : 0 ;
733+ process . stdout . write (
734+ `\r Progress: ${ s . succeeded } /${ s . total } (${ pct } %) | Errors: ${ s . errored } `
735+ ) ;
736+ }
737+ } ,
738+ } ) ;
739+ }
650740 }
651741
652742 console . log ( "\n\nRetrieving results..." ) ;
653743
654- // Get results
655- const results = await this . batchClient . getResults ( batchId , contexts ) ;
744+ // Get results using appropriate client
745+ let results : Map < string , DeminifyResult > ;
746+ if ( isOpenAI ) {
747+ results = await this . openAIBatchClient ! . getResults ( batchId , contexts ) ;
748+ } else {
749+ results = await this . batchClient ! . getResults ( batchId , contexts ) ;
750+ }
656751
657752 console . log ( `Retrieved ${ results . size } results` ) ;
658753
0 commit comments