@xopcai/xopc 0.0.196 → 0.0.197
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/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-B1oxPli_.js → agent-avatar-dicebear-C5st7lt5.js} +1 -1
- package/dist/gateway/static/root/assets/agents-Baxfj44y.js +68 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-vmuJ_Z6i.js → app-management-settings-panel-S8LhoD6G.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BMlEoe-G.js → appearance-settings-D8Cd5vDP.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-0uCxKyE5.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BdE4Mati.js → archive-plugin-qL07mwnY.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CTzaQcLV.js → attachment-load-CqSobpdi.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-XyDat125.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-B25zTNxl.js → binary-plugins-DBRPyLYE.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Cdrf2awF.js → block-editor-6wG1LU7t.js} +46 -46
- package/dist/gateway/static/root/assets/{browser-settings-page-BMTmGMM6.js → browser-settings-page-CrYNMR4w.js} +4 -4
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-BsmHy0ks.js → browser-workflow-inputs-Abil4puY.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-Wx9FrbK-.js → browser-workflows-page-BEu3E0et.js} +1 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CvMcDhGf.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-9T2KXAs1.js → capability-presets-settings-panel-CHJDY-Ih.js} +2 -2
- package/dist/gateway/static/root/assets/{channels-settings-DquD4BPQ.js → channels-settings-Ds9BJbcY.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-api-BC-4ftOM.js → connectors-api-CgWjgPSI.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-NUs-Zf7F.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-BycQlU8Q.js → cron-expression-ZdDBAoqA.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-BvYqHRz0.js → dependency-picker-BGeB1jpn.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-BOb8sEhN.js → desktop-pet-CsLR4pWB.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DStgPb82.js → desktop-pet-settings-CCjT1bdo.js} +1 -1
- package/dist/gateway/static/root/assets/directory-picker-path-field-C-Te1QN3.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-p83TmZFd.js → extension-debug-page-CD73euAM.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DMQ3ovxA.js → extension-page-DAKjpNwd.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BcSKEU8s.js → extension-settings-page-BLSNdlgd.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-C-MmtCc7.js → gateway-config-api-CQrf0k3D.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-CuaRDWbg.js → gateway-settings-CvgH8IJI.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-Dm8TrfGa.js → heartbeat-settings-SPpnqbjl.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-BFoD6047.js +3 -0
- package/dist/gateway/static/root/assets/index-84ys9u-K.js +152 -0
- package/dist/gateway/static/root/assets/index-D-srnucP.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BQb06_jl.js → keyboard-shortcuts-settings-HMhxgOuD.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-D5uL2_Fd.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-DQtsxjGs.js → local-apps-page-DIWkFa3g.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-CDqIY72S.js → logs-page--6v8qq6y.js} +2 -2
- package/dist/gateway/static/root/assets/{management-settings-D7itDEHl.js → management-settings-DtEuS-kR.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-Db-KrpOQ.js → markdown-split-DvVBewS4.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CHN66qs0.js → media-plugins-YVj7NVzD.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-CJtKZM0P.js → notes-page-BDzuL2I9.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-IdjuNXvH.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-HXweXqYE.js → page-tabs-7bSEWfSX.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Dob6Oe2l.js → preview-open-alternatives-tgLbHgcV.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page--RnCc9bb.js → product-open-page-Bwx_CQht.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DnJXSuM4.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-DckZKlBI.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-CfbUHBUH.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Bg1W2__k.js → runtime-tools-settings-panel-Fe05Nus6.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-BI4rVt3u.js → schema-form-CFfyC4CB.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-BCfCh4My.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-Cbi4FvzO.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-C7rzhi7x.js → settings-form-section-gEnEYT_3.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-BS36Mjzz.js → settings-loading-skeleton-BRE_-7Da.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-BDSd7F9Y.js → settings-page-C1zxCpqB.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-CTMmZcwj.js → settings-page-layout-CRpXF_05.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BcHdpmFf.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BeCxg6eb.js → share-preview-page-DU8L68A5.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-CXL1EldF.js → shares-settings-kjTqH9yY.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-QAGpwzIM.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-CyfjEM4D.js → skills-page-lE1-YRdK.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-CnbJncdL.js → skills-page.utils-CYwFWTso.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-CAv0Yk0Y.js → system-settings-panel-CVDsiPKn.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-DsM13-cy.js +1 -0
- package/dist/gateway/static/root/assets/{typed-models-lib-DomX3Szl.js → typed-models-lib-DelyYgoc.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-BLc4gfG0.js → use-autosave-C50Mq5yQ.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-C2kQENTK.js → user-context-page-D-VEOt2A.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-BijmpPjb.js → voice-api-key-field-DYfgTe3Y.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-D7w2JFFq.js → work-discovery-overlay-DPbujsp3.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-D77opady.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BEmugHfL.js → workflow-run-setup-panel-DqIb1oBB.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-B9-PLmlX.js +5 -0
- package/dist/gateway/static/root/index.html +2 -2
- package/dist/package.js +1 -1
- package/dist/src/agent/embedded/execution-context.d.ts +2 -0
- package/dist/src/agent/embedded/execution-context.js +11 -0
- package/dist/src/agent/embedded/index.d.ts +3 -1
- package/dist/src/agent/embedded/index.js +5 -3
- package/dist/src/agent/embedded/run-turn.js +15 -9
- package/dist/src/agent/embedded/session-runner.d.ts +6 -11
- package/dist/src/agent/embedded/session-runner.js +25 -36
- package/dist/src/agent/embedded/transcript-runtime.d.ts +35 -0
- package/dist/src/agent/embedded/transcript-runtime.js +66 -0
- package/dist/src/agent/embedded/types.d.ts +3 -1
- package/dist/src/agent/service.d.ts +15 -0
- package/dist/src/agent/service.js +30 -0
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/hono/routes/home.d.ts +1 -1
- package/dist/src/gateway/hono/routes/home.js +2 -2
- package/dist/src/gateway/hono/routes/index.js +2 -0
- package/dist/src/gateway/hono/routes/projects.js +12 -1
- package/dist/src/gateway/hono/routes/side-chats.d.ts +3 -0
- package/dist/src/gateway/hono/routes/side-chats.js +173 -0
- package/dist/src/gateway/service/agent-runner.d.ts +4 -0
- package/dist/src/gateway/service/agent-runner.js +15 -1
- package/dist/src/gateway/service/run-gateway-agent.js +1 -1
- package/dist/src/gateway/service.d.ts +4 -0
- package/dist/src/gateway/service.js +33 -7
- package/dist/src/gateway/side-chat/context-snapshot.d.ts +11 -0
- package/dist/src/gateway/side-chat/context-snapshot.js +108 -0
- package/dist/src/gateway/side-chat/index.d.ts +5 -0
- package/dist/src/gateway/side-chat/index.js +4 -0
- package/dist/src/gateway/side-chat/manager.d.ts +45 -0
- package/dist/src/gateway/side-chat/manager.js +198 -0
- package/dist/src/gateway/side-chat/run-service.d.ts +22 -0
- package/dist/src/gateway/side-chat/run-service.js +110 -0
- package/dist/src/gateway/side-chat/types.d.ts +61 -0
- package/dist/src/gateway/side-chat/types.js +1 -0
- package/dist/src/routing/session-key-utils.d.ts +0 -1
- package/dist/src/routing/session-key-utils.js +1 -6
- package/dist/src/routing/session-key.js +2 -2
- package/dist/src/tasks/home-query-service.d.ts +24 -0
- package/dist/src/tasks/home-query-service.js +284 -5
- package/dist/src/tasks/index.js +3 -3
- package/dist/src/tasks/project-operating-view-service.d.ts +2 -1
- package/dist/src/tasks/project-operating-view-service.js +27 -4
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/agents-VoFNMGL3.js +0 -68
- package/dist/gateway/static/root/assets/apps-page-CsNB6mv_.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-CW1YWgiX.js +0 -6
- package/dist/gateway/static/root/assets/capabilities-settings-panel-C5l85__e.js +0 -7
- package/dist/gateway/static/root/assets/connectors-page-7zUxVHQg.js +0 -2
- package/dist/gateway/static/root/assets/directory-picker-path-field-DUUr9sq0.js +0 -1
- package/dist/gateway/static/root/assets/home-page-BYhDbUvI.js +0 -3
- package/dist/gateway/static/root/assets/index-BzPwnXho.js +0 -150
- package/dist/gateway/static/root/assets/index-CFFYvilx.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-CHk4x0kR.js +0 -2
- package/dist/gateway/static/root/assets/notes-workbench-epHGeKd5.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-BxOD5-zj.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-D-9AhrH5.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CSUNXLKM.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BxOUBMca.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DAvTIbgw.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-D1v-2Ci-.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BxwkKgVw.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-DGTVJs_N.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-XtoPgPUS.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-D_K2xOWq.js +0 -5
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { validateWebchatContent } from "../../chat-limits.js";
|
|
2
|
+
import { validateSideChatSelections } from "../../side-chat/context-snapshot.js";
|
|
3
|
+
import { SideChatError, parseThinkingLevel } from "../../side-chat/manager.js";
|
|
4
|
+
import "../../side-chat/index.js";
|
|
5
|
+
import { createGatewayRouteLogger, logRouteError } from "../lib/route-logger.js";
|
|
6
|
+
//#region src/gateway/hono/routes/side-chats.ts
|
|
7
|
+
const CLIENT_HEADER = "x-xopc-client-instance-id";
|
|
8
|
+
const log = createGatewayRouteLogger("SideChats");
|
|
9
|
+
function registerSideChatRoutes(authenticated, deps) {
|
|
10
|
+
const { service } = deps;
|
|
11
|
+
authenticated.post("/api/sessions/:parentSessionKey/side-chats", deps.chatRateLimitMiddleware, async (c) => {
|
|
12
|
+
try {
|
|
13
|
+
const body = await c.req.json().catch(() => ({}));
|
|
14
|
+
const clientInstanceId = readClientInstanceId(c, body.clientInstanceId);
|
|
15
|
+
if (body.modelRef !== void 0 && typeof body.modelRef !== "string") throw new SideChatError("modelRef must be a string", "INVALID_REQUEST");
|
|
16
|
+
const modelRef = typeof body.modelRef === "string" ? body.modelRef : void 0;
|
|
17
|
+
let selections;
|
|
18
|
+
try {
|
|
19
|
+
selections = validateSideChatSelections(body.selections);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
throw new SideChatError(error instanceof Error ? error.message : "Invalid selections", "INVALID_REQUEST");
|
|
22
|
+
}
|
|
23
|
+
const sideChat = await service.sideChats.create({
|
|
24
|
+
parentSessionKey: c.req.param("parentSessionKey"),
|
|
25
|
+
clientInstanceId,
|
|
26
|
+
selections,
|
|
27
|
+
config: {
|
|
28
|
+
modelRef,
|
|
29
|
+
thinkingLevel: parseThinkingLevel(body.thinkingLevel)
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return c.json({
|
|
33
|
+
ok: true,
|
|
34
|
+
sideChat
|
|
35
|
+
}, 201);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return respondSideChatError(c, error);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
authenticated.get("/api/side-chats/:sideChatId", (c) => {
|
|
41
|
+
try {
|
|
42
|
+
const sideChat = service.sideChats.get(c.req.param("sideChatId"), readClientInstanceId(c));
|
|
43
|
+
return c.json({
|
|
44
|
+
ok: true,
|
|
45
|
+
sideChat
|
|
46
|
+
});
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return respondSideChatError(c, error);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
authenticated.get("/api/side-chats/:sideChatId/messages", (c) => {
|
|
52
|
+
try {
|
|
53
|
+
const messages = service.sideChats.getMessages(c.req.param("sideChatId"), readClientInstanceId(c));
|
|
54
|
+
return c.json({
|
|
55
|
+
ok: true,
|
|
56
|
+
messages
|
|
57
|
+
});
|
|
58
|
+
} catch (error) {
|
|
59
|
+
return respondSideChatError(c, error);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
authenticated.patch("/api/side-chats/:sideChatId/config", async (c) => {
|
|
63
|
+
try {
|
|
64
|
+
const body = await c.req.json().catch(() => ({}));
|
|
65
|
+
if (body.modelRef !== void 0 && typeof body.modelRef !== "string") throw new SideChatError("modelRef must be a string", "INVALID_REQUEST");
|
|
66
|
+
const modelRef = typeof body.modelRef === "string" ? body.modelRef : void 0;
|
|
67
|
+
const sideChat = service.sideChats.updateConfig(c.req.param("sideChatId"), readClientInstanceId(c, body.clientInstanceId), {
|
|
68
|
+
modelRef,
|
|
69
|
+
thinkingLevel: parseThinkingLevel(body.thinkingLevel)
|
|
70
|
+
});
|
|
71
|
+
return c.json({
|
|
72
|
+
ok: true,
|
|
73
|
+
sideChat
|
|
74
|
+
});
|
|
75
|
+
} catch (error) {
|
|
76
|
+
return respondSideChatError(c, error);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
authenticated.post("/api/side-chats/:sideChatId/heartbeat", (c) => {
|
|
80
|
+
try {
|
|
81
|
+
const sideChat = service.sideChats.heartbeat(c.req.param("sideChatId"), readClientInstanceId(c));
|
|
82
|
+
return c.json({
|
|
83
|
+
ok: true,
|
|
84
|
+
sideChat
|
|
85
|
+
});
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return respondSideChatError(c, error);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
authenticated.post("/api/side-chats/:sideChatId/inputs", deps.chatRateLimitMiddleware, async (c) => {
|
|
91
|
+
try {
|
|
92
|
+
const body = await c.req.json().catch(() => ({}));
|
|
93
|
+
const content = typeof body.content === "string" ? body.content : "";
|
|
94
|
+
const contentError = validateWebchatContent(content);
|
|
95
|
+
if (contentError) throw new SideChatError(contentError, "INVALID_REQUEST");
|
|
96
|
+
const result = service.sideChatRuns.submit(c.req.param("sideChatId"), readClientInstanceId(c, body.clientInstanceId), content);
|
|
97
|
+
return c.json({
|
|
98
|
+
ok: true,
|
|
99
|
+
payload: result
|
|
100
|
+
}, 202);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
return respondSideChatError(c, error);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
authenticated.post("/api/side-chats/:sideChatId/abort", deps.chatRateLimitMiddleware, async (c) => {
|
|
106
|
+
try {
|
|
107
|
+
const body = await c.req.json().catch(() => ({}));
|
|
108
|
+
const aborted = await service.sideChatRuns.abort(c.req.param("sideChatId"), readClientInstanceId(c, body.clientInstanceId), typeof body.runId === "string" ? body.runId : void 0);
|
|
109
|
+
return c.json({
|
|
110
|
+
ok: true,
|
|
111
|
+
payload: { aborted }
|
|
112
|
+
});
|
|
113
|
+
} catch (error) {
|
|
114
|
+
return respondSideChatError(c, error);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
authenticated.post("/api/side-chats/:sideChatId/clarify/:requestId", deps.chatRateLimitMiddleware, async (c) => {
|
|
118
|
+
try {
|
|
119
|
+
const body = await c.req.json().catch(() => ({}));
|
|
120
|
+
const answer = body.skip === true ? "" : typeof body.answer === "string" ? body.answer.trim() : "";
|
|
121
|
+
if (body.skip !== true && !answer) throw new SideChatError("answer is required", "INVALID_REQUEST");
|
|
122
|
+
if (!service.sideChatRuns.submitClarification(c.req.param("sideChatId"), readClientInstanceId(c, body.clientInstanceId), c.req.param("requestId"), answer)) throw new SideChatError("Clarification request not found", "NOT_FOUND");
|
|
123
|
+
return c.json({ ok: true });
|
|
124
|
+
} catch (error) {
|
|
125
|
+
return respondSideChatError(c, error);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
authenticated.delete("/api/side-chats/:sideChatId", async (c) => {
|
|
129
|
+
try {
|
|
130
|
+
return await service.sideChatRuns.dispose(c.req.param("sideChatId"), readClientInstanceId(c)) ? c.json({ ok: true }) : c.json({
|
|
131
|
+
ok: false,
|
|
132
|
+
error: "Side chat not found",
|
|
133
|
+
code: "NOT_FOUND"
|
|
134
|
+
}, 404);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
return respondSideChatError(c, error);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
authenticated.delete("/api/side-chats", async (c) => {
|
|
140
|
+
try {
|
|
141
|
+
const removed = await service.sideChats.disposeClient(readClientInstanceId(c, c.req.query("clientInstanceId")));
|
|
142
|
+
return c.json({
|
|
143
|
+
ok: true,
|
|
144
|
+
removed
|
|
145
|
+
});
|
|
146
|
+
} catch (error) {
|
|
147
|
+
return respondSideChatError(c, error);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function readClientInstanceId(c, fallback) {
|
|
152
|
+
const value = c.req.header(CLIENT_HEADER) || (typeof fallback === "string" ? fallback : "");
|
|
153
|
+
if (!value.trim()) throw new SideChatError("clientInstanceId is required", "INVALID_REQUEST");
|
|
154
|
+
return value.trim();
|
|
155
|
+
}
|
|
156
|
+
function respondSideChatError(c, error) {
|
|
157
|
+
if (!(error instanceof SideChatError)) {
|
|
158
|
+
logRouteError(log, c, error, "Side chat request failed");
|
|
159
|
+
return c.json({
|
|
160
|
+
ok: false,
|
|
161
|
+
error: "Side chat request failed",
|
|
162
|
+
code: "INTERNAL_ERROR"
|
|
163
|
+
}, 500);
|
|
164
|
+
}
|
|
165
|
+
const status = error.code === "NOT_FOUND" ? 404 : error.code === "CONFLICT" ? 409 : error.code === "LIMIT_REACHED" ? 429 : 400;
|
|
166
|
+
return c.json({
|
|
167
|
+
ok: false,
|
|
168
|
+
error: error.message,
|
|
169
|
+
code: error.code
|
|
170
|
+
}, status);
|
|
171
|
+
}
|
|
172
|
+
//#endregion
|
|
173
|
+
export { registerSideChatRoutes };
|
|
@@ -49,6 +49,7 @@ export declare class GatewayAgentRunner {
|
|
|
49
49
|
private readonly clarifyBridge;
|
|
50
50
|
/** Maps webchat session key → active `runId` for `clarify` tool routing. */
|
|
51
51
|
private readonly activeWebchatRunBySession;
|
|
52
|
+
private readonly externalStreamBySession;
|
|
52
53
|
readonly inputs: SessionInputCoordinator;
|
|
53
54
|
constructor(opts: GatewayAgentRunnerOptions);
|
|
54
55
|
/** True when a webchat agent run is currently in-flight for `sessionKey`. */
|
|
@@ -57,6 +58,9 @@ export declare class GatewayAgentRunner {
|
|
|
57
58
|
getClarifyBridge(): ClarifyBridge;
|
|
58
59
|
/** Called from `GatewayService.stop()` so the bridge gets cleaned up. */
|
|
59
60
|
disposeClarifyBridge(): void;
|
|
61
|
+
registerExternalWebchatRun(sessionKey: string, runId: string, publish: (event: ClarifyStreamEvent) => void): void;
|
|
62
|
+
unregisterExternalWebchatRun(sessionKey: string, runId: string): void;
|
|
63
|
+
cancelClarificationForRun(runId: string): void;
|
|
60
64
|
runAgent(message: string, channel: string, chatId: string, origin: TurnOrigin, attachments?: UserTurnAttachment[], thinking?: string, runOptions?: {
|
|
61
65
|
signal?: AbortSignal;
|
|
62
66
|
runId?: string;
|
|
@@ -16,6 +16,7 @@ var GatewayAgentRunner = class {
|
|
|
16
16
|
clarifyBridge = new ClarifyBridge();
|
|
17
17
|
/** Maps webchat session key → active `runId` for `clarify` tool routing. */
|
|
18
18
|
activeWebchatRunBySession = /* @__PURE__ */ new Map();
|
|
19
|
+
externalStreamBySession = /* @__PURE__ */ new Map();
|
|
19
20
|
inputs;
|
|
20
21
|
constructor(opts) {
|
|
21
22
|
this.opts = opts;
|
|
@@ -63,6 +64,19 @@ var GatewayAgentRunner = class {
|
|
|
63
64
|
disposeClarifyBridge() {
|
|
64
65
|
this.clarifyBridge.dispose();
|
|
65
66
|
}
|
|
67
|
+
registerExternalWebchatRun(sessionKey, runId, publish) {
|
|
68
|
+
this.activeWebchatRunBySession.set(sessionKey, runId);
|
|
69
|
+
this.externalStreamBySession.set(sessionKey, publish);
|
|
70
|
+
}
|
|
71
|
+
unregisterExternalWebchatRun(sessionKey, runId) {
|
|
72
|
+
if (this.activeWebchatRunBySession.get(sessionKey) === runId) {
|
|
73
|
+
this.activeWebchatRunBySession.delete(sessionKey);
|
|
74
|
+
this.externalStreamBySession.delete(sessionKey);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
cancelClarificationForRun(runId) {
|
|
78
|
+
this.clarifyBridge.cancelForRun(runId);
|
|
79
|
+
}
|
|
66
80
|
async *runAgent(message, channel, chatId, origin, attachments, thinking, runOptions) {
|
|
67
81
|
const trackedRunId = runOptions?.runId;
|
|
68
82
|
if (trackedRunId) {
|
|
@@ -184,7 +198,7 @@ var GatewayAgentRunner = class {
|
|
|
184
198
|
async requestClarification(opts) {
|
|
185
199
|
const { sessionKey, request, publishStreamFor } = opts;
|
|
186
200
|
const runId = this.activeWebchatRunBySession.get(sessionKey);
|
|
187
|
-
const publishStream = runId ? publishStreamFor(runId) : void 0;
|
|
201
|
+
const publishStream = this.externalStreamBySession.get(sessionKey) ?? (runId ? publishStreamFor(runId) : void 0);
|
|
188
202
|
const deliver = ((await this.opts.sessionIndex.getSessionMetadata(sessionKey).catch(() => null))?.routing)?.source === "telegram" ? async (ctx) => {
|
|
189
203
|
await this.deliverTelegramClarify(ctx);
|
|
190
204
|
} : void 0;
|
|
@@ -9,9 +9,9 @@ import { TaskRunCoordinator } from "../../tasks/task-run-coordinator.js";
|
|
|
9
9
|
import { formatAgentRunErrorForClient } from "../../agent/client-error-format.js";
|
|
10
10
|
import { prependEnvelopeTimestamp } from "../../channels/envelope-timestamp.js";
|
|
11
11
|
import "../chat-limits.js";
|
|
12
|
+
import { ChatStreamMapper } from "../chat-stream/mapper.js";
|
|
12
13
|
import { resolveWebchatSessionKey } from "../resolve-webchat-session-key.js";
|
|
13
14
|
import { recordExplicitRelationshipFollowUp } from "../../user-context/relationship-continuity.js";
|
|
14
|
-
import { ChatStreamMapper } from "../chat-stream/mapper.js";
|
|
15
15
|
import { coalesceThinkingDeltas } from "../chat-stream/thinking-delta-coalescer.js";
|
|
16
16
|
import crypto from "crypto";
|
|
17
17
|
//#region src/gateway/service/run-gateway-agent.ts
|
|
@@ -6,6 +6,7 @@ import { NotesService } from '../notes/index.js';
|
|
|
6
6
|
import { WorkflowRunService } from '../workflows/service/workflow-run-service.js';
|
|
7
7
|
import { ExtensionLoader } from '../extensions/index.js';
|
|
8
8
|
import { SessionIndex } from '../session/index.js';
|
|
9
|
+
import { EphemeralSideChatManager, SideChatRunService } from './side-chat/index.js';
|
|
9
10
|
import type { Config } from '../config/schema.js';
|
|
10
11
|
import { type ResolvedGatewayAuth } from './auth.js';
|
|
11
12
|
import { ModelCatalogSyncService } from '../providers/model-catalog-sync-service.js';
|
|
@@ -79,6 +80,9 @@ export declare class GatewayService {
|
|
|
79
80
|
* `activeWebchatRunBySession` + `runAbortControllers` maps.
|
|
80
81
|
*/
|
|
81
82
|
readonly agentRunner: GatewayAgentRunner;
|
|
83
|
+
/** Process-local, non-persistent side conversations forked from durable sessions. */
|
|
84
|
+
readonly sideChats: EphemeralSideChatManager;
|
|
85
|
+
readonly sideChatRuns: SideChatRunService;
|
|
82
86
|
/**
|
|
83
87
|
* Session CRUD / search / compaction / tag-archive-pin / stats — the gateway
|
|
84
88
|
* REST surface for sessions. Routes should depend on this narrow service
|
|
@@ -44,6 +44,7 @@ import { SessionIndex } from "../session/manager.js";
|
|
|
44
44
|
import "../session/index.js";
|
|
45
45
|
import { ExtensionLoader } from "../extensions/loader.js";
|
|
46
46
|
import "../extensions/index.js";
|
|
47
|
+
import { getEmbeddedExecutionSession } from "../agent/embedded/execution-context.js";
|
|
47
48
|
import { MessageBus, MessageBusShutdownError } from "../infra/bus/queue.js";
|
|
48
49
|
import "../infra/bus/index.js";
|
|
49
50
|
import { AgentService } from "../agent/service.js";
|
|
@@ -77,6 +78,9 @@ import { WorkflowRunService } from "../workflows/service/workflow-run-service.js
|
|
|
77
78
|
import { WorkflowSessionBridge } from "../workflows/service/workflow-session-bridge.js";
|
|
78
79
|
import { HeartbeatService, heartbeatRunnerConfigFromConfig } from "./heartbeat/service.js";
|
|
79
80
|
import "./heartbeat/index.js";
|
|
81
|
+
import { EphemeralSideChatManager } from "./side-chat/manager.js";
|
|
82
|
+
import { SideChatRunService } from "./side-chat/run-service.js";
|
|
83
|
+
import "./side-chat/index.js";
|
|
80
84
|
import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
|
|
81
85
|
import { getExposureManager } from "../remote-access/exposure-manager.js";
|
|
82
86
|
import { assertGatewayAuthNotKnownWeak } from "./security/known-weak-secrets.js";
|
|
@@ -190,6 +194,9 @@ var GatewayService = class {
|
|
|
190
194
|
* `activeWebchatRunBySession` + `runAbortControllers` maps.
|
|
191
195
|
*/
|
|
192
196
|
agentRunner;
|
|
197
|
+
/** Process-local, non-persistent side conversations forked from durable sessions. */
|
|
198
|
+
sideChats;
|
|
199
|
+
sideChatRuns;
|
|
193
200
|
/**
|
|
194
201
|
* Session CRUD / search / compaction / tag-archive-pin / stats — the gateway
|
|
195
202
|
* REST surface for sessions. Routes should depend on this narrow service
|
|
@@ -363,6 +370,21 @@ var GatewayService = class {
|
|
|
363
370
|
},
|
|
364
371
|
completeRealtimeTopic: (topic) => this.realtime.completeTopic(topic)
|
|
365
372
|
});
|
|
373
|
+
let sideChatRuns;
|
|
374
|
+
this.sideChats = new EphemeralSideChatManager({
|
|
375
|
+
getParentMetadata: (sessionKey) => this.sessionIndex.getSessionMetadata(sessionKey),
|
|
376
|
+
loadParentMessages: (sessionKey) => this.sessionIndex.getStore().load(sessionKey),
|
|
377
|
+
getDefaultModelRef: (sessionKey) => this.ensureAgentService().getModelForSession(sessionKey),
|
|
378
|
+
getWorkspacePath: (metadata) => metadata.cwd || this.currentWorkspacePath,
|
|
379
|
+
onBeforeDispose: (sideChatId, clientInstanceId) => sideChatRuns?.abort(sideChatId, clientInstanceId).then(() => void 0)
|
|
380
|
+
});
|
|
381
|
+
this.sideChatRuns = sideChatRuns = new SideChatRunService({
|
|
382
|
+
manager: this.sideChats,
|
|
383
|
+
getAgentService: () => this.ensureAgentService(),
|
|
384
|
+
agentRunner: this.agentRunner,
|
|
385
|
+
publishRealtime: (topic, event, data) => this.realtime.broker.publish(topic, event, data),
|
|
386
|
+
completeRealtimeTopic: (topic) => this.realtime.completeTopic(topic)
|
|
387
|
+
});
|
|
366
388
|
this.sessions = new GatewaySessionsApi({
|
|
367
389
|
sessionIndex: this.sessionIndex,
|
|
368
390
|
getAgentService: () => this.ensureAgentService(),
|
|
@@ -452,13 +474,16 @@ var GatewayService = class {
|
|
|
452
474
|
}
|
|
453
475
|
return null;
|
|
454
476
|
},
|
|
455
|
-
gatewayClarify: { requestClarification: (sessionKey, request) =>
|
|
456
|
-
sessionKey
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
477
|
+
gatewayClarify: { requestClarification: (sessionKey, request) => {
|
|
478
|
+
const executionSessionKey = getEmbeddedExecutionSession() ?? sessionKey;
|
|
479
|
+
return this.agentRunner.requestClarification({
|
|
480
|
+
sessionKey: executionSessionKey,
|
|
481
|
+
request,
|
|
482
|
+
publishStreamFor: (_runId) => (event) => {
|
|
483
|
+
this._agentService.turnDispatcher.enqueueWebchatStreamEvent(executionSessionKey, event);
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
} }
|
|
462
487
|
});
|
|
463
488
|
this._agentService.setChannelManager(this.channelManager);
|
|
464
489
|
this.channelManager.setSessionModelHooks({
|
|
@@ -988,6 +1013,7 @@ var GatewayService = class {
|
|
|
988
1013
|
log.debug("Stopping gateway service...");
|
|
989
1014
|
this.readiness.markStarting();
|
|
990
1015
|
this.endpointTools.close();
|
|
1016
|
+
await this.sideChats.disposeAll();
|
|
991
1017
|
this.realtime.close();
|
|
992
1018
|
await this.proactiveWorker.stop();
|
|
993
1019
|
await this.discussionWorker.stop();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AgentMessage } from '@earendil-works/pi-agent-core';
|
|
2
|
+
import type { SideChatContextSnapshot, SideChatSelection } from './types.js';
|
|
3
|
+
export declare function validateSideChatSelections(value: unknown): SideChatSelection[];
|
|
4
|
+
export declare function createSideChatContextSnapshot(params: {
|
|
5
|
+
parentSessionKey: string;
|
|
6
|
+
parentSessionId: string;
|
|
7
|
+
parentMessages: readonly AgentMessage[];
|
|
8
|
+
selections: readonly SideChatSelection[];
|
|
9
|
+
createdAt: string;
|
|
10
|
+
}): SideChatContextSnapshot;
|
|
11
|
+
export declare function formatSideChatSelections(selections: readonly SideChatSelection[]): string | null;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
//#region src/gateway/side-chat/context-snapshot.ts
|
|
3
|
+
const MAX_SELECTIONS = 20;
|
|
4
|
+
const MAX_SELECTION_CHARS = 32e3;
|
|
5
|
+
const MAX_TOTAL_SELECTION_CHARS = 128e3;
|
|
6
|
+
function selectionText(selection) {
|
|
7
|
+
switch (selection.type) {
|
|
8
|
+
case "message": return selection.content;
|
|
9
|
+
case "text": return selection.text;
|
|
10
|
+
case "file-range": return selection.text;
|
|
11
|
+
case "diff": return selection.diff;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function validateSideChatSelections(value) {
|
|
15
|
+
if (value === void 0) return [];
|
|
16
|
+
if (!Array.isArray(value)) throw new Error("selections must be an array");
|
|
17
|
+
if (value.length > MAX_SELECTIONS) throw new Error(`selections cannot exceed ${MAX_SELECTIONS} items`);
|
|
18
|
+
let totalChars = 0;
|
|
19
|
+
const selections = value.map((candidate, index) => {
|
|
20
|
+
if (!candidate || typeof candidate !== "object") throw new Error(`selection ${index} must be an object`);
|
|
21
|
+
const selection = candidate;
|
|
22
|
+
const id = typeof selection.id === "string" ? selection.id.trim() : "";
|
|
23
|
+
const type = selection.type;
|
|
24
|
+
if (!id) throw new Error(`selection ${index} requires id`);
|
|
25
|
+
let normalized;
|
|
26
|
+
if (type === "message") normalized = {
|
|
27
|
+
id,
|
|
28
|
+
type,
|
|
29
|
+
messageId: requiredString(selection.messageId, `selection ${index} messageId`),
|
|
30
|
+
role: requiredString(selection.role, `selection ${index} role`),
|
|
31
|
+
content: requiredString(selection.content, `selection ${index} content`),
|
|
32
|
+
label: optionalString(selection.label)
|
|
33
|
+
};
|
|
34
|
+
else if (type === "text") normalized = {
|
|
35
|
+
id,
|
|
36
|
+
type,
|
|
37
|
+
text: requiredString(selection.text, `selection ${index} text`),
|
|
38
|
+
sourceMessageId: optionalString(selection.sourceMessageId),
|
|
39
|
+
label: optionalString(selection.label)
|
|
40
|
+
};
|
|
41
|
+
else if (type === "file-range") {
|
|
42
|
+
const startLine = positiveInteger(selection.startLine, `selection ${index} startLine`);
|
|
43
|
+
const endLine = positiveInteger(selection.endLine, `selection ${index} endLine`);
|
|
44
|
+
if (endLine < startLine) throw new Error(`selection ${index} endLine must be >= startLine`);
|
|
45
|
+
normalized = {
|
|
46
|
+
id,
|
|
47
|
+
type,
|
|
48
|
+
path: requiredString(selection.path, `selection ${index} path`),
|
|
49
|
+
startLine,
|
|
50
|
+
endLine,
|
|
51
|
+
text: requiredString(selection.text, `selection ${index} text`),
|
|
52
|
+
contentHash: optionalString(selection.contentHash),
|
|
53
|
+
label: optionalString(selection.label)
|
|
54
|
+
};
|
|
55
|
+
} else if (type === "diff") normalized = {
|
|
56
|
+
id,
|
|
57
|
+
type,
|
|
58
|
+
diff: requiredString(selection.diff, `selection ${index} diff`),
|
|
59
|
+
path: optionalString(selection.path),
|
|
60
|
+
label: optionalString(selection.label)
|
|
61
|
+
};
|
|
62
|
+
else throw new Error(`selection ${index} has unsupported type`);
|
|
63
|
+
const chars = selectionText(normalized).length;
|
|
64
|
+
if (chars > MAX_SELECTION_CHARS) throw new Error(`selection ${index} exceeds ${MAX_SELECTION_CHARS} characters`);
|
|
65
|
+
totalChars += chars;
|
|
66
|
+
return normalized;
|
|
67
|
+
});
|
|
68
|
+
if (totalChars > MAX_TOTAL_SELECTION_CHARS) throw new Error(`selection content exceeds ${MAX_TOTAL_SELECTION_CHARS} characters`);
|
|
69
|
+
return selections;
|
|
70
|
+
}
|
|
71
|
+
function createSideChatContextSnapshot(params) {
|
|
72
|
+
const selections = structuredClone(params.selections);
|
|
73
|
+
const digest = createHash("sha256").update(JSON.stringify({
|
|
74
|
+
messages: params.parentMessages,
|
|
75
|
+
selections
|
|
76
|
+
})).digest("hex");
|
|
77
|
+
return {
|
|
78
|
+
parentSessionKey: params.parentSessionKey,
|
|
79
|
+
parentSessionId: params.parentSessionId,
|
|
80
|
+
parentMessageCount: params.parentMessages.length,
|
|
81
|
+
createdAt: params.createdAt,
|
|
82
|
+
selections,
|
|
83
|
+
contentHash: digest
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function formatSideChatSelections(selections) {
|
|
87
|
+
if (selections.length === 0) return null;
|
|
88
|
+
return `The user attached the following immutable context snapshot to this side chat:\n\n${selections.map((selection, index) => {
|
|
89
|
+
const title = selection.label || `${selection.type} ${index + 1}`;
|
|
90
|
+
if (selection.type === "file-range") return `### ${title}\nSource: ${selection.path}:${selection.startLine}-${selection.endLine}\n\n${selection.text}`;
|
|
91
|
+
if (selection.type === "message") return `### ${title}\nSource message: ${selection.messageId} (${selection.role})\n\n${selection.content}`;
|
|
92
|
+
if (selection.type === "diff") return `### ${title}${selection.path ? `\nSource: ${selection.path}` : ""}\n\n${selection.diff}`;
|
|
93
|
+
return `### ${title}${selection.sourceMessageId ? `\nSource message: ${selection.sourceMessageId}` : ""}\n\n${selection.text}`;
|
|
94
|
+
}).join("\n\n")}`;
|
|
95
|
+
}
|
|
96
|
+
function requiredString(value, label) {
|
|
97
|
+
if (typeof value !== "string" || !value.trim()) throw new Error(`${label} is required`);
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
function optionalString(value) {
|
|
101
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
102
|
+
}
|
|
103
|
+
function positiveInteger(value, label) {
|
|
104
|
+
if (!Number.isInteger(value) || Number(value) < 1) throw new Error(`${label} must be a positive integer`);
|
|
105
|
+
return Number(value);
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
export { createSideChatContextSnapshot, formatSideChatSelections, validateSideChatSelections };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { EphemeralSideChatManager, SideChatError, parseThinkingLevel } from './manager.js';
|
|
2
|
+
export type { EphemeralSideChatManagerOptions } from './manager.js';
|
|
3
|
+
export { validateSideChatSelections } from './context-snapshot.js';
|
|
4
|
+
export { SideChatRunService } from './run-service.js';
|
|
5
|
+
export type { CreateSideChatInput, SideChatConfig, SideChatContextSnapshot, SideChatSelection, SideChatStatus, SideChatView, } from './types.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { validateSideChatSelections } from "./context-snapshot.js";
|
|
2
|
+
import { EphemeralSideChatManager, SideChatError, parseThinkingLevel } from "./manager.js";
|
|
3
|
+
import { SideChatRunService } from "./run-service.js";
|
|
4
|
+
export { EphemeralSideChatManager, SideChatError, SideChatRunService, parseThinkingLevel, validateSideChatSelections };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { AgentMessage, ThinkingLevel } from '@earendil-works/pi-agent-core';
|
|
2
|
+
import { InMemoryTranscriptRuntime } from '../../agent/embedded/transcript-runtime.js';
|
|
3
|
+
import type { SessionMetadata } from '../../session/types.js';
|
|
4
|
+
import type { CreateSideChatInput, SideChatConfig, SideChatStatus, SideChatView } from './types.js';
|
|
5
|
+
export declare class SideChatError extends Error {
|
|
6
|
+
readonly code: 'INVALID_REQUEST' | 'NOT_FOUND' | 'LIMIT_REACHED' | 'CONFLICT';
|
|
7
|
+
constructor(message: string, code: 'INVALID_REQUEST' | 'NOT_FOUND' | 'LIMIT_REACHED' | 'CONFLICT');
|
|
8
|
+
}
|
|
9
|
+
export interface EphemeralSideChatManagerOptions {
|
|
10
|
+
getParentMetadata: (sessionKey: string) => Promise<SessionMetadata | null>;
|
|
11
|
+
loadParentMessages: (sessionKey: string) => Promise<AgentMessage[]>;
|
|
12
|
+
getDefaultModelRef: (sessionKey: string) => string;
|
|
13
|
+
getWorkspacePath: (metadata: SessionMetadata) => string;
|
|
14
|
+
idleTtlMs?: number;
|
|
15
|
+
maxPerClient?: number;
|
|
16
|
+
maxTotal?: number;
|
|
17
|
+
now?: () => number;
|
|
18
|
+
startSweepTimer?: boolean;
|
|
19
|
+
onBeforeDispose?: (sideChatId: string, clientInstanceId: string) => void | Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export declare class EphemeralSideChatManager {
|
|
22
|
+
private readonly options;
|
|
23
|
+
private readonly entries;
|
|
24
|
+
private readonly now;
|
|
25
|
+
private readonly idleTtlMs;
|
|
26
|
+
private readonly maxPerClient;
|
|
27
|
+
private readonly maxTotal;
|
|
28
|
+
private readonly sweepTimer;
|
|
29
|
+
constructor(options: EphemeralSideChatManagerOptions);
|
|
30
|
+
create(input: CreateSideChatInput): Promise<SideChatView>;
|
|
31
|
+
get(id: string, clientInstanceId: string): SideChatView;
|
|
32
|
+
getRuntime(id: string, clientInstanceId: string): InMemoryTranscriptRuntime;
|
|
33
|
+
getMessages(id: string, clientInstanceId: string): AgentMessage[];
|
|
34
|
+
updateConfig(id: string, clientInstanceId: string, patch: Partial<SideChatConfig>): SideChatView;
|
|
35
|
+
heartbeat(id: string, clientInstanceId: string): SideChatView;
|
|
36
|
+
setStatus(id: string, clientInstanceId: string, status: SideChatStatus): SideChatView;
|
|
37
|
+
dispose(id: string, clientInstanceId: string): Promise<boolean>;
|
|
38
|
+
disposeClient(clientInstanceId: string): Promise<number>;
|
|
39
|
+
sweepExpired(at?: number): Promise<number>;
|
|
40
|
+
disposeAll(): Promise<void>;
|
|
41
|
+
private requireEntry;
|
|
42
|
+
private touchEntry;
|
|
43
|
+
private runBeforeDispose;
|
|
44
|
+
}
|
|
45
|
+
export declare function parseThinkingLevel(value: unknown): ThinkingLevel | undefined;
|