@xopcai/xopc 0.0.201 → 0.0.203

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 (164) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-DOhnAQOQ.js → activity-store-SZAay-ze.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D8Cw0Mve.js → agent-avatar-dicebear-DPLJtxoS.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-DyjRuuRa.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-E9Bk-Idp.js → api-C1cSt2ru.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-BubrReXg.js → app-management-settings-panel-B3PCMqor.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-BY5Az2p4.js → appearance-settings-txSx3REK.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-BEhBaooZ.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-BY8843mB.js → archive-plugin-B2VVc17j.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-DG45KScf.js → attachment-load-Crk7x8qR.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-page-BUC6FL6O.js +6 -0
  13. package/dist/gateway/static/root/assets/{binary-plugins-DGIF2ZAv.js → binary-plugins-CLlJsq5D.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-C1Qktr1g.js → block-editor-cJ5lVNAG.js} +46 -46
  15. package/dist/gateway/static/root/assets/browser-settings-page-Bq2m4VpX.js +8 -0
  16. package/dist/gateway/static/root/assets/{browser-workflow-inputs-D_jnndyz.js → browser-workflow-inputs-WRiFG88u.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-workflows-page-DyIRvPaq.js → browser-workflows-page-BHLdVoOC.js} +2 -2
  18. package/dist/gateway/static/root/assets/capabilities-settings-panel-BiQbVvYU.js +7 -0
  19. package/dist/gateway/static/root/assets/{capability-presets-api--tz0mGLY.js → capability-presets-api-DmElfgC9.js} +1 -1
  20. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CYlZQpLY.js +3 -0
  21. package/dist/gateway/static/root/assets/{channel-recipient-api-CkOKF9nc.js → channel-recipient-api-BUEOtPft.js} +1 -1
  22. package/dist/gateway/static/root/assets/channels-settings-DlDiCMhO.js +1 -0
  23. package/dist/gateway/static/root/assets/channels-status-swr-Dm_-934M.js +1 -0
  24. package/dist/gateway/static/root/assets/{connectors-api-FBOe9SWC.js → connectors-api-BCdn44_o.js} +1 -1
  25. package/dist/gateway/static/root/assets/connectors-page-Ce-eaPHw.js +2 -0
  26. package/dist/gateway/static/root/assets/cron-expression-D2hF3t68.js +2 -0
  27. package/dist/gateway/static/root/assets/{date-picker-Dtn7e6TW.js → date-picker-Dvjoq2mB.js} +1 -1
  28. package/dist/gateway/static/root/assets/dependency-picker-zv1OIhk3.js +1 -0
  29. package/dist/gateway/static/root/assets/desktop-pet-DJZhKLTb.js +1 -0
  30. package/dist/gateway/static/root/assets/{desktop-pet-settings-FDmaty3P.js → desktop-pet-settings-B3ubM-eY.js} +1 -1
  31. package/dist/gateway/static/root/assets/{directory-picker-path-field-X2e8xn8j.js → directory-picker-path-field-BZEJIWOT.js} +1 -1
  32. package/dist/gateway/static/root/assets/download-Dk-ZjtO6.js +1 -0
  33. package/dist/gateway/static/root/assets/{extension-debug-page-Dx4MBfga.js → extension-debug-page-Bvq3E1A1.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-Bf_FEDhM.js → extension-page-CuCJjWNm.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-CrOgZxkf.js → extension-settings-page-CpTk_ajr.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-api-CZ4r-7qT.js → gateway-config-api-C2yM6qj7.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-Cv2ywpdb.js → gateway-config-swr-CN-JHMAh.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-settings-DpWmVi0w.js → gateway-settings-COwi--2Q.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-undf-k5g.js → gateway-startup-retry-Dq1RyCjz.js} +1 -1
  40. package/dist/gateway/static/root/assets/{heartbeat-settings-DSQZhSvT.js → heartbeat-settings-Dc6H4VGF.js} +1 -1
  41. package/dist/gateway/static/root/assets/home-page-BB3RGxwm.js +3 -0
  42. package/dist/gateway/static/root/assets/index-CPTLS-Zn.js +85 -0
  43. package/dist/gateway/static/root/assets/index-Dm-cvIpl.css +2 -0
  44. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-Bc3Quw42.js → keyboard-shortcuts-settings-cue30Z5p.js} +1 -1
  45. package/dist/gateway/static/root/assets/local-app-workbench-page-DfO6FOB9.js +2 -0
  46. package/dist/gateway/static/root/assets/local-apps-page-DKQSCsa0.js +1 -0
  47. package/dist/gateway/static/root/assets/{locale-store-CnamlR07.js → locale-store-81Gv0wwo.js} +1 -1
  48. package/dist/gateway/static/root/assets/logs-page-DODbODyl.js +2 -0
  49. package/dist/gateway/static/root/assets/{management-settings-CJmcaVje.js → management-settings--4H26QR-.js} +1 -1
  50. package/dist/gateway/static/root/assets/{markdown-split-AcuFp0TH.js → markdown-split-BTvpyjAi.js} +1 -1
  51. package/dist/gateway/static/root/assets/markdown-view-B12xeflb.css +1 -0
  52. package/dist/gateway/static/root/assets/markdown-view-B4iBrVWK.js +69 -0
  53. package/dist/gateway/static/root/assets/{media-plugins-BvFgsiJL.js → media-plugins-DrejWl8t.js} +1 -1
  54. package/dist/gateway/static/root/assets/messages-ELK_1h2D.js +3 -0
  55. package/dist/gateway/static/root/assets/{notes-page-IW7IQ9nJ.js → notes-page-DfSzeQKd.js} +1 -1
  56. package/dist/gateway/static/root/assets/notes-workbench-DxL4GhwV.js +4 -0
  57. package/dist/gateway/static/root/assets/plus-Q2yW6OE7.js +1 -0
  58. package/dist/gateway/static/root/assets/preview-open-alternatives-yjh1_7K3.js +1 -0
  59. package/dist/gateway/static/root/assets/{product-open-page-CWEzLykF.js → product-open-page-DopWBJLa.js} +1 -1
  60. package/dist/gateway/static/root/assets/project-detail-page-Bl3LJHZB.js +1 -0
  61. package/dist/gateway/static/root/assets/projects-page-DStOErTC.js +1 -0
  62. package/dist/gateway/static/root/assets/remote-access-hub-C_hh9ztK.js +1 -0
  63. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DAohEZrX.js → runtime-tools-settings-panel-_dHhbYV2.js} +2 -2
  64. package/dist/gateway/static/root/assets/{schema-form-C_OBW8A5.js → schema-form-DZhORvJZ.js} +1 -1
  65. package/dist/gateway/static/root/assets/sessions-page-DDY21KYw.js +1 -0
  66. package/dist/gateway/static/root/assets/settings-advanced-gate-BJrHIcw8.js +1 -0
  67. package/dist/gateway/static/root/assets/{settings-form-section-C7w2WS-A.js → settings-form-section-Du5eAgFS.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-loading-skeleton-zwibve4m.js → settings-loading-skeleton-DWS27sv1.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-page-B9W03dSW.js → settings-page-DPD0MwoN.js} +1 -1
  70. package/dist/gateway/static/root/assets/setup-status-panel-CnXN4LH_.js +1 -0
  71. package/dist/gateway/static/root/assets/share-preview-page-D6HmH2ga.js +2 -0
  72. package/dist/gateway/static/root/assets/shares-settings-U3lvtO3Y.js +1 -0
  73. package/dist/gateway/static/root/assets/skill-reload-api-B6GiZgZU.js +1 -0
  74. package/dist/gateway/static/root/assets/skills-page-XVO7d3fh.js +2 -0
  75. package/dist/gateway/static/root/assets/{skills-page.utils-D9QT5cxj.js → skills-page.utils-DwxIpWrI.js} +1 -1
  76. package/dist/gateway/static/root/assets/{system-settings-panel-c1HVtv1Y.js → system-settings-panel-BmKbxR8_.js} +1 -1
  77. package/dist/gateway/static/root/assets/task-detail-page-DA6ItYrc.js +1 -0
  78. package/dist/gateway/static/root/assets/{theme-store-BDyUTObE.js → theme-store-hOF81tUQ.js} +1 -1
  79. package/dist/gateway/static/root/assets/{use-autosave-D6UkH_Ga.js → use-autosave-GJfDpf66.js} +1 -1
  80. package/dist/gateway/static/root/assets/user-context-page-CQ1QrRE6.js +1 -0
  81. package/dist/gateway/static/root/assets/{voice-api-key-field-BOxkKbGh.js → voice-api-key-field-B0zve9EE.js} +1 -1
  82. package/dist/gateway/static/root/assets/work-discovery-overlay-DrIbHnBz.js +1 -0
  83. package/dist/gateway/static/root/assets/work-discovery-page-CQW8pPec.js +1 -0
  84. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-ZA3bP65I.js → workflow-run-setup-panel-D-_zQxim.js} +2 -2
  85. package/dist/gateway/static/root/assets/workflows-page-O21l_f5c.js +5 -0
  86. package/dist/gateway/static/root/assets/{working-directory-picker-modal-BcyiDXU3.js → working-directory-picker-modal-5xYx48tV.js} +1 -1
  87. package/dist/gateway/static/root/assets/x-B_N4OPjy.js +1 -0
  88. package/dist/gateway/static/root/index.html +19 -14
  89. package/dist/package.js +1 -1
  90. package/dist/src/agent/agent-manager.js +2 -1
  91. package/dist/src/agent/embedded/run-for-session.js +3 -2
  92. package/dist/src/agent/embedded/run-turn.js +29 -16
  93. package/dist/src/agent/embedded/types.d.ts +2 -2
  94. package/dist/src/agent/embedded/xopc-stream-bridge.d.ts +2 -1
  95. package/dist/src/agent/embedded/xopc-stream-bridge.js +2 -2
  96. package/dist/src/agent/memory/context-budget.d.ts +6 -1
  97. package/dist/src/agent/memory/context-budget.js +94 -2
  98. package/dist/src/agent/prompt/cache-boundary.d.ts +2 -0
  99. package/dist/src/agent/prompt/cache-boundary.js +10 -1
  100. package/dist/src/agent/prompt/sections/project-context.d.ts +1 -4
  101. package/dist/src/agent/prompt/sections/project-context.js +6 -13
  102. package/dist/src/agent/prompt/service-prompt-builder.js +2 -1
  103. package/dist/src/agent/prompt/system-prompt.d.ts +1 -3
  104. package/dist/src/agent/prompt/system-prompt.js +6 -15
  105. package/dist/src/agent/tools/cache-stability.d.ts +3 -0
  106. package/dist/src/agent/tools/cache-stability.js +19 -0
  107. package/dist/src/agent/tools/factory.js +2 -1
  108. package/dist/src/agent-manifest/schema.d.ts +40 -20
  109. package/dist/src/agent-manifest/schema.js +4 -5
  110. package/dist/src/config/schema.d.ts +40 -20
  111. package/dist/src/extensions/types/providers.d.ts +0 -2
  112. package/dist/src/gateway/hono/lib/config-payload.d.ts +4 -1
  113. package/dist/src/gateway/hono/oauth-async.d.ts +1 -0
  114. package/dist/src/gateway/hono/oauth-async.js +14 -2
  115. package/dist/src/providers/extension-stream-bridge.js +0 -2
  116. package/dist/src/providers/google-managed-prompt-cache.d.ts +14 -0
  117. package/dist/src/providers/google-managed-prompt-cache.js +125 -0
  118. package/dist/src/providers/prompt-cache-fingerprint.d.ts +4 -0
  119. package/dist/src/providers/prompt-cache-fingerprint.js +44 -0
  120. package/dist/src/providers/prompt-cache-lifecycle.d.ts +9 -0
  121. package/dist/src/providers/prompt-cache-lifecycle.js +31 -0
  122. package/dist/src/providers/prompt-cache-observability.d.ts +20 -0
  123. package/dist/src/providers/prompt-cache-observability.js +44 -0
  124. package/dist/src/providers/prompt-cache-payload.d.ts +10 -3
  125. package/dist/src/providers/prompt-cache-payload.js +204 -31
  126. package/dist/src/providers/prompt-cache-plan.d.ts +15 -0
  127. package/dist/src/providers/prompt-cache-plan.js +29 -0
  128. package/package.json +3 -3
  129. package/dist/gateway/static/root/assets/agents-ANavi648.js +0 -68
  130. package/dist/gateway/static/root/assets/apps-page-CFh9MBxc.js +0 -1
  131. package/dist/gateway/static/root/assets/automations-page-751CeNI3.js +0 -6
  132. package/dist/gateway/static/root/assets/browser-settings-page-CGAWs-TT.js +0 -8
  133. package/dist/gateway/static/root/assets/capabilities-settings-panel-CghUK68J.js +0 -7
  134. package/dist/gateway/static/root/assets/capability-presets-settings-panel-XsTfkvUn.js +0 -3
  135. package/dist/gateway/static/root/assets/channels-settings-DkoAZZMe.js +0 -1
  136. package/dist/gateway/static/root/assets/channels-status-swr-DNDvMWpl.js +0 -1
  137. package/dist/gateway/static/root/assets/connectors-page-e4vekkAu.js +0 -2
  138. package/dist/gateway/static/root/assets/cron-expression-Q4QaYjpI.js +0 -2
  139. package/dist/gateway/static/root/assets/dependency-picker-Br6nPaM6.js +0 -1
  140. package/dist/gateway/static/root/assets/desktop-pet-DzTM6aH8.js +0 -1
  141. package/dist/gateway/static/root/assets/home-page-L0uHiu0T.js +0 -3
  142. package/dist/gateway/static/root/assets/index-Bp8I_eX4.css +0 -1
  143. package/dist/gateway/static/root/assets/index-DRrjYYzZ.js +0 -152
  144. package/dist/gateway/static/root/assets/local-app-workbench-page-Copi3sdP.js +0 -2
  145. package/dist/gateway/static/root/assets/local-apps-page-CP9X_vtz.js +0 -1
  146. package/dist/gateway/static/root/assets/logs-page-DMKq6e29.js +0 -2
  147. package/dist/gateway/static/root/assets/messages-D7kOD_o_.js +0 -3
  148. package/dist/gateway/static/root/assets/notes-workbench-Zb8U0anO.js +0 -4
  149. package/dist/gateway/static/root/assets/preview-open-alternatives-C-b34dgQ.js +0 -1
  150. package/dist/gateway/static/root/assets/project-detail-page-BuIbLnan.js +0 -1
  151. package/dist/gateway/static/root/assets/projects-page-BwUfRqNV.js +0 -1
  152. package/dist/gateway/static/root/assets/remote-access-hub-BTaXxcEi.js +0 -1
  153. package/dist/gateway/static/root/assets/sessions-page-BnHoTCD3.js +0 -1
  154. package/dist/gateway/static/root/assets/settings-advanced-gate-BTB_fxjt.js +0 -1
  155. package/dist/gateway/static/root/assets/setup-status-panel-C8Hec2Af.js +0 -1
  156. package/dist/gateway/static/root/assets/share-preview-page-6e3ks2be.js +0 -2
  157. package/dist/gateway/static/root/assets/shares-settings-Bwc5HfLI.js +0 -1
  158. package/dist/gateway/static/root/assets/skill-reload-api-D7kunhqy.js +0 -1
  159. package/dist/gateway/static/root/assets/skills-page-WgkaNzpc.js +0 -2
  160. package/dist/gateway/static/root/assets/task-detail-page-CjP-6WVU.js +0 -1
  161. package/dist/gateway/static/root/assets/user-context-page-D8ZhPDNF.js +0 -1
  162. package/dist/gateway/static/root/assets/work-discovery-overlay-Dd19yK9t.js +0 -1
  163. package/dist/gateway/static/root/assets/work-discovery-page-DUkdJl1e.js +0 -1
  164. package/dist/gateway/static/root/assets/workflows-page-C2b5W5bw.js +0 -5
