Files
openclaw/src/gateway/server-plugins-node-runtime.ts
Peter Steinberger f167089d61 feat(nodes): continue Claude catalog sessions on paired nodes via streaming CLI agent runs (#105833)
* feat(gateway): stream node.invoke progress with idle timeouts and cancel

* feat(node-host): opt-in approval-gated claude cli agent run command

* feat(agents): run node-placed claude-cli turns through streaming node invoke

* feat(anthropic): continue claude catalog sessions on advertising nodes

* docs(nodes): document paired-node claude agent runs and continuation

* chore(plugin-sdk): admit spawn-invocation helper into surface budget

* fix(nodes): harden streaming invoke and node run policy from review findings

* test(node-host): prove multi-token tool-policy argv fails closed

* fix(nodes): allowlist cancel event for apps and break node-host type cycle

* chore(protocol): regenerate Swift gateway models for node invoke progress

* chore(node-host): drop test-only export surface flagged by deadcode ratchet

* style(node-host): merge invoke-types imports

* refactor(nodes): split node agent run modules to satisfy the LOC ratchet

* chore(protocol): regenerate android gateway models and sync export baseline

* chore(plugin-sdk): admit spawn-invocation helper and inherited deprecated drift into surface budget

* chore(plugin-sdk): tolerate inherited agent-core deprecated export

* fix(anthropic): drop node param parser orphaned by upstream catalog split

* ci: sync unused-export baseline with healed main

* test(agents): adopt renamed cli backend prepare helper

* style(node-host): format claude run spawn invocation

* ci: retrigger checks

* chore(plugin-sdk): pin surface budgets to healed-base counts

* fix(protocol): restore untyped lazy validators after upstream style change
2026-07-13 07:39:22 -07:00

42 lines
1.5 KiB
TypeScript

import { getPluginRuntimeGatewayRequestScope } from "../plugins/runtime/gateway-request-scope.js";
import { isNodeCommandAllowed, resolveNodeCommandAllowlist } from "./node-command-policy.js";
import { getFallbackGatewayContext } from "./server-plugin-fallback-context.js";
export function hasInProcessGatewayContext(): boolean {
return Boolean(getPluginRuntimeGatewayRequestScope()?.context ?? getFallbackGatewayContext());
}
export function projectGatewayRuntimeNodes(nodes: unknown[]): unknown[] {
const context = getPluginRuntimeGatewayRequestScope()?.context ?? getFallbackGatewayContext();
return nodes.map((node) => {
if (
!node ||
typeof node !== "object" ||
Array.isArray(node) ||
!context?.nodeRegistry?.get ||
!context.getRuntimeConfig
) {
return node;
}
const nodeRecord = node as Record<string, unknown>;
const nodeId = typeof nodeRecord.nodeId === "string" ? nodeRecord.nodeId : "";
const liveNode = nodeId ? context.nodeRegistry.get(nodeId) : undefined;
if (!liveNode) {
return node;
}
const allowlist = resolveNodeCommandAllowlist(context.getRuntimeConfig(), {
...liveNode,
approvedCommands: liveNode.commands,
});
const invocableCommands = liveNode.commands.filter(
(command) =>
isNodeCommandAllowed({
command,
declaredCommands: liveNode.commands,
allowlist,
}).ok,
);
return Object.assign({}, nodeRecord, { invocableCommands });
});
}