rterm-backend 3.2.1 → 3.2.4
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/bin/gybackend.cjs +214 -15
- package/package.json +2 -2
package/bin/gybackend.cjs
CHANGED
|
@@ -295047,7 +295047,7 @@ var normalizeTerminalResizeTarget = (cols, rows) => {
|
|
|
295047
295047
|
rows: Math.max(1, Math.floor(rows))
|
|
295048
295048
|
};
|
|
295049
295049
|
};
|
|
295050
|
-
var TerminalService = class {
|
|
295050
|
+
var TerminalService = class _TerminalService {
|
|
295051
295051
|
backends = /* @__PURE__ */ new Map();
|
|
295052
295052
|
terminals = /* @__PURE__ */ new Map();
|
|
295053
295053
|
terminalConfigs = /* @__PURE__ */ new Map();
|
|
@@ -295058,6 +295058,8 @@ var TerminalService = class {
|
|
|
295058
295058
|
/** Buffered writes for terminals that aren't writable yet (prevents keystroke loss during reconnection). */
|
|
295059
295059
|
pendingWrites = /* @__PURE__ */ new Map();
|
|
295060
295060
|
pendingWriteTimers = /* @__PURE__ */ new Map();
|
|
295061
|
+
pendingWriteRetries = /* @__PURE__ */ new Map();
|
|
295062
|
+
static MAX_WRITE_RETRIES = 3;
|
|
295061
295063
|
selectionByTerminal = /* @__PURE__ */ new Map();
|
|
295062
295064
|
tasksByTerminal = /* @__PURE__ */ new Map();
|
|
295063
295065
|
activeTaskByTerminal = /* @__PURE__ */ new Map();
|
|
@@ -295619,21 +295621,28 @@ var TerminalService = class {
|
|
|
295619
295621
|
handleData(terminalId, data) {
|
|
295620
295622
|
const sanitizedData = stripInternalControlMarkers(data);
|
|
295621
295623
|
const tab = this.terminals.get(terminalId);
|
|
295622
|
-
|
|
295623
|
-
|
|
295624
|
-
|
|
295625
|
-
|
|
295626
|
-
|
|
295627
|
-
|
|
295628
|
-
|
|
295629
|
-
|
|
295630
|
-
|
|
295631
|
-
|
|
295632
|
-
|
|
295633
|
-
|
|
295634
|
-
|
|
295624
|
+
if (sanitizedData) {
|
|
295625
|
+
const recordingId = this.activeRecordings.get(terminalId);
|
|
295626
|
+
if (recordingId || this.sessionLogger && tab) {
|
|
295627
|
+
const captureData = sanitizedData;
|
|
295628
|
+
const captureTab = tab;
|
|
295629
|
+
const captureId = recordingId;
|
|
295630
|
+
setImmediate(() => {
|
|
295631
|
+
if (captureId && this.sessionRecorder) {
|
|
295632
|
+
try {
|
|
295633
|
+
this.sessionRecorder.out(captureId, captureData);
|
|
295634
|
+
} catch {
|
|
295635
|
+
}
|
|
295636
|
+
}
|
|
295637
|
+
if (this.sessionLogger && captureTab) {
|
|
295638
|
+
if (!this.sessionLogStarted.has(terminalId)) {
|
|
295639
|
+
this.sessionLogStarted.add(terminalId);
|
|
295640
|
+
this.sessionLogger.start(terminalId, { title: captureTab.title || terminalId, type: captureTab.type });
|
|
295641
|
+
}
|
|
295642
|
+
this.sessionLogger.write(terminalId, captureData);
|
|
295643
|
+
}
|
|
295644
|
+
});
|
|
295635
295645
|
}
|
|
295636
|
-
this.sessionLogger.write(terminalId, sanitizedData);
|
|
295637
295646
|
}
|
|
295638
295647
|
if (tab) {
|
|
295639
295648
|
let shouldPublishTabsChanged = false;
|
|
@@ -295952,7 +295961,24 @@ ${promptPrefix}`;
|
|
|
295952
295961
|
if (terminal && this.canWriteToTerminal(terminal)) {
|
|
295953
295962
|
const backend = this.getBackend(terminal.type);
|
|
295954
295963
|
backend.write(terminal.ptyId, data);
|
|
295964
|
+
this.pendingWriteRetries.delete(terminalId);
|
|
295955
295965
|
} else if (terminal) {
|
|
295966
|
+
if (terminal.runtimeState === "exited") {
|
|
295967
|
+
this.pendingWrites.delete(terminalId);
|
|
295968
|
+
this.pendingWriteRetries.delete(terminalId);
|
|
295969
|
+
const timer = this.pendingWriteTimers.get(terminalId);
|
|
295970
|
+
if (timer) {
|
|
295971
|
+
clearTimeout(timer);
|
|
295972
|
+
this.pendingWriteTimers.delete(terminalId);
|
|
295973
|
+
}
|
|
295974
|
+
return;
|
|
295975
|
+
}
|
|
295976
|
+
const retries = this.pendingWriteRetries.get(terminalId) ?? 0;
|
|
295977
|
+
if (retries >= _TerminalService.MAX_WRITE_RETRIES) {
|
|
295978
|
+
this.pendingWrites.delete(terminalId);
|
|
295979
|
+
this.pendingWriteRetries.delete(terminalId);
|
|
295980
|
+
return;
|
|
295981
|
+
}
|
|
295956
295982
|
const pending = this.pendingWrites.get(terminalId) ?? "";
|
|
295957
295983
|
this.pendingWrites.set(terminalId, pending + data);
|
|
295958
295984
|
if (!this.pendingWriteTimers.has(terminalId)) {
|
|
@@ -295962,8 +295988,11 @@ ${promptPrefix}`;
|
|
|
295962
295988
|
const buffered = this.pendingWrites.get(terminalId);
|
|
295963
295989
|
if (term && buffered && this.canWriteToTerminal(term)) {
|
|
295964
295990
|
this.pendingWrites.delete(terminalId);
|
|
295991
|
+
this.pendingWriteRetries.delete(terminalId);
|
|
295965
295992
|
const b = this.getBackend(term.type);
|
|
295966
295993
|
b.write(term.ptyId, buffered);
|
|
295994
|
+
} else {
|
|
295995
|
+
this.pendingWriteRetries.set(terminalId, retries + 1);
|
|
295967
295996
|
}
|
|
295968
295997
|
}, 500);
|
|
295969
295998
|
this.pendingWriteTimers.set(terminalId, timer);
|
|
@@ -296023,6 +296052,7 @@ ${promptPrefix}`;
|
|
|
296023
296052
|
kill(terminalId) {
|
|
296024
296053
|
this.pendingResizeByTerminal.delete(terminalId);
|
|
296025
296054
|
this.pendingWrites.delete(terminalId);
|
|
296055
|
+
this.pendingWriteRetries.delete(terminalId);
|
|
296026
296056
|
const writeTimer = this.pendingWriteTimers.get(terminalId);
|
|
296027
296057
|
if (writeTimer) {
|
|
296028
296058
|
clearTimeout(writeTimer);
|
|
@@ -367362,6 +367392,85 @@ var SINGLE_CALL_TOOL_BOUNDARY_NAMES = /* @__PURE__ */ new Set([
|
|
|
367362
367392
|
"manage_template",
|
|
367363
367393
|
"import_putty"
|
|
367364
367394
|
]);
|
|
367395
|
+
var PARALLEL_SAFE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
367396
|
+
"read_file",
|
|
367397
|
+
"read_terminal_tab",
|
|
367398
|
+
"read_command_output",
|
|
367399
|
+
"list_session_logs",
|
|
367400
|
+
"read_session_log",
|
|
367401
|
+
"search_session_logs",
|
|
367402
|
+
"get_metrics",
|
|
367403
|
+
"get_live_dashboard",
|
|
367404
|
+
"get_monitor_status",
|
|
367405
|
+
"get_cloud_inventory",
|
|
367406
|
+
"get_apm_summary",
|
|
367407
|
+
"get_dem_summary",
|
|
367408
|
+
"get_cost",
|
|
367409
|
+
"get_run_ledger",
|
|
367410
|
+
"list_gateway_methods",
|
|
367411
|
+
"manage_secret",
|
|
367412
|
+
// read operations (list/has) are safe; set/delete are rare
|
|
367413
|
+
"manage_oncall",
|
|
367414
|
+
// open_pages is read-only
|
|
367415
|
+
"manage_gitops",
|
|
367416
|
+
// export/drift/inSync are read-only
|
|
367417
|
+
"manage_playbook_version",
|
|
367418
|
+
// lint/history/diff are read-only
|
|
367419
|
+
"collect_facts",
|
|
367420
|
+
"run_fleet_command",
|
|
367421
|
+
// runs on different terminals — parallel-safe
|
|
367422
|
+
"synapse_health",
|
|
367423
|
+
"synapse_discover",
|
|
367424
|
+
"synapse_agents_summary",
|
|
367425
|
+
"synapse_reputation",
|
|
367426
|
+
"synapse_serve_status",
|
|
367427
|
+
"numbat_health",
|
|
367428
|
+
"numbat_findings_summary",
|
|
367429
|
+
"agentspan_health",
|
|
367430
|
+
"agentspan_list",
|
|
367431
|
+
"agentspan_status",
|
|
367432
|
+
"webintel_health",
|
|
367433
|
+
"web_search",
|
|
367434
|
+
"web_fetch",
|
|
367435
|
+
"web_find_similar",
|
|
367436
|
+
"web_watch_list",
|
|
367437
|
+
"patch_status",
|
|
367438
|
+
"list_requests",
|
|
367439
|
+
"request_status",
|
|
367440
|
+
"sop_search",
|
|
367441
|
+
"sop_get",
|
|
367442
|
+
"iam_user_info",
|
|
367443
|
+
"iam_user_groups",
|
|
367444
|
+
"iam_access_review",
|
|
367445
|
+
"fraudops_pipeline_status",
|
|
367446
|
+
"fraudops_str_status",
|
|
367447
|
+
"fraudops_decision_summary",
|
|
367448
|
+
"netdata_alert_summary",
|
|
367449
|
+
"netdata_correlate"
|
|
367450
|
+
]);
|
|
367451
|
+
function canRunInParallel(toolCalls) {
|
|
367452
|
+
if (toolCalls.length <= 1) return false;
|
|
367453
|
+
for (const tc of toolCalls) {
|
|
367454
|
+
if (SINGLE_CALL_TOOL_BOUNDARY_NAMES.has(tc?.name)) return false;
|
|
367455
|
+
if (!PARALLEL_SAFE_TOOL_NAMES.has(tc?.name)) return false;
|
|
367456
|
+
}
|
|
367457
|
+
const terminalIds = /* @__PURE__ */ new Set();
|
|
367458
|
+
for (const tc of toolCalls) {
|
|
367459
|
+
const args = typeof tc?.args === "string" ? (() => {
|
|
367460
|
+
try {
|
|
367461
|
+
return JSON.parse(tc.args);
|
|
367462
|
+
} catch {
|
|
367463
|
+
return {};
|
|
367464
|
+
}
|
|
367465
|
+
})() : tc?.args || {};
|
|
367466
|
+
const tid = args.terminalId || args.target;
|
|
367467
|
+
if (tid) {
|
|
367468
|
+
if (terminalIds.has(tid)) return false;
|
|
367469
|
+
terminalIds.add(tid);
|
|
367470
|
+
}
|
|
367471
|
+
}
|
|
367472
|
+
return true;
|
|
367473
|
+
}
|
|
367365
367474
|
function clipTextMiddle(input, maxChars) {
|
|
367366
367475
|
if (maxChars <= 0) return "";
|
|
367367
367476
|
if (input.length <= maxChars) return input;
|
|
@@ -368363,6 +368472,31 @@ var AgentService_v2 = class {
|
|
|
368363
368472
|
if (!sessionId) throw new Error("No session ID in state");
|
|
368364
368473
|
const sessionBinding = this.getSessionModelBinding(sessionId);
|
|
368365
368474
|
const queue2 = Array.isArray(state.pendingToolCalls) ? state.pendingToolCalls : [];
|
|
368475
|
+
if (canRunInParallel(queue2)) {
|
|
368476
|
+
const parallelResults = await Promise.all(
|
|
368477
|
+
queue2.map(async (tc) => {
|
|
368478
|
+
const tm = this.createToolMessage(tc);
|
|
368479
|
+
const ec = this.createExecutionContext(
|
|
368480
|
+
sessionId,
|
|
368481
|
+
tm.additional_kwargs._gyshellMessageId,
|
|
368482
|
+
config2
|
|
368483
|
+
);
|
|
368484
|
+
let res = "";
|
|
368485
|
+
try {
|
|
368486
|
+
res = await this.executeToolByName(tc, ec);
|
|
368487
|
+
} catch (err) {
|
|
368488
|
+
res = `Parallel execution error for ${tc.name}: ${err.message}`;
|
|
368489
|
+
}
|
|
368490
|
+
tm.content = res;
|
|
368491
|
+
return tm;
|
|
368492
|
+
})
|
|
368493
|
+
);
|
|
368494
|
+
return {
|
|
368495
|
+
messages: [...state.messages, ...parallelResults],
|
|
368496
|
+
sessionId,
|
|
368497
|
+
pendingToolCalls: []
|
|
368498
|
+
};
|
|
368499
|
+
}
|
|
368366
368500
|
const toolCall = queue2[0];
|
|
368367
368501
|
if (!toolCall) return state;
|
|
368368
368502
|
const toolMessage = this.createToolMessage(toolCall);
|
|
@@ -369215,6 +369349,71 @@ Actually, your intention might be different. Please re-read the description of t
|
|
|
369215
369349
|
};
|
|
369216
369350
|
});
|
|
369217
369351
|
}
|
|
369352
|
+
/** v3.2.4: Execute a single tool by name (used by the parallel execution path).
|
|
369353
|
+
* This is a simplified dispatch that handles the common read-only/parallel-safe tools.
|
|
369354
|
+
* Tools not handled here fall back to the sequential switch/case path. */
|
|
369355
|
+
async executeToolByName(toolCall, executionContext) {
|
|
369356
|
+
const name = toolCall.name;
|
|
369357
|
+
const args = typeof toolCall.args === "string" ? (() => {
|
|
369358
|
+
try {
|
|
369359
|
+
return JSON.parse(toolCall.args);
|
|
369360
|
+
} catch {
|
|
369361
|
+
return {};
|
|
369362
|
+
}
|
|
369363
|
+
})() : toolCall.args || {};
|
|
369364
|
+
const ti = toolImplementations;
|
|
369365
|
+
switch (name) {
|
|
369366
|
+
case "read_terminal_tab":
|
|
369367
|
+
return ti.readTerminalTab(args, executionContext);
|
|
369368
|
+
case "read_command_output":
|
|
369369
|
+
return ti.readCommandOutput(args, executionContext);
|
|
369370
|
+
case "list_session_logs":
|
|
369371
|
+
return ti.listSessionLogs(args, executionContext);
|
|
369372
|
+
case "read_session_log":
|
|
369373
|
+
return ti.readSessionLog(args, executionContext);
|
|
369374
|
+
case "search_session_logs":
|
|
369375
|
+
return ti.searchSessionLogs(args, executionContext);
|
|
369376
|
+
case "get_metrics":
|
|
369377
|
+
return ti.getMetrics(args, executionContext);
|
|
369378
|
+
case "get_live_dashboard":
|
|
369379
|
+
return ti.getLiveDashboard(args, executionContext);
|
|
369380
|
+
case "get_monitor_status":
|
|
369381
|
+
return ti.getMonitorStatus(args, executionContext);
|
|
369382
|
+
case "get_cloud_inventory":
|
|
369383
|
+
return ti.getCloudInventory(args, executionContext);
|
|
369384
|
+
case "get_apm_summary":
|
|
369385
|
+
return ti.getApmSummary(args, executionContext);
|
|
369386
|
+
case "get_dem_summary":
|
|
369387
|
+
return ti.getDemSummary(args, executionContext);
|
|
369388
|
+
case "get_cost":
|
|
369389
|
+
return ti.getCost(args, executionContext);
|
|
369390
|
+
case "get_run_ledger":
|
|
369391
|
+
return ti.getRunLedger(args, executionContext);
|
|
369392
|
+
case "list_gateway_methods":
|
|
369393
|
+
return ti.listGatewayMethods(args, executionContext);
|
|
369394
|
+
case "collect_facts":
|
|
369395
|
+
return ti.collectFacts(args, executionContext);
|
|
369396
|
+
case "run_fleet_command":
|
|
369397
|
+
return ti.runFleetCommand(args, executionContext);
|
|
369398
|
+
case "manage_secret":
|
|
369399
|
+
return ti.manageSecret(args, executionContext);
|
|
369400
|
+
case "manage_oncall":
|
|
369401
|
+
return ti.manageOncall(args, executionContext);
|
|
369402
|
+
case "manage_gitops":
|
|
369403
|
+
return ti.manageGitops(args, executionContext);
|
|
369404
|
+
case "manage_playbook_version":
|
|
369405
|
+
return ti.managePlaybookVersion(args, executionContext);
|
|
369406
|
+
// Plugin tools — delegate to the pluginTools map
|
|
369407
|
+
default: {
|
|
369408
|
+
const pluginHandler = this.pluginTools.get(name);
|
|
369409
|
+
if (pluginHandler) {
|
|
369410
|
+
const result = await pluginHandler(args);
|
|
369411
|
+
return typeof result === "string" ? result : JSON.stringify(result);
|
|
369412
|
+
}
|
|
369413
|
+
return `Tool "${name}" is not supported in parallel execution mode.`;
|
|
369414
|
+
}
|
|
369415
|
+
}
|
|
369416
|
+
}
|
|
369218
369417
|
createReadFileNode() {
|
|
369219
369418
|
return RunnableLambda.from(async (state, config2) => {
|
|
369220
369419
|
const sessionId = state.sessionId;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rterm-backend",
|
|
3
|
-
"version": "3.2.
|
|
4
|
-
"description": "Headless AI-native backend for RTerm / neuralOS — v3.2.
|
|
3
|
+
"version": "3.2.4",
|
|
4
|
+
"description": "Headless AI-native backend for RTerm / neuralOS — v3.2.4: parallel tool execution for compatible tools + per-model requestParams. 11 plugins, 55 plugin tools wired. Transports (SSH/serial/local), SQLite, and NATS libs install automatically.",
|
|
5
5
|
"main": "bin/gybackend.cjs",
|
|
6
6
|
"bin": { "gybackend": "bin/gybackend.cjs" },
|
|
7
7
|
"license": "MIT",
|