@oh-my-pi/pi-ai 8.0.20 → 8.2.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 (39) hide show
  1. package/README.md +11 -12
  2. package/package.json +49 -26
  3. package/src/cli.ts +7 -7
  4. package/src/index.ts +2 -1
  5. package/src/models.generated.ts +100 -101
  6. package/src/providers/amazon-bedrock.ts +12 -13
  7. package/src/providers/anthropic.ts +67 -37
  8. package/src/providers/cursor.ts +57 -57
  9. package/src/providers/google-gemini-cli-usage.ts +2 -2
  10. package/src/providers/google-gemini-cli.ts +8 -10
  11. package/src/providers/google-shared.ts +12 -13
  12. package/src/providers/google-vertex.ts +7 -7
  13. package/src/providers/google.ts +8 -8
  14. package/src/providers/openai-codex/request-transformer.ts +6 -6
  15. package/src/providers/openai-codex-responses.ts +28 -28
  16. package/src/providers/openai-completions.ts +39 -39
  17. package/src/providers/openai-responses.ts +31 -31
  18. package/src/providers/transform-messages.ts +3 -3
  19. package/src/storage.ts +29 -19
  20. package/src/stream.ts +6 -6
  21. package/src/types.ts +1 -2
  22. package/src/usage/claude.ts +4 -4
  23. package/src/usage/github-copilot.ts +3 -4
  24. package/src/usage/google-antigravity.ts +3 -3
  25. package/src/usage/openai-codex.ts +4 -4
  26. package/src/usage/zai.ts +3 -3
  27. package/src/usage.ts +0 -1
  28. package/src/utils/event-stream.ts +4 -4
  29. package/src/utils/oauth/anthropic.ts +0 -1
  30. package/src/utils/oauth/callback-server.ts +2 -3
  31. package/src/utils/oauth/github-copilot.ts +2 -3
  32. package/src/utils/oauth/google-antigravity.ts +0 -1
  33. package/src/utils/oauth/google-gemini-cli.ts +2 -3
  34. package/src/utils/oauth/index.ts +11 -12
  35. package/src/utils/oauth/openai-codex.ts +0 -1
  36. package/src/utils/overflow.ts +2 -2
  37. package/src/utils/retry.ts +78 -0
  38. package/src/utils/validation.ts +4 -5
  39. package/tsconfig.json +0 -42
@@ -0,0 +1,78 @@
1
+ type ErrorLike = {
2
+ message?: string;
3
+ name?: string;
4
+ status?: number;
5
+ statusCode?: number;
6
+ response?: { status?: number };
7
+ cause?: unknown;
8
+ };
9
+
10
+ const TRANSIENT_MESSAGE_PATTERN =
11
+ /overloaded|rate.?limit|usage.?limit|too many requests|service.?unavailable|server error|internal error|connection.?error|fetch failed/i;
12
+
13
+ const VALIDATION_MESSAGE_PATTERN =
14
+ /invalid|validation|bad request|unsupported|schema|missing required|not found|unauthorized|forbidden/i;
15
+
16
+ /**
17
+ * Identify errors that should be retried (timeouts, 5xx, 408, 429, transient network failures).
18
+ */
19
+ export function isRetryableError(error: unknown): boolean {
20
+ const info = error as ErrorLike | null;
21
+ const message = info?.message ?? "";
22
+ const name = info?.name ?? "";
23
+ if (name === "AbortError" || /timeout|timed out|aborted/i.test(message)) return true;
24
+
25
+ const status = extractHttpStatusFromError(error);
26
+ if (status !== undefined) {
27
+ if (status >= 500) return true;
28
+ if (status === 408 || status === 429) return true;
29
+ if (status >= 400 && status < 500) return false;
30
+ }
31
+
32
+ if (VALIDATION_MESSAGE_PATTERN.test(message)) return false;
33
+
34
+ return TRANSIENT_MESSAGE_PATTERN.test(message);
35
+ }
36
+
37
+ export function extractHttpStatusFromError(error: unknown, depth = 0): number | undefined {
38
+ if (!error || typeof error !== "object" || depth > 3) return undefined;
39
+ const info = error as ErrorLike;
40
+ const status =
41
+ info.status ??
42
+ info.statusCode ??
43
+ (info.response && typeof info.response === "object" ? info.response.status : undefined);
44
+ if (typeof status === "number" && status >= 100 && status <= 599) {
45
+ return status;
46
+ }
47
+
48
+ if (info.message) {
49
+ const extracted = extractStatusFromMessage(info.message);
50
+ if (extracted !== undefined) return extracted;
51
+ }
52
+
53
+ if (info.cause) {
54
+ return extractHttpStatusFromError(info.cause, depth + 1);
55
+ }
56
+
57
+ return undefined;
58
+ }
59
+
60
+ function extractStatusFromMessage(message: string): number | undefined {
61
+ const patterns = [
62
+ /error\s*\((\d{3})\)/i,
63
+ /status\s*[:=]?\s*(\d{3})/i,
64
+ /\bhttp\s*(\d{3})\b/i,
65
+ /\b(\d{3})\s*(?:status|error)\b/i,
66
+ ];
67
+
68
+ for (const pattern of patterns) {
69
+ const match = pattern.exec(message);
70
+ if (!match) continue;
71
+ const value = Number(match[1]);
72
+ if (Number.isFinite(value) && value >= 100 && value <= 599) {
73
+ return value;
74
+ }
75
+ }
76
+
77
+ return undefined;
78
+ }
@@ -1,12 +1,11 @@
1
1
  import AjvModule from "ajv";
