mirror of
https://github.com/hansjone/netxops.git
synced 2026-10-20 21:53:28 +08:00
Netx tools: load from netx remote /mcp, add per-tool toggles
- Drop the TypeScript netx tool implementations and the hard-coded TOOLS_BY_GROUP list; register netx__* tools from the server's tools/list (group from _meta.netx.group) and forward tools/call. - Thin Streamable HTTP client on standard fetch (fetchImpl injectable); cached catalog when netx is unreachable, refresh to reconnect. - disabledTools (deny list; new server tools follow their group) and readOnlyOnly (only readOnlyHint=true tools), re-registered live. - Settings card: per-group expandable tool rows with switches and a write marker; skills append a disabled-tools note. - Toggles only control model visibility; netx enforces security. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
2def53e7c7
commit
2ef3a43c63
38 changed files with 5049 additions and 17029 deletions
|
|
@ -13,6 +13,12 @@ import { npmRuntime } from '../scripts/npm-cli.mjs'
|
|||
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
|
||||
const { node, npm } = npmRuntime()
|
||||
/** Inlined into the activate smoke so the packed Host can register without netx. */
|
||||
const OPS_TOOL_NAMES_INLINE = [
|
||||
'queryNmsAlarms', 'aggregateNmsAlarms', 'runNmsDiagnostics', 'queryNmsNeInventory', 'getNmsNe',
|
||||
'queryNmsAlarmsRaw', 'aggregateNmsAlarmsRaw', 'listNmsAlarmFields', 'sqlQueryNms',
|
||||
'listManagedNe', 'getManagedNe', 'execManagedNe', 'getNeExecJob', 'listCliTargets', 'findTopologyPaths',
|
||||
]
|
||||
const run = (args, cwd, env = {}) => {
|
||||
const result = spawnSync(node, args, { cwd, env: { ...process.env, ...env }, encoding: 'utf8', windowsHide: true, timeout: 120_000 })
|
||||
assert.equal(result.status, 0, `${args[0]} failed: ${result.error ?? ''}\n${result.stderr}\n${result.stdout}`)
|
||||
|
|
@ -87,6 +93,14 @@ test('the npm tarball installs offline and supplies every exported artifact and
|
|||
const root = new Context(), tools = new Map(), skills = new Map(), owners = [];
|
||||
class Tools extends Service { constructor(ctx) { super(ctx, 'tools') } register(entry) { assert.ok(!tools.has(entry.name)); tools.set(entry.name, entry); return () => tools.delete(entry.name) } }
|
||||
class Skills extends Service { constructor(ctx) { super(ctx, 'skills') } register(entry) { assert.ok(!skills.has(entry.name)); skills.set(entry.name, entry); return () => skills.delete(entry.name) } }
|
||||
// Seed a cached /mcp catalog so host registration does not need a live netx.
|
||||
const STORE = Symbol.for('dsh-netxops.mcp-catalog-store');
|
||||
const ops = ${JSON.stringify([...OPS_TOOL_NAMES_INLINE])};
|
||||
globalThis[STORE] = { generation: 1, listeners: new Set(), state: {
|
||||
phase: 'connected', mcpUrl: 'http://127.0.0.1:8890/mcp', error: '', listedAt: new Date().toISOString(), fromCache: false,
|
||||
tools: ops.map(name => ({ name, description: name, inputSchema: { type: 'object', properties: {} },
|
||||
readOnlyHint: name !== 'execManagedNe', group: 'ops' })),
|
||||
} };
|
||||
owners.push(await root.plugin(Tools), await root.plugin(Skills));
|
||||
const owner = await root.plugin(host, { installAgentPreset: false, alarmPushEnabled: false, groupOpsPublic: true }); owners.push(owner);
|
||||
assert.equal(owner.state, 2); assert.equal(tools.size, 15);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue