@xopcai/xopc 0.0.264 → 0.0.265
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.
- package/dist/browser-ext/dist/assets/auth-CknJ00ae.js +5844 -0
- package/dist/browser-ext/dist/assets/sidepanel-C69P3v9u.css +113 -0
- package/dist/browser-ext/dist/background.js +200 -68
- package/dist/browser-ext/dist/sidepanel.html +14 -0
- package/dist/browser-ext/dist/sidepanel.js +18832 -0
- package/dist/browser-ext/manifest.json +20 -20
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-BYBCpt7_.js → activity-store-Bhyy6ENz.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D20aBHPJ.js → agent-avatar-dicebear-DRTTU2H3.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-BZvMqNrU.js → agent-defaults-settings-panel-BsXF7LVi.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-6foBELwt.js → agents-DpjWfxYx.js} +1 -1
- package/dist/gateway/static/root/assets/{api-YbtjDbuG.js → api-B2y7ZjZk.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-4ps1RrDU.js → app-management-settings-panel-33Mc81h2.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-C7nBHnkG.js → appearance-settings-C8JECSiJ.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-B_g-rL5b.js → apps-page-t64FcxIZ.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-DfKK1iJO.js → archive-plugin-PzZ6SzfY.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BOU1pdnQ.js → attachment-load-OhLL6K__.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-BePzexAH.js → automations-page-BpAYwuvx.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-7-m5pBEZ.js → automations-workspace-B6aTT5IC.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-Cly8XDyt.js → binary-plugins-B5XpGsHg.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-DzSu62js.js → block-editor-BgEhoTnN.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automation-inputs-8bHj7Fv2.js → browser-automation-inputs-s5I78Iko.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-CzL7Aj2k.js → browser-automations-page-CBLunDRH.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-Dum3mTiz.js → browser-settings-page-CSfpPCuD.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-Ci6qVS-O.js → capabilities-settings-panel-DftNnICK.js} +2 -2
- package/dist/gateway/static/root/assets/{channels-settings-BOGEZnSv.js → channels-settings-CpuWa5qu.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-status-swr-BR8oQ_eP.js → channels-status-swr-_OsWr_vS.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BF9ZXa5Z.js → chat-terminal-dock-mnPsS_GJ.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-DBvEvupa.js → connectors-page-D3nHGnNV.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-expression-BszT_gjK.js → cron-expression-NcGBvIfe.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-D2MKBJ0G.js → date-picker-BrVcl7H5.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DqigBx-G.js → dependency-picker--edd48Y9.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DMPk4CaK.js → desktop-pet-settings-DWredJwO.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-CapspBGG.js → desktop-pet-vuyyb6I6.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CXLsDtrW.js → extension-debug-page-CtBW4ebj.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-B2j87ROw.js → extension-page-CsUrmtW7.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-t1BApw-u.js → extension-settings-page-BUd31AuK.js} +1 -1
- package/dist/gateway/static/root/assets/{files-BArWTfr7.js → files-Be5viEFY.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-BFSesvAC.js → gateway-config-swr-OObCK8jM.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-BFAecoGy.js → gateway-settings-C6FQv7op.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-D1giYgI-.js → gateway-startup-retry-D_TxKN_A.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-CyD9zDcU.js → heartbeat-settings-CDo1Gjp2.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-uItZMiBE.js → home-page-D3_uvVJY.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-BeB-OPqO.js → image-generation-api-fPU9yGsw.js} +1 -1
- package/dist/gateway/static/root/assets/index-Dpu7EKTm.js +74 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-Q_CM-ZCs.js → keyboard-shortcuts-settings-CNVmrCrV.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-DaiBWfOt.js → local-app-workbench-page-B0IVDvs-.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-BALMNCSp.js → local-apps-page-DvkarvLt.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-RJHYFoq9.js → locale-store-DFQX9kTl.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-C-TS7oFg.js → logs-page-BknY0vZf.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-BajkJeYl.js → management-settings-DW6hJINQ.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-BxoQJqHx.js → markdown-view-D-5jHRWg.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-C_8Hl6KG.js → media-plugins-DYautOWY.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-Cf1h5WXB.js → messages-Dj8QuS6e.js} +2 -2
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-CsWIZrZW.js → mobile-pairing-wizard-Dgu03cv-.js} +1 -1
- package/dist/gateway/static/root/assets/{note-detail-panel-CCbPg_GP.js → note-detail-panel-Cv9uH6Jq.js} +3 -3
- package/dist/gateway/static/root/assets/{notes-page-BdxxcUKa.js → notes-page-DcIAiYJn.js} +1 -1
- package/dist/gateway/static/root/assets/{page-tabs-BMYQef5D.js → page-tabs-DF6Q5XvA.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-CKZ-H5hJ.js → preview-open-alternatives-CQJH_jAN.js} +1 -1
- package/dist/gateway/static/root/assets/{product-delivery-CV4pDOtG.js → product-delivery-CCC4FJ3Y.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-zXJIptXs.js → product-open-page-CIGLPFm7.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-DRhhxhZB.js → project-detail-page-D65JfNSw.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-Wt7gF3Sx.js → projects-page-BfWF7Sz-.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-BSfFaxVN.js → registry-api-CsZLatKo.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-B6de5Zrb.js → remote-access-hub-DA1g4CUD.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DcUB5h1f.js → runtime-tools-settings-panel-0-bFSBB8.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-CquWhe7r.js → schema-form-csGbhTUr.js} +1 -1
- package/dist/gateway/static/root/assets/{schemas-BHS7bo06.js → schemas-BaskVM5g.js} +2 -2
- package/dist/gateway/static/root/assets/{sessions-page-BNWO2EVF.js → sessions-page-DXPBNhrZ.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DxeZm67O.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-DwswAefc.js → settings-form-section-YdrdY8B3.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-CoAVmjjs.js → settings-page-Cv9waRn3.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-C9EIcWtH.js → setup-status-panel-DPf-_05Z.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-DWwy_4zh.js → share-preview-page-DBoEHTPn.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-CIUvq27-.js → shares-settings-BQP5yNcO.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-B5T8cgjq.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-CqsgVtVh.js → skills-page-D1G8h2Lt.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-B-N73248.js → skills-page.utils-BNZYTop7.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BndjXuBZ.js → system-settings-panel-ByuppbHi.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-CG6Ha9t7.js → task-detail-page-DNmkrF6y.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-C5ssn64t.js → theme-store-zRT6vaZc.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-BxZdcp3h.js → tunnel-api-CxWGpbwr.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-mj9CUuz1.js → use-autosave-B0l4qubU.js} +1 -1
- package/dist/gateway/static/root/assets/{user-model-page-DKeHMXI4.js → user-model-page-DMsI6YI7.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CzxVMYlr.js → voice-api-key-field-Bcz7boJg.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-COA0V1cK.js → voice-config-api-DpJEu2RQ.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-DMiPK8dp.js → work-discovery-overlay-Dujq1j_u.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C82OXCJK.js → workflow-run-setup-panel-CxNYbLNB.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-HLCUV3rQ.js → workflows-page-Dk1jK2nv.js} +1 -1
- package/dist/gateway/static/root/index.html +12 -12
- package/dist/package.js +1 -1
- package/dist/packages/browser-control-contract/src/index.js +14 -0
- package/dist/packages/endpoint-tools-protocol/src/index.js +2 -1
- package/dist/packages/gateway-contract/src/browser-page-context.js +43 -0
- package/dist/packages/gateway-contract/src/browser-tab-binding.js +29 -0
- package/dist/packages/gateway-contract/src/device-pairing.js +18 -2
- package/dist/packages/realtime-protocol/src/index.js +1 -0
- package/dist/packages/realtime-protocol/src/voice-audio.js +70 -9
- package/dist/packages/realtime-protocol/src/voice.js +65 -17
- package/dist/src/agent/source-context/browser-page.d.ts +3 -0
- package/dist/src/agent/source-context/browser-page.js +39 -0
- package/dist/src/agent/source-context/injector.js +9 -2
- package/dist/src/agent/source-context/types.d.ts +7 -1
- package/dist/src/agent/source-context/types.js +4 -1
- package/dist/src/agent/tools/factory.js +9 -1
- package/dist/src/browser/automations/schema.d.ts +1 -1
- package/dist/src/browser/automations/service.d.ts +1 -1
- package/dist/src/browser/native-messaging-host.d.ts +15 -0
- package/dist/src/browser/native-messaging-host.js +105 -0
- package/dist/src/browser/providers/browser-ext-install.d.ts +17 -1
- package/dist/src/browser/providers/browser-ext-install.js +82 -16
- package/dist/src/browser/providers/extension.d.ts +4 -0
- package/dist/src/browser/providers/extension.js +104 -38
- package/dist/src/browser/runtime/browser-runtime.d.ts +2 -1
- package/dist/src/browser/runtime/browser-runtime.js +6 -2
- package/dist/src/cli/commands/browser.js +13 -3
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/endpoint-tools/runtime.js +2 -0
- package/dist/src/gateway/chat-stream/mapper.js +3 -2
- package/dist/src/gateway/hono/app.js +19 -3
- package/dist/src/gateway/hono/middleware/auth.d.ts +4 -1
- package/dist/src/gateway/hono/middleware/auth.js +12 -1
- package/dist/src/gateway/hono/routes/browser-install.js +1 -1
- package/dist/src/gateway/hono/routes/browser.js +106 -7
- package/dist/src/gateway/hono/routes/devices.js +36 -3
- package/dist/src/gateway/hono/routes/endpoint-tools.js +15 -0
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +20 -2
- package/dist/src/gateway/hono/routes/session-input-handler.js +18 -0
- package/dist/src/gateway/hono/routes/sessions.js +12 -6
- package/dist/src/gateway/hono/routes/voice.js +5 -4
- package/dist/src/gateway/security/gateway-scopes.d.ts +1 -0
- package/dist/src/gateway/security/gateway-scopes.js +10 -1
- package/dist/src/gateway/security/origin-check.d.ts +1 -0
- package/dist/src/gateway/security/origin-check.js +5 -1
- package/dist/src/gateway/service/agent-runner.js +2 -1
- package/dist/src/gateway/service/session-input-coordinator.d.ts +1 -0
- package/dist/src/gateway/service/session-input-coordinator.js +5 -4
- package/dist/src/gateway/service.js +12 -11
- package/dist/src/realtime/runtime.js +2 -1
- package/dist/src/session/client-history.d.ts +4 -1
- package/dist/src/session/client-history.js +6 -3
- package/dist/src/storage/sqlite/browser-tab-binding-repository.d.ts +7 -0
- package/dist/src/storage/sqlite/browser-tab-binding-repository.js +60 -0
- package/dist/src/storage/sqlite/device-access-repository.d.ts +3 -1
- package/dist/src/storage/sqlite/device-access-repository.js +4 -3
- package/dist/src/storage/sqlite/device-pairing-approval.js +6 -4
- package/dist/src/storage/sqlite/device-pairing-repository.d.ts +1 -1
- package/dist/src/storage/sqlite/index.d.ts +1 -0
- package/dist/src/storage/sqlite/index.js +2 -1
- package/dist/src/storage/sqlite/migrations/155_browser_extension.sql +120 -0
- package/dist/src/storage/sqlite/migrations/156_browser_tab_bindings.sql +14 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/voice/realtime/agentBroker.d.ts +54 -0
- package/dist/src/voice/realtime/agentBroker.js +116 -0
- package/dist/src/voice/realtime/agentEngine.js +62 -15
- package/dist/src/voice/realtime/engine.d.ts +2 -1
- package/dist/src/voice/realtime/omniEngine.js +36 -7
- package/dist/src/voice/realtime/pcmFrameBuffer.d.ts +6 -0
- package/dist/src/voice/realtime/pcmFrameBuffer.js +29 -0
- package/dist/src/voice/realtime/runtime.js +97 -21
- package/dist/src/voice/realtime/runtime.types.d.ts +5 -21
- package/dist/src/voice/realtime/turnPolicy.d.ts +36 -0
- package/dist/src/voice/realtime/turnPolicy.js +134 -0
- package/package.json +2 -2
- package/dist/browser-ext/dist/content.js +0 -191
- package/dist/browser-ext/dist/popup.js +0 -32
- package/dist/browser-ext/popup.html +0 -37
- package/dist/gateway/static/root/assets/index-DQtjs2x3.js +0 -74
- package/dist/gateway/static/root/assets/settings-advanced-gate-DK1yTYE4.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DfE3zFVw.js +0 -1
- package/dist/src/voice/realtime/conversationTurn.d.ts +0 -20
- package/dist/src/voice/realtime/conversationTurn.js +0 -83
|
@@ -6,7 +6,7 @@ import { getRuntimeLogStats } from "../utils/logger/stats.js";
|
|
|
6
6
|
import { createLogger } from "../utils/logger/index.js";
|
|
7
7
|
import { init_logger } from "../utils/logger.js";
|
|
8
8
|
import { closeXopcDatabase, openXopcDatabase } from "../storage/sqlite/connection.js";
|
|
9
|
-
import { insertSessionInput } from "../storage/sqlite/session-input-repository.js";
|
|
9
|
+
import { findSessionInput, insertSessionInput } from "../storage/sqlite/session-input-repository.js";
|
|
10
10
|
import { notifyUserContextChange } from "../user-context/changes.js";
|
|
11
11
|
import { getSessionConfig } from "../storage/sqlite/config-repository.js";
|
|
12
12
|
import "../storage/sqlite/index.js";
|
|
@@ -123,6 +123,7 @@ import { GatewayConfigCoordinator } from "./service/config-coordinator.js";
|
|
|
123
123
|
import { GatewayAgentRunner } from "./service/agent-runner.js";
|
|
124
124
|
import { RealtimeRuntime } from "../realtime/runtime.js";
|
|
125
125
|
import { VoiceRealtimeRuntime } from "../voice/realtime/runtime.js";
|
|
126
|
+
import { DurableVoiceAgentBroker } from "../voice/realtime/agentBroker.js";
|
|
126
127
|
import { reconcileMemoryMaintenanceAutomations } from "./memory-maintenance-automation-reconciler.js";
|
|
127
128
|
import { GatewayReadiness } from "./startup-readiness.js";
|
|
128
129
|
import { createGatewayStartupTrace } from "./startup-trace.js";
|
|
@@ -228,16 +229,16 @@ var GatewayService = class {
|
|
|
228
229
|
interruptedDuring: entry.interruptedDuring
|
|
229
230
|
}
|
|
230
231
|
}),
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
}
|
|
232
|
+
agentBroker: new DurableVoiceAgentBroker({
|
|
233
|
+
submit: (input) => this.agentRunner.submitSessionInput(input),
|
|
234
|
+
find: findSessionInput,
|
|
235
|
+
snapshot: (sessionKey) => this.agentRunner.inputs.snapshot(sessionKey),
|
|
236
|
+
currentSequence: (topic) => this.realtime.broker.currentSequence(topic),
|
|
237
|
+
subscribe: (topic, afterSeq, listener) => this.realtime.broker.subscribe(topic, afterSeq, listener),
|
|
238
|
+
cancelRun: async (runId) => {
|
|
239
|
+
await this.agentRunner.abortAgentRun(runId);
|
|
240
|
+
}
|
|
241
|
+
})
|
|
241
242
|
});
|
|
242
243
|
getConfig() {
|
|
243
244
|
return this.config;
|
|
@@ -194,7 +194,8 @@ var RealtimeRuntime = class {
|
|
|
194
194
|
connectionId = crypto.randomUUID();
|
|
195
195
|
let endpointReady;
|
|
196
196
|
if (message.payload.endpoint) {
|
|
197
|
-
|
|
197
|
+
const endpointKindMatches = message.payload.endpoint.kind === message.payload.clientKind || message.payload.clientKind === "browser_extension" && message.payload.endpoint.kind === "browser";
|
|
198
|
+
if (!this.endpointTools || !endpointKindMatches) {
|
|
198
199
|
socket.close(4401, "Realtime endpoint identity is invalid");
|
|
199
200
|
return;
|
|
200
201
|
}
|
|
@@ -15,12 +15,15 @@ export interface ClientHistoryMessage {
|
|
|
15
15
|
/** Whitelisted display metadata; never includes source snapshot text. */
|
|
16
16
|
metadata?: {
|
|
17
17
|
sourceContexts?: Array<{
|
|
18
|
-
kind: 'note';
|
|
18
|
+
kind: 'note' | 'browser_page';
|
|
19
19
|
sourceId: string;
|
|
20
20
|
version: string;
|
|
21
21
|
title: string;
|
|
22
22
|
tokenEstimate?: number;
|
|
23
23
|
truncated?: boolean;
|
|
24
|
+
url?: string;
|
|
25
|
+
capturedAt?: number;
|
|
26
|
+
documentId?: string;
|
|
24
27
|
}>;
|
|
25
28
|
turnOutcome?: TurnOutcome;
|
|
26
29
|
};
|
|
@@ -9,14 +9,17 @@ function sourceContextDisplayMetadata(metadata) {
|
|
|
9
9
|
const sourceContexts = rows.flatMap((value) => {
|
|
10
10
|
if (!value || typeof value !== "object" || Array.isArray(value)) return [];
|
|
11
11
|
const row = value;
|
|
12
|
-
if (row.kind !== "note" || typeof row.sourceId !== "string" || typeof row.version !== "string" || typeof row.title !== "string") return [];
|
|
12
|
+
if (row.kind !== "note" && row.kind !== "browser_page" || typeof row.sourceId !== "string" || typeof row.version !== "string" || typeof row.title !== "string") return [];
|
|
13
13
|
return [{
|
|
14
|
-
kind:
|
|
14
|
+
kind: row.kind,
|
|
15
15
|
sourceId: row.sourceId,
|
|
16
16
|
version: row.version,
|
|
17
17
|
title: row.title,
|
|
18
18
|
...typeof row.tokenEstimate === "number" ? { tokenEstimate: row.tokenEstimate } : {},
|
|
19
|
-
...row.truncated === true ? { truncated: true } : {}
|
|
19
|
+
...row.truncated === true ? { truncated: true } : {},
|
|
20
|
+
...typeof row.url === "string" ? { url: row.url } : {},
|
|
21
|
+
...typeof row.capturedAt === "number" ? { capturedAt: row.capturedAt } : {},
|
|
22
|
+
...typeof row.documentId === "string" ? { documentId: row.documentId } : {}
|
|
20
23
|
}];
|
|
21
24
|
});
|
|
22
25
|
return sourceContexts.length ? { sourceContexts } : void 0;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BrowserTabBinding } from '@xopcai/gateway-contract';
|
|
2
|
+
export declare function getBrowserTabBinding(sessionKey: string, now?: number): BrowserTabBinding | undefined;
|
|
3
|
+
export declare function getBrowserTabBindingById(bindingId: string, now?: number): BrowserTabBinding | undefined;
|
|
4
|
+
export declare function setBrowserTabBinding(input: Omit<BrowserTabBinding, 'id' | 'createdAt' | 'expiresAt'>, now?: number): BrowserTabBinding;
|
|
5
|
+
export declare function deleteBrowserTabBinding(sessionKey: string): boolean;
|
|
6
|
+
export declare function deleteBrowserTabBindingsByEndpoint(endpointId: string): number;
|
|
7
|
+
export declare function deleteBrowserTabBindingsByPrincipal(principalId: string): number;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { getSqliteDatabase } from "./transaction.js";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
//#region src/storage/sqlite/browser-tab-binding-repository.ts
|
|
4
|
+
function bindingFromRow(row) {
|
|
5
|
+
return {
|
|
6
|
+
id: row.binding_id,
|
|
7
|
+
sessionKey: row.session_key,
|
|
8
|
+
principalId: row.principal_id,
|
|
9
|
+
endpointId: row.endpoint_id,
|
|
10
|
+
tabId: row.tab_id,
|
|
11
|
+
windowId: row.window_id,
|
|
12
|
+
documentId: row.document_id,
|
|
13
|
+
urlOrigin: row.url_origin,
|
|
14
|
+
mode: row.mode,
|
|
15
|
+
createdAt: row.created_at,
|
|
16
|
+
expiresAt: row.expires_at
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function getBrowserTabBinding(sessionKey, now = Date.now()) {
|
|
20
|
+
const db = getSqliteDatabase();
|
|
21
|
+
db.prepare("DELETE FROM browser_tab_bindings WHERE expires_at <= ?").run(now);
|
|
22
|
+
const row = db.prepare(`SELECT * FROM browser_tab_bindings WHERE session_key = ?`).get(sessionKey);
|
|
23
|
+
return row ? bindingFromRow(row) : void 0;
|
|
24
|
+
}
|
|
25
|
+
function getBrowserTabBindingById(bindingId, now = Date.now()) {
|
|
26
|
+
const db = getSqliteDatabase();
|
|
27
|
+
db.prepare("DELETE FROM browser_tab_bindings WHERE expires_at <= ?").run(now);
|
|
28
|
+
const row = db.prepare(`SELECT * FROM browser_tab_bindings WHERE binding_id = ?`).get(bindingId);
|
|
29
|
+
return row ? bindingFromRow(row) : void 0;
|
|
30
|
+
}
|
|
31
|
+
function setBrowserTabBinding(input, now = Date.now()) {
|
|
32
|
+
const binding = {
|
|
33
|
+
...input,
|
|
34
|
+
id: randomUUID(),
|
|
35
|
+
createdAt: now,
|
|
36
|
+
expiresAt: now + 480 * 60 * 1e3
|
|
37
|
+
};
|
|
38
|
+
getSqliteDatabase().prepare(`INSERT INTO browser_tab_bindings (
|
|
39
|
+
binding_id, session_key, principal_id, endpoint_id, tab_id, window_id,
|
|
40
|
+
document_id, url_origin, mode, created_at, expires_at
|
|
41
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
42
|
+
ON CONFLICT(session_key) DO UPDATE SET
|
|
43
|
+
binding_id = excluded.binding_id, principal_id = excluded.principal_id,
|
|
44
|
+
endpoint_id = excluded.endpoint_id, tab_id = excluded.tab_id,
|
|
45
|
+
window_id = excluded.window_id, document_id = excluded.document_id,
|
|
46
|
+
url_origin = excluded.url_origin, mode = excluded.mode,
|
|
47
|
+
created_at = excluded.created_at, expires_at = excluded.expires_at`).run(binding.id, binding.sessionKey, binding.principalId, binding.endpointId, binding.tabId, binding.windowId, binding.documentId, binding.urlOrigin, binding.mode, binding.createdAt, binding.expiresAt);
|
|
48
|
+
return binding;
|
|
49
|
+
}
|
|
50
|
+
function deleteBrowserTabBinding(sessionKey) {
|
|
51
|
+
return getSqliteDatabase().prepare("DELETE FROM browser_tab_bindings WHERE session_key = ?").run(sessionKey).changes > 0;
|
|
52
|
+
}
|
|
53
|
+
function deleteBrowserTabBindingsByEndpoint(endpointId) {
|
|
54
|
+
return Number(getSqliteDatabase().prepare("DELETE FROM browser_tab_bindings WHERE endpoint_id = ?").run(endpointId).changes);
|
|
55
|
+
}
|
|
56
|
+
function deleteBrowserTabBindingsByPrincipal(principalId) {
|
|
57
|
+
return Number(getSqliteDatabase().prepare("DELETE FROM browser_tab_bindings WHERE principal_id = ?").run(principalId).changes);
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { deleteBrowserTabBinding, deleteBrowserTabBindingsByEndpoint, deleteBrowserTabBindingsByPrincipal, getBrowserTabBinding, getBrowserTabBindingById, setBrowserTabBinding };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import type { GatewayScope } from '../../gateway/security/gateway-scopes.js';
|
|
3
|
-
export type DevicePlatform = 'ios' | 'android';
|
|
3
|
+
export type DevicePlatform = 'ios' | 'android' | 'chrome';
|
|
4
4
|
export type DevicePublicKeyJwk = crypto.webcrypto.JsonWebKey;
|
|
5
5
|
export type DeviceRecord = {
|
|
6
6
|
id: string;
|
|
7
7
|
displayName: string;
|
|
8
8
|
platform: DevicePlatform;
|
|
9
|
+
extensionId?: string;
|
|
9
10
|
publicKeyJwk: DevicePublicKeyJwk;
|
|
10
11
|
scopes: GatewayScope[];
|
|
11
12
|
createdAt: number;
|
|
@@ -28,6 +29,7 @@ export declare function createDevice(input: {
|
|
|
28
29
|
displayName: string;
|
|
29
30
|
platform: DevicePlatform;
|
|
30
31
|
publicKeyJwk: DevicePublicKeyJwk;
|
|
32
|
+
extensionId?: string;
|
|
31
33
|
scopes: readonly GatewayScope[];
|
|
32
34
|
now?: number;
|
|
33
35
|
}): DeviceRecord;
|
|
@@ -26,6 +26,7 @@ function deviceFromRow(row) {
|
|
|
26
26
|
displayName: row.display_name,
|
|
27
27
|
platform: row.platform,
|
|
28
28
|
publicKeyJwk: JSON.parse(row.public_key_jwk),
|
|
29
|
+
...row.extension_id ? { extensionId: row.extension_id } : {},
|
|
29
30
|
scopes: parseGatewayScopes(row.scopes_json),
|
|
30
31
|
createdAt: row.created_at,
|
|
31
32
|
...row.last_seen_at === null ? {} : { lastSeenAt: row.last_seen_at },
|
|
@@ -37,9 +38,9 @@ function createDevice(input) {
|
|
|
37
38
|
const createdAt = input.now ?? Date.now();
|
|
38
39
|
getSqliteDatabase().prepare(`
|
|
39
40
|
INSERT INTO devices (
|
|
40
|
-
device_id, display_name, platform, public_key_jwk, scopes_json, created_at
|
|
41
|
-
) VALUES (?, ?, ?, ?, ?, ?)
|
|
42
|
-
`).run(id, input.displayName, input.platform, JSON.stringify(input.publicKeyJwk), JSON.stringify([...new Set(input.scopes)]), createdAt);
|
|
41
|
+
device_id, display_name, platform, extension_id, public_key_jwk, scopes_json, created_at
|
|
42
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
43
|
+
`).run(id, input.displayName, input.platform, input.extensionId ?? null, JSON.stringify(input.publicKeyJwk), JSON.stringify([...new Set(input.scopes)]), createdAt);
|
|
43
44
|
return getDevice(id);
|
|
44
45
|
}
|
|
45
46
|
function getDevice(deviceId) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
2
|
import { buildDevicePairingProof, devicePairingCompleteSchema, devicePairingDeviceSchema } from "../../../packages/gateway-contract/src/device-pairing.js";
|
|
3
|
-
import { DEFAULT_MOBILE_SCOPES } from "../../gateway/security/gateway-scopes.js";
|
|
3
|
+
import { DEFAULT_BROWSER_EXTENSION_SCOPES, DEFAULT_MOBILE_SCOPES } from "../../gateway/security/gateway-scopes.js";
|
|
4
4
|
import { createDevice, getDevice, registerInitialDeviceRefreshToken, revokeDevice } from "./device-access-repository.js";
|
|
5
5
|
import { getOrCreateGatewayIdentity } from "./gateway-identity-repository.js";
|
|
6
6
|
import crypto from "node:crypto";
|
|
@@ -19,6 +19,7 @@ const hash = (value) => crypto.createHash("sha256").update(value).digest("hex");
|
|
|
19
19
|
const fail = (code, status) => {
|
|
20
20
|
throw new DevicePairingError(code, status);
|
|
21
21
|
};
|
|
22
|
+
const scopesForPlatform = (platform) => platform === "chrome" ? DEFAULT_BROWSER_EXTENSION_SCOPES : DEFAULT_MOBILE_SCOPES;
|
|
22
23
|
function requestRow(id, now) {
|
|
23
24
|
const db = getSqliteDatabase();
|
|
24
25
|
db.prepare(`UPDATE device_pairing_requests SET status = 'expired', revision = revision + 1
|
|
@@ -133,9 +134,10 @@ function operateDevicePairingRequest(action, body, now = Date.now()) {
|
|
|
133
134
|
return;
|
|
134
135
|
}
|
|
135
136
|
if (current.status !== "approved") fail("PAIRING_NOT_APPROVED");
|
|
137
|
+
const device = devicePairingDeviceSchema.parse(JSON.parse(current.device_json));
|
|
136
138
|
const created = createDevice({
|
|
137
|
-
...
|
|
138
|
-
scopes:
|
|
139
|
+
...device,
|
|
140
|
+
scopes: scopesForPlatform(device.platform),
|
|
139
141
|
now
|
|
140
142
|
});
|
|
141
143
|
registerInitialDeviceRefreshToken(created.id, complete.initialRefreshToken, now);
|
|
@@ -147,7 +149,7 @@ function operateDevicePairingRequest(action, body, now = Date.now()) {
|
|
|
147
149
|
return {
|
|
148
150
|
request: statusFromRow(requestRow(row.request_id, now), now),
|
|
149
151
|
routes: JSON.parse(setup.routes_json),
|
|
150
|
-
...action === "complete" ? { scopes:
|
|
152
|
+
...action === "complete" ? { scopes: scopesForPlatform(devicePairingDeviceSchema.parse(JSON.parse(row.device_json)).platform) } : {}
|
|
151
153
|
};
|
|
152
154
|
}
|
|
153
155
|
//#endregion
|
|
@@ -6,6 +6,7 @@ export { discoverSqlMigrations, listRegisteredMigrationTargets } from './migrati
|
|
|
6
6
|
export { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest, type OpenXopcDatabaseOptions, type XopcDatabase, } from './connection.js';
|
|
7
7
|
export { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';
|
|
8
8
|
export { deleteEndpointSessionBinding, getEndpointSessionBinding, setEndpointSessionBinding, type StoredEndpointSessionBinding, } from './endpoint-session-binding-repository.js';
|
|
9
|
+
export { deleteBrowserTabBinding, deleteBrowserTabBindingsByEndpoint, deleteBrowserTabBindingsByPrincipal, getBrowserTabBinding, getBrowserTabBindingById, setBrowserTabBinding, } from './browser-tab-binding-repository.js';
|
|
9
10
|
export { authenticateDeviceAccessToken, buildRefreshProofMessage, createDevice, getDevice, issueDeviceTokenPair, listDevices, revokeDevice, rotateDeviceRefreshToken, type DeviceAccessIdentity, type DevicePlatform, type DevicePublicKeyJwk, type DeviceRecord, type DeviceTokenPair, } from './device-access-repository.js';
|
|
10
11
|
export { clearGatewayIdentityForTest, getOrCreateGatewayIdentity, signGatewayPayload, type GatewayIdentity, } from './gateway-identity-repository.js';
|
|
11
12
|
export { consumeDevicePairingToken, createDevicePairingSetup, isDevicePairingSetupActive, type DevicePairingSetup, type DeviceRoute, type PairingConsumeResult, } from './device-pairing-repository.js';
|
|
@@ -7,6 +7,7 @@ import { ensureXopcDatabaseSchema } from "./schema.js";
|
|
|
7
7
|
import { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest } from "./connection.js";
|
|
8
8
|
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
9
9
|
import { deleteEndpointSessionBinding, getEndpointSessionBinding, setEndpointSessionBinding } from "./endpoint-session-binding-repository.js";
|
|
10
|
+
import { deleteBrowserTabBinding, deleteBrowserTabBindingsByEndpoint, deleteBrowserTabBindingsByPrincipal, getBrowserTabBinding, getBrowserTabBindingById, setBrowserTabBinding } from "./browser-tab-binding-repository.js";
|
|
10
11
|
import { authenticateDeviceAccessToken, buildRefreshProofMessage, createDevice, getDevice, issueDeviceTokenPair, listDevices, revokeDevice, rotateDeviceRefreshToken } from "./device-access-repository.js";
|
|
11
12
|
import { clearGatewayIdentityForTest, getOrCreateGatewayIdentity, signGatewayPayload } from "./gateway-identity-repository.js";
|
|
12
13
|
import { consumeDevicePairingToken, createDevicePairingSetup, isDevicePairingSetupActive } from "./device-pairing-repository.js";
|
|
@@ -39,4 +40,4 @@ import { appendConnectorExecutionAudit, claimConnectorWebhookDelivery, completeC
|
|
|
39
40
|
import { getConnectorAccount, listConnectorAccounts, reconcileConnectorAccount, refreshConnectorAccountCurrent } from "./connector-account-repository.js";
|
|
40
41
|
import { getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, listConnectorSyncPolicies, upsertConnectorSyncPolicy } from "./connector-sync-policy-repository.js";
|
|
41
42
|
import { getUserTrustPolicy, setUserTrustPolicy } from "./user-trust-repository.js";
|
|
42
|
-
export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, acknowledgeHomeAttention, appendCompactionBoundaryIfUnchanged, appendComposerInputHistory, appendConnectorExecutionAudit, appendTranscriptEntry, applyPendingMigrations, authenticateDeviceAccessToken, bindEndpointPrincipal, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRefreshProofMessage, buildRelationshipPrompt, cancelQueuedSessionInput, claimConnectorWebhookDelivery, claimContextExtractionRun, claimKnowledgeSourceItems, claimNextConnectorLearningJob, claimNextSessionInput, classifyStoredRow, clearComposerInputHistory, clearGatewayIdentityForTest, closeTemporalAssertions, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeClarificationApproval, consumeClarificationResume, consumeConnectorApproval, consumeDevicePairingToken, countKnowledgeSourceItems, createClarificationWait, createCollaborationRule, createConnectorApproval, createContextEvidence, createDevice, createDevicePairingSetup, createEndpointPrincipal, createObjectLinkRecord, createTemporalAssertion, decideConnectorApproval, deleteConnectorConnection, deleteConnectorInstallation, deleteEndpointSessionBinding, deleteKnowledgeSourceItems, deleteNoteAgentContextRecord, deleteNoteRecord, deleteObjectLinkRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, enqueueConnectorLearningJob, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findSessionInput, findSessionKeyBySessionId, finishContextExtractionRun, finishEndpointToolInvocationAudit, finishKnowledgeSyncRun, finishSessionInputRun, getActiveClarification, getActivityEventRecord, getCachedConnectorCatalogEntry, getClarification, getClarificationResumeInput, getClarificationSnapshot, getCollaborationRule, getConnectorAccount, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, getContextExtractionRun, getCurrentSessionId, getDevice, getEndpointPrincipal, getEndpointSessionBinding, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getNoteAgentContextRecord, getNoteRecord, getOrCreateGatewayIdentity, getRelationshipSettings, getSessionConfig, getSessionInputById, getSessionInputState, getSessionMetadata, getSessionPersistedLevels, getSessionTaskPlan, getSqliteDatabase, getUserPeopleIndexState, getUserPerson, getUserTrustPolicy, getXopcDatabase, hasIndependentExtractionOutput, hasSessionConfig, incrementSessionStatsOnAppend, insertSessionInput, inspectSchemaMigrationStatus, isClarificationSuspended, isDevicePairingSetupActive, isHomeAttentionAcknowledged, isProactiveSupportAllowed, isXopcDatabaseOpen, issueDeviceTokenPair, linkContextObjects, listActiveSessionInputRuns, listActivityRecords, listCachedConnectorCatalogEntries, listCollaborationRules, listCompactionBoundaries, listComposerInputHistory, listConnectorAccounts, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listConnectorLearningJobs, listConnectorSyncPolicies, listContextExtractionOutputs, listContextExtractionRuns, listContextObjectRelations, listDevices, listEndpointPrincipals, listEndpointToolInvocationAudits, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTemporalAssertions, listUserPeople, loadCompactionSourceSnapshot, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, mergeUserPeople, metadataToSessionInsert, mutateQueuedSessionInput, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, pruneBoundedKnowledgeSourceItems, readSchemaVersion, readSchemaVersionForTest, reconcileConnectorAccount, recordActivityEvent, recoverSessionInputState, recoverStaleConnectorLearningJobs, refreshConnectorAccountCurrent, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceLatestSessionTurnAndQueueInput, replaceTranscriptRows, replaceUserPeopleIndex, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveClarification, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreBeforeCompactionBoundary, revokeDevice, revokeEndpointPrincipal, rotateDeviceRefreshToken, runSqliteWriteTransaction, searchSessionTranscript, sessionConfigRowToConfig, sessionRowToMetadata, setCollaborationRuleStatus, setConnectorLearningPaused, setEndpointSessionBinding, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setSessionConfig, setSessionInputStatus, setSessionTaskPlan, setUserTrustPolicy, signGatewayPayload, startEndpointToolInvocationAudit, startKnowledgeSyncRun, summarizeUserPeople, supersedeActiveClarification, touchEndpointPrincipal, transcriptEntryRowToStoredRow, updateConnectorLearningJob, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateUserPerson, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertConnectorSyncPolicy, upsertKnowledgeSourceItems, upsertNoteAgentContextRecord, upsertNoteRecord, validateLatestSessionTurnTarget };
|
|
43
|
+
export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, acknowledgeHomeAttention, appendCompactionBoundaryIfUnchanged, appendComposerInputHistory, appendConnectorExecutionAudit, appendTranscriptEntry, applyPendingMigrations, authenticateDeviceAccessToken, bindEndpointPrincipal, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRefreshProofMessage, buildRelationshipPrompt, cancelQueuedSessionInput, claimConnectorWebhookDelivery, claimContextExtractionRun, claimKnowledgeSourceItems, claimNextConnectorLearningJob, claimNextSessionInput, classifyStoredRow, clearComposerInputHistory, clearGatewayIdentityForTest, closeTemporalAssertions, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeClarificationApproval, consumeClarificationResume, consumeConnectorApproval, consumeDevicePairingToken, countKnowledgeSourceItems, createClarificationWait, createCollaborationRule, createConnectorApproval, createContextEvidence, createDevice, createDevicePairingSetup, createEndpointPrincipal, createObjectLinkRecord, createTemporalAssertion, decideConnectorApproval, deleteBrowserTabBinding, deleteBrowserTabBindingsByEndpoint, deleteBrowserTabBindingsByPrincipal, deleteConnectorConnection, deleteConnectorInstallation, deleteEndpointSessionBinding, deleteKnowledgeSourceItems, deleteNoteAgentContextRecord, deleteNoteRecord, deleteObjectLinkRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, enqueueConnectorLearningJob, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findSessionInput, findSessionKeyBySessionId, finishContextExtractionRun, finishEndpointToolInvocationAudit, finishKnowledgeSyncRun, finishSessionInputRun, getActiveClarification, getActivityEventRecord, getBrowserTabBinding, getBrowserTabBindingById, getCachedConnectorCatalogEntry, getClarification, getClarificationResumeInput, getClarificationSnapshot, getCollaborationRule, getConnectorAccount, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getConnectorSyncPolicy, getConnectorSyncPolicyForConnection, getContextExtractionRun, getCurrentSessionId, getDevice, getEndpointPrincipal, getEndpointSessionBinding, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getNoteAgentContextRecord, getNoteRecord, getOrCreateGatewayIdentity, getRelationshipSettings, getSessionConfig, getSessionInputById, getSessionInputState, getSessionMetadata, getSessionPersistedLevels, getSessionTaskPlan, getSqliteDatabase, getUserPeopleIndexState, getUserPerson, getUserTrustPolicy, getXopcDatabase, hasIndependentExtractionOutput, hasSessionConfig, incrementSessionStatsOnAppend, insertSessionInput, inspectSchemaMigrationStatus, isClarificationSuspended, isDevicePairingSetupActive, isHomeAttentionAcknowledged, isProactiveSupportAllowed, isXopcDatabaseOpen, issueDeviceTokenPair, linkContextObjects, listActiveSessionInputRuns, listActivityRecords, listCachedConnectorCatalogEntries, listCollaborationRules, listCompactionBoundaries, listComposerInputHistory, listConnectorAccounts, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listConnectorLearningJobs, listConnectorSyncPolicies, listContextExtractionOutputs, listContextExtractionRuns, listContextObjectRelations, listDevices, listEndpointPrincipals, listEndpointToolInvocationAudits, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTemporalAssertions, listUserPeople, loadCompactionSourceSnapshot, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, mergeUserPeople, metadataToSessionInsert, mutateQueuedSessionInput, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, pruneBoundedKnowledgeSourceItems, readSchemaVersion, readSchemaVersionForTest, reconcileConnectorAccount, recordActivityEvent, recoverSessionInputState, recoverStaleConnectorLearningJobs, refreshConnectorAccountCurrent, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceLatestSessionTurnAndQueueInput, replaceTranscriptRows, replaceUserPeopleIndex, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveClarification, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreBeforeCompactionBoundary, revokeDevice, revokeEndpointPrincipal, rotateDeviceRefreshToken, runSqliteWriteTransaction, searchSessionTranscript, sessionConfigRowToConfig, sessionRowToMetadata, setBrowserTabBinding, setCollaborationRuleStatus, setConnectorLearningPaused, setEndpointSessionBinding, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setSessionConfig, setSessionInputStatus, setSessionTaskPlan, setUserTrustPolicy, signGatewayPayload, startEndpointToolInvocationAudit, startKnowledgeSyncRun, summarizeUserPeople, supersedeActiveClarification, touchEndpointPrincipal, transcriptEntryRowToStoredRow, updateConnectorLearningJob, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateUserPerson, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertConnectorSyncPolicy, upsertKnowledgeSourceItems, upsertNoteAgentContextRecord, upsertNoteRecord, validateLatestSessionTurnTarget };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
PRAGMA defer_foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
-- Rebuild the device table and every table that references it. SQLite rewrites
|
|
4
|
+
-- foreign-key targets on table rename, so rebuilding only `devices` would leave
|
|
5
|
+
-- references pointing at the temporary table name.
|
|
6
|
+
ALTER TABLE notification_deliveries RENAME TO notification_deliveries_v154;
|
|
7
|
+
ALTER TABLE device_pairing_requests RENAME TO device_pairing_requests_v154;
|
|
8
|
+
ALTER TABLE device_refresh_credentials RENAME TO device_refresh_credentials_v154;
|
|
9
|
+
ALTER TABLE device_access_sessions RENAME TO device_access_sessions_v154;
|
|
10
|
+
ALTER TABLE device_push_endpoints RENAME TO device_push_endpoints_v154;
|
|
11
|
+
ALTER TABLE devices RENAME TO devices_v154;
|
|
12
|
+
|
|
13
|
+
DROP INDEX idx_notification_deliveries_due;
|
|
14
|
+
DROP INDEX idx_device_pairing_requests_expiry;
|
|
15
|
+
DROP INDEX idx_device_refresh_credentials_device;
|
|
16
|
+
DROP INDEX idx_device_access_sessions_device;
|
|
17
|
+
|
|
18
|
+
CREATE TABLE devices (
|
|
19
|
+
device_id TEXT PRIMARY KEY,
|
|
20
|
+
display_name TEXT NOT NULL,
|
|
21
|
+
platform TEXT NOT NULL CHECK (platform IN ('ios', 'android', 'chrome')),
|
|
22
|
+
extension_id TEXT CHECK (extension_id IS NULL OR length(extension_id) = 32),
|
|
23
|
+
public_key_jwk TEXT NOT NULL,
|
|
24
|
+
scopes_json TEXT NOT NULL,
|
|
25
|
+
created_at INTEGER NOT NULL,
|
|
26
|
+
last_seen_at INTEGER,
|
|
27
|
+
revoked_at INTEGER,
|
|
28
|
+
CHECK ((platform = 'chrome') = (extension_id IS NOT NULL))
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE TABLE device_refresh_credentials (
|
|
32
|
+
credential_id TEXT PRIMARY KEY,
|
|
33
|
+
device_id TEXT NOT NULL REFERENCES devices(device_id) ON DELETE CASCADE,
|
|
34
|
+
token_hash TEXT NOT NULL,
|
|
35
|
+
expires_at INTEGER NOT NULL,
|
|
36
|
+
created_at INTEGER NOT NULL,
|
|
37
|
+
last_used_at INTEGER,
|
|
38
|
+
replaced_by TEXT REFERENCES device_refresh_credentials(credential_id),
|
|
39
|
+
rotation_request_id TEXT,
|
|
40
|
+
revoked_at INTEGER
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
CREATE TABLE device_access_sessions (
|
|
44
|
+
session_id TEXT PRIMARY KEY,
|
|
45
|
+
device_id TEXT NOT NULL REFERENCES devices(device_id) ON DELETE CASCADE,
|
|
46
|
+
token_hash TEXT NOT NULL,
|
|
47
|
+
expires_at INTEGER NOT NULL,
|
|
48
|
+
created_at INTEGER NOT NULL,
|
|
49
|
+
revoked_at INTEGER
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
CREATE TABLE device_push_endpoints (
|
|
53
|
+
device_id TEXT PRIMARY KEY REFERENCES devices(device_id) ON DELETE CASCADE,
|
|
54
|
+
platform TEXT NOT NULL CHECK (platform IN ('ios', 'android')),
|
|
55
|
+
push_token TEXT NOT NULL UNIQUE,
|
|
56
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
57
|
+
permissions TEXT NOT NULL CHECK (permissions IN ('granted', 'denied', 'unknown')),
|
|
58
|
+
preferences_json TEXT NOT NULL DEFAULT '{}',
|
|
59
|
+
locale TEXT NOT NULL CHECK (locale IN ('en', 'zh')),
|
|
60
|
+
app_version TEXT,
|
|
61
|
+
lease_expires_at INTEGER NOT NULL,
|
|
62
|
+
last_seen_at INTEGER NOT NULL,
|
|
63
|
+
created_at INTEGER NOT NULL,
|
|
64
|
+
updated_at INTEGER NOT NULL
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
CREATE TABLE device_pairing_requests (
|
|
68
|
+
request_id TEXT PRIMARY KEY,
|
|
69
|
+
pairing_id TEXT NOT NULL UNIQUE REFERENCES device_pairing_sessions(pairing_id) ON DELETE CASCADE,
|
|
70
|
+
device_json TEXT NOT NULL,
|
|
71
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'approved', 'completed', 'rejected', 'cancelled', 'expired')),
|
|
72
|
+
revision INTEGER NOT NULL DEFAULT 1,
|
|
73
|
+
confirmation_code TEXT NOT NULL,
|
|
74
|
+
expires_at INTEGER NOT NULL,
|
|
75
|
+
recovery_until INTEGER NOT NULL,
|
|
76
|
+
completion_key TEXT,
|
|
77
|
+
initial_token_hash TEXT,
|
|
78
|
+
device_id TEXT REFERENCES devices(device_id),
|
|
79
|
+
created_at INTEGER NOT NULL
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
CREATE TABLE notification_deliveries (
|
|
83
|
+
event_id TEXT NOT NULL,
|
|
84
|
+
device_id TEXT NOT NULL,
|
|
85
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'accepted', 'delivered', 'dead')),
|
|
86
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
87
|
+
next_attempt_at INTEGER NOT NULL,
|
|
88
|
+
provider_ticket_id TEXT,
|
|
89
|
+
last_error TEXT,
|
|
90
|
+
updated_at INTEGER NOT NULL,
|
|
91
|
+
PRIMARY KEY (event_id, device_id),
|
|
92
|
+
FOREIGN KEY (event_id) REFERENCES notification_events(event_id) ON DELETE CASCADE,
|
|
93
|
+
FOREIGN KEY (device_id) REFERENCES device_push_endpoints(device_id) ON DELETE CASCADE
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
INSERT INTO devices
|
|
97
|
+
SELECT device_id, display_name, platform, NULL, public_key_jwk, scopes_json,
|
|
98
|
+
created_at, last_seen_at, revoked_at
|
|
99
|
+
FROM devices_v154;
|
|
100
|
+
INSERT INTO device_refresh_credentials SELECT * FROM device_refresh_credentials_v154;
|
|
101
|
+
INSERT INTO device_access_sessions SELECT * FROM device_access_sessions_v154;
|
|
102
|
+
INSERT INTO device_push_endpoints SELECT * FROM device_push_endpoints_v154;
|
|
103
|
+
INSERT INTO device_pairing_requests SELECT * FROM device_pairing_requests_v154;
|
|
104
|
+
INSERT INTO notification_deliveries SELECT * FROM notification_deliveries_v154;
|
|
105
|
+
|
|
106
|
+
DROP TABLE notification_deliveries_v154;
|
|
107
|
+
DROP TABLE device_pairing_requests_v154;
|
|
108
|
+
DROP TABLE device_refresh_credentials_v154;
|
|
109
|
+
DROP TABLE device_access_sessions_v154;
|
|
110
|
+
DROP TABLE device_push_endpoints_v154;
|
|
111
|
+
DROP TABLE devices_v154;
|
|
112
|
+
|
|
113
|
+
CREATE INDEX idx_notification_deliveries_due
|
|
114
|
+
ON notification_deliveries(status, next_attempt_at);
|
|
115
|
+
CREATE INDEX idx_device_pairing_requests_expiry
|
|
116
|
+
ON device_pairing_requests(recovery_until);
|
|
117
|
+
CREATE INDEX idx_device_refresh_credentials_device
|
|
118
|
+
ON device_refresh_credentials(device_id, expires_at);
|
|
119
|
+
CREATE INDEX idx_device_access_sessions_device
|
|
120
|
+
ON device_access_sessions(device_id, expires_at);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
CREATE TABLE browser_tab_bindings (
|
|
2
|
+
binding_id TEXT PRIMARY KEY,
|
|
3
|
+
session_key TEXT NOT NULL UNIQUE,
|
|
4
|
+
principal_id TEXT NOT NULL REFERENCES devices(device_id) ON DELETE CASCADE,
|
|
5
|
+
endpoint_id TEXT NOT NULL,
|
|
6
|
+
tab_id TEXT NOT NULL,
|
|
7
|
+
window_id TEXT NOT NULL,
|
|
8
|
+
document_id TEXT NOT NULL,
|
|
9
|
+
url_origin TEXT NOT NULL,
|
|
10
|
+
mode TEXT NOT NULL CHECK (mode IN ('read', 'act')),
|
|
11
|
+
created_at INTEGER NOT NULL,
|
|
12
|
+
expires_at INTEGER NOT NULL
|
|
13
|
+
);
|
|
14
|
+
CREATE INDEX idx_browser_tab_bindings_expiry ON browser_tab_bindings(expires_at);
|
|
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
|
|
|
3
3
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
4
4
|
export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
5
5
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
6
|
-
export declare const XOPC_DB_SCHEMA_VERSION =
|
|
6
|
+
export declare const XOPC_DB_SCHEMA_VERSION = 156;
|
|
7
7
|
export declare function resolveMigrationsDir(override?: string): string;
|
|
8
8
|
/**
|
|
9
9
|
* Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
|
|
@@ -12,7 +12,7 @@ const log = createLogger("Sqlite:Migrations");
|
|
|
12
12
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
13
13
|
const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
14
14
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
15
|
-
const XOPC_DB_SCHEMA_VERSION =
|
|
15
|
+
const XOPC_DB_SCHEMA_VERSION = 156;
|
|
16
16
|
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
17
17
|
function backupBeforeTaskCutover(db, databasePath) {
|
|
18
18
|
db.exec("PRAGMA wal_checkpoint(FULL)");
|
|
@@ -57,7 +57,7 @@ function applySingleMigration(db, migration) {
|
|
|
57
57
|
* Each step runs in its own transaction and updates schema_meta on success.
|
|
58
58
|
*/
|
|
59
59
|
function applyPendingMigrations(db, options = {}) {
|
|
60
|
-
const targetVersion = options.targetVersion ??
|
|
60
|
+
const targetVersion = options.targetVersion ?? 156;
|
|
61
61
|
let currentVersion = readSchemaVersion(db);
|
|
62
62
|
if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
|
|
63
63
|
if (currentVersion >= targetVersion) return currentVersion;
|
|
@@ -94,7 +94,7 @@ function applyPendingMigrations(db, options = {}) {
|
|
|
94
94
|
}
|
|
95
95
|
/** Inspect schema version without mutating the database. */
|
|
96
96
|
function inspectSchemaMigrationStatus(db, options = {}) {
|
|
97
|
-
const appVersion = options.targetVersion ??
|
|
97
|
+
const appVersion = options.targetVersion ?? 156;
|
|
98
98
|
const dbVersion = readSchemaVersion(db);
|
|
99
99
|
if (dbVersion > appVersion) return {
|
|
100
100
|
dbVersion,
|
|
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
|
|
|
19
19
|
export const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
20
20
|
|
|
21
21
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
22
|
-
export const XOPC_DB_SCHEMA_VERSION =
|
|
22
|
+
export const XOPC_DB_SCHEMA_VERSION = 156;
|
|
23
23
|
|
|
24
24
|
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
25
25
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { RealtimeEvent, RealtimeSubscriptionHandle } from '../../realtime/broker.js';
|
|
2
|
+
import type { SessionInput, SessionInputState } from '../../storage/sqlite/session-input-repository.js';
|
|
3
|
+
import type { SubmitSessionInput } from '../../gateway/service/session-input-coordinator.js';
|
|
4
|
+
export interface VoiceAgentEvent {
|
|
5
|
+
type: string;
|
|
6
|
+
payload?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface VoiceAgentTask {
|
|
9
|
+
taskId: string;
|
|
10
|
+
runId: string;
|
|
11
|
+
events: AsyncIterable<VoiceAgentEvent>;
|
|
12
|
+
}
|
|
13
|
+
export interface VoiceAgentBroker {
|
|
14
|
+
delegate(input: {
|
|
15
|
+
sessionKey: string;
|
|
16
|
+
expectedSessionId: string;
|
|
17
|
+
turnId: string;
|
|
18
|
+
text: string;
|
|
19
|
+
signal: AbortSignal;
|
|
20
|
+
}): Promise<VoiceAgentTask>;
|
|
21
|
+
cancel(taskId: string): Promise<boolean>;
|
|
22
|
+
}
|
|
23
|
+
type SubmitResult = {
|
|
24
|
+
ok: true;
|
|
25
|
+
effectiveDelivery: 'next' | 'steer';
|
|
26
|
+
state: SessionInputState;
|
|
27
|
+
} | {
|
|
28
|
+
ok: false;
|
|
29
|
+
code: string;
|
|
30
|
+
};
|
|
31
|
+
type BrokerDependencies = {
|
|
32
|
+
submit(input: SubmitSessionInput): Promise<SubmitResult>;
|
|
33
|
+
find(sessionKey: string, clientMessageId: string): SessionInput | undefined;
|
|
34
|
+
snapshot(sessionKey: string): SessionInputState;
|
|
35
|
+
currentSequence(topic: string): number;
|
|
36
|
+
subscribe(topic: string, afterSeq: number, listener: (event: RealtimeEvent) => void): RealtimeSubscriptionHandle;
|
|
37
|
+
cancelRun(runId: string): Promise<void>;
|
|
38
|
+
};
|
|
39
|
+
/** Durable voice-to-Agent boundary. Playback and socket cancellation only detach event delivery. */
|
|
40
|
+
export declare class DurableVoiceAgentBroker implements VoiceAgentBroker {
|
|
41
|
+
private readonly deps;
|
|
42
|
+
private readonly runByTask;
|
|
43
|
+
constructor(deps: BrokerDependencies);
|
|
44
|
+
delegate(input: {
|
|
45
|
+
sessionKey: string;
|
|
46
|
+
expectedSessionId: string;
|
|
47
|
+
turnId: string;
|
|
48
|
+
text: string;
|
|
49
|
+
signal: AbortSignal;
|
|
50
|
+
}): Promise<VoiceAgentTask>;
|
|
51
|
+
cancel(taskId: string): Promise<boolean>;
|
|
52
|
+
private events;
|
|
53
|
+
}
|
|
54
|
+
export {};
|