@code-yeongyu/senpi 2026.9.9-2 → 2026.9.9

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 (90) hide show
  1. package/CHANGELOG.md +1 -22
  2. package/dist/core/agent-session.d.ts +1 -8
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +0 -33
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
  7. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +1 -4
  8. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
  9. package/dist/core/extensions/builtin/imagegen/skill/SKILL.md +4 -47
  10. package/dist/core/extensions/builtin/imagegen/tool.d.ts +19 -10
  11. package/dist/core/extensions/builtin/imagegen/tool.d.ts.map +1 -1
  12. package/dist/core/extensions/builtin/imagegen/tool.js +45 -21
  13. package/dist/core/extensions/builtin/imagegen/tool.js.map +1 -1
  14. package/dist/core/extensions/loader.d.ts +1 -2
  15. package/dist/core/extensions/loader.d.ts.map +1 -1
  16. package/dist/core/extensions/loader.js +8 -17
  17. package/dist/core/extensions/loader.js.map +1 -1
  18. package/dist/core/extensions/types.d.ts +0 -5
  19. package/dist/core/extensions/types.d.ts.map +1 -1
  20. package/dist/core/extensions/types.js.map +1 -1
  21. package/dist/core/resource-loader.d.ts +0 -2
  22. package/dist/core/resource-loader.d.ts.map +1 -1
  23. package/dist/core/resource-loader.js +7 -11
  24. package/dist/core/resource-loader.js.map +1 -1
  25. package/dist/core/sdk.d.ts.map +1 -1
  26. package/dist/core/sdk.js +1 -13
  27. package/dist/core/sdk.js.map +1 -1
  28. package/dist/core/tools/read.d.ts +1 -5
  29. package/dist/core/tools/read.d.ts.map +1 -1
  30. package/dist/core/tools/read.js +1 -21
  31. package/dist/core/tools/read.js.map +1 -1
  32. package/dist/index.d.ts +0 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +0 -1
  35. package/dist/index.js.map +1 -1
  36. package/dist/main.d.ts.map +1 -1
  37. package/dist/main.js +0 -4
  38. package/dist/main.js.map +1 -1
  39. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  40. package/dist/modes/interactive/interactive-mode.js +0 -3
  41. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  42. package/docs/skills.md +1 -1
  43. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +0 -12
  44. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  45. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  46. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts +6 -3
  47. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts.map +1 -1
  48. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js +33 -15
  49. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js.map +1 -1
  50. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +1 -31
  51. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  52. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +1 -31
  53. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  54. package/node_modules/@earendil-works/pi-ai/dist/images.d.ts +0 -1
  55. package/node_modules/@earendil-works/pi-ai/dist/images.d.ts.map +1 -1
  56. package/node_modules/@earendil-works/pi-ai/dist/images.js +0 -1
  57. package/node_modules/@earendil-works/pi-ai/dist/images.js.map +1 -1
  58. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  59. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  60. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  61. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  62. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  63. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  64. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  65. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  66. package/package.json +7 -7
  67. package/dist/core/extensions/builtin/compaction/resume-admission.d.ts +0 -7
  68. package/dist/core/extensions/builtin/compaction/resume-admission.d.ts.map +0 -1
  69. package/dist/core/extensions/builtin/compaction/resume-admission.js +0 -7
  70. package/dist/core/extensions/builtin/compaction/resume-admission.js.map +0 -1
  71. package/dist/core/extensions/builtin/imagegen/params.d.ts +0 -36
  72. package/dist/core/extensions/builtin/imagegen/params.d.ts.map +0 -1
  73. package/dist/core/extensions/builtin/imagegen/params.js +0 -55
  74. package/dist/core/extensions/builtin/imagegen/params.js.map +0 -1
  75. package/dist/core/extensions/builtin/imagegen/reference-images.d.ts +0 -11
  76. package/dist/core/extensions/builtin/imagegen/reference-images.d.ts.map +0 -1
  77. package/dist/core/extensions/builtin/imagegen/reference-images.js +0 -55
  78. package/dist/core/extensions/builtin/imagegen/reference-images.js.map +0 -1
  79. package/dist/core/tools/read-classifiers.d.ts +0 -17
  80. package/dist/core/tools/read-classifiers.d.ts.map +0 -1
  81. package/dist/core/tools/read-classifiers.js +0 -26
  82. package/dist/core/tools/read-classifiers.js.map +0 -1
  83. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.d.ts +0 -4
  84. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.d.ts.map +0 -1
  85. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.js +0 -11
  86. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.js.map +0 -1
  87. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.d.ts +0 -25
  88. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.d.ts.map +0 -1
  89. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.js +0 -58
  90. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-ai",
3
- "version": "2026.9.9-2",
3
+ "version": "2026.9.9",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -76,7 +76,7 @@
76
76
  "dependencies": {
77
77
  "@anthropic-ai/sdk": "0.123.0",
78
78
  "@aws-sdk/client-bedrock-runtime": "3.1116.0",
79
- "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.9-2",
79
+ "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.9",
80
80
  "@google/genai": "2.18.0",
81
81
  "@smithy/node-http-handler": "4.11.3",
82
82
  "http-proxy-agent": "9.1.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-pty",
3
3
  "private": true,
4
- "version": "2026.9.9-2",
4
+ "version": "2026.9.9",
5
5
  "description": "Typed PTY session loader for Senpi persistent terminals",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-telemetry",
3
- "version": "2026.9.9-2",
3
+ "version": "2026.9.9",
4
4
  "description": "Vendor-neutral telemetry contracts and typed schema utilities for pi",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-tui",
3
- "version": "2026.9.9-2",
3
+ "version": "2026.9.9",
4
4
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi",
3
- "version": "2026.9.9-2",
3
+ "version": "2026.9.9",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -48,9 +48,9 @@
48
48
  "qa:app-server": "node scripts/qa-app-server/run-all.mjs"
49
49
  },
