neuralos 3.3.2 → 3.3.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 +231 -66
- package/neuralos-3.3.4.tgz +0 -0
- package/package.json +40 -5
package/bin/gybackend.cjs
CHANGED
|
@@ -256134,6 +256134,10 @@ var init_schedulerService = __esm({
|
|
|
256134
256134
|
} catch {
|
|
256135
256135
|
}
|
|
256136
256136
|
}
|
|
256137
|
+
try {
|
|
256138
|
+
this.opts.onMinute?.(new Date(cur));
|
|
256139
|
+
} catch {
|
|
256140
|
+
}
|
|
256137
256141
|
cur = new Date(cur.getTime() + 6e4);
|
|
256138
256142
|
}
|
|
256139
256143
|
this.lastTickMs = nowMs;
|
|
@@ -348672,6 +348676,125 @@ var AgentRunLedger = class {
|
|
|
348672
348676
|
}
|
|
348673
348677
|
};
|
|
348674
348678
|
|
|
348679
|
+
// ../../packages/backend/src/services/AgentHelper/utils/safeMemorySaver.ts
|
|
348680
|
+
var CHECKPOINT_STRING_CAP = 8 * 1024;
|
|
348681
|
+
var CHECKPOINT_BYTES_CAP = 16 * 1024 * 1024;
|
|
348682
|
+
var CHECKPOINT_MAX_MESSAGES = 40;
|
|
348683
|
+
function truncateString(input, max = CHECKPOINT_STRING_CAP) {
|
|
348684
|
+
if (input.length <= max) return input;
|
|
348685
|
+
const omitted = input.length - max;
|
|
348686
|
+
return `${input.slice(0, max)}
|
|
348687
|
+
...[truncated ${omitted} chars for checkpoint]...`;
|
|
348688
|
+
}
|
|
348689
|
+
function pruneValue(value, depth = 0) {
|
|
348690
|
+
if (depth > 8) return "[pruned: depth]";
|
|
348691
|
+
if (typeof value === "string") return truncateString(value);
|
|
348692
|
+
if (Array.isArray(value)) {
|
|
348693
|
+
return value.map((item) => pruneValue(item, depth + 1));
|
|
348694
|
+
}
|
|
348695
|
+
if (value && typeof value === "object") {
|
|
348696
|
+
const obj = value;
|
|
348697
|
+
const out = {};
|
|
348698
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
348699
|
+
out[k] = pruneValue(v, depth + 1);
|
|
348700
|
+
}
|
|
348701
|
+
return out;
|
|
348702
|
+
}
|
|
348703
|
+
return value;
|
|
348704
|
+
}
|
|
348705
|
+
function pruneMessagesArray(messages) {
|
|
348706
|
+
const pruned = messages.map((m2) => pruneValue(m2));
|
|
348707
|
+
if (pruned.length <= CHECKPOINT_MAX_MESSAGES) return pruned;
|
|
348708
|
+
const keep = CHECKPOINT_MAX_MESSAGES - 1;
|
|
348709
|
+
const dropped = pruned.length - keep;
|
|
348710
|
+
return [
|
|
348711
|
+
{
|
|
348712
|
+
type: "system",
|
|
348713
|
+
content: `[checkpoint] dropped ${dropped} older messages to stay under memory cap`
|
|
348714
|
+
},
|
|
348715
|
+
...pruned.slice(-keep)
|
|
348716
|
+
];
|
|
348717
|
+
}
|
|
348718
|
+
function pruneCheckpointForSaver(checkpoint) {
|
|
348719
|
+
if (!checkpoint || typeof checkpoint !== "object") return checkpoint;
|
|
348720
|
+
const cp = checkpoint;
|
|
348721
|
+
const next = { ...cp };
|
|
348722
|
+
const channelValues = cp.channel_values;
|
|
348723
|
+
if (channelValues && typeof channelValues === "object") {
|
|
348724
|
+
const channels = { ...channelValues };
|
|
348725
|
+
if (Array.isArray(channels.messages)) {
|
|
348726
|
+
channels.messages = pruneMessagesArray(channels.messages);
|
|
348727
|
+
}
|
|
348728
|
+
for (const [k, v] of Object.entries(channels)) {
|
|
348729
|
+
if (k === "messages") continue;
|
|
348730
|
+
channels[k] = pruneValue(v);
|
|
348731
|
+
}
|
|
348732
|
+
next.channel_values = channels;
|
|
348733
|
+
}
|
|
348734
|
+
if ("pending_sends" in next) {
|
|
348735
|
+
next.pending_sends = pruneValue(next.pending_sends);
|
|
348736
|
+
}
|
|
348737
|
+
return next;
|
|
348738
|
+
}
|
|
348739
|
+
function isAllocationError(error40) {
|
|
348740
|
+
if (!error40) return false;
|
|
348741
|
+
const msg = error40 instanceof Error ? error40.message : String(error40);
|
|
348742
|
+
const name = error40 instanceof Error ? error40.name : "";
|
|
348743
|
+
return name === "RangeError" || /failed to allocate memory|invalid string length|array buffer allocation failed|Cannot allocate|ERR_STRING_TOO_LONG/i.test(
|
|
348744
|
+
msg
|
|
348745
|
+
);
|
|
348746
|
+
}
|
|
348747
|
+
var SafeMemorySaver = class extends MemorySaver {
|
|
348748
|
+
async put(config2, checkpoint, metadata) {
|
|
348749
|
+
const pruned = pruneCheckpointForSaver(checkpoint);
|
|
348750
|
+
try {
|
|
348751
|
+
return await super.put(config2, pruned, pruneValue(metadata));
|
|
348752
|
+
} catch (error40) {
|
|
348753
|
+
if (!isAllocationError(error40)) throw error40;
|
|
348754
|
+
console.warn(
|
|
348755
|
+
"[SafeMemorySaver] checkpoint serialize OOM \u2014 dropping older messages and retrying"
|
|
348756
|
+
);
|
|
348757
|
+
try {
|
|
348758
|
+
const tighter = pruneCheckpointForSaver(pruned);
|
|
348759
|
+
const channels = tighter.channel_values ?? {};
|
|
348760
|
+
if (Array.isArray(channels.messages)) {
|
|
348761
|
+
channels.messages = channels.messages.slice(-8);
|
|
348762
|
+
}
|
|
348763
|
+
tighter.channel_values = channels;
|
|
348764
|
+
return await super.put(config2, tighter, { source: "oom-pruned" });
|
|
348765
|
+
} catch (retryError) {
|
|
348766
|
+
if (!isAllocationError(retryError)) throw retryError;
|
|
348767
|
+
console.warn(
|
|
348768
|
+
"[SafeMemorySaver] checkpoint still too large \u2014 skipping persist so the run can finish"
|
|
348769
|
+
);
|
|
348770
|
+
return {
|
|
348771
|
+
configurable: {
|
|
348772
|
+
thread_id: config2?.configurable?.thread_id,
|
|
348773
|
+
checkpoint_ns: config2?.configurable?.checkpoint_ns ?? "",
|
|
348774
|
+
checkpoint_id: checkpoint?.id
|
|
348775
|
+
}
|
|
348776
|
+
};
|
|
348777
|
+
}
|
|
348778
|
+
}
|
|
348779
|
+
}
|
|
348780
|
+
async putWrites(config2, writes, taskId) {
|
|
348781
|
+
const prunedWrites = Array.isArray(writes) ? writes.map((w) => {
|
|
348782
|
+
if (Array.isArray(w) && w.length >= 2) {
|
|
348783
|
+
return [w[0], pruneValue(w[1]), ...w.slice(2)];
|
|
348784
|
+
}
|
|
348785
|
+
return pruneValue(w);
|
|
348786
|
+
}) : writes;
|
|
348787
|
+
try {
|
|
348788
|
+
return await super.putWrites(config2, prunedWrites, taskId);
|
|
348789
|
+
} catch (error40) {
|
|
348790
|
+
if (!isAllocationError(error40)) throw error40;
|
|
348791
|
+
console.warn(
|
|
348792
|
+
"[SafeMemorySaver] putWrites serialize OOM \u2014 skipping writes persist"
|
|
348793
|
+
);
|
|
348794
|
+
}
|
|
348795
|
+
}
|
|
348796
|
+
};
|
|
348797
|
+
|
|
348675
348798
|
// ../../packages/backend/src/services/AgentHelper/tools/edit_tools.ts
|
|
348676
348799
|
init_zod();
|
|
348677
348800
|
|
|
@@ -369354,13 +369477,17 @@ var AgentService_v2 = class {
|
|
|
369354
369477
|
this.imageAttachmentService = imageAttachmentService || null;
|
|
369355
369478
|
this.fileTransferService = fileTransferService || null;
|
|
369356
369479
|
this.helpers = new AgentHelpers();
|
|
369357
|
-
this.checkpointer = new
|
|
369480
|
+
this.checkpointer = new SafeMemorySaver();
|
|
369358
369481
|
this.initializeGraph();
|
|
369359
369482
|
}
|
|
369360
369483
|
updateSettings(settings) {
|
|
369361
369484
|
this.settings = settings;
|
|
369362
369485
|
this.builtInToolEnabled = settings.tools?.builtIn ?? {};
|
|
369363
369486
|
this.initializeGraph();
|
|
369487
|
+
try {
|
|
369488
|
+
this.triggerEngine?.reloadFrom(settings.automation?.triggers ?? []);
|
|
369489
|
+
} catch {
|
|
369490
|
+
}
|
|
369364
369491
|
}
|
|
369365
369492
|
setEventPublisher(publisher) {
|
|
369366
369493
|
this.helpers.setEventPublisher(publisher);
|
|
@@ -369444,15 +369571,18 @@ var AgentService_v2 = class {
|
|
|
369444
369571
|
return this.helpers.isAbortError(error40);
|
|
369445
369572
|
}
|
|
369446
369573
|
/**
|
|
369447
|
-
* v3.2.18: resolve a fallback model id
|
|
369448
|
-
*
|
|
369574
|
+
* v3.2.18 / v3.3.3: resolve a fallback model (id, name, or provider model
|
|
369575
|
+
* string) to its ModelDefinition. Must use `this.settings` — the previous
|
|
369576
|
+
* `this.options.getSettings` path never existed, so failover always missed.
|
|
369577
|
+
* Prefers an item that has an API key when several share the same model id.
|
|
369449
369578
|
*/
|
|
369450
369579
|
resolveFallbackModelItem(modelId) {
|
|
369451
369580
|
try {
|
|
369452
|
-
const
|
|
369453
|
-
|
|
369454
|
-
const
|
|
369455
|
-
|
|
369581
|
+
const items = this.settings?.models?.items ?? [];
|
|
369582
|
+
if (!modelId) return null;
|
|
369583
|
+
const keyed = items.filter((m2) => !!m2.apiKey);
|
|
369584
|
+
const pool = keyed.length ? keyed : items;
|
|
369585
|
+
return pool.find((m2) => m2.id === modelId) ?? pool.find((m2) => m2.model === modelId) ?? pool.find((m2) => m2.name === modelId) ?? null;
|
|
369456
369586
|
} catch {
|
|
369457
369587
|
return null;
|
|
369458
369588
|
}
|
|
@@ -370021,71 +370151,44 @@ var AgentService_v2 = class {
|
|
|
370021
370151
|
let reasoningContent = "";
|
|
370022
370152
|
let debugRawChunks = [];
|
|
370023
370153
|
const llmTraceStart = Date.now();
|
|
370024
|
-
const fallbacks = sessionBinding.fallbackModels;
|
|
370154
|
+
const fallbacks = sessionBinding.fallbackModels ?? [];
|
|
370025
370155
|
let fullResponse;
|
|
370026
|
-
|
|
370027
|
-
|
|
370028
|
-
|
|
370029
|
-
|
|
370030
|
-
|
|
370031
|
-
|
|
370032
|
-
|
|
370033
|
-
|
|
370034
|
-
|
|
370035
|
-
|
|
370036
|
-
|
|
370037
|
-
|
|
370038
|
-
|
|
370039
|
-
|
|
370040
|
-
|
|
370041
|
-
);
|
|
370042
|
-
modelToUse = fallbackChat.bindTools([...builtInTools, ...mcpTools]);
|
|
370043
|
-
}
|
|
370044
|
-
return await invokeWithRetryAndSanitizedInput({
|
|
370045
|
-
helpers: this.helpers,
|
|
370046
|
-
messages: modelInputMessages,
|
|
370047
|
-
modelSupportsImage: sessionBinding.readFileSupport.image,
|
|
370048
|
-
signal: config2?.signal,
|
|
370049
|
-
operation: async (streamInputMessages) => {
|
|
370050
|
-
const stream = await modelToUse.stream(streamInputMessages, { signal: config2?.signal });
|
|
370051
|
-
let response = null;
|
|
370052
|
-
for await (const chunk2 of stream) {
|
|
370053
|
-
response = response ? response.concat(chunk2) : chunk2;
|
|
370054
|
-
}
|
|
370055
|
-
if (!response) throw new Error("Model stream ended without a usable response.");
|
|
370056
|
-
return response;
|
|
370057
|
-
},
|
|
370058
|
-
onRetry: (attempt) => {
|
|
370059
|
-
this.helpers.sendEvent(sessionId, {
|
|
370060
|
-
type: "alert",
|
|
370061
|
-
message: `Retrying (${attempt}/${MODEL_RETRY_MAX})...`,
|
|
370062
|
-
level: "info",
|
|
370063
|
-
messageId: `retry-${messageId}-${attempt}`
|
|
370064
|
-
});
|
|
370065
|
-
},
|
|
370066
|
-
maxRetries: MODEL_RETRY_MAX,
|
|
370067
|
-
delaysMs: MODEL_RETRY_DELAYS_MS
|
|
370068
|
-
});
|
|
370069
|
-
}, {
|
|
370070
|
-
onAttempt: (a) => {
|
|
370071
|
-
if (!a.ok) {
|
|
370072
|
-
console.warn(`[AgentService_v2] model failover: ${a.model} failed (${a.reason}) after ${a.durationMs}ms`);
|
|
370073
|
-
}
|
|
370156
|
+
const { withModelFailover: withModelFailover2, buildFailoverChain: buildFailoverChain2 } = await Promise.resolve().then(() => (init_modelFailover(), modelFailover_exports));
|
|
370157
|
+
const primaryModel = baseModel?.model ?? baseModel?.modelName ?? "unknown";
|
|
370158
|
+
const chain = buildFailoverChain2(
|
|
370159
|
+
{ model: primaryModel },
|
|
370160
|
+
fallbacks.map((f) => ({ model: f.model, label: f.label }))
|
|
370161
|
+
);
|
|
370162
|
+
const failover = await withModelFailover2(chain, async (candidate) => {
|
|
370163
|
+
let modelToUse = modelWithTools;
|
|
370164
|
+
if (candidate.model !== primaryModel) {
|
|
370165
|
+
partialText = "";
|
|
370166
|
+
reasoningContent = "";
|
|
370167
|
+
debugRawChunks = [];
|
|
370168
|
+
const fallbackItem = this.resolveFallbackModelItem(candidate.model);
|
|
370169
|
+
if (!fallbackItem || !fallbackItem.apiKey) {
|
|
370170
|
+
throw new Error(`fallback model "${candidate.model}" is not configured or has no API key`);
|
|
370074
370171
|
}
|
|
370075
|
-
|
|
370076
|
-
|
|
370077
|
-
|
|
370078
|
-
|
|
370079
|
-
|
|
370172
|
+
this.helpers.sendEvent(sessionId, {
|
|
370173
|
+
type: "alert",
|
|
370174
|
+
message: `Primary model failed \u2014 failing over to ${candidate.label || candidate.model}`,
|
|
370175
|
+
level: "warning",
|
|
370176
|
+
messageId: `failover-${messageId}-${candidate.model}`
|
|
370177
|
+
});
|
|
370178
|
+
const fallbackChat = this.helpers.createChatModel(
|
|
370179
|
+
fallbackItem,
|
|
370180
|
+
shouldUseThinkingModelOnThisPass ? 0.2 : 0.7,
|
|
370181
|
+
null
|
|
370182
|
+
);
|
|
370183
|
+
modelToUse = fallbackChat.bindTools([...builtInTools, ...mcpTools]);
|
|
370080
370184
|
}
|
|
370081
|
-
|
|
370082
|
-
fullResponse = await invokeWithRetryAndSanitizedInput({
|
|
370185
|
+
return await invokeWithRetryAndSanitizedInput({
|
|
370083
370186
|
helpers: this.helpers,
|
|
370084
370187
|
messages: modelInputMessages,
|
|
370085
370188
|
modelSupportsImage: sessionBinding.readFileSupport.image,
|
|
370086
370189
|
signal: config2?.signal,
|
|
370087
370190
|
operation: async (streamInputMessages) => {
|
|
370088
|
-
const stream = await
|
|
370191
|
+
const stream = await modelToUse.stream(streamInputMessages, {
|
|
370089
370192
|
signal: config2?.signal
|
|
370090
370193
|
});
|
|
370091
370194
|
let response = null;
|
|
@@ -370245,6 +370348,19 @@ var AgentService_v2 = class {
|
|
|
370245
370348
|
maxRetries: MODEL_RETRY_MAX,
|
|
370246
370349
|
delaysMs: MODEL_RETRY_DELAYS_MS
|
|
370247
370350
|
});
|
|
370351
|
+
}, {
|
|
370352
|
+
onAttempt: (a) => {
|
|
370353
|
+
if (!a.ok) {
|
|
370354
|
+
console.warn(`[AgentService_v2] model failover: ${a.model} failed (${a.reason}) after ${a.durationMs}ms`);
|
|
370355
|
+
} else if (a.model !== primaryModel) {
|
|
370356
|
+
console.log(`[AgentService_v2] model failover: succeeded on ${a.model} after ${a.durationMs}ms`);
|
|
370357
|
+
}
|
|
370358
|
+
}
|
|
370359
|
+
});
|
|
370360
|
+
if (failover.value !== void 0) {
|
|
370361
|
+
fullResponse = failover.value;
|
|
370362
|
+
} else {
|
|
370363
|
+
throw failover.error ?? new Error("model failover exhausted all candidates");
|
|
370248
370364
|
}
|
|
370249
370365
|
fullResponse.additional_kwargs = {
|
|
370250
370366
|
...fullResponse.additional_kwargs || {},
|
|
@@ -386353,8 +386469,9 @@ function normalizePlaybookSteps(steps) {
|
|
|
386353
386469
|
if (!steps || steps.length === 0) throw new Error("A playbook needs at least one step");
|
|
386354
386470
|
return steps.map((s, idx) => {
|
|
386355
386471
|
const kind = s.kind;
|
|
386356
|
-
|
|
386357
|
-
|
|
386472
|
+
const allowed = ["command", "script", "wait", "template", "playbook", "healthCheck"];
|
|
386473
|
+
if (!allowed.includes(kind)) {
|
|
386474
|
+
throw new Error(`Step ${idx + 1}: kind must be ${allowed.join("|")}`);
|
|
386358
386475
|
}
|
|
386359
386476
|
if (kind === "command" && !(s.command ?? "").trim()) {
|
|
386360
386477
|
throw new Error(`Step ${idx + 1}: command steps need a non-empty command`);
|
|
@@ -386365,6 +386482,15 @@ function normalizePlaybookSteps(steps) {
|
|
|
386365
386482
|
if (kind === "wait" && !(typeof s.waitSeconds === "number" && s.waitSeconds > 0)) {
|
|
386366
386483
|
throw new Error(`Step ${idx + 1}: wait steps need waitSeconds > 0`);
|
|
386367
386484
|
}
|
|
386485
|
+
if (kind === "template" && !(s.templateId ?? "").trim()) {
|
|
386486
|
+
throw new Error(`Step ${idx + 1}: template steps need a templateId`);
|
|
386487
|
+
}
|
|
386488
|
+
if (kind === "playbook" && !(s.playbookId ?? "").trim()) {
|
|
386489
|
+
throw new Error(`Step ${idx + 1}: playbook steps need a playbookId`);
|
|
386490
|
+
}
|
|
386491
|
+
if (kind === "healthCheck" && !(s.healthUrl ?? "").trim()) {
|
|
386492
|
+
throw new Error(`Step ${idx + 1}: healthCheck steps need a healthUrl`);
|
|
386493
|
+
}
|
|
386368
386494
|
if (s.onError && s.onError !== "stop" && s.onError !== "continue") {
|
|
386369
386495
|
throw new Error(`Step ${idx + 1}: onError must be stop|continue`);
|
|
386370
386496
|
}
|
|
@@ -387867,6 +387993,7 @@ var AgentSettingProfileService = class {
|
|
|
387867
387993
|
|
|
387868
387994
|
// ../../packages/backend/src/services/automation/triggerEngine.ts
|
|
387869
387995
|
var import_crypto10 = require("crypto");
|
|
387996
|
+
init_schedulerService();
|
|
387870
387997
|
var DEFAULT_COOLDOWN_S = 300;
|
|
387871
387998
|
var HISTORY_LIMIT_DEFAULT2 = 200;
|
|
387872
387999
|
var MAX_CONCURRENT_DEFAULT = 3;
|
|
@@ -387922,6 +388049,19 @@ var TriggerEngine = class {
|
|
|
387922
388049
|
if (!t) return false;
|
|
387923
388050
|
return this.triggers.delete(t.id);
|
|
387924
388051
|
}
|
|
388052
|
+
/** Replace in-memory triggers from persisted settings (UI save path). */
|
|
388053
|
+
reloadFrom(list) {
|
|
388054
|
+
const previous = new Map(this.triggers);
|
|
388055
|
+
this.triggers.clear();
|
|
388056
|
+
for (const t of list) {
|
|
388057
|
+
const existing = previous.get(t.id);
|
|
388058
|
+
this.triggers.set(t.id, {
|
|
388059
|
+
...t,
|
|
388060
|
+
fireCount: t.fireCount ?? existing?.fireCount ?? 0,
|
|
388061
|
+
lastFiredAt: t.lastFiredAt ?? existing?.lastFiredAt
|
|
388062
|
+
});
|
|
388063
|
+
}
|
|
388064
|
+
}
|
|
387925
388065
|
setEnabled(idOrName, enabled) {
|
|
387926
388066
|
const t = this.get(idOrName);
|
|
387927
388067
|
if (!t) return false;
|
|
@@ -387956,6 +388096,25 @@ var TriggerEngine = class {
|
|
|
387956
388096
|
}
|
|
387957
388097
|
}
|
|
387958
388098
|
}
|
|
388099
|
+
/**
|
|
388100
|
+
* Fire every enabled schedule-kind trigger whose cron matches `at`.
|
|
388101
|
+
* Called from SchedulerService on each minute tick.
|
|
388102
|
+
*/
|
|
388103
|
+
fire_schedule(at) {
|
|
388104
|
+
const fired = [];
|
|
388105
|
+
for (const t of this.triggers.values()) {
|
|
388106
|
+
if (!t.enabled || t.kind !== "schedule") continue;
|
|
388107
|
+
if (!t.cron) continue;
|
|
388108
|
+
try {
|
|
388109
|
+
const due = t.timezone ? matchesCronInTz(t.cron, at, t.timezone) : matchesCron(t.cron, at);
|
|
388110
|
+
if (!due) continue;
|
|
388111
|
+
void this.fire(t, `schedule "${t.cron}" at ${at.toISOString()}`);
|
|
388112
|
+
fired.push(t.id);
|
|
388113
|
+
} catch {
|
|
388114
|
+
}
|
|
388115
|
+
}
|
|
388116
|
+
return fired;
|
|
388117
|
+
}
|
|
387959
388118
|
/** Manually fire any webhook-kind triggers (or test a specific one). */
|
|
387960
388119
|
fire_webhook(triggerIdOrName, reason) {
|
|
387961
388120
|
const fired = [];
|
|
@@ -397541,6 +397700,12 @@ async function startGyBackend() {
|
|
|
397541
397700
|
}
|
|
397542
397701
|
const scheduler = new SchedulerService({
|
|
397543
397702
|
getTasks: () => automationManager.listScheduledTasks(),
|
|
397703
|
+
onMinute: (at) => {
|
|
397704
|
+
try {
|
|
397705
|
+
triggerEngine.fire_schedule(at);
|
|
397706
|
+
} catch {
|
|
397707
|
+
}
|
|
397708
|
+
},
|
|
397544
397709
|
onSkip: (task2, reason) => {
|
|
397545
397710
|
if (reason === "overlap-skip") {
|
|
397546
397711
|
console.warn(
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,11 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neuralos",
|
|
3
|
-
"version": "3.3.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "3.3.4",
|
|
4
|
+
"description": "AI-native terminal & agentic-AI operations platform for Forward Deployed Engineers & SREs: AIOps closed-loop remediation, AI SRE, self-healing infrastructure, runbook automation, ChatOps; executes over SSH/WinRM/serial under policy with tamper-evident audit.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"forward-deployed-engineer",
|
|
7
|
+
"fde",
|
|
8
|
+
"ai-terminal",
|
|
9
|
+
"ai-agent",
|
|
10
|
+
"ssh",
|
|
11
|
+
"winrm",
|
|
12
|
+
"serial-console",
|
|
13
|
+
"cisco",
|
|
14
|
+
"network-automation",
|
|
15
|
+
"sre",
|
|
16
|
+
"observability",
|
|
17
|
+
"incident-response",
|
|
18
|
+
"change-management",
|
|
19
|
+
"infrastructure-automation",
|
|
20
|
+
"runbooks",
|
|
21
|
+
"neuralos",
|
|
22
|
+
"aiops",
|
|
23
|
+
"ai-sre",
|
|
24
|
+
"agentic-ai",
|
|
25
|
+
"chatops",
|
|
26
|
+
"self-healing",
|
|
27
|
+
"runbook-automation",
|
|
28
|
+
"closed-loop-remediation",
|
|
29
|
+
"mcp"
|
|
30
|
+
],
|
|
7
31
|
"license": "MIT",
|
|
8
|
-
"
|
|
32
|
+
"homepage": "https://rterm.app",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/DrOlu/RTerm.git"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18"
|
|
39
|
+
},
|
|
40
|
+
"bin": {
|
|
41
|
+
"gybackend": "bin/gybackend.cjs"
|
|
42
|
+
},
|
|
43
|
+
"main": "bin/gybackend.cjs",
|
|
9
44
|
"dependencies": {
|
|
10
45
|
"@nats-io/jetstream": "^3.4.0",
|
|
11
46
|
"@nats-io/kv": "^3.4.0",
|