aibroker 0.6.1 → 0.6.2

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 (129) hide show
  1. package/README.md +263 -104
  2. package/dist/adapters/iterm/sessions.d.ts +1 -0
  3. package/dist/adapters/iterm/sessions.d.ts.map +1 -1
  4. package/dist/adapters/iterm/sessions.js +23 -0
  5. package/dist/adapters/iterm/sessions.js.map +1 -1
  6. package/dist/adapters/pailot/gateway.d.ts.map +1 -1
  7. package/dist/adapters/pailot/gateway.js +267 -52
  8. package/dist/adapters/pailot/gateway.js.map +1 -1
  9. package/dist/aibp/bridge.d.ts +123 -0
  10. package/dist/aibp/bridge.d.ts.map +1 -0
  11. package/dist/aibp/bridge.js +363 -0
  12. package/dist/aibp/bridge.js.map +1 -0
  13. package/dist/aibp/envelope.d.ts +26 -0
  14. package/dist/aibp/envelope.d.ts.map +1 -0
  15. package/dist/aibp/envelope.js +101 -0
  16. package/dist/aibp/envelope.js.map +1 -0
  17. package/dist/aibp/index.d.ts +11 -0
  18. package/dist/aibp/index.d.ts.map +1 -0
  19. package/dist/aibp/index.js +10 -0
  20. package/dist/aibp/index.js.map +1 -0
  21. package/dist/aibp/registry.d.ts +71 -0
  22. package/dist/aibp/registry.d.ts.map +1 -0
  23. package/dist/aibp/registry.js +408 -0
  24. package/dist/aibp/registry.js.map +1 -0
  25. package/dist/aibp/types.d.ts +91 -0
  26. package/dist/aibp/types.d.ts.map +1 -0
  27. package/dist/aibp/types.js +8 -0
  28. package/dist/aibp/types.js.map +1 -0
  29. package/dist/core/state.d.ts +12 -0
  30. package/dist/core/state.d.ts.map +1 -1
  31. package/dist/core/state.js +34 -0
  32. package/dist/core/state.js.map +1 -1
  33. package/dist/daemon/adapter-registry.d.ts.map +1 -1
  34. package/dist/daemon/adapter-registry.js +32 -3
  35. package/dist/daemon/adapter-registry.js.map +1 -1
  36. package/dist/daemon/command-context.d.ts +4 -0
  37. package/dist/daemon/command-context.d.ts.map +1 -1
  38. package/dist/daemon/commands.d.ts.map +1 -1
  39. package/dist/daemon/commands.js +239 -22
  40. package/dist/daemon/commands.js.map +1 -1
  41. package/dist/daemon/core-handlers.d.ts.map +1 -1
  42. package/dist/daemon/core-handlers.js +276 -15
  43. package/dist/daemon/core-handlers.js.map +1 -1
  44. package/dist/daemon/image-context.d.ts +56 -0
  45. package/dist/daemon/image-context.d.ts.map +1 -0
  46. package/dist/daemon/image-context.js +116 -0
  47. package/dist/daemon/image-context.js.map +1 -0
  48. package/dist/daemon/image-gen/index.d.ts +22 -0
  49. package/dist/daemon/image-gen/index.d.ts.map +1 -0
  50. package/dist/daemon/image-gen/index.js +129 -0
  51. package/dist/daemon/image-gen/index.js.map +1 -0
  52. package/dist/daemon/image-gen/providers/cloudflare.d.ts +13 -0
  53. package/dist/daemon/image-gen/providers/cloudflare.d.ts.map +1 -0
  54. package/dist/daemon/image-gen/providers/cloudflare.js +63 -0
  55. package/dist/daemon/image-gen/providers/cloudflare.js.map +1 -0
  56. package/dist/daemon/image-gen/providers/huggingface.d.ts +12 -0
  57. package/dist/daemon/image-gen/providers/huggingface.d.ts.map +1 -0
  58. package/dist/daemon/image-gen/providers/huggingface.js +58 -0
  59. package/dist/daemon/image-gen/providers/huggingface.js.map +1 -0
  60. package/dist/daemon/image-gen/providers/pollinations.d.ts +11 -0
  61. package/dist/daemon/image-gen/providers/pollinations.d.ts.map +1 -0
  62. package/dist/daemon/image-gen/providers/pollinations.js +39 -0
  63. package/dist/daemon/image-gen/providers/pollinations.js.map +1 -0
  64. package/dist/daemon/image-gen/providers/replicate.d.ts +9 -0
  65. package/dist/daemon/image-gen/providers/replicate.d.ts.map +1 -0
  66. package/dist/daemon/image-gen/providers/replicate.js +158 -0
  67. package/dist/daemon/image-gen/providers/replicate.js.map +1 -0
  68. package/dist/daemon/image-gen/types.d.ts +41 -0
  69. package/dist/daemon/image-gen/types.d.ts.map +1 -0
  70. package/dist/daemon/image-gen/types.js +5 -0
  71. package/dist/daemon/image-gen/types.js.map +1 -0
  72. package/dist/daemon/index.d.ts.map +1 -1
  73. package/dist/daemon/index.js +157 -4
  74. package/dist/daemon/index.js.map +1 -1
  75. package/dist/index.d.ts +1 -1
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +1 -1
  78. package/dist/index.js.map +1 -1
  79. package/dist/mcp/index.js +129 -2
  80. package/dist/mcp/index.js.map +1 -1
  81. package/package.json +1 -1
  82. package/dist/adapters/pailot/gateway (SFConflict mnott 2026-03-06-21-13-56).d.ts +0 -49
  83. package/dist/adapters/pailot/gateway (SFConflict mnott 2026-03-06-21-13-56).d.ts.map +0 -1
  84. package/dist/adapters/pailot/gateway (SFConflict mnott 2026-03-06-21-13-56).js +0 -632
  85. package/dist/adapters/pailot/gateway (SFConflict mnott 2026-03-06-21-13-56).js.map +0 -1
  86. package/dist/adapters/pailot/gateway (SFConflict mnott 2026-03-06-21-13-59).js +0 -632
  87. package/dist/adapters/pailot/gateway (SFConflict mnott 2026-03-06-21-15-36).d.ts +0 -49
  88. package/dist/adapters/pailot/gateway (SFConflict mnott 2026-03-06-21-15-36).d.ts.map +0 -1
  89. package/dist/adapters/pailot/gateway (SFConflict mnott 2026-03-06-21-15-36).js +0 -614
  90. package/dist/adapters/pailot/gateway (SFConflict mnott 2026-03-06-21-15-36).js.map +0 -1
  91. package/dist/adapters/pailot/gateway (SFConflict mnott 2026-03-06-21-15-46).js +0 -614
  92. package/dist/adapters/pailot/gateway.d.ts (SFConflict mnott 2026-03-06-21-13-59).map +0 -1
  93. package/dist/adapters/pailot/gateway.d.ts (SFConflict mnott 2026-03-06-21-15-46).map +0 -1
  94. package/dist/adapters/pailot/gateway.js (SFConflict mnott 2026-03-06-21-13-59).map +0 -1
  95. package/dist/adapters/pailot/gateway.js (SFConflict mnott 2026-03-06-21-15-46).map +0 -1
  96. package/dist/daemon/adapter-registry (SFConflict mnott 2026-03-06-21-15-36).d.ts +0 -63
  97. package/dist/daemon/adapter-registry (SFConflict mnott 2026-03-06-21-15-36).d.ts.map +0 -1
  98. package/dist/daemon/adapter-registry (SFConflict mnott 2026-03-06-21-15-36).js +0 -229
  99. package/dist/daemon/adapter-registry (SFConflict mnott 2026-03-06-21-15-36).js.map +0 -1
  100. package/dist/daemon/image-gen.d.ts +0 -28
  101. package/dist/daemon/image-gen.d.ts.map +0 -1
  102. package/dist/daemon/image-gen.js +0 -97
  103. package/dist/daemon/image-gen.js.map +0 -1
  104. package/dist/daemon/screenshot (SFConflict mnott 2026-03-06-21-13-56).d.ts +0 -12
  105. package/dist/daemon/screenshot (SFConflict mnott 2026-03-06-21-13-56).d.ts.map +0 -1
  106. package/dist/daemon/screenshot (SFConflict mnott 2026-03-06-21-13-56).js +0 -252
  107. package/dist/daemon/screenshot (SFConflict mnott 2026-03-06-21-13-56).js.map +0 -1
  108. package/dist/daemon/screenshot (SFConflict mnott 2026-03-06-21-13-59).js +0 -252
  109. package/dist/daemon/screenshot (SFConflict mnott 2026-03-06-21-15-36).d.ts +0 -12
  110. package/dist/daemon/screenshot (SFConflict mnott 2026-03-06-21-15-36).d.ts.map +0 -1
  111. package/dist/daemon/screenshot (SFConflict mnott 2026-03-06-21-15-36).js +0 -240
  112. package/dist/daemon/screenshot (SFConflict mnott 2026-03-06-21-15-36).js.map +0 -1
  113. package/dist/daemon/screenshot (SFConflict mnott 2026-03-06-21-15-46).js +0 -240
  114. package/dist/daemon/screenshot.d.ts (SFConflict mnott 2026-03-06-21-13-59).map +0 -1
  115. package/dist/daemon/screenshot.d.ts (SFConflict mnott 2026-03-06-21-15-46).map +0 -1
  116. package/dist/daemon/screenshot.js (SFConflict mnott 2026-03-06-21-13-59).map +0 -1
  117. package/dist/daemon/screenshot.js (SFConflict mnott 2026-03-06-21-15-46).map +0 -1
  118. package/dist/mcp/index (SFConflict mnott 2026-03-06-21-13-56).d.ts +0 -23
  119. package/dist/mcp/index (SFConflict mnott 2026-03-06-21-13-56).d.ts.map +0 -1
  120. package/dist/mcp/index (SFConflict mnott 2026-03-06-21-13-56).js +0 -595
  121. package/dist/mcp/index (SFConflict mnott 2026-03-06-21-13-56).js.map +0 -1
  122. package/dist/mcp/index (SFConflict mnott 2026-03-06-21-13-59).js +0 -595
  123. package/dist/mcp/index (SFConflict mnott 2026-03-06-21-15-36).d.ts +0 -23
  124. package/dist/mcp/index (SFConflict mnott 2026-03-06-21-15-36).d.ts.map +0 -1
  125. package/dist/mcp/index (SFConflict mnott 2026-03-06-21-15-36).js +0 -592
  126. package/dist/mcp/index (SFConflict mnott 2026-03-06-21-15-36).js.map +0 -1
  127. package/dist/mcp/index (SFConflict mnott 2026-03-06-21-15-46).js +0 -592
  128. package/dist/mcp/index.js (SFConflict mnott 2026-03-06-21-13-59).map +0 -1
  129. package/dist/mcp/index.js (SFConflict mnott 2026-03-06-21-15-46).map +0 -1