50
50
  "dependencies": {
51
- "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.9.9-2",
52
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.9-2",
53
- "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.9.9-2",
51
+ "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.9.9",
52
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.9",
53
+ "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.9.9",
54
54
  "@silvia-odwyer/photon-node": "0.3.4",
55
55
  "chalk": "6.0.0",
56
56
  "cross-spawn": "7.0.6",
@@ -70,8 +70,8 @@
70
70
  "@anthropic-ai/sdk": "0.123.0",
71
71
  "@aws-sdk/client-bedrock-runtime": "3.1116.0",
72
72
  "@bufbuild/protobuf": "2.14.0",
73
- "@code-yeongyu/senpi-codemode": "2026.9.9-2",
74
- "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.9.9-2",
73
+ "@code-yeongyu/senpi-codemode": "2026.9.9",
74
+ "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.9.9",
75
75
  "@modelcontextprotocol/sdk": "1.30.0",
76
76
  "@mozilla/readability": "0.6.0",
77
77
  "@opentelemetry/api": "1.9.1",
@@ -119,7 +119,7 @@
119
119
  "@csstools/css-parser-algorithms": "4.0.0",
120
120
  "@csstools/css-syntax-patches-for-csstree": "1.1.8",
121
121
  "@csstools/css-tokenizer": "4.0.0",
122
- "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.9-2",
122
+ "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.9",
123
123
  "@exodus/bytes": "1.15.1",
124
124
  "@google/genai": "2.18.0",
125
125
  "@hono/node-server": "2.1.1",
@@ -1,7 +0,0 @@
1
- import type { ModelUsabilityBudgetProjection } from "./model-usability-budget.ts";
2
- export interface ResumeCompactionRequirement {
3
- readonly projection: ModelUsabilityBudgetProjection;
4
- readonly notice: string;
5
- }
6
- export declare function createResumeCompactionRequirement(projection: ModelUsabilityBudgetProjection): ResumeCompactionRequirement;
7
- //# sourceMappingURL=resume-admission.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resume-admission.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/resume-admission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC;AAElF,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,UAAU,EAAE,8BAA8B,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,iCAAiC,CAChD,UAAU,EAAE,8BAA8B,GACxC,2BAA2B,CAK7B"}
@@ -1,7 +0,0 @@
1
- export function createResumeCompactionRequirement(projection) {
2
- return {
3
- projection,
4
- notice: `Context exceeds the model budget by ${projection.shortfallTokens} tokens; compacting before the first prompt.`,
5
- };
6
- }
7
- //# sourceMappingURL=resume-admission.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resume-admission.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/resume-admission.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,iCAAiC,CAChD,UAA0C;IAE1C,OAAO;QACN,UAAU;QACV,MAAM,EAAE,uCAAuC,UAAU,CAAC,eAAe,8CAA8C;KACvH,CAAC;AACH,CAAC","sourcesContent":["import type { ModelUsabilityBudgetProjection } from \"./model-usability-budget.ts\";\n\nexport interface ResumeCompactionRequirement {\n\treadonly projection: ModelUsabilityBudgetProjection;\n\treadonly notice: string;\n}\n\nexport function createResumeCompactionRequirement(\n\tprojection: ModelUsabilityBudgetProjection,\n): ResumeCompactionRequirement {\n\treturn {\n\t\tprojection,\n\t\tnotice: `Context exceeds the model budget by ${projection.shortfallTokens} tokens; compacting before the first prompt.`,\n\t};\n}\n"]}
@@ -1,36 +0,0 @@
1
- import { Type } from "typebox";
2
- export declare const DEFAULT_IMAGE_MODEL = "gpt-image-2.5-sunburst";
3
- export declare const IMAGE_MODEL_NAMES: {
4
- readonly "gpt-image-2.5-sunburst": "GPT Image 2.5 Sunburst";
5
- readonly "gpt-image-2.5-flare": "GPT Image 2.5 Flare";
6
- readonly "gpt-image-2": "GPT Image 2";
7
- };
8
- export declare const Params: Type.TObject<{
9
- prompt: Type.TString;
10
- model: Type.TOptional<Type.TUnion<[Type.TLiteral<"gpt-image-2.5-sunburst">, Type.TLiteral<"gpt-image-2.5-flare">, Type.TLiteral<"gpt-image-2">]>>;
11
- size: Type.TOptional<Type.TString>;
12
- quality: Type.TOptional<Type.TUnion<[Type.TLiteral<"auto">, Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">, Type.TLiteral<"xhigh">, Type.TLiteral<"max">]>>;
13
- reference_image_paths: Type.TOptional<Type.TArray<Type.TString>>;
14
- n: Type.TOptional<Type.TInteger>;
15
- output_path: Type.TOptional<Type.TString>;
16
- }>;
17
- export interface GenerateImageDetails {
18
- paths: string[];
19
- model: string;
20
- source: string;
21
- size: string;
22
- quality: string;
23
- requested: number;
24
- generated: number;
25
- revisedPrompts: string[];
26
- error?: string;
27
- reason?: "missing_config" | "provider_native_bypass" | "invalid_params" | "write_failed" | "provider_error";
28
- }
29
- export declare function failure(message: string, reason: NonNullable<GenerateImageDetails["reason"]>, base: Pick<GenerateImageDetails, "model" | "size" | "quality" | "requested" | "source">): {
30
- content: {
31
- type: "text";
32
- text: string;
33
- }[];
34
- details: GenerateImageDetails;
35
- };
36
- //# sourceMappingURL=params.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"params.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/params.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAC5D,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC;AAEX,eAAO,MAAM,MAAM;;;;;;;;EA6DlB,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,gBAAgB,GAAG,wBAAwB,GAAG,gBAAgB,GAAG,cAAc,GAAG,gBAAgB,CAAC;CAC5G;AAED,wBAAgB,OAAO,CACtB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,WAAW,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,EACnD,IAAI,EAAE,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;;;;;;EAWvF"}
@@ -1,55 +0,0 @@
1
- import { Type } from "typebox";
2
- export const DEFAULT_IMAGE_MODEL = "gpt-image-2.5-sunburst";
3
- export const IMAGE_MODEL_NAMES = {
4
- "gpt-image-2.5-sunburst": "GPT Image 2.5 Sunburst",
5
- "gpt-image-2.5-flare": "GPT Image 2.5 Flare",
6
- "gpt-image-2": "GPT Image 2",
7
- };
8
- export const Params = Type.Object({
9
- prompt: Type.String({
10
- minLength: 1,
11
- maxLength: 32_000,
12
- description: "Detailed description of the desired image, including the end state for edits.",
13
- }),
14
- model: Type.Optional(Type.Union([Type.Literal("gpt-image-2.5-sunburst"), Type.Literal("gpt-image-2.5-flare"), Type.Literal("gpt-image-2")], {
15
- default: DEFAULT_IMAGE_MODEL,
16
- description: "Sunburst (default) is most capable, with precise edits; Flare is fastest for everyday generation; gpt-image-2 is the previous generation.",
17
- })),
18
- size: Type.Optional(Type.String({
19
- default: "auto",
20
- description: "auto, 1024x1024, 1536x1024, 1024x1536, or any WIDTHxHEIGHT with both divisible by 16, aspect between 1:3 and 3:1, max 3840x2160 (e.g. 2048x2048, 2048x1152, 3840x2160)",
21
- })),
22
- quality: Type.Optional(Type.Union([
23
- Type.Literal("auto"),
24
- Type.Literal("low"),
25
- Type.Literal("medium"),
26
- Type.Literal("high"),
27
- Type.Literal("xhigh"),
28
- Type.Literal("max"),
29
- ], {
30
- default: "auto",
31
- description: "Rendering quality. Defaults to auto. xhigh/max are gpt-image-2.5 only, slower and costlier.",
32
- })),
33
- reference_image_paths: Type.Optional(Type.Array(Type.String({ minLength: 1 }), {
34
- minItems: 1,
35
- maxItems: 5,
36
- description: "Local PNG/JPEG/WEBP images to edit or use as references (1-5 files, each at most 50 MB). Paths may be absolute or relative to the working directory.",
37
- })),
38
- n: Type.Optional(Type.Integer({ minimum: 1, maximum: 10, default: 1, description: "How many images to generate." })),
39
- output_path: Type.Optional(Type.String({
40
- minLength: 1,
41
- description: "Where to write the image, relative to the working directory. Must end in .png. Defaults to generated-images/.",
42
- })),
43
- }, { additionalProperties: false });
44
- export function failure(message, reason, base) {
45
- const details = {
46
- ...base,
47
- paths: [],
48
- generated: 0,
49
- revisedPrompts: [],
50
- error: message,
51
- reason,
52
- };
53
- return { content: [{ type: "text", text: message }], details };
54
- }
55
- //# sourceMappingURL=params.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"params.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/params.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,MAAM,CAAC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAChC,wBAAwB,EAAE,wBAAwB;IAClD,qBAAqB,EAAE,qBAAqB;IAC5C,aAAa,EAAE,aAAa;CACnB,CAAC;AAEX,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAChC;IACC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,MAAM;QACjB,WAAW,EAAE,+EAA+E;KAC5F,CAAC;IACF,KAAK,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,KAAK,CACT,CAAC,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,EAC1G;QACC,OAAO,EAAE,mBAAmB;QAC5B,WAAW,EACV,2IAA2I;KAC5I,CACD,CACD;IACD,IAAI,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,MAAM,CAAC;QACX,OAAO,EAAE,MAAM;QACf,WAAW,EACV,wKAAwK;KACzK,CAAC,CACF;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CACrB,IAAI,CAAC,KAAK,CACT;QACC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;KACnB,EACD;QACC,OAAO,EAAE,MAAM;QACf,WAAW,EACV,6FAA6F;KAC9F,CACD,CACD;IACD,qBAAqB,EAAE,IAAI,CAAC,QAAQ,CACnC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE;QACzC,QAAQ,EAAE,CAAC;QACX,QAAQ,EAAE,CAAC;QACX,WAAW,EACV,sJAAsJ;KACvJ,CAAC,CACF;IACD,CAAC,EAAE,IAAI,CAAC,QAAQ,CACf,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,8BAA8B,EAAE,CAAC,CAClG;IACD,WAAW,EAAE,IAAI,CAAC,QAAQ,CACzB,IAAI,CAAC,MAAM,CAAC;QACX,SAAS,EAAE,CAAC;QACZ,WAAW,EACV,+GAA+G;KAChH,CAAC,CACF;CACD,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAC/B,CAAC;AAeF,MAAM,UAAU,OAAO,CACtB,OAAe,EACf,MAAmD,EACnD,IAAuF;IAEvF,MAAM,OAAO,GAAyB;QACrC,GAAG,IAAI;QACP,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,CAAC;QACZ,cAAc,EAAE,EAAE;QAClB,KAAK,EAAE,OAAO;QACd,MAAM;KACN,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;AACzE,CAAC","sourcesContent":["import { Type } from \"typebox\";\n\nexport const DEFAULT_IMAGE_MODEL = \"gpt-image-2.5-sunburst\";\nexport const IMAGE_MODEL_NAMES = {\n\t\"gpt-image-2.5-sunburst\": \"GPT Image 2.5 Sunburst\",\n\t\"gpt-image-2.5-flare\": \"GPT Image 2.5 Flare\",\n\t\"gpt-image-2\": \"GPT Image 2\",\n} as const;\n\nexport const Params = Type.Object(\n\t{\n\t\tprompt: Type.String({\n\t\t\tminLength: 1,\n\t\t\tmaxLength: 32_000,\n\t\t\tdescription: \"Detailed description of the desired image, including the end state for edits.\",\n\t\t}),\n\t\tmodel: Type.Optional(\n\t\t\tType.Union(\n\t\t\t\t[Type.Literal(\"gpt-image-2.5-sunburst\"), Type.Literal(\"gpt-image-2.5-flare\"), Type.Literal(\"gpt-image-2\")],\n\t\t\t\t{\n\t\t\t\t\tdefault: DEFAULT_IMAGE_MODEL,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Sunburst (default) is most capable, with precise edits; Flare is fastest for everyday generation; gpt-image-2 is the previous generation.\",\n\t\t\t\t},\n\t\t\t),\n\t\t),\n\t\tsize: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdefault: \"auto\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"auto, 1024x1024, 1536x1024, 1024x1536, or any WIDTHxHEIGHT with both divisible by 16, aspect between 1:3 and 3:1, max 3840x2160 (e.g. 2048x2048, 2048x1152, 3840x2160)\",\n\t\t\t}),\n\t\t),\n\t\tquality: Type.Optional(\n\t\t\tType.Union(\n\t\t\t\t[\n\t\t\t\t\tType.Literal(\"auto\"),\n\t\t\t\t\tType.Literal(\"low\"),\n\t\t\t\t\tType.Literal(\"medium\"),\n\t\t\t\t\tType.Literal(\"high\"),\n\t\t\t\t\tType.Literal(\"xhigh\"),\n\t\t\t\t\tType.Literal(\"max\"),\n\t\t\t\t],\n\t\t\t\t{\n\t\t\t\t\tdefault: \"auto\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Rendering quality. Defaults to auto. xhigh/max are gpt-image-2.5 only, slower and costlier.\",\n\t\t\t\t},\n\t\t\t),\n\t\t),\n\t\treference_image_paths: Type.Optional(\n\t\t\tType.Array(Type.String({ minLength: 1 }), {\n\t\t\t\tminItems: 1,\n\t\t\t\tmaxItems: 5,\n\t\t\t\tdescription:\n\t\t\t\t\t\"Local PNG/JPEG/WEBP images to edit or use as references (1-5 files, each at most 50 MB). Paths may be absolute or relative to the working directory.\",\n\t\t\t}),\n\t\t),\n\t\tn: Type.Optional(\n\t\t\tType.Integer({ minimum: 1, maximum: 10, default: 1, description: \"How many images to generate.\" }),\n\t\t),\n\t\toutput_path: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tminLength: 1,\n\t\t\t\tdescription:\n\t\t\t\t\t\"Where to write the image, relative to the working directory. Must end in .png. Defaults to generated-images/.\",\n\t\t\t}),\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport interface GenerateImageDetails {\n\tpaths: string[];\n\tmodel: string;\n\tsource: string;\n\tsize: string;\n\tquality: string;\n\trequested: number;\n\tgenerated: number;\n\trevisedPrompts: string[];\n\terror?: string;\n\treason?: \"missing_config\" | \"provider_native_bypass\" | \"invalid_params\" | \"write_failed\" | \"provider_error\";\n}\n\nexport function failure(\n\tmessage: string,\n\treason: NonNullable<GenerateImageDetails[\"reason\"]>,\n\tbase: Pick<GenerateImageDetails, \"model\" | \"size\" | \"quality\" | \"requested\" | \"source\">,\n) {\n\tconst details: GenerateImageDetails = {\n\t\t...base,\n\t\tpaths: [],\n\t\tgenerated: 0,\n\t\trevisedPrompts: [],\n\t\terror: message,\n\t\treason,\n\t};\n\treturn { content: [{ type: \"text\" as const, text: message }], details };\n}\n"]}
@@ -1,11 +0,0 @@
1
- import type { ImageContent } from "@earendil-works/pi-ai/compat";
2
- type ReferenceImages = {
3
- ok: true;
4
- images: ImageContent[];
5
- } | {
6
- ok: false;
7
- error: string;
8
- };
9
- export declare function loadReferenceImages(cwd: string, paths: string[] | undefined): Promise<ReferenceImages>;
10
- export {};
11
- //# sourceMappingURL=reference-images.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reference-images.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/reference-images.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAQjE,KAAK,eAAe,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,YAAY,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAW3F,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC,CA4B5G"}
@@ -1,55 +0,0 @@
1
- import { constants } from "node:fs";
2
- import { open } from "node:fs/promises";
3
- import { resolve } from "node:path";
4
- const MAX_REFERENCE_BYTES = 50 * 1024 * 1024;
5
- const PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
6
- const JPEG_SIGNATURE = Buffer.from([0xff, 0xd8, 0xff]);
7
- const RIFF_SIGNATURE = Buffer.from("RIFF");
8
- const WEBP_SIGNATURE = Buffer.from("WEBP");
9
- function imageMimeType(bytes) {
10
- if (bytes.subarray(0, 8).equals(PNG_SIGNATURE))
11
- return "image/png";
12
- if (bytes.subarray(0, 3).equals(JPEG_SIGNATURE))
13
- return "image/jpeg";
14
- if (bytes.subarray(0, 4).equals(RIFF_SIGNATURE) && bytes.subarray(8, 12).equals(WEBP_SIGNATURE)) {
15
- return "image/webp";
16
- }
17
- return undefined;
18
- }
19
- export async function loadReferenceImages(cwd, paths) {
20
- if (paths === undefined)
21
- return { ok: true, images: [] };
22
- if (paths.length < 1 || paths.length > 5) {
23
- return { ok: false, error: `Error: reference_image_paths must contain 1 to 5 paths (got ${paths.length}).` };
24
- }
25
- const images = [];
26
- for (const path of paths) {
27
- try {
28
- // Nonblocking open lets us reject FIFOs without waiting for a writer.
29
- const file = await open(resolve(cwd, path), constants.O_RDONLY | constants.O_NONBLOCK);
30
- try {
31
- const stat = await file.stat();
32
- if (!stat.isFile())
33
- throw new Error("must be a regular file");
34
- if (stat.size > MAX_REFERENCE_BYTES)
35
- throw new Error("must be at most 50 MB");
36
- const bytes = await file.readFile();
37
- if (bytes.length > MAX_REFERENCE_BYTES)
38
- throw new Error("must be at most 50 MB");
39
- const mimeType = imageMimeType(bytes);
40
- if (mimeType === undefined)
41
- throw new Error("must be a PNG, JPEG, or WEBP image (invalid magic bytes)");
42
- images.push({ type: "image", data: bytes.toString("base64"), mimeType });
43
- }
44
- finally {
45
- await file.close();
46
- }
47
- }
48
- catch (error) {
49
- const reason = error instanceof Error ? error.message : String(error);
50
- return { ok: false, error: `Error: reference image "${path}": ${reason}` };
51
- }
52
- }
53
- return { ok: true, images };
54
- }
55
- //# sourceMappingURL=reference-images.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reference-images.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/reference-images.ts"],"names":[],"mappings":"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","sourcesContent":["import { constants } from \"node:fs\";\nimport { open } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { ImageContent } from \"@earendil-works/pi-ai/compat\";\n\nconst MAX_REFERENCE_BYTES = 50 * 1024 * 1024;\nconst PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\nconst JPEG_SIGNATURE = Buffer.from([0xff, 0xd8, 0xff]);\nconst RIFF_SIGNATURE = Buffer.from(\"RIFF\");\nconst WEBP_SIGNATURE = Buffer.from(\"WEBP\");\n\ntype ReferenceImages = { ok: true; images: ImageContent[] } | { ok: false; error: string };\n\nfunction imageMimeType(bytes: Buffer): string | undefined {\n\tif (bytes.subarray(0, 8).equals(PNG_SIGNATURE)) return \"image/png\";\n\tif (bytes.subarray(0, 3).equals(JPEG_SIGNATURE)) return \"image/jpeg\";\n\tif (bytes.subarray(0, 4).equals(RIFF_SIGNATURE) && bytes.subarray(8, 12).equals(WEBP_SIGNATURE)) {\n\t\treturn \"image/webp\";\n\t}\n\treturn undefined;\n}\n\nexport async function loadReferenceImages(cwd: string, paths: string[] | undefined): Promise<ReferenceImages> {\n\tif (paths === undefined) return { ok: true, images: [] };\n\tif (paths.length < 1 || paths.length > 5) {\n\t\treturn { ok: false, error: `Error: reference_image_paths must contain 1 to 5 paths (got ${paths.length}).` };\n\t}\n\tconst images: ImageContent[] = [];\n\tfor (const path of paths) {\n\t\ttry {\n\t\t\t// Nonblocking open lets us reject FIFOs without waiting for a writer.\n\t\t\tconst file = await open(resolve(cwd, path), constants.O_RDONLY | constants.O_NONBLOCK);\n\t\t\ttry {\n\t\t\t\tconst stat = await file.stat();\n\t\t\t\tif (!stat.isFile()) throw new Error(\"must be a regular file\");\n\t\t\t\tif (stat.size > MAX_REFERENCE_BYTES) throw new Error(\"must be at most 50 MB\");\n\t\t\t\tconst bytes = await file.readFile();\n\t\t\t\tif (bytes.length > MAX_REFERENCE_BYTES) throw new Error(\"must be at most 50 MB\");\n\t\t\t\tconst mimeType = imageMimeType(bytes);\n\t\t\t\tif (mimeType === undefined) throw new Error(\"must be a PNG, JPEG, or WEBP image (invalid magic bytes)\");\n\t\t\t\timages.push({ type: \"image\", data: bytes.toString(\"base64\"), mimeType });\n\t\t\t} finally {\n\t\t\t\tawait file.close();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\t\treturn { ok: false, error: `Error: reference image \"${path}\": ${reason}` };\n\t\t}\n\t}\n\treturn { ok: true, images };\n}\n"]}
@@ -1,17 +0,0 @@
1
- export interface CompactReadClassification {
2
- readonly kind: "docs" | "resource" | "skill" | "memory";
3
- readonly label: string;
4
- readonly headline?: string;
5
- }
6
- export type ReadClassifier = (input: {
7
- readonly absolutePath: string;
8
- readonly cwd: string;
9
- }) => CompactReadClassification | undefined;
10
- /** Register a compact read classifier. The returned function removes this registration. */
11
- export declare function registerReadClassifier(classifier: ReadClassifier): () => void;
12
- /** First registered classifier to claim a path wins; a failed classifier cannot block later ones. */
13
- export declare function classifyRead(input: {
14
- absolutePath: string;
15
- cwd: string;
16
- }): CompactReadClassification | undefined;
17
- //# sourceMappingURL=read-classifiers.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"read-classifiers.d.ts","sourceRoot":"","sources":["../../../src/core/tools/read-classifiers.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB,KAAK,yBAAyB,GAAG,SAAS,CAAC;AAI5C,2FAA2F;AAC3F,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,cAAc,GAAG,MAAM,IAAI,CAO7E;AAED,qGAAqG;AACrG,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,yBAAyB,GAAG,SAAS,CAUhH"}
@@ -1,26 +0,0 @@
1
- const classifiers = [];
2
- /** Register a compact read classifier. The returned function removes this registration. */
3
- export function registerReadClassifier(classifier) {
4
- const entry = { classifier };
5
- classifiers.push(entry);
6
- return () => {
7
- const index = classifiers.indexOf(entry);
8
- if (index !== -1)
9
- classifiers.splice(index, 1);
10
- };
11
- }
12
- /** First registered classifier to claim a path wins; a failed classifier cannot block later ones. */
13
- export function classifyRead(input) {
14
- for (const { classifier } of classifiers) {
15
- try {
16
- const classification = classifier(input);
17
- if (classification !== undefined)
18
- return classification;
19
- }
20
- catch (error) {
21
- console.warn("Read classifier failed:", error);
22
- }
23
- }
24
- return undefined;
25
- }
26
- //# sourceMappingURL=read-classifiers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"read-classifiers.js","sourceRoot":"","sources":["../../../src/core/tools/read-classifiers.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,GAA0C,EAAE,CAAC;AAE9D,2FAA2F;AAC3F,MAAM,UAAU,sBAAsB,CAAC,UAA0B;IAChE,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,CAAC;IAC7B,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,GAAG,EAAE;QACX,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC;AACH,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,YAAY,CAAC,KAA4C;IACxE,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,WAAW,EAAE,CAAC;QAC1C,IAAI,CAAC;YACJ,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,cAAc,KAAK,SAAS;gBAAE,OAAO,cAAc,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC","sourcesContent":["export interface CompactReadClassification {\n\treadonly kind: \"docs\" | \"resource\" | \"skill\" | \"memory\";\n\treadonly label: string;\n\treadonly headline?: string;\n}\n\nexport type ReadClassifier = (input: {\n\treadonly absolutePath: string;\n\treadonly cwd: string;\n}) => CompactReadClassification | undefined;\n\nconst classifiers: Array<{ classifier: ReadClassifier }> = [];\n\n/** Register a compact read classifier. The returned function removes this registration. */\nexport function registerReadClassifier(classifier: ReadClassifier): () => void {\n\tconst entry = { classifier };\n\tclassifiers.push(entry);\n\treturn () => {\n\t\tconst index = classifiers.indexOf(entry);\n\t\tif (index !== -1) classifiers.splice(index, 1);\n\t};\n}\n\n/** First registered classifier to claim a path wins; a failed classifier cannot block later ones. */\nexport function classifyRead(input: { absolutePath: string; cwd: string }): CompactReadClassification | undefined {\n\tfor (const { classifier } of classifiers) {\n\t\ttry {\n\t\t\tconst classification = classifier(input);\n\t\t\tif (classification !== undefined) return classification;\n\t\t} catch (error) {\n\t\t\tconsole.warn(\"Read classifier failed:\", error);\n\t\t}\n\t}\n\treturn undefined;\n}\n"]}
@@ -1,4 +0,0 @@
1
- import type { ImageContent } from "../types.ts";
2
- import type { OpenAIImageParams } from "./openai-images-params.ts";
3
- export declare function buildEditParams(params: OpenAIImageParams, images: ImageContent[]): Promise<OpenAIImageParams>;
4
- //# sourceMappingURL=openai-images-edit.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"openai-images-edit.d.ts","sourceRoot":"","sources":["../../src/api/openai-images-edit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,wBAAsB,eAAe,CAAC,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CASnH"}
@@ -1,11 +0,0 @@
1
- import { toFile } from "openai";
2
- export async function buildEditParams(params, images) {
3
- if (images.length > 16)
4
- throw new Error("OpenAI image edits accept at most 16 reference images");
5
- const image = await Promise.all(images.map(({ data, mimeType }, i) => {
6
- const ext = mimeType.split("/")[1];
7
- return toFile(Buffer.from(data, "base64"), `reference-${i}.${ext}`, { type: mimeType });
8
- }));
9
- return { ...params, image };
10
- }
11
- //# sourceMappingURL=openai-images-edit.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"openai-images-edit.js","sourceRoot":"","sources":["../../src/api/openai-images-edit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAyB,EAAE,MAAsB;IACtF,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IACjG,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IACzF,CAAC,CAAC,CACF,CAAC;IACF,OAAO,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["import { toFile } from \"openai\";\nimport type { ImageContent } from \"../types.ts\";\nimport type { OpenAIImageParams } from \"./openai-images-params.ts\";\n\nexport async function buildEditParams(params: OpenAIImageParams, images: ImageContent[]): Promise<OpenAIImageParams> {\n\tif (images.length > 16) throw new Error(\"OpenAI image edits accept at most 16 reference images\");\n\tconst image = await Promise.all(\n\t\timages.map(({ data, mimeType }, i) => {\n\t\t\tconst ext = mimeType.split(\"/\")[1];\n\t\t\treturn toFile(Buffer.from(data, \"base64\"), `reference-${i}.${ext}`, { type: mimeType });\n\t\t}),\n\t);\n\treturn { ...params, image };\n}\n"]}
@@ -1,25 +0,0 @@
1
- import type { Uploadable } from "openai";
2
- import type { ImageGenerateParamsNonStreaming } from "openai/resources/images.js";
3
- import type { ImagesContext, ImagesModel, ImagesOptions } from "../types.ts";
4
- export type OpenAIImageQuality = "auto" | "low" | "medium" | "high" | "xhigh" | "max";
5
- export type OpenAIImageSize = "auto" | "1024x1024" | "1536x1024" | "1024x1536" | `${number}x${number}`;
6
- export interface OpenAIImagesOptions extends ImagesOptions {
7
- size?: OpenAIImageSize;
8
- quality?: OpenAIImageQuality;
9
- n?: number;
10
- }
11
- export type OpenAIImageParams = Omit<ImageGenerateParamsNonStreaming, "size" | "quality"> & {
12
- size?: OpenAIImageSize;
13
- quality?: OpenAIImageQuality;
14
- image?: Uploadable[];
15
- };
16
- export declare function parseOpenAIImageSize(size: string): {
17
- ok: true;
18
- size: string;
19
- } | {
20
- ok: false;
21
- error: string;
22
- };
23
- export declare function buildParams(model: ImagesModel<"openai-images">, context: ImagesContext, options?: OpenAIImagesOptions): OpenAIImageParams;
24
- export declare function isImageParams(value: unknown): value is OpenAIImageParams;
25
- //# sourceMappingURL=openai-images-params.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"openai-images-params.d.ts","sourceRoot":"","sources":["../../src/api/openai-images-params.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAK7E,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AACtF,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AAEvG,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACzD,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,CAAC,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,+BAA+B,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG;IAC3F,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACrB,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAqB5G;AAED,wBAAgB,WAAW,CAC1B,KAAK,EAAE,WAAW,CAAC,eAAe,CAAC,EACnC,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,mBAAmB,GAC3B,iBAAiB,CAwBnB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB,CAExE"}
@@ -1,58 +0,0 @@
1
- import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
2
- const MAX_PROMPT_CHARS = 32_000;
3
- export function parseOpenAIImageSize(size) {
4
- if (["auto", "1024x1024", "1536x1024", "1024x1536"].includes(size))
5
- return { ok: true, size };
6
- const match = /^\d+x\d+$/.exec(size);
7
- if (!match || match[0] !== size) {
8
- return { ok: false, error: "OpenAI image size must be auto or WIDTHxHEIGHT with integer dimensions" };
9
- }
10
- const [width, height] = size.split("x").map(Number);
11
- if (width > 3840 || height > 3840) {
12
- return { ok: false, error: "OpenAI image size edges must be at most 3840 pixels" };
13
- }
14
- if (width % 16 !== 0 || height % 16 !== 0) {
15
- return { ok: false, error: "OpenAI image size width and height must be divisible by 16" };
16
- }
17
- if (width > height * 3 || height > width * 3) {
18
- return { ok: false, error: "OpenAI image size aspect ratio must be between 1:3 and 3:1 inclusive" };
19
- }
20
- const pixels = width * height;
21
- if (pixels < 655360 || pixels > 8294400) {
22
- return { ok: false, error: "OpenAI image size must contain between 655360 and 8294400 pixels inclusive" };
23
- }
24
- return { ok: true, size };
25
- }
26
- export function buildParams(model, context, options) {
27
- const promptParts = [];
28
- for (const item of context.input) {
29
- if (item.type !== "text")
30
- continue;
31
- const text = sanitizeSurrogates(item.text);
32
- if (text.trim())
33
- promptParts.push(text);
34
- }
35
- const prompt = promptParts.join("\n\n");
36
- if (!prompt.trim())
37
- throw new Error("Image generation requires a non-empty text prompt");
38
- if (prompt.length > MAX_PROMPT_CHARS) {
39
- throw new Error(`Image generation prompt exceeds ${MAX_PROMPT_CHARS} characters`);
40
- }
41
- const size = options?.size ?? "auto";
42
- const parsedSize = parseOpenAIImageSize(size);
43
- if (!parsedSize.ok)
44
- throw new Error(parsedSize.error);
45
- return {
46
- model: model.id,
47
- prompt,
48
- size,
49
- quality: options?.quality ?? "auto",
50
- n: options?.n ?? 1,
51
- output_format: "png",
52
- stream: false,
53
- };
54
- }
55
- export function isImageParams(value) {
56
- return typeof value === "object" && value !== null && "prompt" in value && typeof value.prompt === "string";
57
- }
58
- //# sourceMappingURL=openai-images-params.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"openai-images-params.js","sourceRoot":"","sources":["../../src/api/openai-images-params.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Uploadable } from \"openai\";\nimport type { ImageGenerateParamsNonStreaming } from \"openai/resources/images.js\";\nimport type { ImagesContext, ImagesModel, ImagesOptions } from \"../types.ts\";\nimport { sanitizeSurrogates } from \"../utils/sanitize-unicode.ts\";\n\nconst MAX_PROMPT_CHARS = 32_000;\n\nexport type OpenAIImageQuality = \"auto\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\nexport type OpenAIImageSize = \"auto\" | \"1024x1024\" | \"1536x1024\" | \"1024x1536\" | `${number}x${number}`;\n\nexport interface OpenAIImagesOptions extends ImagesOptions {\n\tsize?: OpenAIImageSize;\n\tquality?: OpenAIImageQuality;\n\tn?: number;\n}\n\nexport type OpenAIImageParams = Omit<ImageGenerateParamsNonStreaming, \"size\" | \"quality\"> & {\n\tsize?: OpenAIImageSize;\n\tquality?: OpenAIImageQuality;\n\timage?: Uploadable[];\n};\n\nexport function parseOpenAIImageSize(size: string): { ok: true; size: string } | { ok: false; error: string } {\n\tif ([\"auto\", \"1024x1024\", \"1536x1024\", \"1024x1536\"].includes(size)) return { ok: true, size };\n\tconst match = /^\\d+x\\d+$/.exec(size);\n\tif (!match || match[0] !== size) {\n\t\treturn { ok: false, error: \"OpenAI image size must be auto or WIDTHxHEIGHT with integer dimensions\" };\n\t}\n\tconst [width, height] = size.split(\"x\").map(Number);\n\tif (width > 3840 || height > 3840) {\n\t\treturn { ok: false, error: \"OpenAI image size edges must be at most 3840 pixels\" };\n\t}\n\tif (width % 16 !== 0 || height % 16 !== 0) {\n\t\treturn { ok: false, error: \"OpenAI image size width and height must be divisible by 16\" };\n\t}\n\tif (width > height * 3 || height > width * 3) {\n\t\treturn { ok: false, error: \"OpenAI image size aspect ratio must be between 1:3 and 3:1 inclusive\" };\n\t}\n\tconst pixels = width * height;\n\tif (pixels < 655360 || pixels > 8294400) {\n\t\treturn { ok: false, error: \"OpenAI image size must contain between 655360 and 8294400 pixels inclusive\" };\n\t}\n\treturn { ok: true, size };\n}\n\nexport function buildParams(\n\tmodel: ImagesModel<\"openai-images\">,\n\tcontext: ImagesContext,\n\toptions?: OpenAIImagesOptions,\n): OpenAIImageParams {\n\tconst promptParts: string[] = [];\n\tfor (const item of context.input) {\n\t\tif (item.type !== \"text\") continue;\n\t\tconst text = sanitizeSurrogates(item.text);\n\t\tif (text.trim()) promptParts.push(text);\n\t}\n\tconst prompt = promptParts.join(\"\\n\\n\");\n\tif (!prompt.trim()) throw new Error(\"Image generation requires a non-empty text prompt\");\n\tif (prompt.length > MAX_PROMPT_CHARS) {\n\t\tthrow new Error(`Image generation prompt exceeds ${MAX_PROMPT_CHARS} characters`);\n\t}\n\tconst size = options?.size ?? \"auto\";\n\tconst parsedSize = parseOpenAIImageSize(size);\n\tif (!parsedSize.ok) throw new Error(parsedSize.error);\n\treturn {\n\t\tmodel: model.id,\n\t\tprompt,\n\t\tsize,\n\t\tquality: options?.quality ?? \"auto\",\n\t\tn: options?.n ?? 1,\n\t\toutput_format: \"png\",\n\t\tstream: false,\n\t};\n}\n\nexport function isImageParams(value: unknown): value is OpenAIImageParams {\n\treturn typeof value === \"object\" && value !== null && \"prompt\" in value && typeof value.prompt === \"string\";\n}\n"]}