@xopcai/xopc 0.0.334 → 0.0.335

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 (121) 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/{agent-avatar-dicebear-B73q7mlz.js → agent-avatar-dicebear-DtmNsTNI.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-B9L2YIXz.js → agent-defaults-settings-panel-AvGo9fao.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-plugin-dialog-COOjsvea.js → agent-plugin-dialog-DZCh4_E1.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agents-CCj1JnLu.js → agents-Drt1vHf6.js} +3 -3
  7. package/dist/gateway/static/root/assets/{agents-admin-api-Cuqi5xZn.js → agents-admin-api-C82B1W9Z.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-CckioKud.js → app-management-settings-panel-IKZm5_s2.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-DDiPIr_Q.js → appearance-settings-DKWGkrVW.js} +1 -1
  10. package/dist/gateway/static/root/assets/{apps-page-Azqy8vfo.js → apps-page-DY6Q7TMZ.js} +1 -1
  11. package/dist/gateway/static/root/assets/{archive-plugin-Dtyr0RhX.js → archive-plugin-DXGAt0G7.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-g3SrFkTC.js → automations-page-DzqfYcqe.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-workspace-B0nW2nZD.js → automations-workspace-qMpqvBz1.js} +1 -1
  14. package/dist/gateway/static/root/assets/{binary-plugins-BwKQVxsU.js → binary-plugins-Cy2FLsPv.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-DD9d5pCt.js → block-editor-BqSpSNnv.js} +1 -1
  16. package/dist/gateway/static/root/assets/{browser-automation-inputs-D2gNdS3e.js → browser-automation-inputs-CLOq1KtH.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-automations-page-BKqqJR7P.js → browser-automations-page-BEeyiVEw.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-settings-page-BZH9bZbk.js → browser-settings-page-D6SygxnY.js} +1 -1
  19. package/dist/gateway/static/root/assets/{capabilities-CHk4RZl4.js → capabilities-BfHgt4uk.js} +1 -1
  20. package/dist/gateway/static/root/assets/{capabilities-page-CfWaVH-6.js → capabilities-page-C9Od0WN-.js} +2 -2
  21. package/dist/gateway/static/root/assets/{capabilities-settings-panel-C5FcWsSe.js → capabilities-settings-panel-6HAVkNE4.js} +1 -1
  22. package/dist/gateway/static/root/assets/{capability-header-actions-Bd66yEOa.js → capability-header-actions-CwcT7mjE.js} +1 -1
  23. package/dist/gateway/static/root/assets/{channels-DIU5Gq4o.js → channels-D5HNBMLS.js} +1 -1
  24. package/dist/gateway/static/root/assets/{chat-terminal-dock-B0nPDJyj.js → chat-terminal-dock-BsxTfU1T.js} +1 -1
  25. package/dist/gateway/static/root/assets/{computer-settings-page-D7PxxaoG.js → computer-settings-page-CH01h8yI.js} +1 -1
  26. package/dist/gateway/static/root/assets/{connector-service-page-BZH4SeQg.js → connector-service-page-CTi8iaOn.js} +1 -1
  27. package/dist/gateway/static/root/assets/{connectors-page-BC81R_fz.js → connectors-page-C3GhbPPg.js} +1 -1
  28. package/dist/gateway/static/root/assets/{date-picker-CDEVYjXI.js → date-picker-DTEOeiC4.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-AInmpSwC.js → dependency-picker-DFA0RZ02.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-Sjgnlq8M.js → desktop-pet-Txr49_Zi.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-BWn0rrhr.js → desktop-pet-settings-Coi0DUai.js} +1 -1
  32. package/dist/gateway/static/root/assets/{device-pairing-wizard-BtW837_d.js → device-pairing-wizard-OPY8ujCN.js} +1 -1
  33. package/dist/gateway/static/root/assets/{directory-picker-path-field-2CpmDx_D.js → directory-picker-path-field-B1ckH4hn.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-debug-page-WWJFj9Z5.js → extension-debug-page-6e8BCEb6.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-page-DL00dFRr.js → extension-page-DgaFykYf.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-settings-page-CN-agjPk.js → extension-settings-page-B-TyR9GM.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-CgIjCxM8.js → gateway-config-swr-Hn1vj6uI.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-realtime-Ciq4c7KT.js → gateway-realtime-CGjSxzj6.js} +1 -1
  39. package/dist/gateway/static/root/assets/gateway-realtime-store-DytaaEu8.js +1 -0
  40. package/dist/gateway/static/root/assets/{gateway-settings-4oD6fhAm.js → gateway-settings-CtjGyqB2.js} +1 -1
  41. package/dist/gateway/static/root/assets/{gateway-startup-retry-i-1lTrwY.js → gateway-startup-retry-CtTVgB7_.js} +1 -1
  42. package/dist/gateway/static/root/assets/{home-page-nEpyJUBY.js → home-page-Cs5fPXcJ.js} +1 -1
  43. package/dist/gateway/static/root/assets/{image-generation-api-gilc-u7M.js → image-generation-api-DBA-bdEM.js} +1 -1
  44. package/dist/gateway/static/root/assets/{imports-page-BivdeiQ5.js → imports-page-C72wCY44.js} +1 -1
  45. package/dist/gateway/static/root/assets/{index-BioG1pRD.js → index-BkSp_1Il.js} +8 -8
  46. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B_8AJTFr.js → keyboard-shortcuts-settings-D1nzw6zI.js} +1 -1
  47. package/dist/gateway/static/root/assets/{local-app-workbench-page-CRtZQrmz.js → local-app-workbench-page-DqB0hGrZ.js} +1 -1
  48. package/dist/gateway/static/root/assets/{local-apps-page-DclxpoqR.js → local-apps-page-D4FX0Ptx.js} +1 -1
  49. package/dist/gateway/static/root/assets/{local-session-drafts-DkolHmyp.js → local-session-drafts-Byxxogdc.js} +1 -1
  50. package/dist/gateway/static/root/assets/{locale-store-BY30D6tg.js → locale-store-7F4l6DRV.js} +1 -1
  51. package/dist/gateway/static/root/assets/{logs-page-DX8TxkRl.js → logs-page-CcWD_-zy.js} +1 -1
  52. package/dist/gateway/static/root/assets/{management-settings-5WFufZ4g.js → management-settings-L9YGzLaz.js} +1 -1
  53. package/dist/gateway/static/root/assets/{markdown-view-DYJnwlDr.js → markdown-view-bxpOryax.js} +1 -1
  54. package/dist/gateway/static/root/assets/{media-plugins-DlJDvwLK.js → media-plugins-DqsiYyAz.js} +1 -1
  55. package/dist/gateway/static/root/assets/{messages-_6IXbP2u.js → messages-DsUnS7rn.js} +2 -2
  56. package/dist/gateway/static/root/assets/{note-detail-panel-GF5Q9Fqy.js → note-detail-panel-DwK9Ndw1.js} +3 -3
  57. package/dist/gateway/static/root/assets/{notes-page-E8o4_Ty9.js → notes-page-D2FvAV9x.js} +1 -1
  58. package/dist/gateway/static/root/assets/{page-context-capture-button-CiCmfRTw.js → page-context-capture-button-CeWnFomm.js} +1 -1
  59. package/dist/gateway/static/root/assets/{page-tabs-Cwp3fGVM.js → page-tabs-B90ywILw.js} +1 -1
  60. package/dist/gateway/static/root/assets/{preview-open-alternatives-DJ5xqGeu.js → preview-open-alternatives-CwuY-FIE.js} +1 -1
  61. package/dist/gateway/static/root/assets/{product-open-page-CcGwNePw.js → product-open-page-CUcJOCAz.js} +1 -1
  62. package/dist/gateway/static/root/assets/{project-detail-page-6hhRBkmC.js → project-detail-page-Blo9-zcq.js} +1 -1
  63. package/dist/gateway/static/root/assets/{projects-page-DUOzRaFI.js → projects-page-C9rh1U9Z.js} +1 -1
  64. package/dist/gateway/static/root/assets/{registry-api-BvVx0G1o.js → registry-api-DU915Prn.js} +1 -1
  65. package/dist/gateway/static/root/assets/{remote-access-hub-BWpWUXiE.js → remote-access-hub-Cw2Beq7s.js} +1 -1
  66. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-C6eDCNHz.js → runtime-tools-settings-panel-Cj8LnZRV.js} +1 -1
  67. package/dist/gateway/static/root/assets/{scenes-page-pF7Lmqnk.js → scenes-page-BZd4VZBP.js} +1 -1
  68. package/dist/gateway/static/root/assets/{schema-form-D8W8q_ez.js → schema-form-CNbrdYAu.js} +1 -1
  69. package/dist/gateway/static/root/assets/session-api-C7i3UFhq.js +1 -0
  70. package/dist/gateway/static/root/assets/{session-manager-BAy2sR2Q.js → session-manager-DAck_U0C.js} +1 -1
  71. package/dist/gateway/static/root/assets/sessions-page-BKt3Cd0a.js +1 -0
  72. package/dist/gateway/static/root/assets/settings-advanced-gate-BToasX5M.js +1 -0
  73. package/dist/gateway/static/root/assets/{settings-form-section-B0cAj0nq.js → settings-form-section-u6ZXo3oJ.js} +1 -1
  74. package/dist/gateway/static/root/assets/{settings-page-DZVVTFxs.js → settings-page-gXacaOIv.js} +1 -1
  75. package/dist/gateway/static/root/assets/{setup-status-panel-DZCPVx9c.js → setup-status-panel-qKaz5drv.js} +1 -1
  76. package/dist/gateway/static/root/assets/{share-preview-page-BkPNyV8c.js → share-preview-page-DdkQ-B5M.js} +1 -1
  77. package/dist/gateway/static/root/assets/{shares-settings-Bqlv5JBi.js → shares-settings-BwFn5CYE.js} +1 -1
  78. package/dist/gateway/static/root/assets/{skill-api-C0dufzQC.js → skill-api-Cf3_ZQOb.js} +1 -1
  79. package/dist/gateway/static/root/assets/skill-reload-api-CdNp1N-Y.js +1 -0
  80. package/dist/gateway/static/root/assets/{skills-page-DB4lR4om.js → skills-page-fKPvwSpa.js} +1 -1
  81. package/dist/gateway/static/root/assets/{system-settings-panel-xjrlhdUz.js → system-settings-panel-CO3l1jdd.js} +1 -1
  82. package/dist/gateway/static/root/assets/{task-detail-page-CB6M7wSs.js → task-detail-page-zClWGuT5.js} +1 -1
  83. package/dist/gateway/static/root/assets/{tunnel-api--68MQEWM.js → tunnel-api-Dw6DW1j5.js} +1 -1
  84. package/dist/gateway/static/root/assets/{usage-page-OLZ00eqD.js → usage-page-QP_8nuHU.js} +1 -1
  85. package/dist/gateway/static/root/assets/{use-autosave-DsnHYpTv.js → use-autosave-ZwnXUpG4.js} +1 -1
  86. package/dist/gateway/static/root/assets/{user-model-page-CoePFpHD.js → user-model-page-B72PRFAI.js} +1 -1
  87. package/dist/gateway/static/root/assets/{voice-api-key-field-CvIXutQp.js → voice-api-key-field-CbIxN5SC.js} +1 -1
  88. package/dist/gateway/static/root/assets/{voice-config-api-Bwy3Al3J.js → voice-config-api-LKFent6f.js} +1 -1
  89. package/dist/gateway/static/root/assets/{work-discovery-overlay-By5_7MLR.js → work-discovery-overlay-WIGHfEL3.js} +1 -1
  90. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-HSMDxDXV.js → workflow-run-setup-panel-Bk0Jhdeq.js} +1 -1
  91. package/dist/gateway/static/root/assets/{workflows-page-DElQ47Da.js → workflows-page-BC385JPr.js} +1 -1
  92. package/dist/gateway/static/root/index.html +14 -14
  93. package/dist/package.js +1 -1
  94. package/dist/packages/gateway-contract/src/sessions.js +11 -0
  95. package/dist/src/agent/agent-instance-gateway.d.ts +0 -2
  96. package/dist/src/agent/agent-manager.d.ts +0 -2
  97. package/dist/src/agent/agent-manager.js +0 -31
  98. package/dist/src/agent/background-review/run-background-review.d.ts +0 -7
  99. package/dist/src/agent/background-review/run-background-review.js +1 -21
  100. package/dist/src/agent/orchestration/agent-orchestrator.js +0 -3
  101. package/dist/src/agent/service/direct-turn-helpers.js +0 -3
  102. package/dist/src/automations/events/event-dispatcher.d.ts +10 -3
  103. package/dist/src/automations/service/automation-service.js +0 -1
  104. package/dist/src/gateway/hono/routes/sessions.js +15 -1
  105. package/dist/src/gateway/service/session-preparation-worker.d.ts +9 -2
  106. package/dist/src/gateway/service.js +3 -3
  107. package/dist/src/home-intelligence/generator.d.ts +8 -1
  108. package/dist/src/home-intelligence/generator.js +25 -14
  109. package/dist/src/home-intelligence/host.d.ts +8 -1
  110. package/dist/src/home-intelligence/host.js +81 -7
  111. package/dist/src/home-intelligence/repository.d.ts +5 -1
  112. package/dist/src/home-intelligence/repository.js +16 -9
  113. package/dist/src/home-intelligence/snapshot.js +4 -4
  114. package/dist/src/storage/sqlite/ai-usage-repository.d.ts +3 -0
  115. package/dist/src/storage/sqlite/ai-usage-repository.js +25 -1
  116. package/package.json +4 -4
  117. package/dist/gateway/static/root/assets/gateway-realtime-store-BHeHN26R.js +0 -1
  118. package/dist/gateway/static/root/assets/session-api-BAyUr97V.js +0 -1
  119. package/dist/gateway/static/root/assets/sessions-page-BDKDqqf9.js +0 -1
  120. package/dist/gateway/static/root/assets/settings-advanced-gate-C9cJWlAq.js +0 -1
  121. package/dist/gateway/static/root/assets/skill-reload-api-3JF2OTBz.js +0 -1
