@intelligentelectron/pdf-analyzer 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/cli/commands.d.ts +6 -2
  2. package/dist/cli/commands.d.ts.map +1 -1
  3. package/dist/cli/commands.js +83 -100
  4. package/dist/cli/commands.js.map +1 -1
  5. package/dist/index.d.ts +2 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +9 -3
  8. package/dist/index.js.map +1 -1
  9. package/dist/keychain.d.ts +21 -7
  10. package/dist/keychain.d.ts.map +1 -1
  11. package/dist/keychain.js +79 -38
  12. package/dist/keychain.js.map +1 -1
  13. package/dist/pdf-utils.d.ts +28 -0
  14. package/dist/pdf-utils.d.ts.map +1 -0
  15. package/dist/pdf-utils.js +93 -0
  16. package/dist/pdf-utils.js.map +1 -0
  17. package/dist/providers/anthropic.d.ts +9 -0
  18. package/dist/providers/anthropic.d.ts.map +1 -0
  19. package/dist/providers/anthropic.js +69 -0
  20. package/dist/providers/anthropic.js.map +1 -0
  21. package/dist/providers/google.d.ts +13 -0
  22. package/dist/providers/google.d.ts.map +1 -0
  23. package/dist/providers/google.js +120 -0
  24. package/dist/providers/google.js.map +1 -0
  25. package/dist/providers/openai.d.ts +9 -0
  26. package/dist/providers/openai.d.ts.map +1 -0
  27. package/dist/providers/openai.js +70 -0
  28. package/dist/providers/openai.js.map +1 -0
  29. package/dist/providers/registry.d.ts +23 -0
  30. package/dist/providers/registry.d.ts.map +1 -0
  31. package/dist/providers/registry.js +44 -0
  32. package/dist/providers/registry.js.map +1 -0
  33. package/dist/providers/types.d.ts +70 -0
  34. package/dist/providers/types.d.ts.map +1 -0
  35. package/dist/providers/types.js +2 -0
  36. package/dist/providers/types.js.map +1 -0
  37. package/dist/server.d.ts +2 -1
  38. package/dist/server.d.ts.map +1 -1
  39. package/dist/server.js +27 -31
  40. package/dist/server.js.map +1 -1
  41. package/dist/service.d.ts +7 -35
  42. package/dist/service.d.ts.map +1 -1
  43. package/dist/service.js +99 -274
  44. package/dist/service.js.map +1 -1
  45. package/dist/types.d.ts +20 -12
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/types.js +15 -45
  48. package/dist/types.js.map +1 -1
  49. package/package.json +12 -4
package/dist/keychain.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * OS-native credential storage for GEMINI_API_KEY.
2
+ * OS-native credential storage.
3
3
  *
4
4
  * Uses platform CLI tools (no native addons) so it works with Bun-compiled binaries.
5
5
  * - macOS: `security` CLI (Keychain Access)
@@ -7,8 +7,7 @@
7
7
  * - Linux: `secret-tool` (libsecret), if available
8
8
  */
9
9
  import { execSync } from "node:child_process";
10
- const DEFAULT_SERVICE_NAME = "pdf-analyzer";
11
- const ACCOUNT_NAME = "GEMINI_API_KEY";
10
+ const DEFAULT_SERVICE = "pdf-analyzer";
12
11
  /** Stdio config that prevents credential leaks to MCP stdio transport. */
13
12
  const SILENT_STDIO = ["pipe", "pipe", "pipe"];