2
2
  import addFormatsModule from "ajv-formats";
3
+ import type { Tool, ToolCall } from "../types";
3
4
 
4
5
  // Handle both default and named exports (ESM/CJS interop)
5
6
  const Ajv = (AjvModule as any).default || AjvModule;
6
7
  const addFormats = (addFormatsModule as any).default || addFormatsModule;
7
8
 
8
- import type { Tool, ToolCall } from "@oh-my-pi/pi-ai/types";
9
-
10
9
  // ============================================================================
11
10
  // Type Coercion Utilities
12
11
  // ============================================================================
@@ -50,7 +49,7 @@ function normalizeExpectedTypes(typeParam: unknown): string[] {
50
49
  * Used to verify that a parsed JSON value is actually what the schema wants.
51
50
  */
52
51
  function matchesExpectedType(value: unknown, expectedTypes: string[]): boolean {
53
- return expectedTypes.some((type) => {
52
+ return expectedTypes.some(type => {
54
53
  switch (type) {
55
54
  case "string":
56
55
  return typeof value === "string";
@@ -157,7 +156,7 @@ function decodeJsonPointer(pointer: string): string[] {
157
156
  return pointer
158
157
  .split("/")
159
158
  .slice(1) // Remove leading empty segment from initial "/"
160
- .map((segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~"));
159
+ .map(segment => segment.replace(/~1/g, "/").replace(/~0/g, "~"));
161
160
  }
162
161
 
163
162
  /**
@@ -310,7 +309,7 @@ if (!isBrowserExtension) {
310
309
  * @throws Error if tool is not found or validation fails
311
310
  */
312
311
  export function validateToolCall(tools: Tool[], toolCall: ToolCall): any {
313
- const tool = tools.find((t) => t.name === toolCall.name);
312
+ const tool = tools.find(t => t.name === toolCall.name);
314
313
  if (!tool) {
315
314
  throw new Error(`Tool "${toolCall.name}" not found`);
316
315
  }
package/tsconfig.json DELETED
@@ -1,42 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2024",
4
- "module": "ESNext",
5
- "lib": [
6
- "ES2024"
7
- ],
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "moduleResolution": "Bundler",
13
- "resolveJsonModule": true,
14
- "allowImportingTsExtensions": true,
15
- "experimentalDecorators": true,
16
- "emitDecoratorMetadata": true,
17
- "useDefineForClassFields": false,
18
- "types": [
19
- "bun",
20
- "node"
21
- ],
22
- "noEmit": true,
23
- "baseUrl": ".",
24
- "paths": {
25
- "@oh-my-pi/pi-ai": [
26
- "./src/index.ts"
27
- ],
28
- "@oh-my-pi/pi-ai/*": [
29
- "./src/*"
30
- ]
31
- }
32
- },
33
- "include": [
34
- "src/**/*.ts"
35
- ],
36
- "exclude": [
37
- "node_modules",
38
- "dist",
39
- "**/*.test.ts",
40
- "test/**"
41
- ]
42
- }