@local-labs-jpollock/local-addon-nexus-ai 0.2.3 → 0.2.4

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 (60) hide show
  1. package/lib/common/constants.d.ts +1 -0
  2. package/lib/common/constants.d.ts.map +1 -1
  3. package/lib/common/constants.js +1 -0
  4. package/lib/common/constants.js.map +1 -1
  5. package/lib/main/ai-gateway/AIGatewayRoutes.d.ts +20 -3
  6. package/lib/main/ai-gateway/AIGatewayRoutes.d.ts.map +1 -1
  7. package/lib/main/ai-gateway/AIGatewayRoutes.js +282 -99
  8. package/lib/main/ai-gateway/AIGatewayRoutes.js.map +1 -1
  9. package/lib/main/ai-gateway/anthropic-client.d.ts +4 -4
  10. package/lib/main/ai-gateway/anthropic-client.js +11 -11
  11. package/lib/main/ai-gateway/anthropic-client.js.map +1 -1
  12. package/lib/main/ai-gateway/google-client.d.ts +48 -0
  13. package/lib/main/ai-gateway/google-client.d.ts.map +1 -0
  14. package/lib/main/ai-gateway/google-client.js +270 -0
  15. package/lib/main/ai-gateway/google-client.js.map +1 -0
  16. package/lib/main/ai-gateway/image-client.d.ts +46 -0
  17. package/lib/main/ai-gateway/image-client.d.ts.map +1 -0
  18. package/lib/main/ai-gateway/image-client.js +140 -0
  19. package/lib/main/ai-gateway/image-client.js.map +1 -0
  20. package/lib/main/ai-gateway/mu-plugin-template.d.ts.map +1 -1
  21. package/lib/main/ai-gateway/mu-plugin-template.js +30 -0
  22. package/lib/main/ai-gateway/mu-plugin-template.js.map +1 -1
  23. package/lib/main/ai-gateway/openai-client.d.ts.map +1 -1
  24. package/lib/main/ai-gateway/openai-client.js +20 -8
  25. package/lib/main/ai-gateway/openai-client.js.map +1 -1
  26. package/lib/main/chat/providers/google.d.ts.map +1 -1
  27. package/lib/main/chat/providers/google.js +1 -1
  28. package/lib/main/chat/providers/google.js.map +1 -1
  29. package/lib/main/chat/providers/openai.d.ts.map +1 -1
  30. package/lib/main/chat/providers/openai.js +3 -2
  31. package/lib/main/chat/providers/openai.js.map +1 -1
  32. package/lib/main/events/HttpEventInterface.d.ts.map +1 -1
  33. package/lib/main/events/HttpEventInterface.js +23 -1
  34. package/lib/main/events/HttpEventInterface.js.map +1 -1
  35. package/lib/main/ipc-handlers.d.ts.map +1 -1
  36. package/lib/main/ipc-handlers.js +7 -2
  37. package/lib/main/ipc-handlers.js.map +1 -1
  38. package/lib/renderer/components/AIGatewayUsagePanel.d.ts +2 -0
  39. package/lib/renderer/components/AIGatewayUsagePanel.d.ts.map +1 -1
  40. package/lib/renderer/components/AIGatewayUsagePanel.js +16 -1
  41. package/lib/renderer/components/AIGatewayUsagePanel.js.map +1 -1
  42. package/lib/renderer/components/NexusPreferences.d.ts.map +1 -1
  43. package/lib/renderer/components/NexusPreferences.js +11 -1
  44. package/lib/renderer/components/NexusPreferences.js.map +1 -1
  45. package/lib/renderer/components/NexusSiteTab.d.ts.map +1 -1
  46. package/lib/renderer/components/NexusSiteTab.js +10 -2
  47. package/lib/renderer/components/NexusSiteTab.js.map +1 -1
  48. package/lib/renderer/components/SidebarSearchPanel.d.ts +7 -1
  49. package/lib/renderer/components/SidebarSearchPanel.d.ts.map +1 -1
  50. package/lib/renderer/components/SidebarSearchPanel.js +49 -7
  51. package/lib/renderer/components/SidebarSearchPanel.js.map +1 -1
  52. package/lib/wp-plugins/ai-provider-for-local-gateway/plugin.php +3 -2
  53. package/lib/wp-plugins/ai-provider-for-local-gateway/src/Metadata/LocalGatewayModelMetadataDirectory.php +88 -60
  54. package/lib/wp-plugins/ai-provider-for-local-gateway/src/Models/LocalGatewayImageGenerationModel.php +170 -0
  55. package/lib/wp-plugins/ai-provider-for-local-gateway/src/Provider/LocalGatewayProvider.php +4 -0
  56. package/package.json +2 -1
  57. package/wp-plugins/ai-provider-for-local-gateway/plugin.php +3 -2
  58. package/wp-plugins/ai-provider-for-local-gateway/src/Metadata/LocalGatewayModelMetadataDirectory.php +88 -60
  59. package/wp-plugins/ai-provider-for-local-gateway/src/Models/LocalGatewayImageGenerationModel.php +170 -0
  60. package/wp-plugins/ai-provider-for-local-gateway/src/Provider/LocalGatewayProvider.php +4 -0