14
13
  /**
@@ -21,20 +20,20 @@ export function escapeShellArg(arg) {
21
20
  // ---------------------------------------------------------------------------
22
21
  // macOS (Keychain)
23
22
  // ---------------------------------------------------------------------------
24
- function getMacOS(service) {
23
+ function getMacOS(service, account) {
25
24
  try {
26
- return execSync(`security find-generic-password -s ${escapeShellArg(service)} -a ${escapeShellArg(ACCOUNT_NAME)} -w`, { stdio: SILENT_STDIO, encoding: "utf-8" }).trim();
25
+ return execSync(`security find-generic-password -s ${escapeShellArg(service)} -a ${escapeShellArg(account)} -w`, { stdio: SILENT_STDIO, encoding: "utf-8" }).trim();
27
26
  }
28
27
  catch {
29
28
  return null;
30
29
  }
31
30
  }
32
- function setMacOS(service, key) {
33
- execSync(`security add-generic-password -s ${escapeShellArg(service)} -a ${escapeShellArg(ACCOUNT_NAME)} -w ${escapeShellArg(key)} -U`, { stdio: SILENT_STDIO });
31
+ function setMacOS(service, account, value) {
32
+ execSync(`security add-generic-password -s ${escapeShellArg(service)} -a ${escapeShellArg(account)} -w ${escapeShellArg(value)} -U`, { stdio: SILENT_STDIO });
34
33
  }
35
- function deleteMacOS(service) {
34
+ function deleteMacOS(service, account) {
36
35
  try {
37
- execSync(`security delete-generic-password -s ${escapeShellArg(service)} -a ${escapeShellArg(ACCOUNT_NAME)}`, { stdio: SILENT_STDIO });
36
+ execSync(`security delete-generic-password -s ${escapeShellArg(service)} -a ${escapeShellArg(account)}`, { stdio: SILENT_STDIO });
38
37
  }
39
38
  catch {
40
39
  // Credential may not exist; ignore
@@ -43,9 +42,13 @@ function deleteMacOS(service) {
43
42
  // ---------------------------------------------------------------------------
44
43
  // Windows (Credential Manager)
45
44
  // ---------------------------------------------------------------------------
46
- function getWindows(service) {
45
+ /** Build a Windows credential target from service + account. */
46
+ function winTarget(service, account) {
47
+ return `${service}/${account}`;
48
+ }
49
+ function getWindows(service, account) {
47
50
  try {
48
- // cmdkey cannot read credential values, so we use PowerShell with P/Invoke
51
+ const target = winTarget(service, account);
49
52
  const script = `
50
53
  Add-Type -Namespace Win32 -Name Cred -MemberDefinition @'
51
54
  [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
@@ -61,7 +64,7 @@ public struct CREDENTIAL {
61
64
  }
62
65
  '@
63
66
  $ptr = [IntPtr]::Zero
64
- if ([Win32.Cred]::CredRead("${service}", 1, 0, [ref]$ptr)) {
67
+ if ([Win32.Cred]::CredRead("${target}", 1, 0, [ref]$ptr)) {
65
68
  $c = [Runtime.InteropServices.Marshal]::PtrToStructure($ptr, [Type][Win32.Cred+CREDENTIAL])
66
69
  $secret = [Runtime.InteropServices.Marshal]::PtrToStringUni($c.CredentialBlob, $c.CredentialBlobSize/2)
67
70
  [Win32.Cred]::CredFree($ptr)
@@ -76,15 +79,17 @@ if ([Win32.Cred]::CredRead("${service}", 1, 0, [ref]$ptr)) {
76
79
  return null;
77
80
  }
78
81
  }
79
- function setWindows(service, key) {
80
- execSync(`cmdkey /generic:${service} /user:${ACCOUNT_NAME} /pass:${escapeShellArg(key)}`, {
82
+ function setWindows(service, account, value) {
83
+ const target = winTarget(service, account);
84
+ execSync(`cmdkey /generic:${target} /user:${account} /pass:${escapeShellArg(value)}`, {
81
85
  stdio: SILENT_STDIO,
82
86
  shell: "cmd.exe",
83
87
  });
84
88
  }
85
- function deleteWindows(service) {
89
+ function deleteWindows(service, account) {
86
90
  try {
87
- execSync(`cmdkey /delete:${service}`, {
91
+ const target = winTarget(service, account);
92
+ execSync(`cmdkey /delete:${target}`, {
88
93
  stdio: SILENT_STDIO,
89
94
  shell: "cmd.exe",
90
95
  });
@@ -96,72 +101,108 @@ function deleteWindows(service) {
96
101
  // ---------------------------------------------------------------------------
97
102
  // Linux (libsecret / secret-tool)
98
103
  // ---------------------------------------------------------------------------
99
- function getLinux(service) {
104
+ function getLinux(service, account) {
100
105
  try {
101
- return (execSync(`secret-tool lookup service ${escapeShellArg(service)} username ${escapeShellArg(ACCOUNT_NAME)}`, { stdio: SILENT_STDIO, encoding: "utf-8" }).trim() || null);
106
+ return (execSync(`secret-tool lookup service ${escapeShellArg(service)} username ${escapeShellArg(account)}`, { stdio: SILENT_STDIO, encoding: "utf-8" }).trim() || null);
102
107
  }
103
108
  catch {
104
109
  return null;
105
110
  }
106
111
  }
107
- function setLinux(service, key) {
108
- execSync(`echo -n ${escapeShellArg(key)} | secret-tool store --label=${escapeShellArg(service)} service ${escapeShellArg(service)} username ${escapeShellArg(ACCOUNT_NAME)}`, { stdio: SILENT_STDIO });
112
+ function setLinux(service, account, value) {
113
+ execSync(`echo -n ${escapeShellArg(value)} | secret-tool store --label=${escapeShellArg(service)} service ${escapeShellArg(service)} username ${escapeShellArg(account)}`, { stdio: SILENT_STDIO });
109
114
  }
110
- function deleteLinux(service) {
115
+ function deleteLinux(service, account) {
111
116
  try {
112
- execSync(`secret-tool clear service ${escapeShellArg(service)} username ${escapeShellArg(ACCOUNT_NAME)}`, { stdio: SILENT_STDIO });
117
+ execSync(`secret-tool clear service ${escapeShellArg(service)} username ${escapeShellArg(account)}`, { stdio: SILENT_STDIO });
113
118
  }
114
119
  catch {
115
120
  // Credential may not exist or secret-tool unavailable; ignore
116
121
  }
117
122
  }
118
123
  // ---------------------------------------------------------------------------
119
- // Public API
124
+ // Generic credential operations
120
125
  // ---------------------------------------------------------------------------
121
- /** Read the stored API key from the OS credential store. Returns null if not found. */
122
- export function getStoredApiKey(service = DEFAULT_SERVICE_NAME) {
126
+ /** Read a value from the OS credential store. */
127
+ export function getStoredValue(account, service = DEFAULT_SERVICE) {
123
128
  switch (process.platform) {
124
129
  case "darwin":
125
- return getMacOS(service);
130
+ return getMacOS(service, account);
126
131
  case "win32":
127
- return getWindows(service);
132
+ return getWindows(service, account);
128
133
  case "linux":
129
- return getLinux(service);
134
+ return getLinux(service, account);
130
135
  default:
131
136
  return null;
132
137
  }
133
138
  }
134
- /** Write the API key to the OS credential store. */
135
- export function setStoredApiKey(key, service = DEFAULT_SERVICE_NAME) {
139
+ /** Write a value to the OS credential store. */
140
+ export function setStoredValue(account, value, service = DEFAULT_SERVICE) {
136
141
  switch (process.platform) {
137
142
  case "darwin":
138
- setMacOS(service, key);
143
+ setMacOS(service, account, value);
139
144
  break;
140
145
  case "win32":
141
- setWindows(service, key);
146
+ setWindows(service, account, value);
142
147
  break;
143
148
  case "linux":
144
- setLinux(service, key);
149
+ setLinux(service, account, value);
145
150
  break;
146
151
  default:
147
152
  throw new Error(`Credential storage is not supported on ${process.platform}`);
148
153
  }
149
154
  }
150
- /** Remove the stored API key from the OS credential store (best-effort). */
151
- export function deleteStoredApiKey(service = DEFAULT_SERVICE_NAME) {
155
+ /** Remove a value from the OS credential store (best-effort). */
156
+ export function deleteStoredValue(account, service = DEFAULT_SERVICE) {
152
157
  switch (process.platform) {
153
158
  case "darwin":
154
- deleteMacOS(service);
159
+ deleteMacOS(service, account);
155
160
  break;
156
161
  case "win32":
157
- deleteWindows(service);
162
+ deleteWindows(service, account);
158
163
  break;
159
164
  case "linux":
160
- deleteLinux(service);
165
+ deleteLinux(service, account);
161
166
  break;
162
167
  default:
163
168
  // No-op on unsupported platforms
164
169
  break;
165
170
  }
166
171
  }
172
+ // ---------------------------------------------------------------------------
173
+ // Convenience API for provider and API key storage
174
+ // ---------------------------------------------------------------------------
175
+ const PROVIDER_ACCOUNT = "PROVIDER";
176
+ const API_KEY_ACCOUNT = "API_KEY";
177
+ const MODEL_ACCOUNT = "MODEL";
178
+ /** Get the active provider ID. Returns null if not set. */
179
+ export function getActiveProvider() {
180
+ return getStoredValue(PROVIDER_ACCOUNT);
181
+ }
182
+ /** Store the active provider ID. */
183
+ export function setActiveProvider(providerId) {
184
+ setStoredValue(PROVIDER_ACCOUNT, providerId);
185
+ }
186
+ /** Get the stored API key. Returns null if not found. */
187
+ export function getApiKey() {
188
+ return getStoredValue(API_KEY_ACCOUNT);
189
+ }
190
+ /** Store the API key. */
191
+ export function setApiKey(key) {
192
+ setStoredValue(API_KEY_ACCOUNT, key);
193
+ }
194
+ /** Get the stored model ID. Returns null if not set. */
195
+ export function getModel() {
196
+ return getStoredValue(MODEL_ACCOUNT);
197
+ }
198
+ /** Store the selected model ID. */
199
+ export function setModel(modelId) {
200
+ setStoredValue(MODEL_ACCOUNT, modelId);
201
+ }
202
+ /** Delete all stored credentials (provider + API key + model). Best-effort. */
203
+ export function deleteAllCredentials() {
204
+ deleteStoredValue(PROVIDER_ACCOUNT);
205
+ deleteStoredValue(API_KEY_ACCOUNT);
206
+ deleteStoredValue(MODEL_ACCOUNT);
207
+ }
167
208
  //# sourceMappingURL=keychain.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"keychain.js","sourceRoot":"","sources":["../src/keychain.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keychain.js","sourceRoot":"","sources":["../src/keychain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Shared PDF utility functions.
3
+ *
4
+ * Contains URL validation, path validation, and PDF fetching logic
5
+ * used by both the service layer and provider implementations.
6
+ */
7
+ /**
8
+ * Check if a string is a Gemini File API URI.
9
+ */
10
+ export declare function isGeminiFileUri(source: string): boolean;
11
+ /**
12
+ * Check if a string is a URL (excluding Gemini File API URIs).
13
+ */
14
+ export declare function isUrl(source: string): boolean;
15
+ /**
16
+ * Validates a local PDF file path.
17
+ * Throws descriptive errors for common issues.
18
+ */
19
+ export declare function validateLocalPath(pdfPath: string): void;
20
+ /**
21
+ * Fetch PDF content from a URL with timeout.
22
+ */
23
+ export declare function fetchPdfFromUrl(url: string): Promise<Buffer>;
24
+ /**
25
+ * Read PDF bytes from a local file path.
26
+ */
27
+ export declare function readPdfBytes(pdfPath: string): Buffer;
28
+ //# sourceMappingURL=pdf-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-utils.d.ts","sourceRoot":"","sources":["../src/pdf-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAU7C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAmBvD;AAKD;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgClE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGpD"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Shared PDF utility functions.
3
+ *
4
+ * Contains URL validation, path validation, and PDF fetching logic
5
+ * used by both the service layer and provider implementations.
6
+ */
7
+ import * as fs from "node:fs";
8
+ import * as path from "node:path";
9
+ /** Gemini File API URI prefix. */
10
+ const GEMINI_FILE_URI_PREFIX = "https://generativelanguage.googleapis.com/";
11
+ /**
12
+ * Check if a string is a Gemini File API URI.
13
+ */
14
+ export function isGeminiFileUri(source) {
15
+ return source.startsWith(GEMINI_FILE_URI_PREFIX);
16
+ }
17
+ /**
18
+ * Check if a string is a URL (excluding Gemini File API URIs).
19
+ */
20
+ export function isUrl(source) {
21
+ if (isGeminiFileUri(source)) {
22
+ return false;
23
+ }
24
+ try {
25
+ const url = new URL(source);
26
+ return url.protocol === "http:" || url.protocol === "https:";
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ /**
33
+ * Validates a local PDF file path.
34
+ * Throws descriptive errors for common issues.
35
+ */
36
+ export function validateLocalPath(pdfPath) {
37
+ const trimmedPath = pdfPath.trim();
38
+ if (!path.isAbsolute(trimmedPath)) {
39
+ throw new Error(`PDF path must be absolute: ${trimmedPath}`);
40
+ }
41
+ if (!fs.existsSync(trimmedPath)) {
42
+ throw new Error(`PDF file not found: ${trimmedPath}`);
43
+ }
44
+ const stats = fs.statSync(trimmedPath);
45
+ if (stats.isDirectory()) {
46
+ throw new Error(`Path is a directory, not a file: ${trimmedPath}`);
47
+ }
48
+ if (!trimmedPath.toLowerCase().endsWith(".pdf")) {
49
+ throw new Error(`File is not a PDF: ${trimmedPath}`);
50
+ }
51
+ }
52
+ /** Timeout for fetching PDFs from URLs (60 seconds). */
53
+ const FETCH_TIMEOUT_MS = 60_000;
54
+ /**
55
+ * Fetch PDF content from a URL with timeout.
56
+ */
57
+ export async function fetchPdfFromUrl(url) {
58
+ const controller = new AbortController();
59
+ const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
60
+ let response;
61
+ try {
62
+ response = await fetch(url, { signal: controller.signal });
63
+ }
64
+ catch (error) {
65
+ if (error instanceof Error && error.name === "AbortError") {
66
+ throw new Error(`Request timed out after ${FETCH_TIMEOUT_MS / 1000}s`);
67
+ }
68
+ const message = error instanceof Error ? error.message : "Unknown error";
69
+ throw new Error(`Failed to fetch URL: ${message}`);
70
+ }
71
+ finally {
72
+ clearTimeout(timeoutId);
73
+ }
74
+ if (!response.ok) {
75
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
76
+ }
77
+ const contentType = response.headers.get("content-type");
78
+ if (contentType &&
79
+ !contentType.includes("application/pdf") &&
80
+ !contentType.includes("octet-stream")) {
81
+ throw new Error(`URL does not point to a PDF file. Content-Type: ${contentType}`);
82
+ }
83
+ const arrayBuffer = await response.arrayBuffer();
84
+ return Buffer.from(arrayBuffer);
85
+ }
86
+ /**
87
+ * Read PDF bytes from a local file path.
88
+ */
89
+ export function readPdfBytes(pdfPath) {
90
+ validateLocalPath(pdfPath);
91
+ return fs.readFileSync(pdfPath.trim());
92
+ }
93
+ //# sourceMappingURL=pdf-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-utils.js","sourceRoot":"","sources":["../src/pdf-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Anthropic Claude provider.
3
+ *
4
+ * Sends PDFs inline as base64/bytes content parts.
5
+ * No File API, no caching.
6
+ */
7
+ import type { ProviderConfig } from "./types.js";
8
+ export declare const anthropicProvider: ProviderConfig;
9
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAoD,MAAM,YAAY,CAAC;AAuDnG,eAAO,MAAM,iBAAiB,EAAE,cAa/B,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Anthropic Claude provider.
3
+ *
4
+ * Sends PDFs inline as base64/bytes content parts.
5
+ * No File API, no caching.
6
+ */
7
+ import { createAnthropic } from "@ai-sdk/anthropic";
8
+ import { fetchPdfFromUrl, readPdfBytes } from "../pdf-utils.js";
9
+ const MODELS = [
10
+ {
11
+ id: "claude-sonnet-4-6",
12
+ displayName: "Claude Sonnet 4.6",
13
+ hint: "Fast and cost-effective",
14
+ },
15
+ { id: "claude-opus-4-6", displayName: "Claude Opus 4.6", hint: "Best and most expensive" },
16
+ ];
17
+ const DEFAULT_MODEL = "claude-opus-4-6";
18
+ /**
19
+ * Prepare a PDF source for Anthropic by reading bytes inline.
20
+ */
21
+ async function preparePdf(source) {
22
+ if (source.kind === "cachedUri") {
23
+ throw new Error("Cached URIs are only supported with the Google provider.");
24
+ }
25
+ let bytes;
26
+ if (source.kind === "bytes") {
27
+ bytes = source.bytes;
28
+ }
29
+ else if (source.kind === "url") {
30
+ bytes = new Uint8Array(await fetchPdfFromUrl(source.url));
31
+ }
32
+ else {
33
+ bytes = new Uint8Array(await readPdfBytes(source.path));
34
+ }
35
+ const part = {
36
+ type: "file",
37
+ data: bytes,
38
+ mediaType: "application/pdf",
39
+ };
40
+ return { fileParts: [part], cachedUri: null };
41
+ }
42
+ /**
43
+ * Check if an error is an Anthropic token limit error.
44
+ */
45
+ function isTokenLimitError(error) {
46
+ if (!(error instanceof Error))
47
+ return false;
48
+ const msg = error.message.toLowerCase();
49
+ return (msg.includes("too many input tokens") ||
50
+ msg.includes("prompt is too long") ||
51
+ msg.includes("maximum context length") ||
52
+ msg.includes("maximum of 100 pdf pages") ||
53
+ msg.includes("pdf pages may be provided"));
54
+ }
55
+ export const anthropicProvider = {
56
+ id: "anthropic",
57
+ displayName: "Anthropic Claude",
58
+ models: MODELS,
59
+ defaultModel: DEFAULT_MODEL,
60
+ apiKeyUrl: "https://console.anthropic.com/settings/keys",
61
+ createModel: (apiKey, modelId) => {
62
+ const anthropic = createAnthropic({ apiKey });
63
+ return anthropic(modelId);
64
+ },
65
+ providerOptions: {},
66
+ preparePdf,
67
+ isTokenLimitError,
68
+ };
69
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,MAAM,GAAkB;IAC5B;QACE,EAAE,EAAE,mBAAmB;QACvB,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE,yBAAyB;KAChC;IACD,EAAE,EAAE,EAAE,iBAAiB,EAAE,WAAW,EAAE,iBAAiB,EAAE,IAAI,EAAE,yBAAyB,EAAE;CAC3F,CAAC;AAEF,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAExC;;GAEG;AACH,KAAK,UAAU,UAAU,CAAC,MAAiB;IACzC,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,KAAiB,CAAC;IAEtB,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC5B,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IACvB,CAAC;SAAM,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACjC,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,IAAI,GAAgB;QACxB,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,KAAK;QACX,SAAS,EAAE,iBAAiB;KAC7B,CAAC;IACF,OAAO,EAAE,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IACxC,OAAO,CACL,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACrC,GAAG,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QAClC,GAAG,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QACtC,GAAG,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QACxC,GAAG,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAC1C,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAmB;IAC/C,EAAE,EAAE,WAAW;IACf,WAAW,EAAE,kBAAkB;IAC/B,MAAM,EAAE,MAAM;IACd,YAAY,EAAE,aAAa;IAC3B,SAAS,EAAE,6CAA6C;IACxD,WAAW,EAAE,CAAC,MAAc,EAAE,OAAe,EAAE,EAAE;QAC/C,MAAM,SAAS,GAAG,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9C,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IACD,eAAe,EAAE,EAAE;IACnB,UAAU;IACV,iBAAiB;CAClB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Google Gemini provider.
3
+ *
4
+ * Uses the Gemini File API for uploading PDFs (supports large files and caching),
5
+ * and the Vercel AI SDK for LLM calls.
6
+ */
7
+ import type { ProviderConfig } from "./types.js";
8
+ /**
9
+ * Check if a string is a Gemini File API URI.
10
+ */
11
+ export declare function isGeminiFileUri(source: string): boolean;
12
+ export declare const googleProvider: ProviderConfig;
13
+ //# sourceMappingURL=google.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/providers/google.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAoD,MAAM,YAAY,CAAC;AAiBnG;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEvD;AA6FD,eAAO,MAAM,cAAc,EAAE,cAe5B,CAAC"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Google Gemini provider.
3
+ *
4
+ * Uses the Gemini File API for uploading PDFs (supports large files and caching),
5
+ * and the Vercel AI SDK for LLM calls.
6
+ */
7
+ import { GoogleGenAI, ApiError } from "@google/genai";
8
+ import { createGoogleGenerativeAI } from "@ai-sdk/google";
9
+ import { fetchPdfFromUrl, validateLocalPath } from "../pdf-utils.js";
10
+ const MODELS = [
11
+ {
12
+ id: "gemini-3-flash-preview",
13
+ displayName: "Gemini 3 Flash",
14
+ hint: "Fast and cost-effective",
15
+ },
16
+ { id: "gemini-3.1-pro-preview", displayName: "Gemini 3.1 Pro", hint: "Best and most expensive" },
17
+ ];
18
+ const DEFAULT_MODEL = "gemini-3.1-pro-preview";
19
+ /** Gemini File API URI prefix. */
20
+ const GEMINI_FILE_URI_PREFIX = "https://generativelanguage.googleapis.com/";
21
+ /**
22
+ * Check if a string is a Gemini File API URI.
23
+ */
24
+ export function isGeminiFileUri(source) {
25
+ return source.startsWith(GEMINI_FILE_URI_PREFIX);
26
+ }
27
+ /**
28
+ * Wait for a file to finish processing on the Gemini File API.
29
+ */
30
+ async function waitForFileReady(client, fileName, maxAttempts = 10) {
31
+ for (let i = 0; i < maxAttempts; i++) {
32
+ const fileInfo = await client.files.get({ name: fileName });
33
+ if (fileInfo.state === "FAILED") {
34
+ throw new Error(`File processing failed: ${fileInfo.name}`);
35
+ }
36
+ if (fileInfo.state !== "PROCESSING") {
37
+ return;
38
+ }
39
+ await new Promise((resolve) => setTimeout(resolve, 2000));
40
+ }
41
+ throw new Error("File processing timed out");
42
+ }
43
+ /**
44
+ * Upload a PDF to the Gemini File API.
45
+ * Returns the Gemini File API URI.
46
+ */
47
+ async function uploadToFileApi(client, data) {
48
+ const file = await client.files.upload(typeof data === "string"
49
+ ? { file: data, config: { mimeType: "application/pdf" } }
50
+ : { file: data, config: { mimeType: "application/pdf" } });
51
+ if (!file.name || !file.uri) {
52
+ throw new Error("File upload failed: missing name or URI");
53
+ }
54
+ await waitForFileReady(client, file.name);
55
+ return file.uri;
56
+ }
57
+ /**
58
+ * Prepare a PDF source for Google Gemini.
59
+ * Uploads to the File API and returns a URL-based file part.
60
+ */
61
+ async function preparePdf(source, apiKey) {
62
+ const client = new GoogleGenAI({ apiKey });
63
+ if (source.kind === "cachedUri") {
64
+ const part = {
65
+ type: "file",
66
+ data: new URL(source.uri),
67
+ mediaType: "application/pdf",
68
+ };
69
+ return { fileParts: [part], cachedUri: source.uri };
70
+ }
71
+ let fileUri;
72
+ if (source.kind === "bytes") {
73
+ const blob = new Blob([source.bytes], { type: "application/pdf" });
74
+ fileUri = await uploadToFileApi(client, blob);
75
+ }
76
+ else if (source.kind === "url") {
77
+ const pdfBuffer = await fetchPdfFromUrl(source.url);
78
+ const blob = new Blob([pdfBuffer], { type: "application/pdf" });
79
+ fileUri = await uploadToFileApi(client, blob);
80
+ }
81
+ else {
82
+ validateLocalPath(source.path);
83
+ fileUri = await uploadToFileApi(client, source.path);
84
+ }
85
+ const part = {
86
+ type: "file",
87
+ data: new URL(fileUri),
88
+ mediaType: "application/pdf",
89
+ };
90
+ return { fileParts: [part], cachedUri: fileUri };
91
+ }
92
+ /**
93
+ * Check if an error is a Gemini token limit error.
94
+ */
95
+ function isTokenLimitError(error) {
96
+ if (error instanceof ApiError) {
97
+ return error.status === 400 && error.message.includes("input token count exceeds");
98
+ }
99
+ if (error instanceof Error) {
100
+ return error.message.includes("input token count exceeds");
101
+ }
102
+ return false;
103
+ }
104
+ export const googleProvider = {
105
+ id: "google",
106
+ displayName: "Google Gemini",
107
+ models: MODELS,
108
+ defaultModel: DEFAULT_MODEL,
109
+ apiKeyUrl: "https://aistudio.google.com/apikey",
110
+ createModel: (apiKey, modelId) => {
111
+ const google = createGoogleGenerativeAI({ apiKey });
112
+ return google(modelId);
113
+ },
114
+ providerOptions: {
115
+ google: { thinkingConfig: { thinkingLevel: "low" } },
116
+ },
117
+ preparePdf,
118
+ isTokenLimitError,
119
+ };
120
+ //# sourceMappingURL=google.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/providers/google.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * OpenAI provider.
3
+ *
4
+ * Sends PDFs inline as bytes content parts.
5
+ * No File API, no caching.
6
+ */
7
+ import type { ProviderConfig } from "./types.js";
8
+ export declare const openaiProvider: ProviderConfig;
9
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAoD,MAAM,YAAY,CAAC;AAsDnG,eAAO,MAAM,cAAc,EAAE,cAe5B,CAAC"}