@@ -164,11 +164,16 @@ export declare const AgentsConfigSchema: z.ZodDefault<z.ZodObject<{
164
164
  maxTurns: z.ZodOptional<z.ZodNumber>;
165
165
  timeoutMs: z.ZodOptional<z.ZodNumber>;
166
166
  maxToolFailuresPerTurn: z.ZodOptional<z.ZodNumber>;
167
- promptCacheRetention: z.ZodOptional<z.ZodEnum<{
168
- none: "none";
169
- short: "short";
170
- long: "long";
171
- }>>;
167
+ promptCache: z.ZodOptional<z.ZodObject<{
168
+ mode: z.ZodDefault<z.ZodEnum<{
169
+ off: "off";
170
+ auto: "auto";
171
+ }>>;
172
+ lifetime: z.ZodDefault<z.ZodEnum<{
173
+ short: "short";
174
+ long: "long";
175
+ }>>;
176
+ }, z.core.$strict>>;
172
177
  }, z.core.$strict>>;
173
178
  locks: z.ZodOptional<z.ZodArray<z.ZodString>>;
174
179
  }, z.core.$strict>>>;
@@ -299,11 +304,16 @@ export declare const AgentsConfigSchema: z.ZodDefault<z.ZodObject<{
299
304
  maxTurns: z.ZodOptional<z.ZodNumber>;
300
305
  timeoutMs: z.ZodOptional<z.ZodNumber>;
301
306
  maxToolFailuresPerTurn: z.ZodOptional<z.ZodNumber>;
302
- promptCacheRetention: z.ZodOptional<z.ZodEnum<{
303
- none: "none";
304
- short: "short";
305
- long: "long";
306
- }>>;
307
+ promptCache: z.ZodOptional<z.ZodObject<{
308
+ mode: z.ZodDefault<z.ZodEnum<{
309
+ off: "off";
310
+ auto: "auto";
311
+ }>>;
312
+ lifetime: z.ZodDefault<z.ZodEnum<{
313
+ short: "short";
314
+ long: "long";
315
+ }>>;
316
+ }, z.core.$strict>>;
307
317
  }, z.core.$strict>>;