@@ -3,7 +3,6 @@ import { init_logger } from "../../utils/logger.js";
3
3
  import { abortEmbeddedRun } from "../embedded/runs.js";
4
4
  import { persistInboundAttachments } from "../../channels/attachments/inbound-persist.js";
5
5
  import { buildTranscriptUserMessage, clearPendingTranscriptUserMessage, hydrateUserTurnForLlm, setPendingTranscriptUserMessage } from "../inbound/attachment-pipeline.js";
6
- import { extractAgentUserPlainText } from "../memory/user-message-text.js";
7
6
  import { resolveEffectiveThinkingLevel } from "../../session/thinking-resolve.js";
8
7
  import { runEmbeddedTurnForSession } from "../embedded/run-for-session.js";
9
8
  import { randomUUID } from "node:crypto";
@@ -68,7 +67,6 @@ var AgentOrchestrator = class {
68
67
  agentManager: this.agentManager
69
68
  });
70
69
  setPendingTranscriptUserMessage(conversationId, userMessage);
71
- const userPlainForMemory = extractAgentUserPlainText(userMessage);
72
70
  const turnId = randomUUID();
73
71
  const userContext = await this.agentManager.prepareUserTurnContext(userMessage, conversationId, turnId);
74
72
  const userMessageForModel = userMessage;