@@ -0,0 +1,116 @@
1
+ /**
2
+ * daemon/image-context.ts — Per-session image context for conversational refinement.
3
+ *
4
+ * Tracks prompt history and the last generated image per routing context.
5
+ * The composite key (source:recipient:sessionId) ensures complete isolation
6
+ * between users, adapters, and sessions.
7
+ */
8
+ const MAX_HISTORY = 8;
9
+ const DEFAULT_TTL_MS = 30 * 60 * 1000; // 30 minutes
10
+ const store = new Map();
11
+ /**
12
+ * Build the composite routing key for image context lookup.
13
+ * Format: "{source}:{recipient}:{sessionId}"
14
+ */
15
+ export function buildImageContextKey(source, recipient, sessionId) {
16
+ return `${source}:${recipient ?? ""}:${sessionId ?? ""}`;
17
+ }
18
+ export function getImageContext(key) {
19
+ return store.get(key);
20
+ }
21
+ export function setImageContext(key, ctx) {
22
+ store.set(key, ctx);
23
+ }
24
+ export function clearImageContext(key) {
25
+ store.delete(key);
26
+ }
27
+ /**
28
+ * Remove image contexts that haven't been updated within the TTL window.
29
+ * Returns the number of evicted entries.
30
+ */
31
+ export function pruneStaleContexts(ttlMs = DEFAULT_TTL_MS) {
32
+ const cutoff = Date.now() - ttlMs;
33
+ let evicted = 0;
34
+ for (const [key, ctx] of store) {
35
+ if (ctx.updatedAt < cutoff) {
36
+ store.delete(key);
37
+ evicted++;
38
+ }
39
+ }
40
+ return evicted;
41
+ }
42
+ /**
43
+ * Classify an incoming text message as a new image request, a refinement
44
+ * of the current image context, or unrelated to image generation.
45
+ *
46
+ * Only returns "refine" when there is an actual signal — a pronoun
47
+ * referencing the image, a modification verb, or a style keyword.
48
+ * Messages that don't contain any image-related signal fall through
49
+ * as "unrelated" so they reach normal routing (Claude, slash commands, etc.).
50
+ */
51
+ export function classifyImageRequest(text, context) {
52
+ // No context — always new
53
+ if (!context || context.promptHistory.length === 0) {
54
+ return { type: "new", prompt: text };
55
+ }
56
+ const lower = text.toLowerCase().trim();
57
+ // Explicit new-image signals (English + German)
58
+ if (/^(new image|different image|new picture|start over|forget the image|neues bild|vergiss das bild)[:\s]/i.test(text) ||
59
+ /^(new image|different image|new picture|start over|forget the image|neues bild|vergiss das bild)$/i.test(text)) {
60
+ const prompt = text.replace(/^[^:]+:\s*/i, "").trim();
61
+ return { type: "new", prompt: prompt || text };
62
+ }
63
+ // Refinement signals: pronouns + modification verbs (English)
64
+ if (/\b(it|the image|the picture|that)\b/i.test(text) ||
65
+ /^(put|add|remove|change|make|give|turn|render|show)\b/i.test(text) ||
66
+ /\b(style|as a|in a|black and white|watercolor|oil paint(ing)?|sketch|pixelated|cartoon|anime)\b/i.test(lower) ||
67
+ /\b(more|less|brighter|darker|bigger|smaller|closer|farther)\b/i.test(lower)) {
68
+ return { type: "refine", prompt: text };
69
+ }
70
+ // Refinement signals: German
71
+ if (/\b(das bild|das foto)\b/i.test(lower) ||
72
+ /^(mach|ändere|füge hinzu|entferne|gib|zeig|setz)\b/i.test(lower)) {
73
+ return { type: "refine", prompt: text };
74
+ }
75
+ // Prepositional phrases that only make sense as image modifications
76
+ // e.g., "with a hat", "in watercolor", "but bigger", "without the chair"
77
+ if (/^(with|without|in|but|and|plus|minus)\b/i.test(lower)) {
78
+ return { type: "refine", prompt: text };
79
+ }
80
+ if (/^(mit|ohne|in|aber|und|als)\b/i.test(lower)) {
81
+ return { type: "refine", prompt: text };
82
+ }
83
+ // No image-related signal — this message is not about the image
84
+ return { type: "unrelated", prompt: text };
85
+ }
86
+ /**
87
+ * Build a combined prompt from the full prompt history using prompt chaining.
88
+ *
89
+ * The first entry is the base description; subsequent entries are refinement
90
+ * phrases appended with ", ". Cap at MAX_HISTORY entries.
91
+ */
92
+ export function buildChainedPrompt(history) {
93
+ const capped = history.slice(0, MAX_HISTORY);
94
+ if (capped.length === 1)
95
+ return capped[0];
96
+ const [base, ...modifications] = capped;
97
+ return `${base}, ${modifications.join(", ")}`;
98
+ }
99
+ /**
100
+ * Append a new prompt phrase to the context's history, enforcing the cap.
101
+ * Returns an updated context object (does NOT mutate the original).
102
+ */
103
+ export function appendPromptToContext(existing, prompt, imageBuffer, imageMime = "image/png") {
104
+ const history = existing ? [...existing.promptHistory] : [];
105
+ history.push(prompt);
106
+ // Enforce cap
107
+ while (history.length > MAX_HISTORY)
108
+ history.shift();
109
+ return {
110
+ promptHistory: history,
111
+ lastImage: imageBuffer ?? existing?.lastImage,
112
+ lastImageMime: imageBuffer ? imageMime : (existing?.lastImageMime ?? "image/png"),
113
+ updatedAt: Date.now(),
114
+ };
115
+ }
116
+ //# sourceMappingURL=image-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-context.js","sourceRoot":"","sources":["../../src/daemon/image-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * daemon/image-gen/index.ts — Provider-pluggable image generation.
3
+ *
4
+ * Public interface: generateImage() — identical signature to the old image-gen.ts.
5
+ * Callers only need to update their import path.
6
+ *
7
+ * Provider resolution order:
8
+ * 1. ~/.aibroker/image-gen.json (explicit config)
9
+ * 2. Env var detection: REPLICATE_API_TOKEN → CLOUDFLARE_AI_TOKEN → HF_API_TOKEN
10
+ * 3. Fallback: Pollinations (no auth, always works)
11
+ */
12
+ import type { GenerateImageOptions, GenerateImageResult, ImageProvider, ImageProviderConfig } from "./types.js";
13
+ export type { GenerateImageOptions, GenerateImageResult, ImageProvider, ImageProviderConfig };
14
+ /**
15
+ * Generate an image from a text prompt.
16
+ *
17
+ * Provider is resolved from ~/.aibroker/image-gen.json, then env vars,
18
+ * then falls back to Pollinations (no auth needed).
19
+ */
20
+ export declare function generateImage(opts: GenerateImageOptions): Promise<GenerateImageResult>;
21
+ export declare function getConfiguredProvider(): ImageProvider;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/daemon/image-gen/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMhH,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,aAAa,EAAE,mBAAmB,EAAE,CAAC;AAI9F;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAG5F;AAED,wBAAgB,qBAAqB,IAAI,aAAa,CA0BrD"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * daemon/image-gen/index.ts — Provider-pluggable image generation.
3
+ *
4
+ * Public interface: generateImage() — identical signature to the old image-gen.ts.
5
+ * Callers only need to update their import path.
6
+ *
7
+ * Provider resolution order:
8
+ * 1. ~/.aibroker/image-gen.json (explicit config)
9
+ * 2. Env var detection: REPLICATE_API_TOKEN → CLOUDFLARE_AI_TOKEN → HF_API_TOKEN
10
+ * 3. Fallback: Pollinations (no auth, always works)
11
+ */
12
+ import { readFileSync } from "fs";
13
+ import { homedir } from "os";
14
+ import { join } from "path";
15
+ import { log } from "../../core/log.js";
16
+ import { createReplicateProvider } from "./providers/replicate.js";
17
+ import { createCloudflareProvider } from "./providers/cloudflare.js";
18
+ import { createHuggingFaceProvider } from "./providers/huggingface.js";
19
+ import { createPollinationsProvider } from "./providers/pollinations.js";
20
+ const CONFIG_PATH = join(homedir(), ".aibroker", "image-gen.json");
21
+ /**
22
+ * Generate an image from a text prompt.
23
+ *
24
+ * Provider is resolved from ~/.aibroker/image-gen.json, then env vars,
25
+ * then falls back to Pollinations (no auth needed).
26
+ */
27
+ export async function generateImage(opts) {
28
+ const provider = getConfiguredProvider();
29
+ return provider.generate(opts);
30
+ }
31
+ export function getConfiguredProvider() {
32
+ // 1. Explicit config file
33
+ const config = loadConfig();
34
+ if (config) {
35
+ return buildProvider(config);
36
+ }
37
+ // 2. Env var detection
38
+ if (process.env.REPLICATE_API_TOKEN) {
39
+ log("Image gen: detected REPLICATE_API_TOKEN, using replicate");
40
+ return createReplicateProvider();
41
+ }
42
+ if (process.env.CLOUDFLARE_AI_TOKEN) {
43
+ log("Image gen: detected CLOUDFLARE_AI_TOKEN, using cloudflare");
44
+ return createCloudflareProvider();
45
+ }
46
+ if (process.env.HF_API_TOKEN) {
47
+ log("Image gen: detected HF_API_TOKEN, using huggingface");
48
+ return createHuggingFaceProvider();
49
+ }
50
+ // 3. Fallback: Pollinations (no auth needed)
51
+ log("Image gen: no token detected, falling back to pollinations");
52
+ return createPollinationsProvider();
53
+ }
54
+ function buildProvider(config) {
55
+ switch (config.provider) {
56
+ case "replicate":
57
+ return createReplicateProvider(config);
58
+ case "cloudflare":
59
+ return createCloudflareProvider(config);
60
+ case "huggingface":
61
+ return createHuggingFaceProvider(config);
62
+ case "pollinations":
63
+ return createPollinationsProvider();
64
+ case "custom":
65
+ return loadCustomProvider(config);
66
+ default:
67
+ log(`Image gen: unknown provider "${config.provider}", falling back to pollinations`);
68
+ return createPollinationsProvider();
69
+ }
70
+ }
71
+ /**
72
+ * Load a custom image provider from a user-supplied module.
73
+ *
74
+ * The module must export a `createProvider` function:
75
+ * export function createProvider(config: ImageProviderConfig): ImageProvider
76
+ *
77
+ * Example module (my-provider.js):
78
+ * export function createProvider(config) {
79
+ * return {
80
+ * name: "my-provider",
81
+ * async generate(opts) {
82
+ * const res = await fetch("https://my-api.com/generate", { ... });
83
+ * return { images: [Buffer.from(await res.arrayBuffer())], model: "my-model", durationMs: 0 };
84
+ * }
85
+ * };
86
+ * }
87
+ *
88
+ * Config (~/.aibroker/image-gen.json):
89
+ * { "provider": "custom", "modulePath": "/path/to/my-provider.js", "options": { "apiKey": "..." } }
90
+ */
91
+ function loadCustomProvider(config) {
92
+ if (!config.modulePath) {
93
+ throw new Error('Image gen: custom provider requires "modulePath" in ~/.aibroker/image-gen.json');
94
+ }
95
+ log(`Image gen: loading custom provider from ${config.modulePath}`);
96
+ // Dynamic import is async, so we return a lazy wrapper that loads on first call
97
+ let cached = null;
98
+ return {
99
+ name: `custom (${config.modulePath})`,
100
+ async generate(opts) {
101
+ if (!cached) {
102
+ const mod = await import(config.modulePath);
103
+ if (typeof mod.createProvider !== "function") {
104
+ throw new Error(`Image gen: custom module ${config.modulePath} must export createProvider(config): ImageProvider`);
105
+ }
106
+ cached = mod.createProvider(config);
107
+ log(`Image gen: custom provider "${cached.name}" loaded`);
108
+ }
109
+ return cached.generate(opts);
110
+ },
111
+ };
112
+ }
113
+ function loadConfig() {
114
+ try {
115
+ const raw = readFileSync(CONFIG_PATH, "utf8");
116
+ const parsed = JSON.parse(raw);
117
+ if (typeof parsed.provider === "string") {
118
+ log(`Image gen: loaded config from ${CONFIG_PATH} (provider: ${parsed.provider})`);
119
+ return parsed;
120
+ }
121
+ log(`Image gen: config at ${CONFIG_PATH} missing "provider" field, ignoring`);
122
+ return null;
123
+ }
124
+ catch {
125
+ // File doesn't exist or is malformed — not an error, just use env/fallback
126
+ return null;
127
+ }
128
+ }
129
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/daemon/image-gen/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * daemon/image-gen/providers/cloudflare.ts — Cloudflare Workers AI image generation provider.
3
+ *
4
+ * Uses Cloudflare's AI REST API with the Flux schnell model.
5
+ * Free tier: 10,000 neurons/day.
6
+ *
7
+ * Requires:
8
+ * CLOUDFLARE_AI_TOKEN — API token with AI:Run permission
9
+ * CLOUDFLARE_ACCOUNT_ID — Cloudflare account ID
10
+ */
11
+ import type { ImageProvider, ImageProviderConfig } from "../types.js";
12
+ export declare function createCloudflareProvider(config?: ImageProviderConfig): ImageProvider;
13
+ //# sourceMappingURL=cloudflare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../../src/daemon/image-gen/providers/cloudflare.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAA6C,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAIjH,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,mBAAgD,GAAG,aAAa,CA+DhH"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * daemon/image-gen/providers/cloudflare.ts — Cloudflare Workers AI image generation provider.
3
+ *
4
+ * Uses Cloudflare's AI REST API with the Flux schnell model.
5
+ * Free tier: 10,000 neurons/day.
6
+ *
7
+ * Requires:
8
+ * CLOUDFLARE_AI_TOKEN — API token with AI:Run permission
9
+ * CLOUDFLARE_ACCOUNT_ID — Cloudflare account ID
10
+ */
11
+ import { log } from "../../../core/log.js";
12
+ const DEFAULT_MODEL = "@cf/black-forest-labs/flux-1-schnell";
13
+ export function createCloudflareProvider(config = { provider: "cloudflare" }) {
14
+ return {
15
+ name: "cloudflare",
16
+ async generate(opts) {
17
+ const tokenEnv = config.apiTokenEnv ?? "CLOUDFLARE_AI_TOKEN";
18
+ const token = config.apiToken ?? process.env[tokenEnv];
19
+ if (!token) {
20
+ throw new Error(`Cloudflare API error: ${tokenEnv} not set`);
21
+ }
22
+ const accountId = config.accountId ?? process.env.CLOUDFLARE_ACCOUNT_ID;
23
+ if (!accountId) {
24
+ throw new Error("Cloudflare API error: CLOUDFLARE_ACCOUNT_ID not set");
25
+ }
26
+ const model = opts.model ?? config.model ?? DEFAULT_MODEL;
27
+ const startMs = Date.now();
28
+ const endpoint = `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/run/${model}`;
29
+ log(`Image gen: using cloudflare (${model})`);
30
+ const body = {
31
+ prompt: opts.prompt,
32
+ num_steps: 4, // Flux schnell optimal
33
+ };
34
+ if (opts.width)
35
+ body.width = opts.width;
36
+ if (opts.height)
37
+ body.height = opts.height;
38
+ const res = await fetch(endpoint, {
39
+ method: "POST",
40
+ headers: {
41
+ Authorization: `Bearer ${token}`,
42
+ "Content-Type": "application/json",
43
+ },
44
+ body: JSON.stringify(body),
45
+ });
46
+ if (!res.ok) {
47
+ const errText = await res.text();
48
+ throw new Error(`Cloudflare API error (${res.status}): ${errText}`);
49
+ }
50
+ // Cloudflare returns JSON with base64 image
51
+ const data = await res.json();
52
+ if (!data.success || !data.result?.image) {
53
+ const errMsg = data.errors?.map((e) => e.message).join(", ") ?? "unknown error";
54
+ throw new Error(`Cloudflare API error: ${errMsg}`);
55
+ }
56
+ const imageBuffer = Buffer.from(data.result.image, "base64");
57
+ const durationMs = Date.now() - startMs;
58
+ log(`Image gen: completed in ${durationMs}ms, 1 image(s), ${imageBuffer.length} bytes total`);
59
+ return { images: [imageBuffer], model, durationMs };
60
+ },
61
+ };
62
+ }
63
+ //# sourceMappingURL=cloudflare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../../../src/daemon/image-gen/providers/cloudflare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * daemon/image-gen/providers/huggingface.ts — Hugging Face Inference API image generation provider.
3
+ *
4
+ * Uses the HF Inference API to run image generation models.
5
+ * Default model: black-forest-labs/FLUX.1-schnell
6
+ * Free tier: rate-limited.
7
+ *
8
+ * Requires HF_API_TOKEN env var (or apiToken in config).
9
+ */
10
+ import type { ImageProvider, ImageProviderConfig } from "../types.js";
11
+ export declare function createHuggingFaceProvider(config?: ImageProviderConfig): ImageProvider;
12
+ //# sourceMappingURL=huggingface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"huggingface.d.ts","sourceRoot":"","sources":["../../../../src/daemon/image-gen/providers/huggingface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAA6C,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAKjH,wBAAgB,yBAAyB,CAAC,MAAM,GAAE,mBAAiD,GAAG,aAAa,CAsDlH"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * daemon/image-gen/providers/huggingface.ts — Hugging Face Inference API image generation provider.
3
+ *
4
+ * Uses the HF Inference API to run image generation models.
5
+ * Default model: black-forest-labs/FLUX.1-schnell
6
+ * Free tier: rate-limited.
7
+ *
8
+ * Requires HF_API_TOKEN env var (or apiToken in config).
9
+ */
10
+ import { log } from "../../../core/log.js";
11
+ const HF_API_BASE = "https://api-inference.huggingface.co/models";
12
+ const DEFAULT_MODEL = "black-forest-labs/FLUX.1-schnell";
13
+ export function createHuggingFaceProvider(config = { provider: "huggingface" }) {
14
+ return {
15
+ name: "huggingface",
16
+ async generate(opts) {
17
+ const tokenEnv = config.apiTokenEnv ?? "HF_API_TOKEN";
18
+ const token = config.apiToken ?? process.env[tokenEnv];
19
+ if (!token) {
20
+ throw new Error(`Hugging Face API error: ${tokenEnv} not set. Get one at https://huggingface.co/settings/tokens`);
21
+ }
22
+ const model = opts.model ?? config.model ?? DEFAULT_MODEL;
23
+ const startMs = Date.now();
24
+ const endpoint = `${HF_API_BASE}/${model}`;
25
+ log(`Image gen: using huggingface (${model})`);
26
+ const body = {
27
+ inputs: opts.prompt,
28
+ };
29
+ // HF accepts parameters for image dimensions
30
+ if (opts.width || opts.height) {
31
+ body.parameters = {
32
+ ...(opts.width ? { width: opts.width } : {}),
33
+ ...(opts.height ? { height: opts.height } : {}),
34
+ };
35
+ }
36
+ const res = await fetch(endpoint, {
37
+ method: "POST",
38
+ headers: {
39
+ Authorization: `Bearer ${token}`,
40
+ "Content-Type": "application/json",
41
+ "Accept": "image/*",
42
+ },
43
+ body: JSON.stringify(body),
44
+ });
45
+ if (!res.ok) {
46
+ const errText = await res.text();
47
+ throw new Error(`Hugging Face API error (${res.status}): ${errText}`);
48
+ }
49
+ // HF returns image bytes directly in the response body
50
+ const arrayBuf = await res.arrayBuffer();
51
+ const imageBuffer = Buffer.from(arrayBuf);
52
+ const durationMs = Date.now() - startMs;
53
+ log(`Image gen: completed in ${durationMs}ms, 1 image(s), ${imageBuffer.length} bytes total`);
54
+ return { images: [imageBuffer], model, durationMs };
55
+ },
56
+ };
57
+ }
58
+ //# sourceMappingURL=huggingface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"huggingface.js","sourceRoot":"","sources":["../../../../src/daemon/image-gen/providers/huggingface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAG3C,MAAM,WAAW,GAAG,6CAA6C,CAAC;AAClE,MAAM,aAAa,GAAG,kCAAkC,CAAC;AAEzD,MAAM,UAAU,yBAAyB,CAAC,SAA8B,EAAE,QAAQ,EAAE,aAAa,EAAE;IACjG,OAAO;QACL,IAAI,EAAE,aAAa;QAEnB,KAAK,CAAC,QAAQ,CAAC,IAA0B;YACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,IAAI,cAAc,CAAC;YACtD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACvD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,6DAA6D,CAAC,CAAC;YACpH,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,aAAa,CAAC;YAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,GAAG,WAAW,IAAI,KAAK,EAAE,CAAC;YAE3C,GAAG,CAAC,iCAAiC,KAAK,GAAG,CAAC,CAAC;YAE/C,MAAM,IAAI,GAA4B;gBACpC,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAC;YAEF,6CAA6C;YAC7C,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC9B,IAAI,CAAC,UAAU,GAAG;oBAChB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC5C,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAChD,CAAC;YACJ,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,KAAK,EAAE;oBAChC,cAAc,EAAE,kBAAkB;oBAClC,QAAQ,EAAE,SAAS;iBACpB;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC3B,CAAC,CAAC;YAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBACjC,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,MAAM,MAAM,OAAO,EAAE,CAAC,CAAC;YACxE,CAAC;YAED,uDAAuD;YACvD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;YAExC,GAAG,CAAC,2BAA2B,UAAU,mBAAmB,WAAW,CAAC,MAAM,cAAc,CAAC,CAAC;YAE9F,OAAO,EAAE,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QACtD,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * daemon/image-gen/providers/pollinations.ts — Pollinations.ai image generation provider.
3
+ *
4
+ * Free, no authentication required.
5
+ * Endpoint: https://image.pollinations.ai/prompt/{encoded_prompt}
6
+ *
7
+ * Returns image bytes directly — no API key needed.
8
+ */
9
+ import type { ImageProvider } from "../types.js";
10
+ export declare function createPollinationsProvider(): ImageProvider;
11
+ //# sourceMappingURL=pollinations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pollinations.d.ts","sourceRoot":"","sources":["../../../../src/daemon/image-gen/providers/pollinations.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAA6C,aAAa,EAAE,MAAM,aAAa,CAAC;AAK5F,wBAAgB,0BAA0B,IAAI,aAAa,CAmC1D"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * daemon/image-gen/providers/pollinations.ts — Pollinations.ai image generation provider.
3
+ *
4
+ * Free, no authentication required.
5
+ * Endpoint: https://image.pollinations.ai/prompt/{encoded_prompt}
6
+ *
7
+ * Returns image bytes directly — no API key needed.
8
+ */
9
+ import { log } from "../../../core/log.js";
10
+ const POLLINATIONS_BASE = "https://image.pollinations.ai/prompt";
11
+ const DEFAULT_MODEL = "flux";
12
+ export function createPollinationsProvider() {
13
+ return {
14
+ name: "pollinations",
15
+ async generate(opts) {
16
+ const model = opts.model ?? DEFAULT_MODEL;
17
+ const startMs = Date.now();
18
+ const params = new URLSearchParams({
19
+ nologo: "true",
20
+ model,
21
+ ...(opts.width ? { width: String(opts.width) } : {}),
22
+ ...(opts.height ? { height: String(opts.height) } : {}),
23
+ });
24
+ const encodedPrompt = encodeURIComponent(opts.prompt);
25
+ const endpoint = `${POLLINATIONS_BASE}/${encodedPrompt}?${params.toString()}`;
26
+ log(`Image gen: using pollinations (${model})`);
27
+ const res = await fetch(endpoint);
28
+ if (!res.ok) {
29
+ throw new Error(`Pollinations API error (${res.status}): ${await res.text()}`);
30
+ }
31
+ const arrayBuf = await res.arrayBuffer();
32
+ const imageBuffer = Buffer.from(arrayBuf);
33
+ const durationMs = Date.now() - startMs;
34
+ log(`Image gen: completed in ${durationMs}ms, 1 image(s), ${imageBuffer.length} bytes total`);
35
+ return { images: [imageBuffer], model, durationMs };
36
+ },
37
+ };
38
+ }
39
+ //# sourceMappingURL=pollinations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pollinations.js","sourceRoot":"","sources":["../../../../src/daemon/image-gen/providers/pollinations.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAG3C,MAAM,iBAAiB,GAAG,sCAAsC,CAAC;AACjE,MAAM,aAAa,GAAG,MAAM,CAAC;AAE7B,MAAM,UAAU,0BAA0B;IACxC,OAAO;QACL,IAAI,EAAE,cAAc;QAEpB,KAAK,CAAC,QAAQ,CAAC,IAA0B;YACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,aAAa,CAAC;YAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE3B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;gBACjC,MAAM,EAAE,MAAM;gBACd,KAAK;gBACL,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpD,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACxD,CAAC,CAAC;YAEH,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAG,GAAG,iBAAiB,IAAI,aAAa,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;YAE9E,GAAG,CAAC,kCAAkC,KAAK,GAAG,CAAC,CAAC;YAEhD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;YAElC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACjF,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;YAExC,GAAG,CAAC,2BAA2B,UAAU,mBAAmB,WAAW,CAAC,MAAM,cAAc,CAAC,CAAC;YAE9F,OAAO,EAAE,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QACtD,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * daemon/image-gen/providers/replicate.ts — Replicate image generation provider.
3
+ *
4
+ * Uses the Replicate Flux schnell model by default.
5
+ * Requires REPLICATE_API_TOKEN env var (or apiToken in config).
6
+ */
7
+ import type { ImageProvider, ImageProviderConfig } from "../types.js";
8
+ export declare function createReplicateProvider(config?: ImageProviderConfig): ImageProvider;
9
+ //# sourceMappingURL=replicate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replicate.d.ts","sourceRoot":"","sources":["../../../../src/daemon/image-gen/providers/replicate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAA6C,aAAa,EAAE,mBAAmB,EAAsB,MAAM,aAAa,CAAC;AAKrI,wBAAgB,uBAAuB,CAAC,MAAM,GAAE,mBAA+C,GAAG,aAAa,CAsK9G"}