308
318
  prompt: z.ZodOptional<z.ZodObject<{
309
319
  customInstructions: z.ZodOptional<z.ZodString>;
@@ -1699,11 +1709,16 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1699
1709
  maxTurns: z.ZodOptional<z.ZodNumber>;
1700
1710
  timeoutMs: z.ZodOptional<z.ZodNumber>;
1701
1711
  maxToolFailuresPerTurn: z.ZodOptional<z.ZodNumber>;
1702
- promptCacheRetention: z.ZodOptional<z.ZodEnum<{
1703
- none: "none";
1704
- short: "short";
1705
- long: "long";
1706
- }>>;
1712
+ promptCache: z.ZodOptional<z.ZodObject<{
1713
+ mode: z.ZodDefault<z.ZodEnum<{
1714
+ off: "off";
1715
+ auto: "auto";
1716
+ }>>;
1717
+ lifetime: z.ZodDefault<z.ZodEnum<{
1718
+ short: "short";
1719
+ long: "long";
1720
+ }>>;
1721
+ }, z.core.$strict>>;
1707
1722
  }, z.core.$strict>>;
1708
1723
  locks: z.ZodOptional<z.ZodArray<z.ZodString>>;
1709
1724
  }, z.core.$strict>>>;
@@ -1834,11 +1849,16 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1834
1849
  maxTurns: z.ZodOptional<z.ZodNumber>;
