Skip to content

Commit 2ab1077

Browse files
Update Effect AI example to use shared fixtures module
- Import utilities from @openrouter-examples/shared/fixtures - Read verification codes from JSON metadata - Use absolute paths for PDF files - Remove hard-coded EXPECTED_CODES
1 parent 9b474d5 commit 2ab1077

File tree

1 file changed

+34
-70
lines changed

1 file changed

+34
-70
lines changed

typescript/effect-ai/src/plugin-file-parser/file-parser-all-sizes.ts

Lines changed: 34 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* - Layer-based dependency injection
88
* - Type-safe error handling with Effect
99
* - File processing with the FileParserPlugin
10+
* - Uses shared fixtures module with absolute paths
1011
*
1112
* To run: bun run typescript/effect-ai/src/plugin-file-parser/file-parser-all-sizes.ts
1213
*/
@@ -17,54 +18,18 @@ import * as LanguageModel from '@effect/ai/LanguageModel';
1718
import * as Prompt from '@effect/ai/Prompt';
1819
import { FetchHttpClient } from '@effect/platform';
1920
import * as BunContext from '@effect/platform-bun/BunContext';
21+
import {
22+
type PdfSize,
23+
PDF_SIZES,
24+
extractCode,
25+
formatSize,
26+
getPdfPath,
27+
getPdfSize,
28+
readExpectedCode,
29+
readPdfAsDataUrl,
30+
} from '@openrouter-examples/shared/fixtures';
2031
import { Console, Effect, Layer, Redacted } from 'effect';
2132

22-
const PDF_SIZES = ['small', 'medium', 'large', 'xlarge'] as const;
23-
24-
/**
25-
* Expected verification codes from PDFs
26-
*/
27-
const EXPECTED_CODES: Record<string, string> = {
28-
small: 'SMALL-7X9Q2',
29-
medium: 'MEDIUM-K4P8R',
30-
large: 'LARGE-M9N3T',
31-
xlarge: 'XLARGE-F6H2V',
32-
};
33-
34-
/**
35-
* Convert a PDF file to a base64 data URL
36-
*/
37-
const readPdfDataUrl = (filePath: string) =>
38-
Effect.promise(async () => {
39-
const pdfFile = Bun.file(filePath);
40-
const pdfBuffer = await pdfFile.arrayBuffer();
41-
const base64PDF = Buffer.from(pdfBuffer).toString('base64');
42-
return `data:application/pdf;base64,${base64PDF}`;
43-
});
44-
45-
/**
46-
* Get a PDF file's size for logging
47-
*/
48-
const getFileSize = (filePath: string) => Effect.sync(() => Bun.file(filePath).size);
49-
50-
/**
51-
* Format file size for display
52-
*/
53-
function formatSize(bytes: number): string {
54-
if (bytes < 1024 * 1024) {
55-
return `${(bytes / 1024).toFixed(0)} KB`;
56-
}
57-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
58-
}
59-
60-
/**
61-
* Extract verification code from response text
62-
*/
63-
function extractCode(text: string): string | null {
64-
const match = text.match(/[A-Z]+-[A-Z0-9]{5}/);
65-
return match ? match[0] : null;
66-
}
67-
6833
/**
6934
* OpenRouter FileParserPlugin configuration
7035
* This plugin enables server-side PDF parsing using OpenRouter's file parser
@@ -84,17 +49,15 @@ const fileParserConfig: OpenRouterLanguageModel.Config.Service = {
8449
/**
8550
* Process a single PDF file with logging and error handling
8651
*/
87-
const processPdf = (size: string, expectedCode: string) =>
52+
const processPdf = (size: PdfSize, expectedCode: string) =>
8853
Effect.gen(function* () {
89-
const filePath = `./fixtures/pdfs/${size}.pdf`;
90-
9154
yield* Console.log(`\n=== ${size.toUpperCase()} PDF ===`);
9255

93-
const sizeBytes = yield* getFileSize(filePath);
56+
const sizeBytes = getPdfSize(size);
9457
yield* Console.log(`Size: ${formatSize(sizeBytes)}`);
9558
yield* Console.log(`Expected: ${expectedCode}`);
9659

97-
const dataUrl = yield* readPdfDataUrl(filePath);
60+
const dataUrl = yield* Effect.promise(() => readPdfAsDataUrl(size));
9861

9962
/**
10063
* Construct prompt with file attachment for file parser plugin
@@ -140,32 +103,33 @@ const processPdf = (size: string, expectedCode: string) =>
140103
* Main program orchestrating all PDF runs
141104
*/
142105
const program = Effect.gen(function* () {
143-
yield* Console.log(
144-
'╔════════════════════════════════════════════════════════════════════════════╗',
145-
);
146-
yield* Console.log(
147-
'║ OpenRouter FileParserPlugin - Effect AI ║',
148-
);
149-
yield* Console.log(
150-
'╚════════════════════════════════════════════════════════════════════════════╝',
151-
);
106+
yield* Console.log('╔════════════════════════════════════════════════════════════════════════════╗');
107+
yield* Console.log('║ OpenRouter FileParserPlugin - Effect AI ║');
108+
yield* Console.log('╚════════════════════════════════════════════════════════════════════════════╝');
152109
yield* Console.log();
153110
yield* Console.log('Testing PDF processing with verification code extraction');
154111
yield* Console.log();
155112

156-
const logFailure = (label: string) => (error: unknown) =>
157-
Effect.gen(function* () {
158-
yield* Console.error(`Error processing ${label}:`, error);
159-
return {
160-
success: false,
161-
extracted: null,
162-
expected: EXPECTED_CODES[label] || '',
163-
};
164-
});
113+
const logFailure =
114+
(label: string) =>
115+
(error: unknown) =>
116+
Effect.gen(function* () {
117+
yield* Console.error(`Error processing ${label}:`, error);
118+
return {
119+
success: false,
120+
extracted: null,
121+
expected: '',
122+
};
123+
});
165124

166125
const results = yield* Effect.all(
167126
PDF_SIZES.map((size) =>
168-
processPdf(size, EXPECTED_CODES[size]).pipe(Effect.catchAll(logFailure(size))),
127+
Effect.gen(function* () {
128+
const expectedCode = yield* Effect.promise(() => readExpectedCode(size));
129+
return yield* processPdf(size, expectedCode).pipe(
130+
Effect.catchAll(logFailure(size)),
131+
);
132+
}),
169133
),
170134
{ concurrency: 'unbounded' },
171135
);

0 commit comments

Comments
 (0)