@@ -96,7 +94,6 @@ var AgentOrchestrator = class {
96
94
  clearPendingTranscriptUserMessage(conversationId, userMessage);
97
95
  }
98
96
  })();
99
- this.agentManager.scheduleUserUnderstandingMaintenance(conversationId, userPlainForMemory, turnId);
100
97
  this.agentManager.scheduleBackgroundReviewAfterUserTurn(conversationId);
101
98
  if (turnResult.ok) {
102
99
  this.onEmbeddedTurnComplete?.(conversationId, turnResult.lastAssistantText);
@@ -3,7 +3,6 @@ import { getConnectionResumeInput, init_connection_wait_repository } from "../..
3
3
  import { resolveImageHandlingStrategy } from "../image/vision-detection.js";
4
4
  import { hydrateUserTurnForLlm } from "../inbound/attachment-pipeline.js";
5
5
  import { buildTaskExecutionDirective } from "../../tasks/task-context-assembler.js";
6
- import { extractAgentUserPlainText } from "../memory/user-message-text.js";
7
6
  import { shouldSkipResetOverlapCommand } from "../../session/reset-triggers.js";
8
7
  import { parseSlashCommand } from "../../chat-commands/command-parse.js";
9
8
  import { commandRegistry } from "../../chat-commands/registry.js";
@@ -99,7 +98,6 @@ async function runDirectAgentTurn(deps, input) {
99
98
  const isConnectionResume = Boolean(getConnectionResumeInput(input.conversationId, turnId));
100
99
  const isClarificationResume = Boolean(getClarificationResumeInput(input.conversationId, turnId));
101
100
  const isResume = isConnectionResume || isClarificationResume;
102
- const userPlain = extractAgentUserPlainText(input.userMessage);
103
101
  const userContext = await deps.agentManager.prepareUserTurnContext(input.userMessage, input.conversationId, turnId);
104
102
  const sourceContexts = input.sourceContexts ?? [];
105
103
  const userMessageForModel = prependAgentContext(injectSourceContextsIntoUserMessage(input.userMessage, sourceContexts), buildTaskExecutionDirective(input.conversationId));
@@ -127,7 +125,6 @@ async function runDirectAgentTurn(deps, input) {
127
125
  beforeTurn: isResume ? void 0 : () => deps.agentManager.beginBackgroundReviewUserTurn(input.conversationId),
128
126
  onEvent: input.onEvent
129
127
  });
130
- if (!isResume) deps.agentManager.scheduleUserUnderstandingMaintenance(input.conversationId, userPlain, turnId);
131
128
  if (!isResume && result.stopReason !== "connection_required" && result.stopReason !== "clarification_required") deps.agentManager.scheduleBackgroundReviewAfterUserTurn(input.conversationId);
132
129
  return result;
133
130
  }
