@memo-code/memo 0.8.8 → 0.8.10
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/README.md +1 -0
- package/dist/web/server/main.cjs +286 -184
- package/dist/web/ui/assets/{_baseUniq-kMerwpPq.js → _baseUniq-DltOgNCU.js} +1 -1
- package/dist/web/ui/assets/{arc-BulUmzON.js → arc-CsVqK9Lb.js} +1 -1
- package/dist/web/ui/assets/{architectureDiagram-VXUJARFQ-CkXEUKP9.js → architectureDiagram-VXUJARFQ-BkwnFF8Y.js} +1 -1
- package/dist/web/ui/assets/{blockDiagram-VD42YOAC-DXcW7NDi.js → blockDiagram-VD42YOAC-CA94VAjC.js} +1 -1
- package/dist/web/ui/assets/{c4Diagram-YG6GDRKO-QrajWDN7.js → c4Diagram-YG6GDRKO-C0WsU_nq.js} +1 -1
- package/dist/web/ui/assets/channel-CM-YZjf5.js +1 -0
- package/dist/web/ui/assets/{chunk-4BX2VUAB-CzB06K-m.js → chunk-4BX2VUAB-DglUTwZW.js} +1 -1
- package/dist/web/ui/assets/{chunk-55IACEB6-e5LXEkOB.js → chunk-55IACEB6-DOOGSRjL.js} +1 -1
- package/dist/web/ui/assets/{chunk-B4BG7PRW-YVg5pH4D.js → chunk-B4BG7PRW-w6hF0Zcb.js} +1 -1
- package/dist/web/ui/assets/{chunk-DI55MBZ5-Carl7-xm.js → chunk-DI55MBZ5-C0Vb_bLp.js} +1 -1
- package/dist/web/ui/assets/{chunk-FMBD7UC4-06dN5sRQ.js → chunk-FMBD7UC4-Ctx35DPt.js} +1 -1
- package/dist/web/ui/assets/{chunk-QN33PNHL-Cl3zdZ7K.js → chunk-QN33PNHL-DtVZR3nr.js} +1 -1
- package/dist/web/ui/assets/{chunk-QZHKN3VN-CDOQBeOx.js → chunk-QZHKN3VN-Ch_jdCsH.js} +1 -1
- package/dist/web/ui/assets/{chunk-TZMSLE5B-DWeaVk_X.js → chunk-TZMSLE5B-BePFLhiS.js} +1 -1
- package/dist/web/ui/assets/classDiagram-2ON5EDUG-5ACEbCYo.js +1 -0
- package/dist/web/ui/assets/classDiagram-v2-WZHVMYZB-5ACEbCYo.js +1 -0
- package/dist/web/ui/assets/clone-DIMUORAQ.js +1 -0
- package/dist/web/ui/assets/{code-block-OCS4YCEC-DmdcLUqO.js → code-block-OCS4YCEC-B7AH2kqV.js} +1 -1
- package/dist/web/ui/assets/{cose-bilkent-S5V4N54A-CDHjR7aY.js → cose-bilkent-S5V4N54A-BBRhnVZA.js} +1 -1
- package/dist/web/ui/assets/{dagre-6UL2VRFP-BvAH8ysH.js → dagre-6UL2VRFP-B6v_Z71G.js} +1 -1
- package/dist/web/ui/assets/{diagram-PSM6KHXK-CKk6ZAaV.js → diagram-PSM6KHXK-Ce-iOIx7.js} +1 -1
- package/dist/web/ui/assets/{diagram-QEK2KX5R-Ewj4cQfm.js → diagram-QEK2KX5R-DXcCGip6.js} +1 -1
- package/dist/web/ui/assets/{diagram-S2PKOQOG-B-i75ELR.js → diagram-S2PKOQOG-DVADDX-W.js} +1 -1
- package/dist/web/ui/assets/{erDiagram-Q2GNP2WA-BMe1fyY7.js → erDiagram-Q2GNP2WA-C8AlUD42.js} +1 -1
- package/dist/web/ui/assets/{flowDiagram-NV44I4VS-DTOpgGDg.js → flowDiagram-NV44I4VS-D7Sf06Qi.js} +1 -1
- package/dist/web/ui/assets/{ganttDiagram-JELNMOA3-DdrlqPr-.js → ganttDiagram-JELNMOA3-DC1ZI7BI.js} +1 -1
- package/dist/web/ui/assets/{gitGraphDiagram-NY62KEGX-DOpYoqH8.js → gitGraphDiagram-NY62KEGX-BfZ1rfoJ.js} +1 -1
- package/dist/web/ui/assets/{graph-DNq5-vTB.js → graph-BQpF6Nij.js} +1 -1
- package/dist/web/ui/assets/index-CHzX9Qy5.js +441 -0
- package/dist/web/ui/assets/index-pRZWTg6V.css +1 -0
- package/dist/web/ui/assets/{infoDiagram-WHAUD3N6-D3Wwcqmd.js → infoDiagram-WHAUD3N6-DpMWPNO4.js} +1 -1
- package/dist/web/ui/assets/{journeyDiagram-XKPGCS4Q-BKDrlvIB.js → journeyDiagram-XKPGCS4Q-C1NnAV9d.js} +1 -1
- package/dist/web/ui/assets/{kanban-definition-3W4ZIXB7-Dj6sXTJI.js → kanban-definition-3W4ZIXB7-Dwx-vzmF.js} +1 -1
- package/dist/web/ui/assets/{layout-4XvXY0m8.js → layout-pecnt6B2.js} +1 -1
- package/dist/web/ui/assets/{linear-CUPS720l.js → linear-McmfKs1N.js} +1 -1
- package/dist/web/ui/assets/{min-KWXImKVx.js → min-E1T_dxKi.js} +1 -1
- package/dist/web/ui/assets/{mindmap-definition-VGOIOE7T-D9ty43l7.js → mindmap-definition-VGOIOE7T-EDAtU3iP.js} +1 -1
- package/dist/web/ui/assets/{pieDiagram-ADFJNKIX-BlMxxSdO.js → pieDiagram-ADFJNKIX-Cn-bUvlG.js} +1 -1
- package/dist/web/ui/assets/{quadrantDiagram-AYHSOK5B-Cam0yXvU.js → quadrantDiagram-AYHSOK5B-rDZ_wUTY.js} +1 -1
- package/dist/web/ui/assets/{requirementDiagram-UZGBJVZJ-D_yH3UAt.js → requirementDiagram-UZGBJVZJ-B8HT8i6v.js} +1 -1
- package/dist/web/ui/assets/{sankeyDiagram-TZEHDZUN-Dm93-uJ1.js → sankeyDiagram-TZEHDZUN-DQNSFlyU.js} +1 -1
- package/dist/web/ui/assets/{sequenceDiagram-WL72ISMW-D6C4PHTO.js → sequenceDiagram-WL72ISMW-CtGDTINH.js} +1 -1
- package/dist/web/ui/assets/{stateDiagram-FKZM4ZOC-msXCFM-o.js → stateDiagram-FKZM4ZOC-vyJFWQYy.js} +1 -1
- package/dist/web/ui/assets/stateDiagram-v2-4FDKWEC3-CrSesN6R.js +1 -0
- package/dist/web/ui/assets/{timeline-definition-IT6M3QCI-OhdHqGpr.js → timeline-definition-IT6M3QCI-Bd8FOmSP.js} +1 -1
- package/dist/web/ui/assets/{treemap-KMMF4GRG-BBa7Tuyx.js → treemap-KMMF4GRG-DH-VqRiC.js} +1 -1
- package/dist/web/ui/assets/{xychartDiagram-PRI3JC2R-CwWrUftO.js → xychartDiagram-PRI3JC2R-BQK9j5Ts.js} +1 -1
- package/dist/web/ui/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/ui/assets/channel-DcFyxfzD.js +0 -1
- package/dist/web/ui/assets/classDiagram-2ON5EDUG-DmyEwwBr.js +0 -1
- package/dist/web/ui/assets/classDiagram-v2-WZHVMYZB-DmyEwwBr.js +0 -1
- package/dist/web/ui/assets/clone-DZ5SCP6k.js +0 -1
- package/dist/web/ui/assets/index-B3TLzmaO.js +0 -441
- package/dist/web/ui/assets/index-BSSBc2rS.css +0 -1
- package/dist/web/ui/assets/stateDiagram-v2-4FDKWEC3-BxRi32Am.js +0 -1
package/README.md
CHANGED
|
@@ -84,6 +84,7 @@ memo web --host 127.0.0.1 --port 5494 --open
|
|
|
84
84
|
- Sidebar includes dedicated entries for `MCP Servers` and `Skills`:
|
|
85
85
|
- MCP: create/edit/remove/login/logout and active toggles.
|
|
86
86
|
- Skills: create/delete, detail preview, and active toggles.
|
|
87
|
+
- Web chat input panel shows live context usage percentage.
|
|
87
88
|
|
|
88
89
|
## Configuration
|
|
89
90
|
|
package/dist/web/server/main.cjs
CHANGED
|
@@ -142776,6 +142776,7 @@ var require_chat_service = __commonJS({
|
|
|
142776
142776
|
var stream_service_1 = require_stream_service();
|
|
142777
142777
|
var workspaces_service_1 = require_workspaces_service();
|
|
142778
142778
|
var MAX_LIVE_SESSIONS = 20;
|
|
142779
|
+
var MAX_QUEUED_INPUTS = 3;
|
|
142779
142780
|
function normalizeMode(value) {
|
|
142780
142781
|
if (value === "none" || value === "once" || value === "full")
|
|
142781
142782
|
return value;
|
|
@@ -142847,6 +142848,7 @@ var require_chat_service = __commonJS({
|
|
|
142847
142848
|
await this.workspacesService.touchLastUsed(workspace.id);
|
|
142848
142849
|
const config = await this.memoConfigService.load();
|
|
142849
142850
|
const provider = this.selectProvider(config.providers, input.providerName, config.current_provider);
|
|
142851
|
+
const contextWindow = (0, core_1.resolveContextWindowForProvider)(config, provider);
|
|
142850
142852
|
const sessionId = (0, node_crypto_1.randomUUID)();
|
|
142851
142853
|
const runtime = await this.createRuntime({
|
|
142852
142854
|
id: sessionId,
|
|
@@ -142858,7 +142860,8 @@ var require_chat_service = __commonJS({
|
|
|
142858
142860
|
cwd: workspace.cwd,
|
|
142859
142861
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
142860
142862
|
activeMcpServers: input.activeMcpServers && input.activeMcpServers.length > 0 ? input.activeMcpServers : config.active_mcp_servers,
|
|
142861
|
-
toolPermissionMode: normalizeMode(input.toolPermissionMode)
|
|
142863
|
+
toolPermissionMode: normalizeMode(input.toolPermissionMode),
|
|
142864
|
+
contextWindow
|
|
142862
142865
|
});
|
|
142863
142866
|
this.sessions.set(runtime.id, runtime);
|
|
142864
142867
|
this.touchSession(runtime);
|
|
@@ -142878,6 +142881,7 @@ var require_chat_service = __commonJS({
|
|
|
142878
142881
|
await this.workspacesService.touchLastUsed(workspace.id);
|
|
142879
142882
|
const config = await this.memoConfigService.load();
|
|
142880
142883
|
const provider = this.selectProvider(config.providers, void 0, config.current_provider);
|
|
142884
|
+
const contextWindow = (0, core_1.resolveContextWindowForProvider)(config, provider);
|
|
142881
142885
|
const historyMessages = [];
|
|
142882
142886
|
const turns = [];
|
|
142883
142887
|
for (const turn of detail.turns) {
|
|
@@ -142910,7 +142914,8 @@ var require_chat_service = __commonJS({
|
|
|
142910
142914
|
startedAt: detail.date.startedAt,
|
|
142911
142915
|
activeMcpServers: config.active_mcp_servers,
|
|
142912
142916
|
toolPermissionMode: "once",
|
|
142913
|
-
historyFilePath: detail.filePath
|
|
142917
|
+
historyFilePath: detail.filePath,
|
|
142918
|
+
contextWindow
|
|
142914
142919
|
});
|
|
142915
142920
|
const system = runtime.agentSession.history[0];
|
|
142916
142921
|
runtime.agentSession.history = system ? [system, ...historyMessages] : [...historyMessages];
|
|
@@ -143033,23 +143038,70 @@ var require_chat_service = __commonJS({
|
|
|
143033
143038
|
}
|
|
143034
143039
|
async submitInput(sessionId, input) {
|
|
143035
143040
|
const session = this.requireSession(sessionId);
|
|
143041
|
+
const trimmed = input.trim();
|
|
143042
|
+
if (!trimmed) {
|
|
143043
|
+
throw new common_1.BadRequestException("input is required");
|
|
143044
|
+
}
|
|
143036
143045
|
if (session.status === "running") {
|
|
143046
|
+
if (session.queuedInputs.length >= MAX_QUEUED_INPUTS) {
|
|
143047
|
+
return {
|
|
143048
|
+
accepted: false,
|
|
143049
|
+
kind: "turn",
|
|
143050
|
+
status: "error",
|
|
143051
|
+
message: `Queue is full (max ${MAX_QUEUED_INPUTS}).`
|
|
143052
|
+
};
|
|
143053
|
+
}
|
|
143054
|
+
session.queuedInputs.push({
|
|
143055
|
+
id: (0, node_crypto_1.randomUUID)(),
|
|
143056
|
+
input: trimmed,
|
|
143057
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
143058
|
+
});
|
|
143059
|
+
this.touchSession(session);
|
|
143060
|
+
this.streamService.broadcast(session.id, {
|
|
143061
|
+
type: "session.snapshot",
|
|
143062
|
+
payload: this.toState(session)
|
|
143063
|
+
});
|
|
143037
143064
|
return {
|
|
143038
|
-
accepted:
|
|
143065
|
+
accepted: true,
|
|
143039
143066
|
kind: "turn",
|
|
143040
|
-
status: "
|
|
143041
|
-
message: "Session is busy."
|
|
143067
|
+
status: "ok"
|
|
143042
143068
|
};
|
|
143043
143069
|
}
|
|
143044
|
-
const trimmed = input.trim();
|
|
143045
|
-
if (!trimmed) {
|
|
143046
|
-
throw new common_1.BadRequestException("input is required");
|
|
143047
|
-
}
|
|
143048
143070
|
if (trimmed.startsWith("/")) {
|
|
143049
143071
|
return this.runSlashCommand(session, trimmed);
|
|
143050
143072
|
}
|
|
143051
143073
|
return this.runCoreTurn(session, trimmed, trimmed);
|
|
143052
143074
|
}
|
|
143075
|
+
removeQueuedInput(sessionId, queueId) {
|
|
143076
|
+
const session = this.requireSession(sessionId);
|
|
143077
|
+
const targetQueueId = queueId.trim();
|
|
143078
|
+
if (!targetQueueId) {
|
|
143079
|
+
throw new common_1.BadRequestException("queueId is required");
|
|
143080
|
+
}
|
|
143081
|
+
const next = session.queuedInputs.filter((item) => item.id !== targetQueueId);
|
|
143082
|
+
if (next.length === session.queuedInputs.length) {
|
|
143083
|
+
return { removed: false };
|
|
143084
|
+
}
|
|
143085
|
+
session.queuedInputs = next;
|
|
143086
|
+
this.touchSession(session);
|
|
143087
|
+
this.streamService.broadcast(session.id, {
|
|
143088
|
+
type: "session.snapshot",
|
|
143089
|
+
payload: this.toState(session)
|
|
143090
|
+
});
|
|
143091
|
+
return { removed: true };
|
|
143092
|
+
}
|
|
143093
|
+
sendQueuedInputNow(sessionId) {
|
|
143094
|
+
const session = this.requireSession(sessionId);
|
|
143095
|
+
if (session.queuedInputs.length === 0) {
|
|
143096
|
+
return { triggered: false };
|
|
143097
|
+
}
|
|
143098
|
+
if (session.status === "running") {
|
|
143099
|
+
this.cancelCurrentTurn(sessionId);
|
|
143100
|
+
return { triggered: true };
|
|
143101
|
+
}
|
|
143102
|
+
void this.drainQueuedInputs(session);
|
|
143103
|
+
return { triggered: true };
|
|
143104
|
+
}
|
|
143053
143105
|
cancelCurrentTurn(sessionId) {
|
|
143054
143106
|
const session = this.requireSession(sessionId);
|
|
143055
143107
|
if (session.status === "running") {
|
|
@@ -143061,6 +143113,12 @@ var require_chat_service = __commonJS({
|
|
|
143061
143113
|
async compactSession(sessionId) {
|
|
143062
143114
|
const session = this.requireSession(sessionId);
|
|
143063
143115
|
const result = await session.agentSession.compactHistory("manual");
|
|
143116
|
+
session.currentContextTokens = Math.max(0, result.afterTokens);
|
|
143117
|
+
this.touchSession(session);
|
|
143118
|
+
this.streamService.broadcast(session.id, {
|
|
143119
|
+
type: "session.snapshot",
|
|
143120
|
+
payload: this.toState(session)
|
|
143121
|
+
});
|
|
143064
143122
|
this.streamService.broadcast(session.id, {
|
|
143065
143123
|
type: "system.message",
|
|
143066
143124
|
payload: {
|
|
@@ -143119,6 +143177,10 @@ var require_chat_service = __commonJS({
|
|
|
143119
143177
|
title: "New Session",
|
|
143120
143178
|
resetTurns: true
|
|
143121
143179
|
});
|
|
143180
|
+
this.streamService.broadcast(session.id, {
|
|
143181
|
+
type: "session.snapshot",
|
|
143182
|
+
payload: this.toState(session)
|
|
143183
|
+
});
|
|
143122
143184
|
this.sendSystemMessage(session, "New Session", "Started a fresh session.");
|
|
143123
143185
|
return { accepted: true, kind: "command", status: "ok" };
|
|
143124
143186
|
}
|
|
@@ -143206,9 +143268,41 @@ var require_chat_service = __commonJS({
|
|
|
143206
143268
|
};
|
|
143207
143269
|
}
|
|
143208
143270
|
}
|
|
143271
|
+
async drainQueuedInputs(session) {
|
|
143272
|
+
if (session.status !== "idle")
|
|
143273
|
+
return;
|
|
143274
|
+
if (session.queueDraining)
|
|
143275
|
+
return;
|
|
143276
|
+
if (session.queuedInputs.length === 0)
|
|
143277
|
+
return;
|
|
143278
|
+
session.queueDraining = true;
|
|
143279
|
+
try {
|
|
143280
|
+
while (session.status === "idle" && session.queuedInputs.length > 0) {
|
|
143281
|
+
const next = session.queuedInputs.shift();
|
|
143282
|
+
if (!next)
|
|
143283
|
+
break;
|
|
143284
|
+
this.touchSession(session);
|
|
143285
|
+
this.streamService.broadcast(session.id, {
|
|
143286
|
+
type: "session.snapshot",
|
|
143287
|
+
payload: this.toState(session)
|
|
143288
|
+
});
|
|
143289
|
+
const input = next.input.trim();
|
|
143290
|
+
if (!input)
|
|
143291
|
+
continue;
|
|
143292
|
+
if (input.startsWith("/")) {
|
|
143293
|
+
await this.runSlashCommand(session, input);
|
|
143294
|
+
} else {
|
|
143295
|
+
await this.runCoreTurn(session, input, input);
|
|
143296
|
+
}
|
|
143297
|
+
}
|
|
143298
|
+
} finally {
|
|
143299
|
+
session.queueDraining = false;
|
|
143300
|
+
}
|
|
143301
|
+
}
|
|
143209
143302
|
async recreateSessionRuntime(session, options) {
|
|
143210
143303
|
this.resolvePendingApprovals(session, "deny");
|
|
143211
143304
|
await session.agentSession.close();
|
|
143305
|
+
const config = await this.memoConfigService.load();
|
|
143212
143306
|
if (options.providerName)
|
|
143213
143307
|
session.providerName = options.providerName;
|
|
143214
143308
|
if (options.model)
|
|
@@ -143222,6 +143316,11 @@ var require_chat_service = __commonJS({
|
|
|
143222
143316
|
if (options.title) {
|
|
143223
143317
|
session.title = options.title;
|
|
143224
143318
|
}
|
|
143319
|
+
session.contextWindow = (0, core_1.resolveContextWindowForProvider)(config, {
|
|
143320
|
+
name: session.providerName,
|
|
143321
|
+
model: session.model
|
|
143322
|
+
});
|
|
143323
|
+
session.currentContextTokens = 0;
|
|
143225
143324
|
if (options.resetTurns) {
|
|
143226
143325
|
session.turn = 0;
|
|
143227
143326
|
session.turns = [];
|
|
@@ -143275,6 +143374,10 @@ var require_chat_service = __commonJS({
|
|
|
143275
143374
|
historyFilePath: input.historyFilePath,
|
|
143276
143375
|
turns: [],
|
|
143277
143376
|
pendingApprovals: /* @__PURE__ */ new Map(),
|
|
143377
|
+
currentContextTokens: 0,
|
|
143378
|
+
contextWindow: input.contextWindow,
|
|
143379
|
+
queuedInputs: [],
|
|
143380
|
+
queueDraining: false,
|
|
143278
143381
|
agentSession: null
|
|
143279
143382
|
};
|
|
143280
143383
|
runtime.agentSession = await this.createCoreSession(runtime);
|
|
@@ -143325,10 +143428,11 @@ var require_chat_service = __commonJS({
|
|
|
143325
143428
|
});
|
|
143326
143429
|
},
|
|
143327
143430
|
hooks: {
|
|
143328
|
-
onTurnStart: ({ turn, input }) => {
|
|
143431
|
+
onTurnStart: ({ turn, input, promptTokens }) => {
|
|
143329
143432
|
runtime.status = "running";
|
|
143330
143433
|
runtime.activeTurn = turn;
|
|
143331
143434
|
runtime.turn = Math.max(runtime.turn, turn);
|
|
143435
|
+
runtime.currentContextTokens = typeof promptTokens === "number" && Number.isFinite(promptTokens) ? Math.max(0, promptTokens) : runtime.currentContextTokens;
|
|
143332
143436
|
const displayInput = runtime.nextInputDisplay ?? input;
|
|
143333
143437
|
runtime.nextInputDisplay = void 0;
|
|
143334
143438
|
const record = this.getOrCreateTurnRecord(runtime, turn);
|
|
@@ -143350,7 +143454,24 @@ var require_chat_service = __commonJS({
|
|
|
143350
143454
|
type: "turn.start",
|
|
143351
143455
|
payload: {
|
|
143352
143456
|
turn,
|
|
143353
|
-
input: displayInput
|
|
143457
|
+
input: displayInput,
|
|
143458
|
+
promptTokens
|
|
143459
|
+
}
|
|
143460
|
+
});
|
|
143461
|
+
},
|
|
143462
|
+
onContextUsage: ({ turn, step, phase, promptTokens, contextWindow, thresholdTokens, usagePercent }) => {
|
|
143463
|
+
runtime.currentContextTokens = Math.max(0, promptTokens);
|
|
143464
|
+
runtime.contextWindow = Math.max(0, contextWindow);
|
|
143465
|
+
this.streamService.broadcast(runtime.id, {
|
|
143466
|
+
type: "context.usage",
|
|
143467
|
+
payload: {
|
|
143468
|
+
turn,
|
|
143469
|
+
step,
|
|
143470
|
+
phase,
|
|
143471
|
+
promptTokens,
|
|
143472
|
+
contextWindow,
|
|
143473
|
+
thresholdTokens,
|
|
143474
|
+
usagePercent
|
|
143354
143475
|
}
|
|
143355
143476
|
});
|
|
143356
143477
|
},
|
|
@@ -143416,6 +143537,7 @@ var require_chat_service = __commonJS({
|
|
|
143416
143537
|
type: "session.snapshot",
|
|
143417
143538
|
payload: this.toState(runtime)
|
|
143418
143539
|
});
|
|
143540
|
+
void this.drainQueuedInputs(runtime);
|
|
143419
143541
|
},
|
|
143420
143542
|
onTitleGenerated: ({ title }) => {
|
|
143421
143543
|
runtime.title = title;
|
|
@@ -143442,6 +143564,7 @@ var require_chat_service = __commonJS({
|
|
|
143442
143564
|
sessionId: runtime.id,
|
|
143443
143565
|
mode: "interactive",
|
|
143444
143566
|
providerName: runtime.providerName,
|
|
143567
|
+
contextWindow: runtime.contextWindow,
|
|
143445
143568
|
activeMcpServers: runtime.activeMcpServers,
|
|
143446
143569
|
toolPermissionMode: runtime.toolPermissionMode,
|
|
143447
143570
|
dangerous: runtime.toolPermissionMode === "full",
|
|
@@ -143516,7 +143639,10 @@ var require_chat_service = __commonJS({
|
|
|
143516
143639
|
params: session.pendingApproval.params
|
|
143517
143640
|
} : void 0,
|
|
143518
143641
|
activeMcpServers: session.activeMcpServers,
|
|
143519
|
-
toolPermissionMode: session.toolPermissionMode
|
|
143642
|
+
toolPermissionMode: session.toolPermissionMode,
|
|
143643
|
+
queuedInputs: session.queuedInputs.map((item) => ({ ...item })),
|
|
143644
|
+
currentContextTokens: session.currentContextTokens,
|
|
143645
|
+
contextWindow: session.contextWindow
|
|
143520
143646
|
};
|
|
143521
143647
|
}
|
|
143522
143648
|
toSnapshot(session) {
|
|
@@ -144363,6 +144489,8 @@ var require_rpc_router_service = __commonJS({
|
|
|
144363
144489
|
var workspaces_service_1 = require_workspaces_service();
|
|
144364
144490
|
var session_runtime_registry_service_1 = require_session_runtime_registry_service();
|
|
144365
144491
|
var ws_errors_1 = require_ws_errors();
|
|
144492
|
+
var TOOL_PERMISSION_MODES = ["none", "once", "full"];
|
|
144493
|
+
var APPROVAL_DECISIONS = ["once", "session", "deny"];
|
|
144366
144494
|
function asObject(input) {
|
|
144367
144495
|
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
144368
144496
|
return {};
|
|
@@ -144382,6 +144510,32 @@ var require_rpc_router_service = __commonJS({
|
|
|
144382
144510
|
const trimmed = value.trim();
|
|
144383
144511
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
144384
144512
|
}
|
|
144513
|
+
function asFiniteNumber(value) {
|
|
144514
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
144515
|
+
}
|
|
144516
|
+
function asStringArray(value) {
|
|
144517
|
+
if (!Array.isArray(value))
|
|
144518
|
+
return void 0;
|
|
144519
|
+
return value.filter((item) => typeof item === "string");
|
|
144520
|
+
}
|
|
144521
|
+
function requireTrimmedStringArray(input, key) {
|
|
144522
|
+
if (!Array.isArray(input[key])) {
|
|
144523
|
+
throw new ws_errors_1.WsRpcError("BAD_REQUEST", `${key} must be string[]`);
|
|
144524
|
+
}
|
|
144525
|
+
return input[key].filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
144526
|
+
}
|
|
144527
|
+
function asEnum(value, allowed) {
|
|
144528
|
+
if (typeof value !== "string")
|
|
144529
|
+
return void 0;
|
|
144530
|
+
return allowed.includes(value) ? value : void 0;
|
|
144531
|
+
}
|
|
144532
|
+
function requireEnum(value, allowed, message) {
|
|
144533
|
+
const parsed = asEnum(value, allowed);
|
|
144534
|
+
if (!parsed) {
|
|
144535
|
+
throw new ws_errors_1.WsRpcError("BAD_REQUEST", message);
|
|
144536
|
+
}
|
|
144537
|
+
return parsed;
|
|
144538
|
+
}
|
|
144385
144539
|
var RpcRouterService = class RpcRouterService {
|
|
144386
144540
|
sessionsService;
|
|
144387
144541
|
chatService;
|
|
@@ -144389,6 +144543,7 @@ var require_rpc_router_service = __commonJS({
|
|
|
144389
144543
|
skillsService;
|
|
144390
144544
|
workspacesService;
|
|
144391
144545
|
sessionRegistry;
|
|
144546
|
+
handlers;
|
|
144392
144547
|
constructor(sessionsService, chatService, mcpService, skillsService, workspacesService, sessionRegistry) {
|
|
144393
144548
|
this.sessionsService = sessionsService;
|
|
144394
144549
|
this.chatService = chatService;
|
|
@@ -144396,199 +144551,140 @@ var require_rpc_router_service = __commonJS({
|
|
|
144396
144551
|
this.skillsService = skillsService;
|
|
144397
144552
|
this.workspacesService = workspacesService;
|
|
144398
144553
|
this.sessionRegistry = sessionRegistry;
|
|
144554
|
+
this.handlers = {
|
|
144555
|
+
...this.buildSessionHandlers(),
|
|
144556
|
+
...this.buildChatHandlers(),
|
|
144557
|
+
...this.buildMcpHandlers(),
|
|
144558
|
+
...this.buildSkillHandlers(),
|
|
144559
|
+
...this.buildWorkspaceHandlers()
|
|
144560
|
+
};
|
|
144399
144561
|
}
|
|
144400
144562
|
async dispatch(context, method, params) {
|
|
144401
|
-
const
|
|
144402
|
-
if (
|
|
144403
|
-
|
|
144404
|
-
}
|
|
144405
|
-
if (method === "sessions.detail") {
|
|
144406
|
-
const sessionId = requireString(input, "sessionId");
|
|
144407
|
-
return this.sessionsService.getSessionDetail(sessionId);
|
|
144408
|
-
}
|
|
144409
|
-
if (method === "sessions.events") {
|
|
144410
|
-
const sessionId = requireString(input, "sessionId");
|
|
144411
|
-
return this.sessionsService.getSessionEvents(sessionId, input);
|
|
144412
|
-
}
|
|
144413
|
-
if (method === "sessions.remove") {
|
|
144414
|
-
const sessionId = requireString(input, "sessionId");
|
|
144415
|
-
return this.chatService.deleteSession(sessionId);
|
|
144563
|
+
const handler = this.handlers[method];
|
|
144564
|
+
if (!handler) {
|
|
144565
|
+
throw new ws_errors_1.WsRpcError("METHOD_NOT_FOUND", `Unknown method: ${method}`);
|
|
144416
144566
|
}
|
|
144417
|
-
|
|
144418
|
-
|
|
144419
|
-
|
|
144567
|
+
return handler(context, asObject(params));
|
|
144568
|
+
}
|
|
144569
|
+
buildSessionHandlers() {
|
|
144570
|
+
return {
|
|
144571
|
+
"sessions.list": (_context, input) => this.sessionsService.list(input),
|
|
144572
|
+
"sessions.detail": (_context, input) => this.sessionsService.getSessionDetail(requireString(input, "sessionId")),
|
|
144573
|
+
"sessions.events": (_context, input) => this.sessionsService.getSessionEvents(requireString(input, "sessionId"), input),
|
|
144574
|
+
"sessions.remove": (_context, input) => this.chatService.deleteSession(requireString(input, "sessionId"))
|
|
144575
|
+
};
|
|
144576
|
+
}
|
|
144577
|
+
buildChatHandlers() {
|
|
144578
|
+
return {
|
|
144579
|
+
"chat.session.create": (_context, input) => this.chatService.createSession({
|
|
144420
144580
|
providerName: asString(input.providerName),
|
|
144421
144581
|
workspaceId: asString(input.workspaceId),
|
|
144422
144582
|
cwd: asString(input.cwd),
|
|
144423
|
-
toolPermissionMode:
|
|
144424
|
-
activeMcpServers:
|
|
144425
|
-
})
|
|
144426
|
-
|
|
144427
|
-
|
|
144428
|
-
return this.chatService.listProviders();
|
|
144429
|
-
}
|
|
144430
|
-
if (method === "chat.runtimes.list") {
|
|
144431
|
-
return this.chatService.listRuntimeBadges({
|
|
144583
|
+
toolPermissionMode: asEnum(input.toolPermissionMode, TOOL_PERMISSION_MODES),
|
|
144584
|
+
activeMcpServers: asStringArray(input.activeMcpServers)
|
|
144585
|
+
}),
|
|
144586
|
+
"chat.providers.list": () => this.chatService.listProviders(),
|
|
144587
|
+
"chat.runtimes.list": (_context, input) => this.chatService.listRuntimeBadges({
|
|
144432
144588
|
workspaceId: asString(input.workspaceId)
|
|
144433
|
-
})
|
|
144434
|
-
|
|
144435
|
-
|
|
144436
|
-
|
|
144437
|
-
|
|
144438
|
-
|
|
144439
|
-
|
|
144440
|
-
|
|
144441
|
-
|
|
144442
|
-
|
|
144443
|
-
|
|
144444
|
-
|
|
144445
|
-
|
|
144589
|
+
}),
|
|
144590
|
+
"chat.session.state": (context, input) => this.chatService.getSessionState(this.requireOwnedSession(input, context)),
|
|
144591
|
+
"chat.session.attach": async (context, input) => {
|
|
144592
|
+
const sessionId = requireString(input, "sessionId");
|
|
144593
|
+
this.sessionRegistry.claim(sessionId, context.connectionId);
|
|
144594
|
+
try {
|
|
144595
|
+
return await this.chatService.attachSession(sessionId);
|
|
144596
|
+
} catch (error) {
|
|
144597
|
+
this.sessionRegistry.release(sessionId, context.connectionId);
|
|
144598
|
+
throw error;
|
|
144599
|
+
}
|
|
144600
|
+
},
|
|
144601
|
+
"chat.session.close": (context, input) => {
|
|
144602
|
+
const sessionId = this.requireOwnedSession(input, context);
|
|
144603
|
+
const result = this.chatService.closeSession(sessionId);
|
|
144446
144604
|
this.sessionRegistry.release(sessionId, context.connectionId);
|
|
144447
|
-
|
|
144448
|
-
}
|
|
144449
|
-
|
|
144450
|
-
|
|
144451
|
-
|
|
144452
|
-
|
|
144453
|
-
|
|
144454
|
-
|
|
144455
|
-
|
|
144456
|
-
|
|
144457
|
-
|
|
144458
|
-
|
|
144459
|
-
|
|
144460
|
-
|
|
144461
|
-
|
|
144462
|
-
|
|
144463
|
-
|
|
144464
|
-
|
|
144465
|
-
|
|
144466
|
-
|
|
144467
|
-
|
|
144468
|
-
|
|
144469
|
-
|
|
144470
|
-
|
|
144471
|
-
|
|
144472
|
-
|
|
144473
|
-
|
|
144474
|
-
this.
|
|
144475
|
-
|
|
144476
|
-
|
|
144477
|
-
|
|
144478
|
-
|
|
144479
|
-
|
|
144480
|
-
|
|
144481
|
-
|
|
144482
|
-
|
|
144483
|
-
|
|
144484
|
-
this.sessionRegistry.requireOwner(sessionId, context.connectionId);
|
|
144485
|
-
return this.chatService.compactSession(sessionId);
|
|
144486
|
-
}
|
|
144487
|
-
if (method === "chat.approval.respond") {
|
|
144488
|
-
const sessionId = requireString(input, "sessionId");
|
|
144489
|
-
const fingerprint = requireString(input, "fingerprint");
|
|
144490
|
-
const decision = input.decision;
|
|
144491
|
-
if (decision !== "once" && decision !== "session" && decision !== "deny") {
|
|
144492
|
-
throw new ws_errors_1.WsRpcError("BAD_REQUEST", "decision must be once | session | deny");
|
|
144493
|
-
}
|
|
144494
|
-
this.sessionRegistry.requireOwner(sessionId, context.connectionId);
|
|
144495
|
-
return this.chatService.applyApprovalDecision(sessionId, fingerprint, decision);
|
|
144496
|
-
}
|
|
144497
|
-
if (method === "mcp.servers.list") {
|
|
144498
|
-
return this.mcpService.list();
|
|
144499
|
-
}
|
|
144500
|
-
if (method === "mcp.servers.get") {
|
|
144501
|
-
return this.mcpService.get(requireString(input, "name"));
|
|
144502
|
-
}
|
|
144503
|
-
if (method === "mcp.servers.create") {
|
|
144504
|
-
const name = requireString(input, "name");
|
|
144505
|
-
return this.mcpService.create(name, input.config);
|
|
144506
|
-
}
|
|
144507
|
-
if (method === "mcp.servers.update") {
|
|
144508
|
-
const name = requireString(input, "name");
|
|
144509
|
-
return this.mcpService.update(name, input.config);
|
|
144510
|
-
}
|
|
144511
|
-
if (method === "mcp.servers.remove") {
|
|
144512
|
-
return this.mcpService.remove(requireString(input, "name"));
|
|
144513
|
-
}
|
|
144514
|
-
if (method === "mcp.servers.login") {
|
|
144515
|
-
const name = requireString(input, "name");
|
|
144516
|
-
const scopes = Array.isArray(input.scopes) ? input.scopes.filter((item) => typeof item === "string") : void 0;
|
|
144517
|
-
return this.mcpService.login(name, scopes);
|
|
144518
|
-
}
|
|
144519
|
-
if (method === "mcp.servers.logout") {
|
|
144520
|
-
return this.mcpService.logout(requireString(input, "name"));
|
|
144521
|
-
}
|
|
144522
|
-
if (method === "mcp.active.set") {
|
|
144523
|
-
if (!Array.isArray(input.names)) {
|
|
144524
|
-
throw new ws_errors_1.WsRpcError("BAD_REQUEST", "names must be string[]");
|
|
144525
|
-
}
|
|
144526
|
-
const names = input.names.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
144527
|
-
return this.mcpService.setActive(names);
|
|
144528
|
-
}
|
|
144529
|
-
if (method === "skills.list") {
|
|
144530
|
-
return this.skillsService.list({
|
|
144605
|
+
return result;
|
|
144606
|
+
},
|
|
144607
|
+
"chat.files.suggest": (context, input) => {
|
|
144608
|
+
const sessionId = asString(input.sessionId);
|
|
144609
|
+
if (sessionId) {
|
|
144610
|
+
this.sessionRegistry.requireOwner(sessionId, context.connectionId);
|
|
144611
|
+
}
|
|
144612
|
+
return this.chatService.suggestFiles({
|
|
144613
|
+
query: typeof input.query === "string" ? input.query : "",
|
|
144614
|
+
limit: asFiniteNumber(input.limit),
|
|
144615
|
+
sessionId,
|
|
144616
|
+
workspaceId: asString(input.workspaceId)
|
|
144617
|
+
});
|
|
144618
|
+
},
|
|
144619
|
+
"chat.input.submit": (context, input) => this.chatService.submitInput(this.requireOwnedSession(input, context), requireString(input, "input")),
|
|
144620
|
+
"chat.queue.remove": (context, input) => this.chatService.removeQueuedInput(this.requireOwnedSession(input, context), requireString(input, "queueId")),
|
|
144621
|
+
"chat.queue.send_now": (context, input) => this.chatService.sendQueuedInputNow(this.requireOwnedSession(input, context)),
|
|
144622
|
+
"chat.turn.cancel": (context, input) => this.chatService.cancelCurrentTurn(this.requireOwnedSession(input, context)),
|
|
144623
|
+
"chat.session.compact": (context, input) => this.chatService.compactSession(this.requireOwnedSession(input, context)),
|
|
144624
|
+
"chat.approval.respond": (context, input) => this.chatService.applyApprovalDecision(this.requireOwnedSession(input, context), requireString(input, "fingerprint"), requireEnum(input.decision, APPROVAL_DECISIONS, "decision must be once | session | deny"))
|
|
144625
|
+
};
|
|
144626
|
+
}
|
|
144627
|
+
buildMcpHandlers() {
|
|
144628
|
+
return {
|
|
144629
|
+
"mcp.servers.list": () => this.mcpService.list(),
|
|
144630
|
+
"mcp.servers.get": (_context, input) => this.mcpService.get(requireString(input, "name")),
|
|
144631
|
+
"mcp.servers.create": (_context, input) => this.mcpService.create(requireString(input, "name"), input.config),
|
|
144632
|
+
"mcp.servers.update": (_context, input) => this.mcpService.update(requireString(input, "name"), input.config),
|
|
144633
|
+
"mcp.servers.remove": (_context, input) => this.mcpService.remove(requireString(input, "name")),
|
|
144634
|
+
"mcp.servers.login": (_context, input) => this.mcpService.login(requireString(input, "name"), asStringArray(input.scopes)),
|
|
144635
|
+
"mcp.servers.logout": (_context, input) => this.mcpService.logout(requireString(input, "name")),
|
|
144636
|
+
"mcp.active.set": (_context, input) => this.mcpService.setActive(requireTrimmedStringArray(input, "names"))
|
|
144637
|
+
};
|
|
144638
|
+
}
|
|
144639
|
+
buildSkillHandlers() {
|
|
144640
|
+
return {
|
|
144641
|
+
"skills.list": (_context, input) => this.skillsService.list({
|
|
144531
144642
|
scope: input.scope,
|
|
144532
144643
|
q: input.q,
|
|
144533
144644
|
workspaceId: input.workspaceId
|
|
144534
|
-
})
|
|
144535
|
-
|
|
144536
|
-
|
|
144537
|
-
return this.skillsService.get(requireString(input, "id"));
|
|
144538
|
-
}
|
|
144539
|
-
if (method === "skills.create") {
|
|
144540
|
-
return this.skillsService.create({
|
|
144645
|
+
}),
|
|
144646
|
+
"skills.get": (_context, input) => this.skillsService.get(requireString(input, "id")),
|
|
144647
|
+
"skills.create": (_context, input) => this.skillsService.create({
|
|
144541
144648
|
scope: input.scope,
|
|
144542
144649
|
name: input.name,
|
|
144543
144650
|
description: input.description,
|
|
144544
144651
|
content: input.content,
|
|
144545
144652
|
workspaceId: input.workspaceId
|
|
144546
|
-
})
|
|
144547
|
-
|
|
144548
|
-
if (method === "skills.update") {
|
|
144549
|
-
return this.skillsService.update(requireString(input, "id"), {
|
|
144653
|
+
}),
|
|
144654
|
+
"skills.update": (_context, input) => this.skillsService.update(requireString(input, "id"), {
|
|
144550
144655
|
description: input.description,
|
|
144551
144656
|
content: input.content
|
|
144552
|
-
})
|
|
144553
|
-
|
|
144554
|
-
|
|
144555
|
-
|
|
144556
|
-
|
|
144557
|
-
|
|
144558
|
-
|
|
144559
|
-
|
|
144560
|
-
|
|
144561
|
-
const ids = input.ids.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
|
|
144562
|
-
return this.skillsService.setActive(ids);
|
|
144563
|
-
}
|
|
144564
|
-
if (method === "workspace.list") {
|
|
144565
|
-
return this.workspacesService.list();
|
|
144566
|
-
}
|
|
144567
|
-
if (method === "workspace.add") {
|
|
144568
|
-
return this.workspacesService.add({
|
|
144657
|
+
}),
|
|
144658
|
+
"skills.remove": (_context, input) => this.skillsService.remove(requireString(input, "id")),
|
|
144659
|
+
"skills.active.set": (_context, input) => this.skillsService.setActive(requireTrimmedStringArray(input, "ids"))
|
|
144660
|
+
};
|
|
144661
|
+
}
|
|
144662
|
+
buildWorkspaceHandlers() {
|
|
144663
|
+
return {
|
|
144664
|
+
"workspace.list": () => this.workspacesService.list(),
|
|
144665
|
+
"workspace.add": (_context, input) => this.workspacesService.add({
|
|
144569
144666
|
cwd: input.cwd,
|
|
144570
144667
|
name: input.name
|
|
144571
|
-
})
|
|
144572
|
-
|
|
144573
|
-
if (method === "workspace.update") {
|
|
144574
|
-
return this.workspacesService.update(requireString(input, "workspaceId"), {
|
|
144668
|
+
}),
|
|
144669
|
+
"workspace.update": (_context, input) => this.workspacesService.update(requireString(input, "workspaceId"), {
|
|
144575
144670
|
name: input.name
|
|
144576
|
-
})
|
|
144577
|
-
|
|
144578
|
-
|
|
144579
|
-
|
|
144580
|
-
|
|
144581
|
-
|
|
144582
|
-
|
|
144583
|
-
|
|
144584
|
-
|
|
144585
|
-
}
|
|
144586
|
-
|
|
144587
|
-
|
|
144588
|
-
|
|
144589
|
-
|
|
144590
|
-
|
|
144591
|
-
|
|
144671
|
+
}),
|
|
144672
|
+
"workspace.remove": async (_context, input) => {
|
|
144673
|
+
const workspaceId = requireString(input, "workspaceId");
|
|
144674
|
+
const sessionsResult = await this.sessionsService.removeSessionsByWorkspace(workspaceId);
|
|
144675
|
+
const workspaceResult = await this.workspacesService.remove(workspaceId);
|
|
144676
|
+
return {
|
|
144677
|
+
...workspaceResult,
|
|
144678
|
+
deletedSessions: sessionsResult.deletedSessions
|
|
144679
|
+
};
|
|
144680
|
+
},
|
|
144681
|
+
"workspace.fs.list": (_context, input) => this.workspacesService.listDirectories(asString(input.path))
|
|
144682
|
+
};
|
|
144683
|
+
}
|
|
144684
|
+
requireOwnedSession(input, context) {
|
|
144685
|
+
const sessionId = requireString(input, "sessionId");
|
|
144686
|
+
this.sessionRegistry.requireOwner(sessionId, context.connectionId);
|
|
144687
|
+
return sessionId;
|
|
144592
144688
|
}
|
|
144593
144689
|
};
|
|
144594
144690
|
exports2.RpcRouterService = RpcRouterService;
|
|
@@ -144952,6 +145048,12 @@ var require_ws_gateway_service = __commonJS({
|
|
|
144952
145048
|
data: { sessionId, ...frame.payload }
|
|
144953
145049
|
};
|
|
144954
145050
|
}
|
|
145051
|
+
if (frame.type === "context.usage") {
|
|
145052
|
+
return {
|
|
145053
|
+
topic: "chat.context.usage",
|
|
145054
|
+
data: { sessionId, ...frame.payload }
|
|
145055
|
+
};
|
|
145056
|
+
}
|
|
144955
145057
|
if (frame.type === "turn.final") {
|
|
144956
145058
|
return {
|
|
144957
145059
|
topic: "chat.turn.final",
|