neuralos 3.3.8 → 3.4.0
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
CHANGED
|
@@ -350712,12 +350712,12 @@ var BUILTIN_TOOL_INFO = [
|
|
|
350712
350712
|
{
|
|
350713
350713
|
name: "write_file",
|
|
350714
350714
|
description: WRITE_FILE_TOOL_DESCRIPTION,
|
|
350715
|
-
|
|
350715
|
+
shortDescription: "Write a full file (replace contents)"
|
|
350716
350716
|
},
|
|
350717
350717
|
{
|
|
350718
350718
|
name: "edit_file",
|
|
350719
350719
|
description: EDIT_FILE_TOOL_DESCRIPTION,
|
|
350720
|
-
|
|
350720
|
+
shortDescription: "Edit a file by replacing an exact string"
|
|
350721
350721
|
},
|
|
350722
350722
|
{
|
|
350723
350723
|
name: "skill",
|
|
@@ -354867,6 +354867,7 @@ var CORE_METHODS = [
|
|
|
354867
354867
|
m("tools:getMcp", "tools", "List MCP tools.", "1.0.0"),
|
|
354868
354868
|
m("tools:setMcpEnabled", "tools", "Enable/disable an MCP tool.", "1.0.0"),
|
|
354869
354869
|
m("tools:getBuiltIn", "tools", "List built-in agent tools with enabled state.", "1.0.0"),
|
|
354870
|
+
m("tools:getPlugins", "tools", "List plugin agent tools (name, plugin, description).", "3.4.0"),
|
|
354870
354871
|
m("tools:setBuiltInEnabled", "tools", "Enable/disable a built-in tool.", "1.0.0", { name: { type: "string" }, enabled: { type: "boolean" } })
|
|
354871
354872
|
];
|
|
354872
354873
|
var DESCRIBE_METHOD = m(
|
|
@@ -369458,6 +369459,7 @@ var AgentService_v2 = class {
|
|
|
369458
369459
|
pluginTools = /* @__PURE__ */ new Map();
|
|
369459
369460
|
/** Plugin tool schemas (for toolsForModel injection). */
|
|
369460
369461
|
pluginToolSchemas = [];
|
|
369462
|
+
pluginToolMeta = [];
|
|
369461
369463
|
passChatTempExportService = new PassChatTempExportService();
|
|
369462
369464
|
fallbackCompactionHistoryExportService = null;
|
|
369463
369465
|
activeAgentRunIdsBySession = /* @__PURE__ */ new Map();
|
|
@@ -369516,11 +369518,35 @@ var AgentService_v2 = class {
|
|
|
369516
369518
|
* pluginTools (so the dispatch switch's default case can call them). */
|
|
369517
369519
|
setPluginTools(tools2) {
|
|
369518
369520
|
this.pluginTools = new Map(tools2.map((t) => [t.name, t.handler]));
|
|
369519
|
-
this.
|
|
369521
|
+
this.pluginToolMeta = tools2.map((t) => ({
|
|
369520
369522
|
name: t.name,
|
|
369521
|
-
description: t.description,
|
|
369522
|
-
|
|
369523
|
+
description: t.description || t.name,
|
|
369524
|
+
plugin: t.plugin || "plugin"
|
|
369523
369525
|
}));
|
|
369526
|
+
this.pluginToolSchemas = tools2.map((t) => {
|
|
369527
|
+
const params = t.params && typeof t.params === "object" ? t.params : {};
|
|
369528
|
+
const looksJsonSchema = typeof params.type === "string";
|
|
369529
|
+
const parameters = looksJsonSchema ? params : {
|
|
369530
|
+
type: "object",
|
|
369531
|
+
properties: params,
|
|
369532
|
+
additionalProperties: true
|
|
369533
|
+
};
|
|
369534
|
+
return {
|
|
369535
|
+
type: "function",
|
|
369536
|
+
function: {
|
|
369537
|
+
name: t.name,
|
|
369538
|
+
description: t.description || t.name,
|
|
369539
|
+
parameters
|
|
369540
|
+
}
|
|
369541
|
+
};
|
|
369542
|
+
});
|
|
369543
|
+
}
|
|
369544
|
+
/** Plugin tools in OpenAI bindTools shape (empty until setPluginTools). */
|
|
369545
|
+
getPluginToolSchemas() {
|
|
369546
|
+
return this.pluginToolSchemas;
|
|
369547
|
+
}
|
|
369548
|
+
listPluginTools() {
|
|
369549
|
+
return this.pluginToolMeta.map((t) => ({ ...t, enabled: true }));
|
|
369524
369550
|
}
|
|
369525
369551
|
/** Wire a session-log handle so list_session_logs / read_session_log work. */
|
|
369526
369552
|
setSessionLogger(logger) {
|
|
@@ -370142,9 +370168,11 @@ var AgentService_v2 = class {
|
|
|
370142
370168
|
}
|
|
370143
370169
|
);
|
|
370144
370170
|
const baseModel = shouldUseThinkingModelOnThisPass ? sessionBinding.thinkingModel || sessionBinding.model : sessionBinding.model;
|
|
370171
|
+
const pluginOpenAiTools = this.pluginToolSchemas;
|
|
370145
370172
|
const modelWithTools = baseModel.bindTools([
|
|
370146
370173
|
...builtInTools,
|
|
370147
|
-
...mcpTools
|
|
370174
|
+
...mcpTools,
|
|
370175
|
+
...pluginOpenAiTools
|
|
370148
370176
|
]);
|
|
370149
370177
|
const messageId = v4_default();
|
|
370150
370178
|
let partialText = "";
|
|
@@ -370180,7 +370208,11 @@ var AgentService_v2 = class {
|
|
|
370180
370208
|
shouldUseThinkingModelOnThisPass ? 0.2 : 0.7,
|
|
370181
370209
|
null
|
|
370182
370210
|
);
|
|
370183
|
-
modelToUse = fallbackChat.bindTools([
|
|
370211
|
+
modelToUse = fallbackChat.bindTools([
|
|
370212
|
+
...builtInTools,
|
|
370213
|
+
...mcpTools,
|
|
370214
|
+
...pluginOpenAiTools
|
|
370215
|
+
]);
|
|
370184
370216
|
}
|
|
370185
370217
|
return await invokeWithRetryAndSanitizedInput({
|
|
370186
370218
|
helpers: this.helpers,
|
|
@@ -376649,6 +376681,15 @@ var WebSocketGatewayAdapter = class {
|
|
|
376649
376681
|
}
|
|
376650
376682
|
return await this.options.toolsBridge.getBuiltIn();
|
|
376651
376683
|
}
|
|
376684
|
+
case "tools:getPlugins": {
|
|
376685
|
+
if (!this.options.toolsBridge?.getPlugins) {
|
|
376686
|
+
throw new WebSocketRpcError(
|
|
376687
|
+
"METHOD_NOT_FOUND",
|
|
376688
|
+
"tools:getPlugins is not available on this websocket gateway."
|
|
376689
|
+
);
|
|
376690
|
+
}
|
|
376691
|
+
return await this.options.toolsBridge.getPlugins();
|
|
376692
|
+
}
|
|
376652
376693
|
case "tools:setBuiltInEnabled": {
|
|
376653
376694
|
if (!this.options.toolsBridge?.setBuiltInEnabled) {
|
|
376654
376695
|
throw new WebSocketRpcError(
|
|
@@ -392577,6 +392618,23 @@ var PluginRegistry = class {
|
|
|
392577
392618
|
allTools() {
|
|
392578
392619
|
return this.list().filter((p) => p.enabled && !p.error).flatMap((p) => p.tools);
|
|
392579
392620
|
}
|
|
392621
|
+
/** Flatten enabled plugin tools for AgentService.setPluginTools. */
|
|
392622
|
+
collectAgentTools() {
|
|
392623
|
+
const out = [];
|
|
392624
|
+
for (const record2 of this.list()) {
|
|
392625
|
+
if (record2.error || !record2.enabled) continue;
|
|
392626
|
+
for (const tool2 of record2.tools) {
|
|
392627
|
+
out.push({
|
|
392628
|
+
name: tool2.name,
|
|
392629
|
+
description: tool2.description ?? "",
|
|
392630
|
+
params: tool2.params ?? {},
|
|
392631
|
+
handler: tool2.handler,
|
|
392632
|
+
plugin: record2.manifest.name
|
|
392633
|
+
});
|
|
392634
|
+
}
|
|
392635
|
+
}
|
|
392636
|
+
return out;
|
|
392637
|
+
}
|
|
392580
392638
|
/** All triggers from enabled plugins. */
|
|
392581
392639
|
allTriggers() {
|
|
392582
392640
|
return this.list().filter((p) => p.enabled && !p.error).flatMap((p) => p.triggers);
|
|
@@ -398016,25 +398074,15 @@ async function startGyBackend() {
|
|
|
398016
398074
|
Promise.race([
|
|
398017
398075
|
observability.pluginRegistry.reload(),
|
|
398018
398076
|
new Promise((_, reject) => setTimeout(() => reject(new Error("plugin reload timeout (10s)")), 1e4))
|
|
398019
|
-
]).then((
|
|
398020
|
-
const pluginTools =
|
|
398021
|
-
|
|
398022
|
-
|
|
398023
|
-
|
|
398024
|
-
|
|
398025
|
-
|
|
398026
|
-
description: tool2.description ?? "",
|
|
398027
|
-
params: tool2.params ?? {},
|
|
398028
|
-
handler: tool2.handler
|
|
398029
|
-
});
|
|
398030
|
-
}
|
|
398031
|
-
}
|
|
398032
|
-
if (pluginTools.length > 0) {
|
|
398033
|
-
agentService.setPluginTools(pluginTools);
|
|
398034
|
-
console.log(`[gybackend] Wired ${pluginTools.length} plugin tools from ${pluginRecords.filter((r) => !r.error && r.enabled).length} plugins into the agent.`);
|
|
398035
|
-
} else {
|
|
398036
|
-
console.log("[gybackend] No plugin tools found to wire.");
|
|
398077
|
+
]).then(() => {
|
|
398078
|
+
const pluginTools = observability.pluginRegistry.collectAgentTools();
|
|
398079
|
+
agentService.setPluginTools(pluginTools);
|
|
398080
|
+
const enabled = observability.pluginRegistry.list().filter((r) => !r.error && r.enabled).length;
|
|
398081
|
+
try {
|
|
398082
|
+
gatewayService.broadcastRaw("tools:pluginsUpdated", agentService.listPluginTools());
|
|
398083
|
+
} catch {
|
|
398037
398084
|
}
|
|
398085
|
+
console.log(`[gybackend] Wired ${pluginTools.length} plugin tools from ${enabled} plugins into the agent.`);
|
|
398038
398086
|
}).catch((e) => {
|
|
398039
398087
|
console.warn("[gybackend] Plugin tool wiring skipped:", e instanceof Error ? e.message : String(e));
|
|
398040
398088
|
});
|
|
@@ -398698,6 +398746,7 @@ async function startGyBackend() {
|
|
|
398698
398746
|
const settings = settingsService.getSettings();
|
|
398699
398747
|
return buildBuiltInToolStatusSummary(settings.tools?.builtIn);
|
|
398700
398748
|
},
|
|
398749
|
+
getPlugins: () => agentService.listPluginTools(),
|
|
398701
398750
|
setBuiltInEnabled: async (name, enabled) => {
|
|
398702
398751
|
const settings = settingsService.getSettings();
|
|
398703
398752
|
const nextBuiltIn = { ...settings.tools?.builtIn ?? {} };
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neuralos",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
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
5
|
"keywords": [
|
|
6
6
|
"forward-deployed-engineer",
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* monid-bridge — thin wrapper around the official Monid CLI.
|
|
2
|
+
* monid-bridge — thin wrapper around the official Monid CLI (v0.1.6).
|
|
3
3
|
*
|
|
4
|
-
* Settings → Plugins → Monid (settings.monid):
|
|
5
|
-
*
|
|
6
|
-
* The API key is NEVER stored in settings.json. Saving a key in the UI runs
|
|
7
|
-
* `monid keys add -k <key> -l <label>` (see applyMonidApiKey).
|
|
4
|
+
* Settings → Plugins → Monid (settings.monid): enabled, binaryPath, keyLabel
|
|
5
|
+
* API key is NEVER stored in settings.json (`monid keys add -k … -l …`).
|
|
8
6
|
*
|
|
9
|
-
* Agent tools: monid_health, monid_discover, monid_run.
|
|
7
|
+
* Agent tools: monid_health, monid_discover, monid_inspect, monid_run.
|
|
8
|
+
*
|
|
9
|
+
* Argv MUST match `monid <cmd> --help`:
|
|
10
|
+
* discover --query <q> [--limit n] [--min-score s] --json
|
|
11
|
+
* inspect --provider <p> --endpoint <e> --json
|
|
12
|
+
* run --provider <p> --endpoint <e> [--input json] [--query json] [--path json] --json
|
|
13
|
+
* Bare `discover <query>` / `run <tool>` are false positives (CLI rejects them).
|
|
10
14
|
*/
|
|
11
15
|
|
|
12
16
|
import { createRequire } from 'node:module'
|
|
@@ -23,25 +27,80 @@ export function resolveConfig(ctx = {}, env = process.env) {
|
|
|
23
27
|
}
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
function reqStr(v, name) {
|
|
31
|
+
const s = String(v ?? '').trim()
|
|
32
|
+
if (!s) throw new Error(`${name} is required`)
|
|
33
|
+
return s
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function optJsonFlag(argv, flag, value) {
|
|
37
|
+
if (value == null) return
|
|
38
|
+
const s = typeof value === 'string' ? value.trim() : JSON.stringify(value)
|
|
39
|
+
if (!s) return
|
|
40
|
+
argv.push(flag, s)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function optNumFlag(argv, flag, value) {
|
|
44
|
+
if (value == null || value === '') return
|
|
45
|
+
const n = Number(value)
|
|
46
|
+
if (!Number.isFinite(n)) throw new Error(`${flag} must be a number`)
|
|
47
|
+
argv.push(flag, String(n))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Build argv AFTER the binary name.
|
|
52
|
+
* Always pass --json so agents get structured output (no ANSI).
|
|
53
|
+
*/
|
|
27
54
|
export function buildMonidArgv(sub, params = {}) {
|
|
28
55
|
switch (sub) {
|
|
29
56
|
case 'version':
|
|
30
57
|
return ['--version']
|
|
31
58
|
case 'keys-list':
|
|
32
59
|
return ['keys', 'list']
|
|
60
|
+
case 'whoami':
|
|
61
|
+
return ['whoami']
|
|
33
62
|
case 'discover': {
|
|
34
|
-
const q =
|
|
35
|
-
|
|
36
|
-
|
|
63
|
+
const q = reqStr(params.query, 'query')
|
|
64
|
+
const argv = ['discover', '--query', q]
|
|
65
|
+
optNumFlag(argv, '--limit', params.limit)
|
|
66
|
+
optNumFlag(argv, '--min-score', params.minScore ?? params['min-score'])
|
|
67
|
+
argv.push('--json')
|
|
68
|
+
return argv
|
|
69
|
+
}
|
|
70
|
+
case 'inspect': {
|
|
71
|
+
const provider = reqStr(params.provider, 'provider')
|
|
72
|
+
const endpoint = reqStr(params.endpoint, 'endpoint')
|
|
73
|
+
return ['inspect', '--provider', provider, '--endpoint', endpoint, '--json']
|
|
37
74
|
}
|
|
38
75
|
case 'run': {
|
|
76
|
+
// FN: agents may pass tool="provider/endpoint" from older docs.
|
|
77
|
+
let provider = String(params.provider || '').trim()
|
|
78
|
+
let endpoint = String(params.endpoint || '').trim()
|
|
39
79
|
const tool = String(params.tool || '').trim()
|
|
40
|
-
if (!
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
80
|
+
if ((!provider || !endpoint) && tool) {
|
|
81
|
+
const slash = tool.indexOf('/')
|
|
82
|
+
if (slash > 0) {
|
|
83
|
+
provider = provider || tool.slice(0, slash)
|
|
84
|
+
endpoint = endpoint || tool.slice(slash)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!provider) throw new Error('monid_run needs provider (slug from discover)')
|
|
88
|
+
if (!endpoint) throw new Error('monid_run needs endpoint (path from discover, e.g. /news/search)')
|
|
89
|
+
if (!endpoint.startsWith('/')) {
|
|
90
|
+
throw new Error('endpoint must start with / (Monid endpoint path, not a free-form tool name)')
|
|
91
|
+
}
|
|
92
|
+
const argv = ['run', '--provider', provider, '--endpoint', endpoint]
|
|
93
|
+
const input = params.input ?? params.body
|
|
94
|
+
if (input != null && String(input).trim()) {
|
|
95
|
+
argv.push('--input', typeof input === 'string' ? input : JSON.stringify(input))
|
|
44
96
|
}
|
|
97
|
+
optJsonFlag(argv, '--query', params.queryParams ?? params.query)
|
|
98
|
+
optJsonFlag(argv, '--path', params.pathParams ?? params.path)
|
|
99
|
+
if (params.wait != null && params.wait !== false && params.wait !== '') {
|
|
100
|
+
argv.push('--wait')
|
|
101
|
+
if (params.wait !== true) argv.push(String(params.wait))
|
|
102
|
+
}
|
|
103
|
+
argv.push('--json')
|
|
45
104
|
return argv
|
|
46
105
|
}
|
|
47
106
|
default:
|
|
@@ -49,21 +108,30 @@ export function buildMonidArgv(sub, params = {}) {
|
|
|
49
108
|
}
|
|
50
109
|
}
|
|
51
110
|
|
|
111
|
+
/** True if argv looks like the broken 3.3.8 shapes (for tests / guards). */
|
|
112
|
+
export function isLegacyBrokenArgv(argv) {
|
|
113
|
+
if (!Array.isArray(argv) || argv.length < 2) return false
|
|
114
|
+
if (argv[0] === 'discover' && argv[1] !== '--query' && !argv[1].startsWith('-')) return true
|
|
115
|
+
if (argv[0] === 'run' && argv[1] !== '--provider' && !String(argv[1]).startsWith('-')) return true
|
|
116
|
+
return false
|
|
117
|
+
}
|
|
118
|
+
|
|
52
119
|
async function runMonid(ctx, cfg, argv) {
|
|
120
|
+
const env = { ...process.env, NO_COLOR: '1' }
|
|
53
121
|
if (typeof ctx.runCommand === 'function') {
|
|
54
|
-
const cmdline = [cfg.binaryPath, ...argv].map((a) => (/\s/.test(a) ?
|
|
55
|
-
return ctx.runCommand({ command: cmdline })
|
|
122
|
+
const cmdline = [cfg.binaryPath, ...argv].map((a) => (/\s/.test(a) ? JSON.stringify(a) : a)).join(' ')
|
|
123
|
+
return ctx.runCommand({ command: cmdline, env })
|
|
56
124
|
}
|
|
57
125
|
if (typeof ctx.exec === 'function') {
|
|
58
|
-
const cmdline = [cfg.binaryPath, ...argv].map((a) => (/\s/.test(a) ?
|
|
59
|
-
return ctx.exec(cmdline)
|
|
126
|
+
const cmdline = [cfg.binaryPath, ...argv].map((a) => (/\s/.test(a) ? JSON.stringify(a) : a)).join(' ')
|
|
127
|
+
return ctx.exec(cmdline, { env })
|
|
60
128
|
}
|
|
61
129
|
const { execFile } = require('node:child_process')
|
|
62
130
|
return new Promise((resolve) => {
|
|
63
|
-
execFile(cfg.binaryPath, argv, { timeout: 120000, env
|
|
131
|
+
execFile(cfg.binaryPath, argv, { timeout: 120000, env }, (err, stdout, stderr) => {
|
|
64
132
|
resolve({
|
|
65
133
|
ok: !err,
|
|
66
|
-
exitCode: err?.code
|
|
134
|
+
exitCode: typeof err?.code === 'number' ? err.code : err ? 1 : 0,
|
|
67
135
|
stdout: String(stdout ?? ''),
|
|
68
136
|
stderr: String(stderr ?? ''),
|
|
69
137
|
error: err ? String(err.message) : undefined,
|
|
@@ -80,7 +148,7 @@ async function guarded(fn, log) {
|
|
|
80
148
|
log?.(`[monid] ${msg}`)
|
|
81
149
|
return {
|
|
82
150
|
error: msg,
|
|
83
|
-
hint: 'Install @monid-ai/cli (`npm i -g @monid-ai/cli`) and paste an API key in Settings → Plugins → Monid
|
|
151
|
+
hint: 'Install @monid-ai/cli (`npm i -g @monid-ai/cli`) and paste an API key in Settings → Plugins → Monid. discover needs --query; run needs --provider and --endpoint.',
|
|
84
152
|
}
|
|
85
153
|
}
|
|
86
154
|
}
|
|
@@ -101,15 +169,19 @@ export function register(ctx) {
|
|
|
101
169
|
guarded(async () => {
|
|
102
170
|
const ver = await runMonid(ctx, cfg, buildMonidArgv('version'))
|
|
103
171
|
const keys = await runMonid(ctx, cfg, buildMonidArgv('keys-list'))
|
|
104
|
-
|
|
172
|
+
const who = await runMonid(ctx, cfg, buildMonidArgv('whoami'))
|
|
173
|
+
return { binaryPath: cfg.binaryPath, keyLabel: cfg.keyLabel, version: ver, keys, whoami: who }
|
|
105
174
|
}, log),
|
|
106
175
|
})
|
|
107
176
|
|
|
108
177
|
registerTool({
|
|
109
178
|
name: 'monid_discover',
|
|
110
|
-
description:
|
|
179
|
+
description:
|
|
180
|
+
'Search Monid data endpoints with natural language (company news, people, enrichment). Uses `monid discover --query`. Do not pass a bare positional query.',
|
|
111
181
|
params: {
|
|
112
|
-
query: { type: 'string', description: '
|
|
182
|
+
query: { type: 'string', description: 'Natural-language search (required)' },
|
|
183
|
+
limit: { type: 'number', description: 'Max results (max 50)', optional: true },
|
|
184
|
+
minScore: { type: 'number', description: 'Minimum relevance score', optional: true },
|
|
113
185
|
},
|
|
114
186
|
handler: async (p) =>
|
|
115
187
|
guarded(async () => {
|
|
@@ -119,12 +191,32 @@ export function register(ctx) {
|
|
|
119
191
|
}, log),
|
|
120
192
|
})
|
|
121
193
|
|
|
194
|
+
registerTool({
|
|
195
|
+
name: 'monid_inspect',
|
|
196
|
+
description: 'Get full details for one Monid endpoint (`monid inspect --provider --endpoint`).',
|
|
197
|
+
params: {
|
|
198
|
+
provider: { type: 'string', description: 'Provider slug (e.g. context.dev)' },
|
|
199
|
+
endpoint: { type: 'string', description: 'Endpoint path (e.g. /news/search)' },
|
|
200
|
+
},
|
|
201
|
+
handler: async (p) =>
|
|
202
|
+
guarded(async () => {
|
|
203
|
+
const argv = buildMonidArgv('inspect', p)
|
|
204
|
+
const r = await runMonid(ctx, cfg, argv)
|
|
205
|
+
return { argv: [cfg.binaryPath, ...argv], ...r }
|
|
206
|
+
}, log),
|
|
207
|
+
})
|
|
208
|
+
|
|
122
209
|
registerTool({
|
|
123
210
|
name: 'monid_run',
|
|
124
|
-
description:
|
|
211
|
+
description:
|
|
212
|
+
'Execute a Monid endpoint (`monid run --provider --endpoint`). provider+endpoint from discover; optional JSON --input / --query / --path. Not `monid run <toolName>`.',
|
|
125
213
|
params: {
|
|
126
|
-
|
|
127
|
-
|
|
214
|
+
provider: { type: 'string', description: 'Provider slug', optional: true },
|
|
215
|
+
endpoint: { type: 'string', description: 'Endpoint path starting with /', optional: true },
|
|
216
|
+
tool: { type: 'string', description: 'Optional shorthand provider/endpoint', optional: true },
|
|
217
|
+
input: { type: 'string', description: 'Body JSON string', optional: true },
|
|
218
|
+
queryParams: { type: 'string', description: 'Query-parameters JSON string', optional: true },
|
|
219
|
+
pathParams: { type: 'string', description: 'Path-parameters JSON string', optional: true },
|
|
128
220
|
},
|
|
129
221
|
handler: async (p) =>
|
|
130
222
|
guarded(async () => {
|
|
@@ -1,27 +1,75 @@
|
|
|
1
|
-
import { buildMonidArgv, resolveConfig } from './index.mjs'
|
|
1
|
+
import { buildMonidArgv, isLegacyBrokenArgv, resolveConfig } from './index.mjs'
|
|
2
2
|
|
|
3
3
|
const assert = (c, m) => {
|
|
4
4
|
if (!c) throw new Error(`assert failed: ${m}`)
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
// --- config ---
|
|
7
8
|
assert(resolveConfig({ settings: {} }).enabled === true, 'enabled default')
|
|
8
9
|
assert(resolveConfig({ settings: { monid: { enabled: false } } }).enabled === false, 'disabled')
|
|
9
10
|
assert(resolveConfig({ settings: { monid: { binaryPath: '/opt/monid' } } }).binaryPath === '/opt/monid', 'bin')
|
|
10
11
|
assert(resolveConfig({}, { MONID_BIN: 'custom-monid' }).binaryPath === 'custom-monid', 'env bin')
|
|
11
12
|
|
|
13
|
+
// --- FP: 3.3.8 positional argv must be detected as broken ---
|
|
14
|
+
assert(isLegacyBrokenArgv(['discover', 'company news']) === true, 'FP discover positional')
|
|
15
|
+
assert(isLegacyBrokenArgv(['run', 'foo']) === true, 'FP run positional')
|
|
16
|
+
assert(isLegacyBrokenArgv(['discover', '--query', 'company news']) === false, 'good discover')
|
|
17
|
+
assert(isLegacyBrokenArgv(['run', '--provider', 'x', '--endpoint', '/y']) === false, 'good run')
|
|
18
|
+
|
|
19
|
+
const disc = buildMonidArgv('discover', { query: 'company news', limit: 5 })
|
|
20
|
+
assert(!isLegacyBrokenArgv(disc), 'new discover not legacy')
|
|
21
|
+
assert(disc[0] === 'discover' && disc[1] === '--query' && disc[2] === 'company news', `disc=${disc}`)
|
|
22
|
+
assert(disc.includes('--limit') && disc.includes('5') && disc.includes('--json'), 'limit+json')
|
|
23
|
+
|
|
12
24
|
assert(buildMonidArgv('version').join(' ') === '--version', 'version')
|
|
13
25
|
assert(buildMonidArgv('keys-list').join(' ') === 'keys list', 'keys list')
|
|
14
|
-
assert(buildMonidArgv('
|
|
15
|
-
|
|
26
|
+
assert(buildMonidArgv('whoami').join(' ') === 'whoami', 'whoami')
|
|
27
|
+
|
|
28
|
+
const insp = buildMonidArgv('inspect', { provider: 'context.dev', endpoint: '/news/search' })
|
|
29
|
+
assert(insp.join(' ') === 'inspect --provider context.dev --endpoint /news/search --json', insp.join(' '))
|
|
30
|
+
|
|
31
|
+
const run = buildMonidArgv('run', {
|
|
32
|
+
provider: 'context.dev',
|
|
33
|
+
endpoint: '/news/search',
|
|
34
|
+
input: '{"q":"acme"}',
|
|
35
|
+
})
|
|
36
|
+
assert(run[0] === 'run' && run.includes('--provider') && run.includes('context.dev'), 'run provider')
|
|
37
|
+
assert(run.includes('--endpoint') && run.includes('/news/search'), 'run endpoint')
|
|
38
|
+
assert(run.includes('--input') && run.includes('--json'), 'run input+json')
|
|
39
|
+
assert(!isLegacyBrokenArgv(run), 'new run not legacy')
|
|
40
|
+
|
|
41
|
+
// FN: tool="provider/endpoint" shorthand
|
|
42
|
+
const fromTool = buildMonidArgv('run', { tool: 'apollo/mixed_companies/search' })
|
|
43
|
+
assert(fromTool.includes('apollo') && fromTool.includes('/mixed_companies/search'), `fromTool=${fromTool}`)
|
|
16
44
|
|
|
45
|
+
// FN: queryParams / pathParams
|
|
46
|
+
const withQP = buildMonidArgv('run', {
|
|
47
|
+
provider: 'akta',
|
|
48
|
+
endpoint: '/v1/news',
|
|
49
|
+
queryParams: '{"q":"x"}',
|
|
50
|
+
pathParams: '{"id":"1"}',
|
|
51
|
+
})
|
|
52
|
+
assert(withQP.includes('--query') && withQP.includes('{"q":"x"}'), 'query flag')
|
|
53
|
+
assert(withQP.includes('--path') && withQP.includes('{"id":"1"}'), 'path flag')
|
|
54
|
+
|
|
55
|
+
// rejects
|
|
17
56
|
let threw = false
|
|
18
|
-
try { buildMonidArgv('discover', { query: '' }) } catch { threw = true }
|
|
19
|
-
assert(threw, '
|
|
57
|
+
try { buildMonidArgv('discover', { query: ' ' }) } catch { threw = true }
|
|
58
|
+
assert(threw, 'empty query')
|
|
59
|
+
threw = false
|
|
60
|
+
try { buildMonidArgv('run', { tool: 'not-a-path' }) } catch { threw = true }
|
|
61
|
+
assert(threw, 'run without provider/endpoint')
|
|
20
62
|
threw = false
|
|
21
|
-
try { buildMonidArgv('run', {}) } catch { threw = true }
|
|
22
|
-
assert(threw, '
|
|
63
|
+
try { buildMonidArgv('run', { provider: 'x', endpoint: 'news' }) } catch { threw = true }
|
|
64
|
+
assert(threw, 'endpoint must start with /')
|
|
65
|
+
threw = false
|
|
66
|
+
try { buildMonidArgv('inspect', { provider: 'x' }) } catch { threw = true }
|
|
67
|
+
assert(threw, 'inspect needs endpoint')
|
|
23
68
|
threw = false
|
|
24
69
|
try { buildMonidArgv('nope') } catch { threw = true }
|
|
25
70
|
assert(threw, 'unknown sub')
|
|
71
|
+
threw = false
|
|
72
|
+
try { buildMonidArgv('discover', { query: 'q', limit: 'nope' }) } catch { threw = true }
|
|
73
|
+
assert(threw, 'bad limit')
|
|
26
74
|
|
|
27
75
|
console.log('monid-bridge: all cases passed')
|
package/neuralos-3.3.8.tgz
DELETED
|
Binary file
|