@@ -1,5 +1,12 @@
1
- import type { AutomationEventEnvelope, AutomationRun } from '../domain/types.js';
2
- import type { AutomationService } from '../service/automation-service.js';
1
+ import type { AutomationEvent, AutomationEventEnvelope, AutomationRun } from '../domain/types.js';
2
+ export interface AutomationEventDispatchService {
3
+ availableRunSlots(): number;
4
+ queueRunAtomically(id: string, opts: {
5
+ manual: boolean;
6
+ event?: AutomationEvent;
7
+ }): AutomationRun;
8
+ dispatchQueuedRun(runId: string): void;
9
+ }
3
10
  export declare class AutomationEventDispatcher {
4
11
  private readonly automationService;
5
12
  private readonly options;
@@ -8,7 +15,7 @@ export declare class AutomationEventDispatcher {
8
15
  private stopping;
9
16
  private readonly owner;
10
17
  private readonly abortController;
11
- constructor(automationService: AutomationService, options?: {
18
+ constructor(automationService: AutomationEventDispatchService, options?: {
12
19
  onEvent?: (event: AutomationEventEnvelope, signal?: AbortSignal) => void | Promise<void>;
13
20
  onDeadLetter?: (input: {
14
21
  phase: 'event_projection' | 'event_delivery';
@@ -9,7 +9,6 @@ import { getAutomationEventDeliveryRunId, getAutomationEventForRun, getAutomatio
9
9
  import { computeNextAutomationRunAtMs, timerDelayUntil } from "../domain/schedule.js";
10
10
  import { AutomationActionExecutor } from "./action-executor.js";
11
11
  import { AutomationEventDispatcher } from "../events/event-dispatcher.js";
12
- import "../events/index.js";
13
12
  import { AutomationDeliveryRouter, getAutomationResultDeliveryMetrics, listAutomationResultDeliveries, retryAutomationResultDelivery } from "../delivery/delivery-router.js";
14
13
  import "../delivery/index.js";
15
14
  import { randomUUID } from "node:crypto";
@@ -3,6 +3,7 @@ import { SessionDiscoveryQuerySchema } from "../../../../packages/gateway-contra
3
3
  import { init_src } from "../../../../packages/gateway-contract/src/index.js";
4
4
  import "../../../session/types.js";
5
5
  import { SidebarLayoutConflictError, getSidebarLayout, init_sidebar_layout_repository, replaceSidebarLayout, sortBySidebarLayout } from "../../../storage/sqlite/sidebar-layout-repository.js";
6
+ import { summarizeAiUsageByConversations } from "../../../storage/sqlite/ai-usage-repository.js";
6
7
  import { messagesToClientHistory } from "../../../session/client-history.js";
7
8
  import { evictEmbeddedSessionRunner } from "../../../agent/embedded/session-runner.js";
8
9
  import { SessionEnvironmentService } from "../../../execution-environments/session-environment-service.js";
@@ -286,7 +287,20 @@ function registerSessionsRoutes(authenticated, deps) {
286
287
  limit: query.limit ? parseInt(query.limit) : void 0,
287
288
  offset: query.offset ? parseInt(query.offset) : void 0
288
289
  });
289
- return c.json(result);
290
+ const usageByConversation = summarizeAiUsageByConversations(result.items.map((item) => item.key));
291
+ return c.json({
292
+ ...result,
293
+ items: result.items.map((item) => ({
294
+ ...item,
295
+ usage: usageByConversation.get(item.key) ?? {
296
+ calls: 0,
297
+ unknownCostCalls: 0,
298
+ totalTokens: 0,
299
+ knownCostUsd: "0",
300
+ costCompleteness: "unknown"
301
+ }
302
+ }))
303
+ });
290
304
  });
291
305
  authenticated.get("/api/sessions/stats", async (c) => {
292
306
  const result = await service.sessions.stats();
@@ -1,4 +1,11 @@
1
- import type { GatewayService } from '../service.js';
1
+ import type { ProjectService } from '../../projects/project-service.js';
2
+ import type { SessionInputState } from '../../storage/sqlite/session-input-repository.js';
3
+ export interface SessionPreparationWorkerService {
4
+ projects: Pick<ProjectService, 'get'>;
5
+ drainSessionInputs(conversationId: string): Promise<unknown>;
6
+ getSessionInputState(conversationId: string): SessionInputState;
7
+ emit(type: string, payload: unknown): void;
8
+ }
2
9
  export declare class SessionPreparationWorker {
3
10
  private readonly service;
4
11
  private timer?;
@@ -6,7 +13,7 @@ export declare class SessionPreparationWorker {
6
13
  private cleaning;
7
14
  private cleanupTask?;
8
15
  private readonly environments;
9
- constructor(service: GatewayService);
16
+ constructor(service: SessionPreparationWorkerService);
10
17
  start(): void;
11
18
  stop(): Promise<void>;
12
19
  wake(conversationId: string): void;
@@ -79,14 +79,14 @@ import "../knowledge/index.js";
79
79
  import { ConnectionRecoveryService } from "../connectors/connection-recovery-service.js";
80
80
  import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
81
81
  import { startConnectorSupervisor } from "../connectors/supervisor.js";
82
+ import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
83
+ import "../endpoint-tools/index.js";
82
84
  import { DiscussionService } from "../discussions/service.js";
83
85
  import { DiscussionOrganizer } from "../discussions/organizer.js";
84
86
  import { DiscussionLiveWorker } from "../discussions/live-worker.js";
85
87
  import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
86
88
  import { DiscussionSealer } from "../discussions/sealer.js";
87
89
  import "../discussions/index.js";
88
- import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
89
- import "../endpoint-tools/index.js";
90
90
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
91
91
  import { prepareAutomationAgentSession } from "./automation-agent-session.js";
92
92
  import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
@@ -143,8 +143,8 @@ import { createGatewayStartupTrace } from "./startup-trace.js";
143
143
  import { GatewaySceneHost } from "./scenes/host.js";
144
144
  import { checkAppContextAccess, prepareAppContext } from "./service/app-context-access.js";
145
145
  import { applyAutomaticVoiceLanguage, inferProductLanguageFromEnvironment, initializeVoiceDefaults } from "../voice/language-profile.js";
146
- import { HomeIntelligenceHost } from "../home-intelligence/host.js";
147
146
  import { HomeAdviceGenerator } from "../home-intelligence/generator.js";
147
+ import { HomeIntelligenceHost } from "../home-intelligence/host.js";
148
148
  import { HomeSnapshotBuilder } from "../home-intelligence/snapshot.js";
149
149
  import { HomeCapabilityPreflightService } from "../home-intelligence/capability-preflight.js";
150
150
  import crypto from "node:crypto";
@@ -118,8 +118,15 @@ export interface HomeModelGeneration {
118
118
  estimatedCostUsd?: number;
119
119
  };
120
120
  }
121
+ export interface HomeProviderCallBudget {
122
+ allowProviderCall(): boolean;
123
+ }
124
+ export declare class HomeAdviceBudgetExceededError extends Error {
125
+ readonly usage: HomeModelGeneration['usage'];
126
+ constructor(usage?: HomeModelGeneration['usage']);
127
+ }
121
128
  export declare class HomeAdviceGenerator {
122
129
  private readonly config;
123
130
  constructor(config: () => Config);
124
- generate(snapshot: HomeContextSnapshot, capabilities: HomeCapabilityInventory, signal?: AbortSignal): Promise<HomeModelGeneration>;
131
+ generate(snapshot: HomeContextSnapshot, capabilities: HomeCapabilityInventory, signal?: AbortSignal, budget?: HomeProviderCallBudget): Promise<HomeModelGeneration>;
125
132
  }
@@ -146,11 +146,18 @@ function addUsage(left, right) {
146
146
  estimatedCostUsd: add(left.estimatedCostUsd, right.estimatedCostUsd)
147
147
  };
148
148
  }
149
+ var HomeAdviceBudgetExceededError = class extends Error {
150
+ constructor(usage = {}) {
151
+ super("Home intelligence provider budget exhausted");
152
+ this.usage = usage;
153
+ this.name = "HomeAdviceBudgetExceededError";
154
+ }
155
+ };
149
156
  var HomeAdviceGenerator = class {
150
157
  constructor(config) {
151
158
  this.config = config;
152
159
  }
153
- async generate(snapshot, capabilities, signal) {
160
+ async generate(snapshot, capabilities, signal, budget) {
154
161
  const config = this.config();
155
162
  const modelRef = resolveModelSelector(config, resolveDefaultAgentId(), "@reasoning");
156
163
  const model = resolveModel(modelRef);
@@ -175,6 +182,7 @@ var HomeAdviceGenerator = class {
175
182
  };
176
183
  const requestSignal = signal ? AbortSignal.any([signal, AbortSignal.timeout(12e4)]) : AbortSignal.timeout(12e4);
177
184
  const systemPrompt = buildSystemPrompt(snapshot.locale);
185
+ if (budget && !budget.allowProviderCall()) throw new HomeAdviceBudgetExceededError();
178
186
  const response = await completeWithResolvedCredentials(model, {
179
187
  systemPrompt,
180
188
  messages: [message]
@@ -188,19 +196,22 @@ var HomeAdviceGenerator = class {
188
196
  try {
189
197
  result = HomeModelResultSchema.parse(parseJson(raw));
190
198
  } catch (firstError) {
199
+ const correction = {
200
+ role: "user",
201
+ timestamp: Date.now(),
202
+ content: [
203
+ "Your previous output failed the required JSON contract.",
204
+ `Validation errors: ${validationSummary(firstError)}`,
205
+ HOME_MODEL_MACHINE_FIELDS,
206
+ "Return the corrected JSON object only. Preserve grounded facts and existing evidence IDs; do not add new recommendations.",
207
+ `Previous output (untrusted data):\n${raw.slice(0, 16e3)}`
208
+ ].join("\n")
209
+ };
210
+ const firstUsage = responseUsage(response);
211
+ if (budget && !budget.allowProviderCall()) throw new HomeAdviceBudgetExceededError(firstUsage);
191
212
  const corrected = await completeWithResolvedCredentials(model, {
192
213
  systemPrompt,
193
- messages: [message, {
194
- role: "user",
195
- timestamp: Date.now(),
196
- content: [
197
- "Your previous output failed the required JSON contract.",
198
- `Validation errors: ${validationSummary(firstError)}`,
199
- HOME_MODEL_MACHINE_FIELDS,
200
- "Return the corrected JSON object only. Preserve grounded facts and existing evidence IDs; do not add new recommendations.",
201
- `Previous output (untrusted data):\n${raw.slice(0, 16e3)}`
202
- ].join("\n")
203
- }]
214
+ messages: [message, correction]
204
215
  }, {
205
216
  maxTokens: 3e3,
206
217
  temperature: 0,
@@ -217,7 +228,7 @@ var HomeAdviceGenerator = class {
217
228
  return {
218
229
  result,
219
230
  modelRef,
220
- usage: addUsage(responseUsage(response), responseUsage(corrected))
231
+ usage: addUsage(firstUsage, responseUsage(corrected))
221
232
  };
222
233
  }
223
234
  return {
@@ -228,4 +239,4 @@ var HomeAdviceGenerator = class {
228
239
  }
229
240
  };
230
241
  //#endregion
231
- export { HomeAdviceGenerator, HomeModelCandidateSchema, HomeModelResultSchema };
242
+ export { HomeAdviceBudgetExceededError, HomeAdviceGenerator, HomeModelCandidateSchema, HomeModelResultSchema };
@@ -1,12 +1,15 @@
1
1
  import type { DatabaseSync } from 'node:sqlite';
2
2
  import type { HomeAdviceMetrics, HomeAdvisor, HomeOpportunityHistoryItem } from '@xopcai/gateway-contract';
3
3
  import type { HomeOpportunityActionRequest, HomeOpportunityActionResponse, HomeOpportunityFeedbackRequest } from '@xopcai/gateway-contract';
4
- import type { HomeAdviceGenerator } from './generator.js';
4
+ import { type HomeAdviceGenerator } from './generator.js';
5
5
  import { type HomeGenerationReason, type HomePrincipal } from './repository.js';
6
6
  import { HomeSnapshotBuilder } from './snapshot.js';
7
7
  import type { HomeCapabilityInventory } from './types.js';
8
8
  import { type HomeOpportunityNotification } from './notification.js';
9
9
  import type { HomeCapabilityRequirement, HomeCapabilityResolution } from './capability-preflight.js';
10
+ export declare const HOME_CONTEXT_REFRESH_COOLDOWN_MS: number;
11
+ export declare const DAILY_HOME_PROVIDER_CALL_BUDGET = 12;
12
+ export declare const DAILY_HOME_TOKEN_BUDGET = 120000;
10
13
  export interface HomeIntelligenceHostDeps {
11
14
  principal: HomePrincipal;
12
15
  snapshot: HomeSnapshotBuilder;
@@ -32,6 +35,8 @@ export declare class HomeIntelligenceHost {
32
35
  private stopped;
33
36
  private abortController;
34
37
  private localeHint;
38
+ private contextRefreshTimer?;
39
+ private readonly pendingContextReasons;
35
40
  constructor(db: DatabaseSync, deps: HomeIntelligenceHostDeps);
36
41
  start(): void;
37
42
  stop(): void;
@@ -39,6 +44,8 @@ export declare class HomeIntelligenceHost {
39
44
  getMetrics(since?: number): HomeAdviceMetrics;
40
45
  getHistory(): HomeOpportunityHistoryItem[];
41
46
  requestRefresh(reason: HomeGenerationReason, idempotencyKey?: string, locale?: string): string;
47
+ private currentFingerprint;
48
+ private scheduleContextRefresh;
42
49
  sourceChanged(input: {
43
50
  sourceInstanceId: string;
44
51
  revision: string;
@@ -1,5 +1,6 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
+ import { HomeAdviceBudgetExceededError } from "./generator.js";
3
4
  import { homePatternKey } from "./strategy.js";
4
5
  import { HomeAdvicePolicy } from "./policy.js";
5
6
  import { HomeIntelligenceRepository } from "./repository.js";
@@ -11,7 +12,16 @@ init_logger();
11
12
  const log = createLogger("HomeIntelligence");
12
13
  const POLL_INTERVAL_MS = 5e3;
13
14
  const GENERATION_LEASE_MS = 5 * 6e4;
14
- const DAILY_MODEL_GENERATION_BUDGET = 12;
15
+ const HOME_CONTEXT_REFRESH_COOLDOWN_MS = 30 * 6e4;
16
+ const DAILY_HOME_PROVIDER_CALL_BUDGET = 12;
17
+ const DAILY_HOME_TOKEN_BUDGET = 12e4;
18
+ const HOME_USAGE_OPERATION = "home.generate_advice";
19
+ const CONTEXT_REFRESH_REASONS = new Set([
20
+ "project_changed",
21
+ "task_changed",
22
+ "connector_changed",
23
+ "conversation_changed"
24
+ ]);
15
25
  function generationFingerprint(snapshotHash, capabilities) {
16
26
  return createHash("sha256").update(JSON.stringify({
17
27
  snapshotHash,
@@ -29,6 +39,8 @@ var HomeIntelligenceHost = class {
29
39
  stopped = false;
30
40
  abortController = new AbortController();
31
41
  localeHint;
42
+ contextRefreshTimer;
43
+ pendingContextReasons = /* @__PURE__ */ new Set();
32
44
  constructor(db, deps) {
33
45
  this.deps = deps;
34
46
  this.repository = new HomeIntelligenceRepository(db);
@@ -49,6 +61,9 @@ var HomeIntelligenceHost = class {
49
61
  this.abortController = new AbortController();
50
62
  if (this.timer) clearInterval(this.timer);
51
63
  this.timer = void 0;
64
+ if (this.contextRefreshTimer) clearTimeout(this.contextRefreshTimer);
65
+ this.contextRefreshTimer = void 0;
66
+ this.pendingContextReasons.clear();
52
67
  }
53
68
  getAdvisor() {
54
69
  if (this.deps.enabled?.() === false) return { state: "disabled" };
@@ -65,6 +80,16 @@ var HomeIntelligenceHost = class {
65
80
  if (this.deps.enabled?.() === false) return "disabled";
66
81
  const now = this.now();
67
82
  if (locale) this.localeHint = locale.toLowerCase().startsWith("zh") ? "zh" : "en";
83
+ if (CONTEXT_REFRESH_REASONS.has(reason)) {
84
+ const fingerprint = this.currentFingerprint(now);
85
+ if (this.repository.getLatestSnapshotHash(this.deps.principal) === fingerprint) return "unchanged";
86
+ const lastRequestedAt = this.repository.getLatestContextRefreshRequestedAt(this.deps.principal);
87
+ if (lastRequestedAt !== void 0 && now < lastRequestedAt + 18e5) {
88
+ this.pendingContextReasons.add(reason);
89
+ this.scheduleContextRefresh(lastRequestedAt + HOME_CONTEXT_REFRESH_COOLDOWN_MS - now);
90
+ return "cooldown";
91
+ }
92
+ }
68
93
  const bucket = Math.floor(now / (reason === "manual_refresh" ? 1 : 5 * 6e4));
69
94
  const request = this.repository.enqueue(this.deps.principal, {
70
95
  idempotencyKey: idempotencyKey ?? `${reason}:${bucket}`,
@@ -74,6 +99,32 @@ var HomeIntelligenceHost = class {
74
99
  this.tick();
75
100
  return request.generationId;
76
101
  }
102
+ currentFingerprint(now) {
103
+ const successfulPatterns = this.repository.getSuccessfulPatterns(this.deps.principal);
104
+ return generationFingerprint(this.deps.snapshot.build({
105
+ now,
106
+ locale: this.localeHint,
107
+ successfulPatterns
108
+ }).hash, this.deps.capabilities());
109
+ }
110
+ scheduleContextRefresh(delayMs) {
111
+ if (this.contextRefreshTimer) return;
112
+ this.contextRefreshTimer = setTimeout(() => {
113
+ this.contextRefreshTimer = void 0;
114
+ if (this.stopped || this.pendingContextReasons.size === 0) return;
115
+ const reasons = [...this.pendingContextReasons];
116
+ this.pendingContextReasons.clear();
117
+ const now = this.now();
118
+ if (this.repository.getLatestSnapshotHash(this.deps.principal) === this.currentFingerprint(now)) return;
119
+ this.repository.enqueue(this.deps.principal, {
120
+ idempotencyKey: `context_refresh:${Math.floor(now / HOME_CONTEXT_REFRESH_COOLDOWN_MS)}`,
121
+ reasons,
122
+ requestedAt: now
123
+ });
124
+ this.tick();
125
+ }, Math.max(1, delayMs));
126
+ this.contextRefreshTimer.unref?.();
127
+ }
77
128
  sourceChanged(input) {
78
129
  const now = this.now();
79
130
  const invalidated = this.repository.invalidateOpportunitiesByEvidenceSources(this.deps.principal, new Set([
@@ -174,16 +225,18 @@ var HomeIntelligenceHost = class {
174
225
  let generation;
175
226
  const startOfDay = new Date(startedAt);
176
227
  startOfDay.setHours(0, 0, 0, 0);
177
- const modelGenerationAttempts = this.repository.countModelGenerationAttemptsSince(this.deps.principal, startOfDay.getTime(), claim.generationId);
178
- const manualRefresh = claim.reasons.includes("manual_refresh");
179
- const result = modelGenerationAttempts >= DAILY_MODEL_GENERATION_BUDGET && !manualRefresh ? {
228
+ const providerBudgetAvailable = () => {
229
+ const usage = this.repository.getProviderUsageSince(startOfDay.getTime(), HOME_USAGE_OPERATION);
230
+ return usage.calls < 12 && usage.totalTokens < 12e4;
231
+ };
232
+ const result = !providerBudgetAvailable() ? {
180
233
  state: "quiet",
181
234
  reason: "budget_exhausted"
182
- } : previousHash === currentFingerprint && !manualRefresh ? {
235
+ } : previousHash === currentFingerprint && !claim.reasons.includes("manual_refresh") ? {
183
236
  state: "quiet",
184
237
  reason: "no_change"
185
238
  } : await (async () => {
186
- generation = await this.deps.generator.generate(snapshot, capabilities, this.abortController.signal);
239
+ generation = await this.deps.generator.generate(snapshot, capabilities, this.abortController.signal, { allowProviderCall: providerBudgetAvailable });
187
240
  return new HomeAdvicePolicy((requirements, options) => this.resolveCapabilityRequirements(requirements, Boolean(options?.degradedActionAvailable)), this.repository.listSuppressionKeys(this.deps.principal), new Map(successfulPatterns.map((item) => [homePatternKey(item.projectId, item.outcome), item.successCount])), this.repository.getPersonalization(this.deps.principal, this.now())).apply(snapshot, generation.result, this.now());
188
241
  })();
189
242
  const completedAt = this.now();
@@ -212,6 +265,27 @@ var HomeIntelligenceHost = class {
212
265
  this.repository.fail(claim, this.now(), "cancelled", this.now());
213
266
  return;
214
267
  }
268
+ if (error instanceof HomeAdviceBudgetExceededError) {
269
+ const completedAt = this.now();
270
+ this.repository.complete(claim, {
271
+ result: {
272
+ state: "quiet",
273
+ reason: "budget_exhausted"
274
+ },
275
+ snapshotHash: currentFingerprint ?? this.repository.getLatestSnapshotHash(this.deps.principal) ?? "budget-exhausted",
276
+ evidenceIds: [],
277
+ inputTokens: error.usage.inputTokens,
278
+ outputTokens: error.usage.outputTokens,
279
+ estimatedCostUsd: error.usage.estimatedCostUsd,
280
+ outcomeReason: "budget_exhausted",
281
+ completedAt
282
+ });
283
+ this.deps.publish("home.advisor.updated", {
284
+ state: "quiet",
285
+ reason: "budget_exhausted"
286
+ });
287
+ return;
288
+ }
215
289
  const message = error instanceof Error ? error.message : String(error);
216
290
  if (/no api key|no default model|credentials|unknown model|local model/i.test(message)) {
217
291
  const completedAt = this.now();
@@ -246,4 +320,4 @@ var HomeIntelligenceHost = class {
246
320
  }
247
321
  };
248
322
  //#endregion
249
- export { HomeIntelligenceHost };
323
+ export { DAILY_HOME_PROVIDER_CALL_BUDGET, DAILY_HOME_TOKEN_BUDGET, HOME_CONTEXT_REFRESH_COOLDOWN_MS, HomeIntelligenceHost };
@@ -58,7 +58,11 @@ export declare class HomeIntelligenceRepository {
58
58
  };
59
59
  fail(claim: HomeGenerationClaim, now: number, errorCode: string, retryAt?: number): void;
60
60
  getLatestSnapshotHash(principal: HomePrincipal): string | undefined;
61
- countModelGenerationAttemptsSince(principal: HomePrincipal, since: number, currentGenerationId: string): number;
61
+ getLatestContextRefreshRequestedAt(principal: HomePrincipal): number | undefined;
62
+ getProviderUsageSince(startedAt: number, operation: string): {
63
+ calls: number;
64
+ totalTokens: number;
65
+ };
62
66
  listSuppressionKeys(principal: HomePrincipal): Set<string>;
63
67
  getSuccessfulPatterns(principal: HomePrincipal): HomeSuccessfulPattern[];
64
68
  getPersonalization(principal: HomePrincipal, now: number): HomeAdvicePersonalization;
@@ -151,16 +151,23 @@ var HomeIntelligenceRepository = class {
151
151
  OR outcome_reason NOT IN ('no_change', 'budget_exhausted'))
152
152
  ORDER BY completed_at DESC, rowid DESC LIMIT 1`).get(principal.ownerId, principal.workspaceId)?.snapshot_hash ?? void 0;
153
153
  }
154
- countModelGenerationAttemptsSince(principal, since, currentGenerationId) {
155
- const row = this.db.prepare(`SELECT COALESCE(SUM(CASE
156
- WHEN generation_id = ? THEN MAX(attempt - 1, 0)
157
- WHEN model_ref IS NOT NULL THEN 1
158
- WHEN status IN ('failed', 'retry_wait') THEN attempt
159
- ELSE 0
160
- END), 0) AS count
154
+ getLatestContextRefreshRequestedAt(principal) {
155
+ const row = this.db.prepare(`SELECT MAX(requested_at) AS requested_at
161
156
  FROM home_advice_generations
162
- WHERE owner_id = ? AND workspace_id = ? AND COALESCE(started_at, requested_at) >= ?`).get(currentGenerationId, principal.ownerId, principal.workspaceId, since);
163
- return Number(row.count);
157
+ WHERE owner_id = ? AND workspace_id = ?
158
+ AND EXISTS (
159
+ SELECT 1 FROM json_each(reasons_json)
160
+ WHERE value IN ('project_changed', 'task_changed', 'connector_changed', 'conversation_changed')
161
+ )`).get(principal.ownerId, principal.workspaceId);
162
+ return row.requested_at === null ? void 0 : Number(row.requested_at);
163
+ }
164
+ getProviderUsageSince(startedAt, operation) {
165
+ const row = this.db.prepare(`SELECT COUNT(*) AS calls, COALESCE(SUM(total_tokens), 0) AS total_tokens
166
+ FROM ai_usage_events WHERE operation = ? AND started_at >= ?`).get(operation, startedAt);
167
+ return {
168
+ calls: Number(row.calls),
169
+ totalTokens: Number(row.total_tokens)
170
+ };
164
171
  }
165
172
  listSuppressionKeys(principal) {
166
173
  const rows = this.db.prepare(`SELECT f.scope_json, p.kind, p.project_id
@@ -110,10 +110,10 @@ var HomeSnapshotBuilder = class {
110
110
  const successfulPatterns = [...input.successfulPatterns ?? []].filter((item) => item.successCount > 0).sort((left, right) => right.successCount - left.successCount || left.outcome.localeCompare(right.outcome)).slice(0, 20);
111
111
  const stableContent = {
112
112
  locale: input.locale,
113
- projects,
114
- tasks,
115
- knowledge,
116
- recentSessions,
113
+ projects: projects.map(({ updatedAt: _updatedAt, ...project }) => project),
114
+ tasks: tasks.map(({ updatedAt: _updatedAt, ...task }) => task),
115
+ knowledge: knowledge.map(({ updatedAt: _updatedAt, ...item }) => item),
116
+ recentSessions: recentSessions.map(({ updatedAt: _updatedAt, ...session }) => session),
117
117
  successfulPatterns
118
118
  };
119
119
  return {
@@ -29,6 +29,9 @@ export type AiUsageTotals = {
29
29
  knownCostUsd: string;
30
30
  costCompleteness: 'complete' | 'partial' | 'unknown';
31
31
  };
32
+ export type ConversationAiUsageTotals = Pick<AiUsageTotals, 'calls' | 'unknownCostCalls' | 'totalTokens' | 'knownCostUsd' | 'costCompleteness'>;
33
+ /** Aggregate all retained AI usage records for the requested conversations. */
34
+ export declare function summarizeAiUsageByConversations(conversationIds: readonly string[]): Map<string, ConversationAiUsageTotals>;
32
35
  export declare function summarizeAiUsage(query: AiUsageQuery): {
33
36
  totals: AiUsageTotals;
34
37
  byCategory: Array<{
@@ -94,6 +94,30 @@ const TOTALS_SQL = `COUNT(*) AS calls,
94
94
  COALESCE(SUM(cache_write_tokens), 0) AS cache_write_tokens,
95
95
  COALESCE(SUM(total_tokens), 0) AS total_tokens,
96
96
  COALESCE(SUM(estimated_cost_microusd), 0) AS known_cost_microusd`;
97
+ /** Aggregate all retained AI usage records for the requested conversations. */
98
+ function summarizeAiUsageByConversations(conversationIds) {
99
+ const uniqueIds = [...new Set(conversationIds.filter(Boolean))];
100
+ const result = /* @__PURE__ */ new Map();
101
+ const db = getSqliteDatabase();
102
+ for (let offset = 0; offset < uniqueIds.length; offset += 500) {
103
+ const batch = uniqueIds.slice(offset, offset + 500);
104
+ const rows = db.prepare(`SELECT conversation_id, ${TOTALS_SQL}
105
+ FROM ai_usage_events
106
+ WHERE conversation_id IN (${batch.map(() => "?").join(", ")})
107
+ GROUP BY conversation_id`).all(...batch);
108
+ for (const row of rows) {
109
+ const totals = totalsFromRow(row);
110
+ result.set(String(row.conversation_id), {
111
+ calls: totals.calls,
112
+ unknownCostCalls: totals.unknownCostCalls,
113
+ totalTokens: totals.totalTokens,
114
+ knownCostUsd: totals.knownCostUsd,
115
+ costCompleteness: totals.costCompleteness
116
+ });
117
+ }
118
+ }
119
+ return result;
120
+ }
97
121
  function summarizeAiUsage(query) {
98
122
  const { sql, values } = queryWhere(query);
99
123
  const db = getSqliteDatabase();
@@ -172,4 +196,4 @@ function listAiUsageTrace(traceId) {
172
196
  ORDER BY started_at ASC, id ASC`).all(traceId).map(eventFromRow);
173
197
  }
174
198
  //#endregion
175
- export { AI_USAGE_RETENTION_MS, finishAiUsageEvent, getAiUsageEvent, getAiUsageEventView, insertAiUsageEvent, listAiUsageEvents, listAiUsageTrace, markStaleAiUsageEventsUnknown, pruneAiUsageEvents, summarizeAiUsage };
199
+ export { AI_USAGE_RETENTION_MS, finishAiUsageEvent, getAiUsageEvent, getAiUsageEventView, insertAiUsageEvent, listAiUsageEvents, listAiUsageTrace, markStaleAiUsageEventsUnknown, pruneAiUsageEvents, summarizeAiUsage, summarizeAiUsageByConversations };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xopcai/xopc",
3
- "version": "0.0.334",
3
+ "version": "0.0.335",
4
4
  "description": "Local-first personal AI for the one-person company, with durable context, tasks, workflows, automations, and local or cloud models.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -159,12 +159,12 @@
159
159
  "vitest": "4.1.5",
160
160
  "vue": "^3.5.35",
161
161
  "@xopcai/browser-control-contract": "0.1.0",
162
+ "@xopcai/endpoint-tools-client": "0.0.0",
162
163
  "@xopcai/computer-control-contract": "0.1.0",
163
164
  "@xopcai/endpoint-tools-protocol": "0.0.0",
164
165
  "@xopcai/gateway-contract": "0.0.0",
165
- "@xopcai/endpoint-tools-client": "0.0.0",
166
- "@xopcai/realtime-client": "0.0.0",
167
- "@xopcai/realtime-protocol": "0.0.0"
166
+ "@xopcai/realtime-protocol": "0.0.0",
167
+ "@xopcai/realtime-client": "0.0.0"
168
168
  },
169
169
  "scripts": {
170
170
  "assets:brand": "node scripts/generate-brand-assets.mjs",
@@ -1 +0,0 @@
1
- import{p as e}from"./locale-store-BY30D6tg.js";var t=e(()=>({connectionState:`idle`,error:null}));function n(e){t.setState(e)}export{t as n,n as t};
@@ -1 +0,0 @@
1
- import{a as e,r as t}from"./locale-store-BY30D6tg.js";import{d as n,g as r,h as i,i as a,l as o,p as s,r as c,s as l,t as u,u as d,v as f}from"./schemas-CObaziC7.js";import{t as p}from"./gateway-startup-retry-i-1lTrwY.js";var m=f().transform(e=>e.toLowerCase()).brand(),h=s().trim().regex(/^[a-z0-9][a-z0-9._-]{0,127}$/i).brand(),g=u([`active`,`idle`,`archived`,`pinned`]),_=d({agentId:s().optional(),source:s().optional(),accountId:s().optional(),peerKind:s().optional(),peerId:s().optional(),threadId:s().optional(),scopeId:s().optional()}).passthrough();d({agentId:s().optional(),projectId:s().optional(),key:s(),transcriptId:h.optional(),name:s().optional(),title:s().optional(),displayName:s().optional(),messageCount:o(),updatedAt:s(),sourceChannel:s().optional(),status:g.optional(),routing:_.optional()}).passthrough();var v=d({items:c(r()),total:o(),limit:o(),offset:o(),hasMore:a()}),y=d({role:s(),content:r(),timestamp:i([s(),o()]).optional()}).passthrough(),b=d({key:s(),messages:c(y)}).passthrough(),ee=d({session:b}),x=d({session:d({key:s(),transcriptId:h.optional(),messages:c(y),name:s().optional(),status:g.optional(),sourceChannel:s().optional(),sourceChatId:s().optional(),projectId:s().optional(),customData:n(s(),r()).optional(),routing:_.optional()}).passthrough(),pagination:d({total:o(),limit:o(),offset:o(),hasMore:a(),before:s().optional(),nextBeforeCursor:s().optional(),revision:o().int().nonnegative().optional()}).passthrough()}).passthrough(),S=d({ok:l(!0),conversationId:f(),rowCount:o().int().nonnegative(),lastTurnId:s().min(1),session:b}).passthrough(),C=d({ok:a().optional(),payload:d({active:a(),runId:s().optional()}).passthrough().optional()}).passthrough(),w=d({ok:a().optional(),error:s().optional()}).passthrough(),T=w.extend({renamed:a().optional()}),E=w.extend({reset:a().optional(),transcriptId:h.optional(),previousTranscriptId:s().optional(),session:r().optional()}),D=d({totalSessions:o(),activeSessions:o(),archivedSessions:o(),pinnedSessions:o(),totalMessages:o(),totalTokens:o(),oldestSession:s().optional(),newestSession:s().optional(),byChannel:n(s(),o())}).passthrough();d({ok:a(),payload:d({conversationId:f(),transcriptId:h,session:r()}).passthrough().optional(),error:s().optional()}).passthrough();var O=d({ok:l(!0),projects:d({items:c(d({project:r(),sessions:c(r()),sessionTotal:o(),sessionHasMore:a()}).passthrough()),total:o(),limit:o(),offset:o(),hasMore:a()}),inbox:v,pinned:c(r()).default([]),layouts:n(s(),d({itemIds:c(s()),revision:o().int().nonnegative()})).default({})}).passthrough();function k(e){return ee.parse(e)}function A(e){return x.parse(e)}function j(e){return S.parse(e)}function M(e){return C.parse(e)}function N(e){return w.parse(e)}function P(e){return T.parse(e)}function F(e){return E.parse(e)}function I(e){return D.parse(e)}function L(e){return O.parse(e)}function R(e){let t=M(e).payload,n=typeof t?.runId==`string`?t.runId.trim():``;return!t?.active||!n?{active:!1}:{active:!0,runId:n}}function z(e){let t=new URLSearchParams;if(!e)return``;e.status&&t.set(`status`,e.status),e.search&&t.set(`search`,e.search),e.channel&&t.set(`channel`,e.channel),e.sources?.length&&t.set(`sources`,e.sources.join(`,`)),e.purposes?.length&&t.set(`purposes`,e.purposes.join(`,`)),e.activity&&t.set(`activity`,e.activity),e.agentId&&t.set(`agentId`,e.agentId),e.excludeArchived&&t.set(`excludeArchived`,`true`),e.projectId&&t.set(`projectId`,e.projectId),e.unassigned&&t.set(`unassigned`,`true`),e.updatedAfter!=null&&t.set(`updatedAfter`,String(e.updatedAfter)),e.includePinned&&t.set(`includePinned`,`true`),e.includeConversationId&&t.set(`includeConversationId`,e.includeConversationId),e.sessionTypes?.length&&t.set(`types`,e.sessionTypes.join(`,`)),e.sortBy&&t.set(`sortBy`,e.sortBy),e.sortOrder&&t.set(`sortOrder`,e.sortOrder),e.limit!=null&&t.set(`limit`,String(e.limit)),e.offset!=null&&t.set(`offset`,String(e.offset));let n=t.toString();return n?`?${n}`:``}function B(e,t){let n=[];t?.includeTranscript&&n.push(`transcript`),t?.includeTranscriptRows&&n.push(`transcriptRows`);let r=n.length?`?include=${n.join(`,`)}`:``;return`/api/sessions/${encodeURIComponent(e)}${r}`}function te(e){return`/api/sessions/${encodeURIComponent(e)}/fork-at-turn`}function V(e,t){let n=new URLSearchParams;n.set(`limit`,String(t?.limit??50));let r=t?.before?.trim();return r?n.set(`before`,r):t?.offset!=null&&n.set(`offset`,String(t.offset)),`/api/sessions/${encodeURIComponent(e)}/history?${n.toString()}`}function H(e){return`/api/sessions/${encodeURIComponent(e)}/run`}function U(){return`/api/sessions/stats`}function W(e){let t=new URLSearchParams;e?.projectLimit!=null&&t.set(`projectLimit`,String(e.projectLimit)),e?.projectOffset!=null&&t.set(`projectOffset`,String(e.projectOffset)),e?.sessionPreviewLimit!=null&&t.set(`sessionPreviewLimit`,String(e.sessionPreviewLimit)),e?.inboxLimit!=null&&t.set(`inboxLimit`,String(e.inboxLimit)),e?.inboxOffset!=null&&t.set(`inboxOffset`,String(e.inboxOffset)),e?.staleDays!=null&&t.set(`staleDays`,String(e.staleDays)),e?.includeConversationId&&t.set(`includeConversationId`,e.includeConversationId);let n=t.toString();return`/api/sidebar/chat-list${n?`?${n}`:``}`}function G(e){return`/api/sidebar/layouts/${encodeURIComponent(e)}`}function K(e,t){let n=encodeURIComponent(e);return t===`delete`?`/api/sessions/${n}`:`/api/sessions/${n}/${t}`}function q(e){return e?JSON.stringify({status:e.status,search:e.search,channel:e.channel,sources:e.sources,purposes:e.purposes,activity:e.activity,agentId:e.agentId,excludeArchived:e.excludeArchived,projectId:e.projectId,unassigned:e.unassigned,updatedAfter:e.updatedAfter,includePinned:e.includePinned,includeConversationId:e.includeConversationId,sessionTypes:e.sessionTypes,sortBy:e.sortBy,sortOrder:e.sortOrder,limit:e.limit,offset:e.offset}):`default`}var J=new Map;async function Y(e){let n=q(e),r=J.get(n);if(r)return r;let i=t(`/api/sessions${z(e)}`),a=(async()=>{let e=await p(i);if(!e.ok){let t=await e.json().catch(()=>({})),n=typeof t.error==`string`?t.error:t.error?.message;throw Error(n??`HTTP ${e.status}`)}return await e.json()})().finally(()=>{J.delete(n)});return J.set(n,a),a}async function X(n){return L(await e(t(W(n))))}async function Z(n){let r=await e(t(G(n.containerId)),{method:`PUT`,body:JSON.stringify({itemIds:n.itemIds,expectedRevision:n.expectedRevision})});if(!r.ok||!r.layout)throw Error(r.error??`Failed to save sidebar order`);return r.layout}async function Q(){return I(await e(t(U())))}async function ne(n,r){let i=k(await e(t(B(n,r))));if(!i.session)throw Error(`Session not found`);return i.session}async function re(n){let r=await e(t(`/api/sessions/resolve`),{method:`POST`,body:JSON.stringify(n)});if(!r.ok||!r.payload)throw Error(r.error??`Session not found`);return r.payload}async function ie(n){N(await e(t(K(n,`delete`)),{method:`DELETE`}))}async function ae(n,r){return{renamed:P(await e(t(K(n,`rename`)),{method:`POST`,body:JSON.stringify({name:r})})).renamed===!0}}async function oe(n){N(await e(t(K(n,`archive`)),{method:`POST`}))}async function $(n){N(await e(t(K(n,`unarchive`)),{method:`POST`}))}async function se(n){N(await e(t(K(n,`pin`)),{method:`POST`}))}async function ce(n){N(await e(t(K(n,`unpin`)),{method:`POST`}))}async function le(n){return(await e(t(`/api/sessions/${encodeURIComponent(n)}/export?format=json`))).content}export{R as _,ne as a,F as b,se as c,Z as d,$ as f,H as g,V as h,X as i,ae as l,te as m,ie as n,Q as o,ce as p,le as r,Y as s,oe as t,re as u,j as v,m as x,A as y};