1835
1850
  timeoutMs: z.ZodOptional<z.ZodNumber>;
1836
1851
  maxToolFailuresPerTurn: z.ZodOptional<z.ZodNumber>;
1837
- promptCacheRetention: z.ZodOptional<z.ZodEnum<{
1838
- none: "none";
1839
- short: "short";
1840
- long: "long";
1841
- }>>;
1852
+ promptCache: z.ZodOptional<z.ZodObject<{
1853
+ mode: z.ZodDefault<z.ZodEnum<{
1854
+ off: "off";
1855
+ auto: "auto";
1856
+ }>>;
1857
+ lifetime: z.ZodDefault<z.ZodEnum<{
1858
+ short: "short";
1859
+ long: "long";
1860
+ }>>;
1861
+ }, z.core.$strict>>;
1842
1862
  }, z.core.$strict>>;
1843
1863
  prompt: z.ZodOptional<z.ZodObject<{
1844
1864
  customInstructions: z.ZodOptional<z.ZodString>;
@@ -92,8 +92,6 @@ export interface ProviderStreamParams {
92
92
  maxRetries?: number;
93
93
  /** Provider request metadata */
94
94
  metadata?: Record<string, unknown>;
95
- /** Prompt cache retention preference */
96
- cacheRetention?: string;
97
95
  /** Preferred transport, if the provider supports multiple transports */
98
96
  transport?: string;
99
97
  /** Custom token budgets for thinking levels */
@@ -191,7 +191,10 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
191
191
  maxTurns?: number;
192
192
  timeoutMs?: number;
193
193
  maxToolFailuresPerTurn?: number;
194
- promptCacheRetention?: "none" | "short" | "long";
194
+ promptCache?: {
195
+ mode: "off" | "auto";
196
+ lifetime: "short" | "long";
197
+ };
195
198
  };
196
199
  locks?: string[];
197
200
  }>;
@@ -9,6 +9,7 @@ import { Hono } from 'hono';
9
9
  import type { GatewayService } from '../service.js';