@@ -84,6 +84,7 @@ export declare const IPC_CHANNELS: {
84
84
  readonly AI_GATEWAY_GET_RATE_LIMIT: "nexus-ai:ai-gateway:get-rate-limit";
85
85
  readonly AI_GATEWAY_SET_RATE_LIMIT: "nexus-ai:ai-gateway:set-rate-limit";
86
86
  readonly AI_GATEWAY_CHECK_RATE_LIMIT: "nexus-ai:ai-gateway:check-rate-limit";
87
+ readonly AI_GATEWAY_USAGE_UPDATED: "nexus-ai:ai-gateway:usage-updated";
87
88
  readonly AI_CONTEXT_GENERATE: "nexus-ai:ai-context:generate";
88
89
  readonly AI_CONTEXT_GET_STATUS: "nexus-ai:ai-context:get-status";
89
90
  readonly WPE_SYNC_ALL: "nexus-ai:wpe:sync-all";
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,YAAY,CAAC;AACpC,eAAO,MAAM,YAAY,aAAa,CAAC;AAMvC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyJf,CAAC;AAMX,eAAO,MAAM,SAAS;;;;;;CAMZ,CAAC;AAEX,eAAO,MAAM,cAAc;;;CAGjB,CAAC;AAMX,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAC1C,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AACxC,eAAO,MAAM,oBAAoB,eAAe,CAAC;AACjD,eAAO,MAAM,wBAAwB,sCAAsC,CAAC;AAE5E,eAAO,MAAM,cAAc;;;;;;;;CAQjB,CAAC;AAMX,eAAO,MAAM,YAAY;;;;;;;;;;;CAWf,CAAC;AAMX,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,aAAa,qBAAqB,CAAC;AAChD,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAMzC,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAChE,eAAO,MAAM,oBAAoB,eAAe,CAAC;AACjD,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAChD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAMjD,0CAA0C;AAC1C,eAAO,MAAM,mBAAmB,UA2B/B,CAAC;AAEF,2CAA2C;AAC3C,eAAO,MAAM,eAAe,MAAM,CAAC;AAMnC,eAAO,MAAM,eAAe,2BAA2B,CAAC;AACxD,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAM9C,eAAO,MAAM,aAAa;;;CAGhB,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,YAAY,CAAC;AACpC,eAAO,MAAM,YAAY,aAAa,CAAC;AAMvC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Jf,CAAC;AAMX,eAAO,MAAM,SAAS;;;;;;CAMZ,CAAC;AAEX,eAAO,MAAM,cAAc;;;CAGjB,CAAC;AAMX,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAC1C,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AACxC,eAAO,MAAM,oBAAoB,eAAe,CAAC;AACjD,eAAO,MAAM,wBAAwB,sCAAsC,CAAC;AAE5E,eAAO,MAAM,cAAc;;;;;;;;CAQjB,CAAC;AAMX,eAAO,MAAM,YAAY;;;;;;;;;;;CAWf,CAAC;AAMX,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,aAAa,qBAAqB,CAAC;AAChD,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAMzC,eAAO,MAAM,mBAAmB,+BAA+B,CAAC;AAChE,eAAO,MAAM,oBAAoB,eAAe,CAAC;AACjD,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAChD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAMjD,0CAA0C;AAC1C,eAAO,MAAM,mBAAmB,UA2B/B,CAAC;AAEF,2CAA2C;AAC3C,eAAO,MAAM,eAAe,MAAM,CAAC;AAMnC,eAAO,MAAM,eAAe,2BAA2B,CAAC;AACxD,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAM9C,eAAO,MAAM,aAAa;;;CAGhB,CAAC"}
@@ -107,6 +107,7 @@ exports.IPC_CHANNELS = {
107
107
  AI_GATEWAY_GET_RATE_LIMIT: `${exports.ADDON_PREFIX}:ai-gateway:get-rate-limit`,
108
108
  AI_GATEWAY_SET_RATE_LIMIT: `${exports.ADDON_PREFIX}:ai-gateway:set-rate-limit`,
109
109
  AI_GATEWAY_CHECK_RATE_LIMIT: `${exports.ADDON_PREFIX}:ai-gateway:check-rate-limit`,
110
+ AI_GATEWAY_USAGE_UPDATED: `${exports.ADDON_PREFIX}:ai-gateway:usage-updated`,
110
111
  // AI Context File Generation
111
112
  AI_CONTEXT_GENERATE: `${exports.ADDON_PREFIX}:ai-context:generate`,
112
113
  AI_CONTEXT_GET_STATUS: `${exports.ADDON_PREFIX}:ai-context:get-status`,
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,12 @@
2
2
  * AI Gateway Routes
3
3
  *
4
4
  * HTTP routes for the AI Gateway that routes AI requests from WordPress
5
- * to provider APIs (Anthropic, OpenAI, etc.) with tracking and rate limiting.
5
+ * to provider APIs (Anthropic, OpenAI, Google) with tracking and rate limiting.
6
+ *
7
+ * Endpoints:
8
+ * POST /ai-gateway/v1/chat/completions — text generation (all providers)
9
+ * POST /ai-gateway/v1/images/generations — image generation (OpenAI)
10
+ * GET /ai-gateway/v1/models — list available models
6
11
  */
7
12
  import * as http from 'http';
8
13
  import type { RegistryStorage } from '../content/IndexRegistry';
@@ -25,11 +30,23 @@ export declare class AIGatewayRoutes {
25
30
  * Handle /ai-gateway/v1/chat/completions endpoint
26
31
  */
27
32
  handleChatCompletions(req: http.IncomingMessage, res: http.ServerResponse): Promise<void>;
33
+ /**
34
+ * Handle /ai-gateway/v1/images/generations endpoint (OpenAI-compatible).
35
+ */
36
+ handleImageGenerations(req: http.IncomingMessage, res: http.ServerResponse): Promise<void>;
28
37
  /**
29
38
  * Handle /ai-gateway/v1/models endpoint.
30
- * Returns models for the currently configured global provider.
39
+ *
40
+ * Returns ONLY models for the globally configured provider — this ensures
41
+ * WordPress plugins surface the right model list and don't accidentally pick
42
+ * a model from a different provider than what the user configured.
43
+ */
44
+ handleModels(_req: http.IncomingMessage, res: http.ServerResponse): void;
45
+ /**
46
+ * Validate X-Auth-Token and return siteId, or send 401 and return null.
31
47
  */
32
- handleModels(req: http.IncomingMessage, res: http.ServerResponse): void;
48
+ private authenticateRequest;
49
+ private recordAndRespond;
33
50
  private readBody;
34
51
  private sendError;
35
52
  private getSiteName;
@@ -1 +1 @@
1
- {"version":3,"file":"AIGatewayRoutes.d.ts","sourceRoot":"","sources":["../../../src/main/ai-gateway/AIGatewayRoutes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAOhE,OAAO,EAGL,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAuBjB,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE;QACN,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC5B,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;QAC7C,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;KAC7B,CAAC;IACF,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACxD;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,eAAe,CAAC,CAAuC;gBAEnD,OAAO,EAAE,sBAAsB;IAM3C;;OAEG;IACG,qBAAqB,CACzB,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IAsMhB;;;OAGG;IACH,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,GAAG,IAAI;IAsBvE,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,gBAAgB;CAazB"}
1
+ {"version":3,"file":"AIGatewayRoutes.d.ts","sourceRoot":"","sources":["../../../src/main/ai-gateway/AIGatewayRoutes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAShE,OAAO,EAGL,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAsFjB,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE;QACN,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC5B,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;QAC7C,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;KAC7B,CAAC;IACF,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACxD;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,eAAe,CAAC,CAAuC;gBAEnD,OAAO,EAAE,sBAAsB;IAM3C;;OAEG;IACG,qBAAqB,CACzB,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IAiHhB;;OAEG;IACG,sBAAsB,CAC1B,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IA8FhB;;;;;;OAMG;IACH,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,GAAG,IAAI;IAoDxE;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,gBAAgB;IA2DxB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,gBAAgB;CAOzB"}
@@ -3,7 +3,12 @@
3
3
  * AI Gateway Routes
4
4
  *
5
5
  * HTTP routes for the AI Gateway that routes AI requests from WordPress
6
- * to provider APIs (Anthropic, OpenAI, etc.) with tracking and rate limiting.
6
+ * to provider APIs (Anthropic, OpenAI, Google) with tracking and rate limiting.
7
+ *
8
+ * Endpoints:
9
+ * POST /ai-gateway/v1/chat/completions — text generation (all providers)
10
+ * POST /ai-gateway/v1/images/generations — image generation (OpenAI)
11
+ * GET /ai-gateway/v1/models — list available models
7
12
  */
8
13
  Object.defineProperty(exports, "__esModule", { value: true });
9
14
  exports.AIGatewayRoutes = void 0;
@@ -12,26 +17,86 @@ const token_manager_1 = require("./token-manager");
12
17
  const format_translator_1 = require("./format-translator");
13
18
  const anthropic_client_1 = require("./anthropic-client");
14
19
  const openai_client_1 = require("./openai-client");
20
+ const google_client_1 = require("./google-client");
21
+ const image_client_1 = require("./image-client");
15
22
  const rate_limiter_1 = require("./rate-limiter");
16
23
  /**
17
- * Maps known model IDs to their provider.
18
- * Extend this when adding new providers or model families.
24
+ * Maps known model IDs to their chat provider.
19
25
  * Falls back to the globally configured provider for unknown models.
20
26
  */
21
27
  const MODEL_PROVIDER_MAP = {
22
- // Anthropic — Claude models
28
+ // Anthropic — current models
29
+ 'claude-opus-4-6': 'anthropic',
30
+ 'claude-sonnet-4-6': 'anthropic',
23
31
  'claude-haiku-4-5-20251001': 'anthropic',
24
- 'claude-sonnet-4-5-20250514': 'anthropic',
25
- 'claude-opus-4-6-20251015': 'anthropic',
26
- // OpenAI — GPT models
27
- 'gpt-4o-mini': 'openai',
28
- 'gpt-4o': 'openai',
32
+ 'claude-haiku-4-5': 'anthropic',
33
+ // Anthropic — legacy (still available)
34
+ 'claude-sonnet-4-5-20250929': 'anthropic',
35
+ 'claude-opus-4-5-20251101': 'anthropic',
36
+ 'claude-sonnet-4-20250514': 'anthropic',
37
+ 'claude-opus-4-20250514': 'anthropic',
38
+ // OpenAI — GPT-4.1 family
29
39
  'gpt-4.1': 'openai',
30
40
  'gpt-4.1-mini': 'openai',
31
- 'o1': 'openai',
32
- 'o1-mini': 'openai',
41
+ 'gpt-4.1-nano': 'openai',
42
+ // OpenAI — GPT-4o family
43
+ 'gpt-4o': 'openai',
44
+ 'gpt-4o-mini': 'openai',
45
+ // OpenAI — reasoning models
46
+ 'o4-mini': 'openai',
33
47
  'o3': 'openai',
34
48
  'o3-mini': 'openai',
49
+ 'o1': 'openai',
50
+ 'o1-mini': 'openai',
51
+ // Google — Gemini 2.x
52
+ 'gemini-2.5-pro': 'google',
53
+ 'gemini-2.5-flash': 'google',
54
+ 'gemini-2.0-flash': 'google',
55
+ 'gemini-2.0-flash-lite': 'google',
56
+ // Google — Gemini 1.5
57
+ 'gemini-1.5-pro': 'google',
58
+ 'gemini-1.5-flash': 'google',
59
+ 'gemini-1.5-flash-8b': 'google',
60
+ };
61
+ /** Models surfaced in /models by provider */
62
+ const CATALOG = {
63
+ anthropic: [
64
+ { id: 'claude-opus-4-6', label: 'Claude Opus 4.6', tier: 'powerful' },
65
+ { id: 'claude-sonnet-4-6', label: 'Claude Sonnet 4.6', tier: 'balanced' },
66
+ { id: 'claude-haiku-4-5-20251001', label: 'Claude Haiku 4.5', tier: 'fast' },
67
+ ],
68
+ openai: [
69
+ { id: 'gpt-4.1', label: 'GPT-4.1', tier: 'powerful' },
70
+ { id: 'gpt-4.1-mini', label: 'GPT-4.1 Mini', tier: 'balanced' },
71
+ { id: 'gpt-4.1-nano', label: 'GPT-4.1 Nano', tier: 'fast' },
72
+ { id: 'gpt-4o', label: 'GPT-4o', tier: 'powerful' },
73
+ { id: 'gpt-4o-mini', label: 'GPT-4o Mini', tier: 'balanced' },
74
+ { id: 'o4-mini', label: 'o4-mini', tier: 'reasoning' },
75
+ { id: 'o3', label: 'o3', tier: 'reasoning' },
76
+ { id: 'o3-mini', label: 'o3-mini', tier: 'reasoning' },
77
+ { id: 'o1', label: 'o1', tier: 'reasoning' },
78
+ { id: 'o1-mini', label: 'o1-mini', tier: 'reasoning' },
79
+ ],
80
+ openai_image: [
81
+ { id: 'gpt-image-1', label: 'GPT Image 1', tier: 'image' },
82
+ { id: 'gpt-image-1.5', label: 'GPT Image 1.5', tier: 'image' },
83
+ { id: 'gpt-image-1-mini', label: 'GPT Image 1 Mini', tier: 'image' },
84
+ { id: 'dall-e-3', label: 'DALL·E 3', tier: 'image' },
85
+ { id: 'dall-e-2', label: 'DALL·E 2', tier: 'image' },
86
+ ],
87
+ google: [
88
+ { id: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro', tier: 'powerful' },
89
+ { id: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash', tier: 'balanced' },
90
+ { id: 'gemini-2.0-flash', label: 'Gemini 2.0 Flash', tier: 'balanced' },
91
+ { id: 'gemini-2.0-flash-lite', label: 'Gemini 2.0 Flash Lite', tier: 'fast' },
92
+ { id: 'gemini-1.5-pro', label: 'Gemini 1.5 Pro', tier: 'powerful' },
93
+ { id: 'gemini-1.5-flash', label: 'Gemini 1.5 Flash', tier: 'balanced' },
94
+ ],
95
+ google_image: [
96
+ { id: 'imagen-4.0-generate-001', label: 'Imagen 4', tier: 'image' },
97
+ { id: 'imagen-4.0-ultra-generate-001', label: 'Imagen 4 Ultra', tier: 'image' },
98
+ { id: 'imagen-4.0-fast-generate-001', label: 'Imagen 4 Fast', tier: 'image' },
99
+ ],
35
100
  };
36
101
  class AIGatewayRoutes {
37
102
  constructor(options) {
@@ -43,71 +108,34 @@ class AIGatewayRoutes {
43
108
  * Handle /ai-gateway/v1/chat/completions endpoint
44
109
  */
45
110
  async handleChatCompletions(req, res) {
46
- // 1. Validate X-Auth-Token header
47
- const authToken = req.headers['x-auth-token'];
48
- if (!authToken) {
49
- this.sendError(res, 401, 'Missing X-Auth-Token header');
111
+ const siteId = this.authenticateRequest(req, res);
112
+ if (!siteId)
50
113
  return;
51
- }
52
- // 2. Lookup site ID from token.
53
- // Primary: per-site token registered via storeSiteToken() (nexus_ai_gateway_tokens).
54
- // Fallback: validate token against the webhook auth token (http_webhook_info.authToken),
55
- // which is stable and shared with the MU plugin as NEXUS_AI_AUTH_TOKEN.
56
- // In that case, get the site ID from the X-WP-Site-ID header.
57
- let siteId = (0, token_manager_1.getSiteIdFromToken)(this.storage, authToken);
58
- if (!siteId) {
59
- // Fall back to validating the shared webhook auth token + X-WP-Site-ID header.
60
- // The site ID from the header is validated against the index registry so callers
61
- // cannot attribute requests to arbitrary sites they don't own.
62
- const webhookInfo = this.storage.get('http_webhook_info');
63
- const webhookToken = webhookInfo?.authToken;
64
- if (webhookToken && authToken === webhookToken) {
65
- const headerSiteId = req.headers['x-wp-site-id'];
66
- if (headerSiteId) {
67
- const indexRegistry = this.storage.get(constants_1.STORAGE_KEYS.INDEX_REGISTRY);
68
- if (indexRegistry && Object.prototype.hasOwnProperty.call(indexRegistry, headerSiteId)) {
69
- siteId = headerSiteId;
70
- }
71
- }
72
- }
73
- }
74
- if (!siteId) {
75
- this.sendError(res, 401, 'Invalid authentication token');
76
- return;
77
- }
78
- // 3. Parse request body
79
114
  const body = await this.readBody(req);
80
115
  let openAIRequest;
81
116
  try {
82
117
  openAIRequest = JSON.parse(body);
83
118
  }
84
- catch (err) {
119
+ catch {
85
120
  this.sendError(res, 400, 'Invalid JSON in request body');
86
121
  return;
87
122
  }
88
- // Validate required fields
89
123
  if (!openAIRequest.model || !openAIRequest.messages) {
90
124
  this.sendError(res, 400, 'Missing required fields: model, messages');
91
125
  return;
92
126
  }
93
- this.logger.info(`[AIGateway] Request from site ${siteId}: model=${openAIRequest.model}, messages=${openAIRequest.messages.length}`);
94
- // 4. Check rate limits
127
+ this.logger.info(`[AIGateway] Chat request from site ${siteId}: model=${openAIRequest.model}, messages=${openAIRequest.messages.length}`);
95
128
  const rateLimitStatus = (0, rate_limiter_1.checkRateLimit)(this.storage, siteId);
96
129
  if (!rateLimitStatus.allowed) {
97
130
  this.logger.warn(`[AIGateway] Rate limit exceeded for site ${siteId}: ${rateLimitStatus.reason}`);
98
131
  this.sendError(res, 429, rateLimitStatus.reason || 'Rate limit exceeded');
99
132
  return;
100
133
  }
101
- // 5. Determine which provider to use.
102
- // MODEL_PROVIDER_MAP gives an exact match for known models.
103
- // Unknown models fall back to the globally configured provider.
104
134
  const apiKeys = (this.storage.get(constants_1.STORAGE_KEYS.API_KEYS) ?? {});
105
135
  const settings = (this.storage.get(constants_1.STORAGE_KEYS.SETTINGS) ?? {});
106
136
  const model = openAIRequest.model;
107
- const globalProvider = settings.aiProvider ?? 'anthropic';
108
- const resolvedProvider = MODEL_PROVIDER_MAP[model] ?? globalProvider;
109
- const useAnthropic = resolvedProvider === 'anthropic';
110
- const useOpenAI = resolvedProvider === 'openai';
137
+ const globalProvider = (settings.aiProvider ?? 'anthropic');
138
+ const resolvedProvider = (MODEL_PROVIDER_MAP[model] ?? globalProvider);
111
139
  const startTime = Date.now();
112
140
  let openAIResponse;
113
141
  let promptTokens;
@@ -115,13 +143,12 @@ class AIGatewayRoutes {
115
143
  let responseId;
116
144
  let actualProvider;
117
145
  let costUsd;
118
- if (useAnthropic) {
146
+ if (resolvedProvider === 'anthropic') {
119
147
  const anthropicKey = apiKeys.anthropic;
120
148
  if (!anthropicKey) {
121
149
  this.sendError(res, 503, 'Anthropic API key not configured in Local');
122
150
  return;
123
151
  }
124
- // 6a. Translate → Anthropic format → call → translate back
125
152
  const anthropicRequest = (0, format_translator_1.translateToAnthropic)(openAIRequest);
126
153
  let anthropicResponse;
127
154
  try {
@@ -139,13 +166,12 @@ class AIGatewayRoutes {
139
166
  actualProvider = 'anthropic';
140
167
  costUsd = (0, anthropic_client_1.calculateAnthropicCost)(model, promptTokens, completionTokens);
141
168
  }
142
- else if (useOpenAI) {
169
+ else if (resolvedProvider === 'openai') {
143
170
  const openaiKey = apiKeys.openai;
144
171
  if (!openaiKey) {
145
172
  this.sendError(res, 503, 'OpenAI API key not configured in Local');
146
173
  return;
147
174
  }
148
- // 6b. OpenAI format is already correct — pass through directly
149
175
  let openaiResponse;
150
176
  try {
151
177
  openaiResponse = await (0, openai_client_1.callOpenAIAPI)(openAIRequest, { apiKey: openaiKey, logger: this.logger });
@@ -162,19 +188,209 @@ class AIGatewayRoutes {
162
188
  actualProvider = 'openai';
163
189
  costUsd = (0, openai_client_1.calculateOpenAICost)(model, promptTokens, completionTokens);
164
190
  }
191
+ else if (resolvedProvider === 'google') {
192
+ const googleKey = apiKeys.google;
193
+ if (!googleKey) {
194
+ this.sendError(res, 503, 'Google API key not configured in Local');
195
+ return;
196
+ }
197
+ let googleResponse;
198
+ try {
199
+ googleResponse = await (0, google_client_1.callGoogleAPI)(openAIRequest, { apiKey: googleKey, logger: this.logger });
200
+ }
201
+ catch (err) {
202
+ this.logger.error('[AIGateway] Google API call failed:', err);
203
+ this.sendError(res, 502, `Google API error: ${err instanceof Error ? err.message : 'Unknown error'}`);
204
+ return;
205
+ }
206
+ openAIResponse = googleResponse;
207
+ promptTokens = googleResponse.usage?.prompt_tokens ?? 0;
208
+ completionTokens = googleResponse.usage?.completion_tokens ?? 0;
209
+ responseId = googleResponse.id ?? `chatcmpl-google-${Date.now()}`;
210
+ actualProvider = 'google';
211
+ costUsd = (0, google_client_1.calculateGoogleCost)(model, promptTokens, completionTokens);
212
+ }
165
213
  else {
166
214
  this.sendError(res, 503, `No API key configured for model: ${model}`);
167
215
  return;
168
216
  }
217
+ this.recordAndRespond(req, res, siteId, model, actualProvider, openAIResponse, promptTokens, completionTokens, responseId, costUsd, Date.now() - startTime);
218
+ }
219
+ /**
220
+ * Handle /ai-gateway/v1/images/generations endpoint (OpenAI-compatible).
221
+ */
222
+ async handleImageGenerations(req, res) {
223
+ const siteId = this.authenticateRequest(req, res);
224
+ if (!siteId)
225
+ return;
226
+ const body = await this.readBody(req);
227
+ let imageRequest;
228
+ try {
229
+ imageRequest = JSON.parse(body);
230
+ }
231
+ catch {
232
+ this.sendError(res, 400, 'Invalid JSON in request body');
233
+ return;
234
+ }
235
+ if (!imageRequest.model || !imageRequest.prompt) {
236
+ this.sendError(res, 400, 'Missing required fields: model, prompt');
237
+ return;
238
+ }
239
+ const isGoogleImage = google_client_1.GOOGLE_IMAGE_MODELS.has(imageRequest.model);
240
+ const isOpenAIImage = image_client_1.IMAGE_MODELS.has(imageRequest.model);
241
+ if (!isGoogleImage && !isOpenAIImage) {
242
+ const all = [...image_client_1.IMAGE_MODELS, ...google_client_1.GOOGLE_IMAGE_MODELS].join(', ');
243
+ this.sendError(res, 400, `Unsupported image model: ${imageRequest.model}. Supported: ${all}`);
244
+ return;
245
+ }
246
+ const apiKeys = (this.storage.get(constants_1.STORAGE_KEYS.API_KEYS) ?? {});
247
+ this.logger.info(`[AIGateway] Image request from site ${siteId}: model=${imageRequest.model}, prompt="${imageRequest.prompt.substring(0, 60)}..."`);
248
+ const startTime = Date.now();
249
+ let imageResponse;
250
+ let costUsd;
251
+ if (isGoogleImage) {
252
+ const googleKey = apiKeys.google;
253
+ if (!googleKey) {
254
+ this.sendError(res, 503, 'Google API key not configured in Local (required for Imagen)');
255
+ return;
256
+ }
257
+ try {
258
+ imageResponse = await (0, google_client_1.callGoogleImageAPI)(imageRequest, { apiKey: googleKey, logger: this.logger });
259
+ }
260
+ catch (err) {
261
+ this.logger.error('[AIGateway] Imagen API call failed:', err);
262
+ this.sendError(res, 502, `Imagen API error: ${err instanceof Error ? err.message : 'Unknown error'}`);
263
+ return;
264
+ }
265
+ costUsd = (0, google_client_1.calculateGoogleImageCost)(imageRequest.model, imageRequest.n ?? 1);
266
+ }
267
+ else {
268
+ const openaiKey = apiKeys.openai;
269
+ if (!openaiKey) {
270
+ this.sendError(res, 503, 'OpenAI API key not configured in Local (required for image generation)');
271
+ return;
272
+ }
273
+ try {
274
+ imageResponse = await (0, image_client_1.callImageAPI)(imageRequest, { apiKey: openaiKey, logger: this.logger });
275
+ }
276
+ catch (err) {
277
+ this.logger.error('[AIGateway] Image API call failed:', err);
278
+ this.sendError(res, 502, `Image API error: ${err instanceof Error ? err.message : 'Unknown error'}`);
279
+ return;
280
+ }
281
+ costUsd = (0, image_client_1.calculateImageCost)(imageRequest.model, imageRequest.n ?? 1, imageRequest.size ?? '1024x1024');
282
+ }
169
283
  const durationMs = Date.now() - startTime;
170
- // 7. Extract caller information from headers
284
+ this.logger.info(`[AIGateway] Image success: site=${siteId}, model=${imageRequest.model}, n=${imageRequest.n ?? 1}, cost=$${costUsd.toFixed(4)}, duration=${durationMs}ms`);
285
+ // Record usage (no token counts for image gen)
286
+ const usageRecord = {
287
+ id: `img-${Date.now()}`,
288
+ siteId,
289
+ siteName: this.getSiteName(siteId),
290
+ model: imageRequest.model,
291
+ provider: 'openai',
292
+ timestamp: Date.now(),
293
+ promptTokens: 0,
294
+ completionTokens: 0,
295
+ totalTokens: 0,
296
+ costUsd,
297
+ durationMs,
298
+ };
299
+ this.storeUsageRecord(usageRecord);
300
+ if (this.onUsageRecorded)
301
+ this.onUsageRecorded(usageRecord);
302
+ res.writeHead(200, { 'Content-Type': 'application/json' });
303
+ res.end(JSON.stringify(imageResponse));
304
+ }
305
+ /**
306
+ * Handle /ai-gateway/v1/models endpoint.
307
+ *
308
+ * Returns ONLY models for the globally configured provider — this ensures
309
+ * WordPress plugins surface the right model list and don't accidentally pick
310
+ * a model from a different provider than what the user configured.
311
+ */
312
+ handleModels(_req, res) {
313
+ const apiKeys = (this.storage.get(constants_1.STORAGE_KEYS.API_KEYS) ?? {});
314
+ const settings = (this.storage.get(constants_1.STORAGE_KEYS.SETTINGS) ?? {});
315
+ const globalProvider = settings.aiProvider || 'anthropic';
316
+ const models = [];
317
+ const ts = 1700000000;
318
+ switch (globalProvider) {
319
+ case 'openai':
320
+ if (apiKeys.openai) {
321
+ for (const m of [...CATALOG.openai, ...CATALOG.openai_image]) {
322
+ models.push({ id: m.id, object: 'model', created: ts, owned_by: 'openai' });
323
+ }
324
+ }
325
+ break;
326
+ case 'google':
327
+ if (apiKeys.google) {
328
+ for (const m of [...CATALOG.google, ...CATALOG.google_image]) {
329
+ models.push({ id: m.id, object: 'model', created: ts, owned_by: 'google' });
330
+ }
331
+ }
332
+ break;
333
+ case 'anthropic':
334
+ default:
335
+ if (apiKeys.anthropic) {
336
+ for (const m of CATALOG.anthropic) {
337
+ models.push({ id: m.id, object: 'model', created: ts, owned_by: 'anthropic' });
338
+ }
339
+ }
340
+ break;
341
+ }
342
+ // Fallback: no key for global provider — return that provider's catalog anyway
343
+ // so the plugin at least sees what models are expected (user needs to add the key)
344
+ if (models.length === 0) {
345
+ const fallback = globalProvider === 'openai' ? CATALOG.openai
346
+ : globalProvider === 'google' ? CATALOG.google
347
+ : CATALOG.anthropic;
348
+ for (const m of fallback) {
349
+ models.push({ id: m.id, object: 'model', created: ts, owned_by: globalProvider });
350
+ }
351
+ }
352
+ res.writeHead(200, { 'Content-Type': 'application/json' });
353
+ res.end(JSON.stringify({ object: 'list', data: models }));
354
+ }
355
+ // ---------------------------------------------------------------------------
356
+ // Private helpers
357
+ // ---------------------------------------------------------------------------
358
+ /**
359
+ * Validate X-Auth-Token and return siteId, or send 401 and return null.
360
+ */
361
+ authenticateRequest(req, res) {
362
+ const authToken = req.headers['x-auth-token'];
363
+ if (!authToken) {
364
+ this.sendError(res, 401, 'Missing X-Auth-Token header');
365
+ return null;
366
+ }
367
+ let siteId = (0, token_manager_1.getSiteIdFromToken)(this.storage, authToken);
368
+ if (!siteId) {
369
+ const webhookInfo = this.storage.get('http_webhook_info');
370
+ const webhookToken = webhookInfo?.authToken;
371
+ if (webhookToken && authToken === webhookToken) {
372
+ const headerSiteId = req.headers['x-wp-site-id'];
373
+ if (headerSiteId) {
374
+ const indexRegistry = this.storage.get(constants_1.STORAGE_KEYS.INDEX_REGISTRY);
375
+ if (indexRegistry && Object.prototype.hasOwnProperty.call(indexRegistry, headerSiteId)) {
376
+ siteId = headerSiteId;
377
+ }
378
+ }
379
+ }
380
+ }
381
+ if (!siteId) {
382
+ this.sendError(res, 401, 'Invalid authentication token');
383
+ return null;
384
+ }
385
+ return siteId;
386
+ }
387
+ recordAndRespond(req, res, siteId, model, actualProvider, openAIResponse, promptTokens, completionTokens, responseId, costUsd, durationMs) {
171
388
  const callerPlugin = req.headers['x-wp-caller-plugin'];
172
389
  const callerTheme = req.headers['x-wp-caller-theme'];
173
390
  const callerFeature = req.headers['x-wp-caller-feature'];
174
391
  const callerSource = req.headers['x-wp-caller-source'];
175
392
  const callerUserId = req.headers['x-wp-user-id'];
176
393
  const callerUserRole = req.headers['x-wp-user-role'];
177
- // 8. Log usage
178
394
  const usageRecord = {
179
395
  id: responseId,
180
396
  siteId,
@@ -194,54 +410,24 @@ class AIGatewayRoutes {
194
410
  callerUserId: callerUserId ? parseInt(callerUserId, 10) : undefined,
195
411
  callerUserRole,
196
412
  };
197
- // Build caller description for logging
198
413
  const callerDesc = callerPlugin
199
414
  ? `plugin:${callerPlugin}${callerFeature ? `/${callerFeature}` : ''}`
200
- : callerTheme
201
- ? `theme:${callerTheme}`
202
- : callerSource
203
- ? `core:${callerFeature || callerSource}`
415
+ : callerTheme ? `theme:${callerTheme}`
416
+ : callerSource ? `core:${callerFeature || callerSource}`
204
417
  : 'unknown';
205
418
  this.logger.info(`[AIGateway] Success: site=${siteId}, provider=${actualProvider}, caller=${callerDesc}, model=${model}, ` +
206
- `tokens=${usageRecord.totalTokens} (${usageRecord.promptTokens}+${usageRecord.completionTokens}), ` +
419
+ `tokens=${usageRecord.totalTokens} (${promptTokens}+${completionTokens}), ` +
207
420
  `cost=$${costUsd.toFixed(4)}, duration=${durationMs}ms`);
208
- // 12. Store usage record
209
421
  this.storeUsageRecord(usageRecord);
210
- // Notify listeners
211
- if (this.onUsageRecorded) {
422
+ if (this.onUsageRecorded)
212
423
  this.onUsageRecorded(usageRecord);
213
- }
214
- // 13. Return response
215
424
  res.writeHead(200, { 'Content-Type': 'application/json' });
216
425
  res.end(JSON.stringify(openAIResponse));
217
426
  }
218
- /**
219
- * Handle /ai-gateway/v1/models endpoint.
220
- * Returns models for the currently configured global provider.
221
- */
222
- handleModels(req, res) {
223
- const settings = (this.storage.get(constants_1.STORAGE_KEYS.SETTINGS) ?? {});
224
- const provider = settings.aiProvider ?? 'anthropic';
225
- const anthropicModels = [
226
- { id: 'claude-haiku-4-5-20251001', object: 'model', created: 1700000000, owned_by: 'anthropic' },
227
- { id: 'claude-sonnet-4-5-20250514', object: 'model', created: 1700000000, owned_by: 'anthropic' },
228
- { id: 'claude-opus-4-6-20251015', object: 'model', created: 1700000000, owned_by: 'anthropic' },
229
- ];
230
- const openaiModels = [
231
- { id: 'gpt-4o-mini', object: 'model', created: 1700000000, owned_by: 'openai' },
232
- { id: 'gpt-4o', object: 'model', created: 1700000000, owned_by: 'openai' },
233
- { id: 'gpt-4.1', object: 'model', created: 1700000000, owned_by: 'openai' },
234
- ];
235
- const models = provider === 'openai' ? openaiModels : anthropicModels;
236
- res.writeHead(200, { 'Content-Type': 'application/json' });
237
- res.end(JSON.stringify({ object: 'list', data: models }));
238
- }
239
427
  readBody(req) {
240
428
  return new Promise((resolve, reject) => {
241
429
  let body = '';
242
- req.on('data', (chunk) => {
243
- body += chunk.toString();
244
- });
430
+ req.on('data', (chunk) => { body += chunk.toString(); });
245
431
  req.on('end', () => resolve(body));
246
432
  req.on('error', (err) => reject(err));
247
433
  });
@@ -251,7 +437,6 @@ class AIGatewayRoutes {
251
437
  res.end(JSON.stringify({ error: { message, type: 'invalid_request_error' } }));
252
438
  }
253
439
  getSiteName(siteId) {
254
- // Look up from index registry — populated by content indexing on site start
255
440
  const indexRegistry = this.storage.get(constants_1.STORAGE_KEYS.INDEX_REGISTRY);
256
441
  if (indexRegistry && indexRegistry[siteId]?.siteName) {
257
442
  return indexRegistry[siteId].siteName;
@@ -262,10 +447,8 @@ class AIGatewayRoutes {
262
447
  const USAGE_KEY = 'nexus_ai_gateway_usage';
263
448
  const records = (this.storage.get(USAGE_KEY) ?? []);
264
449
  records.push(record);
265
- // Keep last 1000 records (prevent unbounded growth)
266
- if (records.length > 1000) {
450
+ if (records.length > 1000)
267
451
  records.splice(0, records.length - 1000);
268
- }
269
452
  this.storage.set(USAGE_KEY, records);
270
453
  }
271
454
  }