10
10
  import { type OAuthCredentials } from '../../auth/oauth/types.js';
11
11
  export declare function refreshModelCatalogAfterOAuth(provider: string, service: Pick<GatewayService, 'getModelCatalogSync'>): Promise<void>;
12
+ export declare function normalizeDesktopOAuthReturnPath(value: unknown): string | undefined;
12
13
  export declare function resolveOAuthLoginMethodPreference(params: {
13
14
  requestedMethod?: unknown;
14
15
  supportedMethods?: readonly string[];
@@ -53,6 +53,18 @@ setInterval(() => {
53
53
  function generateSessionId() {
54
54
  return `oauth_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
55
55
  }
56
+ function normalizeDesktopOAuthReturnPath(value) {
57
+ if (typeof value !== "string") return void 0;
58
+ const path = value.trim();
59
+ if (path.length === 0 || path.length > 2048 || !path.startsWith("/") || path.startsWith("//") || path.includes("\\") || /[\u0000-\u001f\u007f]/.test(path)) return;
60
+ return path;
61
+ }
62
+ function desktopOAuthReturnUrl(sessionId, returnPath) {
63
+ const params = new URLSearchParams({ request_id: sessionId });
64
+ const normalizedReturnPath = normalizeDesktopOAuthReturnPath(returnPath);
65
+ if (normalizedReturnPath) params.set("return_path", normalizedReturnPath);
66
+ return `xopc://cloud/model-connected?${params.toString()}`;
67
+ }
56
68
  function cancelOAuthSession(session, message = "OAuth flow cancelled") {
57
69
  if (session.abortController) session.abortController.abort();
58
70
  if (session.manualCodeResolve) session.manualCodeResolve("");
@@ -110,7 +122,7 @@ function createOAuthAsyncHandler(service) {
110
122
  const session = {
111
123
  id: sessionId,
112
124
  provider,
113
- ...body.client === "desktop" && provider === "xopc-cloud" ? { returnToAppUrl: `xopc://cloud/model-connected?request_id=${encodeURIComponent(sessionId)}` } : {},
125
+ ...body.client === "desktop" && provider === "xopc-cloud" ? { returnToAppUrl: desktopOAuthReturnUrl(sessionId, body.returnPath) } : {},
114
126
  preferredLoginMethod: preferredOAuthLoginMethod({
115
127
  provider,
116
128
  requestedMethod: body.loginMethod,
@@ -330,4 +342,4 @@ function deleteOAuthCredentialsFromCache(provider) {
330
342
  oauthCredentialsCache.delete(provider);
331
343
  }
332
344
  //#endregion
333
- export { createOAuthAsyncHandler, deleteOAuthCredentialsFromCache, getOAuthCredentialsFromCache, refreshModelCatalogAfterOAuth, resolveOAuthLoginMethodPreference, setOAuthCredentialsToCache };
345
+ export { createOAuthAsyncHandler, deleteOAuthCredentialsFromCache, getOAuthCredentialsFromCache, normalizeDesktopOAuthReturnPath, refreshModelCatalogAfterOAuth, resolveOAuthLoginMethodPreference, setOAuthCredentialsToCache };
@@ -51,7 +51,6 @@ function collectExtraStreamOptions(options) {
51
51
  "signal",
52
52
  "apiKey",
53
53
  "transport",
54
- "cacheRetention",
55
54
  "sessionId",
56
55
  "onPayload",
57
56
  "onResponse",
@@ -93,7 +92,6 @@ function createExtensionAwareStreamFn() {
93
92
  timeoutMs: options?.timeoutMs,
94
93
  maxRetries: options?.maxRetries,
95
94
  metadata: options?.metadata,
96
- cacheRetention: options?.cacheRetention,
97
95
  transport: options?.transport,
98
96
  thinkingBudgets: options?.thinkingBudgets,
99
97
  extra: collectExtraStreamOptions(options),
@@ -0,0 +1,14 @@
1
+ import type { Api, Model } from '@earendil-works/pi-ai';
2
+ import type { PromptCachePolicy } from './prompt-cache-plan.js';
3
+ export declare function applyGoogleManagedPromptCache(params: {
4
+ model: Model<Api>;
5
+ context: {
6
+ systemPrompt?: string;
7
+ };
8
+ payload: unknown;
9
+ policy: PromptCachePolicy;
10
+ apiKey?: string;
11
+ fetchImpl?: typeof fetch;
12
+ now?: number;
13
+ }): Promise<unknown>;
14
+ export declare function clearGoogleManagedPromptCaches(): void;
@@ -0,0 +1,125 @@
1
+ import { splitPromptCacheBoundary, stripPromptCacheBoundary } from "../agent/prompt/cache-boundary.js";
2
+ import { canonicalizeCacheValue, digestCacheText } from "./prompt-cache-fingerprint.js";
3
+ //#region src/providers/google-managed-prompt-cache.ts
4
+ const DEFAULT_GOOGLE_API_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
5
+ const MIN_CACHEABLE_PROMPT_CHARS = 4096;
6
+ const FAILURE_BACKOFF_MS = 10 * 6e4;
7
+ const MAX_CACHE_ENTRIES = 128;
8
+ const entries = /* @__PURE__ */ new Map();
9
+ const pendingCreates = /* @__PURE__ */ new Map();
10
+ function asRecord(value) {
11
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
12
+ }
13
+ function resolveBaseUrl(model) {
14
+ return (model.baseUrl?.trim() || DEFAULT_GOOGLE_API_BASE_URL).replace(/\/models(?:\/.*)?$/, "").replace(/\/+$/, "");
15
+ }
16
+ function resolveTtlSeconds(policy) {
17
+ return policy.lifetime === "long" ? 3600 : 300;
18
+ }
19
+ function parseExpiry(expireTime, fallback) {
20
+ if (typeof expireTime !== "string") return fallback;
21
+ const parsed = Date.parse(expireTime);
22
+ return Number.isFinite(parsed) ? parsed : fallback;
23
+ }
24
+ function remember(key, entry) {
25
+ entries.delete(key);
26
+ entries.set(key, entry);
27
+ while (entries.size > MAX_CACHE_ENTRIES) {
28
+ const oldest = entries.keys().next().value;
29
+ if (typeof oldest !== "string") break;
30
+ entries.delete(oldest);
31
+ }
32
+ }
33
+ function insertDynamicRuntimeContext(payload, dynamicSuffix) {
34
+ if (!dynamicSuffix || !Array.isArray(payload.contents)) return payload;
35
+ const contents = [...payload.contents];
36
+ const insertAt = Math.max(0, contents.length - 1);
37
+ contents.splice(insertAt, 0, {
38
+ role: "user",
39
+ parts: [{ text: `<runtime_context>\n${dynamicSuffix}\n</runtime_context>` }]
40
+ });
41
+ return {
42
+ ...payload,
43
+ contents
44
+ };
45
+ }
46
+ async function applyGoogleManagedPromptCache(params) {
47
+ if (params.policy.mode === "off") return params.payload;
48
+ const payload = asRecord(params.payload);
49
+ const config = asRecord(payload?.config);
50
+ const apiKey = params.apiKey?.trim();
51
+ if (!payload || !config || !apiKey) return params.payload;
52
+ const split = splitPromptCacheBoundary(params.context.systemPrompt ?? "");
53
+ const stablePrompt = split?.stablePrefix ?? stripPromptCacheBoundary(params.context.systemPrompt ?? "");
54
+ const dynamicSuffix = split?.dynamicSuffix ?? "";
55
+ if (stablePrompt.length < MIN_CACHEABLE_PROMPT_CHARS) return params.payload;
56
+ const cacheConfig = {
57
+ tools: config.tools,
58
+ toolConfig: config.toolConfig
59
+ };
60
+ const key = digestCacheText(`${params.model.provider}\0${params.model.id}\0${stablePrompt}\0${canonicalizeCacheValue(cacheConfig)}`);
61
+ const now = params.now ?? Date.now();
62
+ const existing = entries.get(key);
63
+ let name;
64
+ if (existing?.status === "ready" && existing.expiresAt - now > 3e4) name = existing.name;
65
+ else if (existing?.status === "failed" && existing.retryAt > now) return params.payload;
66
+ else {
67
+ const ttlSeconds = resolveTtlSeconds(params.policy);
68
+ let pending = pendingCreates.get(key);
69
+ if (!pending) {
70
+ pending = (async () => {
71
+ try {
72
+ const response = await (params.fetchImpl ?? globalThis.fetch)(`${resolveBaseUrl(params.model)}/cachedContents`, {
73
+ method: "POST",
74
+ headers: {
75
+ "content-type": "application/json",
76
+ "x-goog-api-key": apiKey
77
+ },
78
+ body: JSON.stringify({
79
+ model: params.model.id.startsWith("models/") ? params.model.id : `models/${params.model.id}`,
80
+ ttl: `${ttlSeconds}s`,
81
+ systemInstruction: { parts: [{ text: stablePrompt }] },
82
+ ...config.tools ? { tools: config.tools } : {},
83
+ ...config.toolConfig ? { toolConfig: config.toolConfig } : {}
84
+ })
85
+ });
86
+ if (!response.ok) throw new Error(`Google cachedContents returned ${response.status}`);
87
+ const body = await response.json();
88
+ if (typeof body.name !== "string" || !body.name.trim()) throw new Error("Google cachedContents response did not include a name");
89
+ return {
90
+ status: "ready",
91
+ name: body.name.trim(),
92
+ expiresAt: parseExpiry(body.expireTime, now + ttlSeconds * 1e3)
93
+ };
94
+ } catch {
95
+ return {
96
+ status: "failed",
97
+ retryAt: now + FAILURE_BACKOFF_MS
98
+ };
99
+ }
100
+ })();
101
+ pendingCreates.set(key, pending);
102
+ }
103
+ const created = await pending.finally(() => pendingCreates.delete(key));
104
+ remember(key, created);
105
+ if (created.status === "failed") return params.payload;
106
+ name = created.name;
107
+ }
108
+ const nextConfig = {
109
+ ...config,
110
+ cachedContent: name
111
+ };
112
+ delete nextConfig.systemInstruction;
113
+ delete nextConfig.tools;
114
+ delete nextConfig.toolConfig;
115
+ return insertDynamicRuntimeContext({
116
+ ...payload,
117
+ config: nextConfig
118
+ }, dynamicSuffix);
119
+ }
120
+ function clearGoogleManagedPromptCaches() {
121
+ entries.clear();
122
+ pendingCreates.clear();
123
+ }
124
+ //#endregion
125
+ export { applyGoogleManagedPromptCache, clearGoogleManagedPromptCaches };
@@ -0,0 +1,4 @@
1
+ /** Canonical JSON used only for bounded prompt-cache fingerprints. */
2
+ export declare function canonicalizeCacheValue(value: unknown): string;
3
+ export declare function digestCacheValue(value: unknown): string;
4
+ export declare function digestCacheText(value: string): string;
@@ -0,0 +1,44 @@
1
+ import { createHash } from "node:crypto";
2
+ //#region src/providers/prompt-cache-fingerprint.ts
3
+ function asRecord(value) {
4
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
5
+ }
6
+ const MAX_FINGERPRINT_DEPTH = 64;
7
+ const MAX_FINGERPRINT_NODES = 2e4;
8
+ const MAX_FINGERPRINT_STRING_CHARS = 1e5;
9
+ function canonicalize(value, state, depth) {
10
+ state.nodes += 1;
11
+ if (depth > MAX_FINGERPRINT_DEPTH || state.nodes > MAX_FINGERPRINT_NODES) return "\"[fingerprint-limit]\"";
12
+ if (typeof value === "string" && value.length > MAX_FINGERPRINT_STRING_CHARS) return JSON.stringify(`${value.slice(0, MAX_FINGERPRINT_STRING_CHARS)}[fingerprint-limit]`);
13
+ if (Array.isArray(value)) {
14
+ if (state.seen.has(value)) return "\"[circular]\"";
15
+ state.seen.add(value);
16
+ const result = `[${value.map((entry) => canonicalize(entry, state, depth + 1)).join(",")}]`;
17
+ state.seen.delete(value);
18
+ return result;
19
+ }
20
+ const record = asRecord(value);
21
+ if (record) {
22
+ if (state.seen.has(record)) return "\"[circular]\"";
23
+ state.seen.add(record);
24
+ const result = `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalize(record[key], state, depth + 1)}`).join(",")}}`;
25
+ state.seen.delete(record);
26
+ return result;
27
+ }
28
+ return JSON.stringify(value) ?? "null";
29
+ }
30
+ /** Canonical JSON used only for bounded prompt-cache fingerprints. */
31
+ function canonicalizeCacheValue(value) {
32
+ return canonicalize(value, {
33
+ nodes: 0,
34
+ seen: /* @__PURE__ */ new WeakSet()
35
+ }, 0);
36
+ }
37
+ function digestCacheValue(value) {
38
+ return createHash("sha256").update(canonicalizeCacheValue(value)).digest("base64url");
39
+ }
40
+ function digestCacheText(value) {
41
+ return createHash("sha256").update(value).digest("base64url");
42
+ }
43
+ //#endregion
44
+ export { canonicalizeCacheValue, digestCacheText, digestCacheValue };
@@ -0,0 +1,9 @@
1
+ import type { Api, Model } from '@earendil-works/pi-ai';
2
+ import type { PromptCachePolicy } from './prompt-cache-plan.js';
3
+ export declare function resolvePromptCacheTtlMs(model: Model<Api>, policy: PromptCachePolicy): number;
4
+ export declare function recordPromptCacheTouch(sessionKey: string, model: Model<Api>, usage: {
5
+ cacheRead?: number;
6
+ cacheWrite?: number;
7
+ }, now?: number): void;
8
+ export declare function isPromptCacheExpired(sessionKey: string, model: Model<Api>, policy: PromptCachePolicy, now?: number): boolean;
9
+ export declare function clearPromptCacheTouches(): void;
@@ -0,0 +1,31 @@
1
+ //#region src/providers/prompt-cache-lifecycle.ts
2
+ const cacheTouchByScope = /* @__PURE__ */ new Map();
3
+ const MAX_CACHE_TOUCHES = 512;
4
+ function scopeKey(sessionKey, model) {
5
+ return `${sessionKey}\0${model.provider}/${model.id}`;
6
+ }
7
+ function resolvePromptCacheTtlMs(model, policy) {
8
+ if (model.api === "openai-responses" && /^gpt-5\.6(?:-|$)/.test(model.id)) return 30 * 6e4;
9
+ return policy.lifetime === "long" ? 60 * 6e4 : 5 * 6e4;
10
+ }
11
+ function recordPromptCacheTouch(sessionKey, model, usage, now = Date.now()) {
12
+ if ((usage.cacheRead ?? 0) <= 0 && (usage.cacheWrite ?? 0) <= 0) return;
13
+ const key = scopeKey(sessionKey, model);
14
+ cacheTouchByScope.delete(key);
15
+ cacheTouchByScope.set(key, now);
16
+ while (cacheTouchByScope.size > MAX_CACHE_TOUCHES) {
17
+ const oldest = cacheTouchByScope.keys().next().value;
18
+ if (typeof oldest !== "string") break;
19
+ cacheTouchByScope.delete(oldest);
20
+ }
21
+ }
22
+ function isPromptCacheExpired(sessionKey, model, policy, now = Date.now()) {
23
+ if (policy.mode === "off") return false;
24
+ const touchedAt = cacheTouchByScope.get(scopeKey(sessionKey, model));
25
+ return touchedAt !== void 0 && now - touchedAt >= resolvePromptCacheTtlMs(model, policy);
26
+ }
27
+ function clearPromptCacheTouches() {
28
+ cacheTouchByScope.clear();
29
+ }
30
+ //#endregion
31
+ export { clearPromptCacheTouches, isPromptCacheExpired, recordPromptCacheTouch, resolvePromptCacheTtlMs };
@@ -0,0 +1,20 @@
1
+ import type { Api, Model } from '@earendil-works/pi-ai';
2
+ export type PromptCacheChangeReason = 'model_changed' | 'reasoning_changed' | 'system_changed' | 'dynamic_context_changed' | 'tools_changed';
3
+ export interface PromptCacheSnapshot {
4
+ modelRef: string;
5
+ api: string;
6
+ reasoning?: string;
7
+ stableSystemDigest: string;
8
+ dynamicSystemDigest: string;
9
+ toolDigest: string;
10
+ toolCount: number;
11
+ }
12
+ export declare function buildPromptCacheSnapshot(params: {
13
+ model: Model<Api>;
14
+ systemPrompt?: string;
15
+ tools?: unknown[];
16
+ reasoning?: string;
17
+ }): PromptCacheSnapshot;
18
+ export declare function diffPromptCacheSnapshots(previous: PromptCacheSnapshot | undefined, next: PromptCacheSnapshot): PromptCacheChangeReason[];
19
+ export declare function observePromptCacheSnapshot(scope: string, snapshot: PromptCacheSnapshot): PromptCacheChangeReason[];
20
+ export declare function clearPromptCacheObservations(): void;
@@ -0,0 +1,44 @@
1
+ import { splitPromptCacheBoundary, stripPromptCacheBoundary } from "../agent/prompt/cache-boundary.js";
2
+ import { digestCacheText, digestCacheValue } from "./prompt-cache-fingerprint.js";
3
+ //#region src/providers/prompt-cache-observability.ts
4
+ const MAX_TRACKED_SCOPES = 512;
5
+ const previousByScope = /* @__PURE__ */ new Map();
6
+ function buildPromptCacheSnapshot(params) {
7
+ const rawPrompt = params.systemPrompt ?? "";
8
+ const split = splitPromptCacheBoundary(rawPrompt);
9
+ return {
10
+ modelRef: `${params.model.provider}/${params.model.id}`,
11
+ api: params.model.api,
12
+ ...params.reasoning ? { reasoning: params.reasoning } : {},
13
+ stableSystemDigest: digestCacheText(split?.stablePrefix ?? stripPromptCacheBoundary(rawPrompt)),
14
+ dynamicSystemDigest: digestCacheText(split?.dynamicSuffix ?? ""),
15
+ toolDigest: digestCacheValue(params.tools ?? []),
16
+ toolCount: params.tools?.length ?? 0
17
+ };
18
+ }
19
+ function diffPromptCacheSnapshots(previous, next) {
20
+ if (!previous) return [];
21
+ const reasons = [];
22
+ if (previous.modelRef !== next.modelRef || previous.api !== next.api) reasons.push("model_changed");
23
+ if (previous.reasoning !== next.reasoning) reasons.push("reasoning_changed");
24
+ if (previous.stableSystemDigest !== next.stableSystemDigest) reasons.push("system_changed");
25
+ if (previous.dynamicSystemDigest !== next.dynamicSystemDigest) reasons.push("dynamic_context_changed");
26
+ if (previous.toolDigest !== next.toolDigest) reasons.push("tools_changed");
27
+ return reasons;
28
+ }
29
+ function observePromptCacheSnapshot(scope, snapshot) {
30
+ const reasons = diffPromptCacheSnapshots(previousByScope.get(scope), snapshot);
31
+ previousByScope.delete(scope);
32
+ previousByScope.set(scope, snapshot);
33
+ while (previousByScope.size > MAX_TRACKED_SCOPES) {
34
+ const oldest = previousByScope.keys().next().value;
35
+ if (typeof oldest !== "string") break;
36
+ previousByScope.delete(oldest);
37
+ }
38
+ return reasons;
39
+ }
40
+ function clearPromptCacheObservations() {
41
+ previousByScope.clear();
42
+ }
43
+ //#endregion
44
+ export { buildPromptCacheSnapshot, clearPromptCacheObservations, diffPromptCacheSnapshots, observePromptCacheSnapshot };
@@ -1,13 +1,20 @@
1
1
  import type { Api, Model, SimpleStreamOptions } from '@earendil-works/pi-ai';
2
- export declare function transformPromptCachePayload(model: Model<Api>, payload: unknown): unknown;
2
+ import { type PromptCachePlan, type PromptCachePolicy } from './prompt-cache-plan.js';
3
3
  export declare function buildPromptCacheKey(model: Model<Api>, context: {
4
4
  systemPrompt?: string;
5
5
  tools?: unknown[];
6
- }): string;
6
+ }, reasoning?: string): string;
7
+ export declare function buildPromptCachePlan(model: Model<Api>, context: {
8
+ systemPrompt?: string;
9
+ tools?: unknown[];
10
+ }, policyInput?: PromptCachePolicy, reasoning?: string): PromptCachePlan;
11
+ export declare function transformPromptCachePayload(model: Model<Api>, payload: unknown, plan?: PromptCachePlan, context?: {
12
+ systemPrompt?: string;
13
+ }): unknown;
7
14
  export declare function preparePromptCacheContext<T extends {
8
15
  systemPrompt?: string;
9
16
  }>(model: Model<Api>, context: T): T;
10
17
  export declare function withPromptCachePayloadTransform(model: Model<Api>, context: {
11
18
  systemPrompt?: string;
12
19
  tools?: unknown[];
13
- }, options: SimpleStreamOptions | undefined): SimpleStreamOptions | undefined;
20
+ }, options: SimpleStreamOptions | undefined, policyInput?: PromptCachePolicy): SimpleStreamOptions;