@praxis-ai/praxis 0.1.1 → 0.1.2
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/dist/agentCore/index.d.ts +45 -6
- package/dist/agentCore/index.js +14 -2
- package/dist/applicationLayer/applicationContract.d.ts +2 -0
- package/dist/applicationLayer/applicationRuntime.d.ts +6 -1
- package/dist/applicationLayer/applicationRuntime.js +37 -3
- package/dist/applicationLayer/index.d.ts +1 -0
- package/dist/basetool/core/shellRun.js +6 -1
- package/dist/rax_packageManager/raxCli.js +42 -1
- package/dist/runtimeImplementation/praxisRuntimeKernel.d.ts +6 -0
- package/dist/runtimeImplementation/praxisRuntimeKernel.js +165 -14
- package/dist/runtimeImplementation/runtime.componentPlane/runtimeComponentRegistry.d.ts +1 -1
- package/dist/runtimeImplementation/runtime.componentPlane/runtimeComponentRegistry.js +2 -2
- package/dist/runtimeImplementation/runtime.dependencyPlane/dependencySourceRegistry.d.ts +1 -1
- package/dist/runtimeImplementation/runtime.dependencyPlane/dependencySourceRegistry.js +12 -0
- package/dist/runtimeImplementation/runtime.dependencyPlane/dependencyTypes.js +2 -0
- package/dist/runtimeImplementation/runtime.execEngine/baseToolExecutorPortFactory.d.ts +3 -0
- package/dist/runtimeImplementation/runtime.execEngine/baseToolExecutorPortFactory.js +45 -7
- package/dist/runtimeImplementation/runtime.execEngine/mcpRuntimeAdapter.js +56 -0
- package/dist/runtimeImplementation/runtime.mcpPlane/index.d.ts +114 -0
- package/dist/runtimeImplementation/runtime.mcpPlane/index.js +167 -0
- package/dist/runtimeImplementation/runtime.sandboxPlane/baseToolSandboxPlanner.js +0 -2
- package/dist/runtimeImplementation/runtime.sandboxPlane/raxcellSandboxProvider.d.ts +19 -0
- package/dist/runtimeImplementation/runtime.sandboxPlane/raxcellSandboxProvider.js +172 -0
- package/dist/runtimeImplementation/runtime.sandboxPlane/sandboxCommandRunner.d.ts +13 -1
- package/dist/runtimeImplementation/runtime.sandboxPlane/sandboxCommandRunner.js +230 -186
- package/dist/runtimeImplementation/runtime.sandboxPlane/sandboxPolicyMiddleware.d.ts +175 -0
- package/dist/runtimeImplementation/runtime.sandboxPlane/sandboxPolicyMiddleware.js +142 -0
- package/dist/runtimeImplementation/runtime.sandboxPlane/sandboxRuntimeProvider.d.ts +9 -0
- package/dist/runtimeImplementation/runtime.sandboxPlane/sandboxRuntimeProvider.js +115 -205
- package/dist/runtimeImplementation/runtimeAgentManifest.js +7 -3
- package/package.json +3 -1
- package/raxode-tui/dist/raxode-cli/backend/agents/codingAgent/agent.js +3 -3
- package/raxode-tui/dist/raxode-cli/backend/application/backendModuleInventory.js +3 -3
- package/raxode-tui/dist/raxode-cli/backend/application/localReadinessProbe.d.ts +1 -0
- package/raxode-tui/dist/raxode-cli/backend/application/localReadinessProbe.js +50 -4
- package/raxode-tui/dist/raxode-cli/backend/application/raxcellSandboxProvider.d.ts +12 -0
- package/raxode-tui/dist/raxode-cli/backend/application/raxcellSandboxProvider.js +58 -0
- package/raxode-tui/dist/raxode-cli/backend/application/runtimeReadiness.d.ts +1 -0
- package/raxode-tui/dist/raxode-cli/backend/application/runtimeReadiness.js +3 -1
- package/raxode-tui/dist/raxode-cli/backend/application/stdioApplicationServer.d.ts +2 -0
- package/raxode-tui/dist/raxode-cli/backend/application/stdioApplicationServer.js +7 -0
- package/raxode-tui/dist/raxode-cli/backend/directApplicationBackend.d.ts +2 -0
- package/raxode-tui/dist/raxode-cli/backend/directApplicationBackend.js +21 -1
- package/raxode-tui/dist/raxode-cli/backend/raxodeBackend.d.ts +1 -1
- package/raxode-tui/dist/raxode-cli/backend/raxodeBackend.js +8 -0
- package/raxode-tui/dist/raxode-cli/frontend/tui/cli/raxode-cli.js +19 -1
- package/raxode-tui/package.json +2 -1
- package/tsconfig.json +16 -1
|
@@ -42,6 +42,7 @@ import { approvalInterfaceEnvelope, } from "../interfaceAdapter/interfaceEnvelop
|
|
|
42
42
|
import { createInMemorySessionStateEventStore, createSqliteSessionStateEventStore, } from "./runtimeSessionStateEventStore.js";
|
|
43
43
|
import { applyRaxStorageInitPlan, createStoragePlaneRuntime, } from "./runtime.storagePlane/storagePlaneRuntime.js";
|
|
44
44
|
import { prepareSandboxRuntime, } from "./runtime.sandboxPlane/sandboxRuntimeProvider.js";
|
|
45
|
+
import { buildMcpServerProfilesFromManifest, mcp, planMcpHarnessExposure, } from "./runtime.mcpPlane/index.js";
|
|
45
46
|
async function inferFilesystemActionForTool(input) {
|
|
46
47
|
if (input.toolId !== "patch.apply")
|
|
47
48
|
return undefined;
|
|
@@ -289,6 +290,77 @@ function defaultMcpServerId(toolId, args) {
|
|
|
289
290
|
return undefined;
|
|
290
291
|
return readString(args.serverId) ?? "local-mcp";
|
|
291
292
|
}
|
|
293
|
+
function withRuntimeHarnessTools(manifest, dynamicTools) {
|
|
294
|
+
if (dynamicTools.length === 0)
|
|
295
|
+
return manifest;
|
|
296
|
+
const byId = new Map();
|
|
297
|
+
for (const tool of [...manifest.harness.tools, ...dynamicTools]) {
|
|
298
|
+
byId.set(tool.toolId, tool);
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
...manifest,
|
|
302
|
+
harness: {
|
|
303
|
+
...manifest.harness,
|
|
304
|
+
tools: [...byId.values()],
|
|
305
|
+
metadata: {
|
|
306
|
+
...manifest.harness.metadata,
|
|
307
|
+
runtimeMcpDynamicToolCount: dynamicTools.length,
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function withRuntimeMcpModule(manifest, module) {
|
|
313
|
+
if (module === undefined || manifest.harness.modules.mcp !== undefined)
|
|
314
|
+
return manifest;
|
|
315
|
+
const byId = new Map();
|
|
316
|
+
for (const tool of [...manifest.harness.tools, ...mcp.recommendedTools()]) {
|
|
317
|
+
byId.set(tool.toolId, tool);
|
|
318
|
+
}
|
|
319
|
+
return {
|
|
320
|
+
...manifest,
|
|
321
|
+
harness: {
|
|
322
|
+
...manifest.harness,
|
|
323
|
+
modules: {
|
|
324
|
+
...manifest.harness.modules,
|
|
325
|
+
mcp: module,
|
|
326
|
+
},
|
|
327
|
+
tools: [...byId.values()],
|
|
328
|
+
runtimeRequirements: manifest.harness.runtimeRequirements.includes("runtime.mcp")
|
|
329
|
+
? manifest.harness.runtimeRequirements
|
|
330
|
+
: [...manifest.harness.runtimeRequirements, "runtime.mcp"],
|
|
331
|
+
metadata: {
|
|
332
|
+
...manifest.harness.metadata,
|
|
333
|
+
runtimeMcpModuleSource: "runtime.options.mcpModule",
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function normalizeMcpNativeToolDeclaration(tool) {
|
|
339
|
+
if (!isRecord(tool))
|
|
340
|
+
return undefined;
|
|
341
|
+
const name = readString(tool.name);
|
|
342
|
+
if (name === undefined)
|
|
343
|
+
return undefined;
|
|
344
|
+
const description = readString(tool.description) ?? readString(tool.title) ?? name;
|
|
345
|
+
const schema = isRecord(tool.inputSchema) ? tool.inputSchema : isRecord(tool.input_schema) ? tool.input_schema : {};
|
|
346
|
+
return { name, description, inputSchema: schema };
|
|
347
|
+
}
|
|
348
|
+
async function discoverRuntimeMcpDynamicTools(manifest, executor) {
|
|
349
|
+
const profiles = buildMcpServerProfilesFromManifest(manifest);
|
|
350
|
+
if (profiles.length === 0 || executor.mcp?.listTools === undefined)
|
|
351
|
+
return [];
|
|
352
|
+
const inventory = {};
|
|
353
|
+
for (const profile of profiles) {
|
|
354
|
+
const listed = await executor.mcp.listTools({ serverId: profile.serverId });
|
|
355
|
+
if (listed?.ok !== true)
|
|
356
|
+
continue;
|
|
357
|
+
const rawTools = Array.isArray(listed.output?.tools) ? listed.output.tools : [];
|
|
358
|
+
inventory[profile.serverId] = rawTools
|
|
359
|
+
.map(normalizeMcpNativeToolDeclaration)
|
|
360
|
+
.filter((tool) => tool !== undefined);
|
|
361
|
+
}
|
|
362
|
+
return planMcpHarnessExposure(manifest, inventory).servers.flatMap((server) => [...server.dynamicToolSpecs]);
|
|
363
|
+
}
|
|
292
364
|
function providerToolMappings(manifest) {
|
|
293
365
|
return createProviderToolMappings(manifest.harness.tools);
|
|
294
366
|
}
|
|
@@ -523,30 +595,54 @@ function shellCommandPathScanSource(command) {
|
|
|
523
595
|
function isShellCommandAllowedSystemPath(token) {
|
|
524
596
|
return token === "/dev/null";
|
|
525
597
|
}
|
|
598
|
+
function escapeRegExp(value) {
|
|
599
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
600
|
+
}
|
|
526
601
|
function shellCommandAbsolutePathTokens(command) {
|
|
527
602
|
const matches = shellCommandPathScanSource(command).matchAll(/(^|[\s"'`=({[,;|&<>])\/(?!\/)[^\s"'`$;&|<>()[\]{}]*/gu);
|
|
528
603
|
return [...matches]
|
|
529
604
|
.map((match) => stripShellPathToken((match[0] ?? "").slice(match[1]?.length ?? 0)))
|
|
530
605
|
.filter((token) => token.length > 1 && !token.includes("\0") && !isShellCommandAllowedSystemPath(token));
|
|
531
606
|
}
|
|
607
|
+
function shellCommandPathAccess(command, token) {
|
|
608
|
+
const source = shellCommandPathScanSource(command);
|
|
609
|
+
const escaped = escapeRegExp(token);
|
|
610
|
+
const quotedToken = `["']?${escaped}["']?`;
|
|
611
|
+
if (new RegExp(`(?:^|[\\s;|&])(?:\\d?>|\\d?>>|>|>>|<>)\\s*${quotedToken}(?:\\s|$|[;&|])`, "u").test(source)) {
|
|
612
|
+
return "write";
|
|
613
|
+
}
|
|
614
|
+
if (new RegExp(`\\btee\\b[^\\n;&|]*${quotedToken}`, "u").test(source))
|
|
615
|
+
return "write";
|
|
616
|
+
if (new RegExp(`\\bsed\\b[^\\n;&|]*\\s-i\\b[^\\n;&|]*${quotedToken}`, "u").test(source))
|
|
617
|
+
return "write";
|
|
618
|
+
if (new RegExp(`\\b(?:touch|mkdir|rm|rmdir|chmod|chown)\\b[^\\n;&|]*${quotedToken}`, "u").test(source))
|
|
619
|
+
return "write";
|
|
620
|
+
if (new RegExp(`Path\\(\\s*["']${escaped}["']\\s*\\)[\\s\\S]*\\b(?:write_text|append_text)\\s*\\(`, "u").test(source)) {
|
|
621
|
+
return "write";
|
|
622
|
+
}
|
|
623
|
+
return "read";
|
|
624
|
+
}
|
|
532
625
|
function shellCommandOutsideAllowedRootsMetadata(input) {
|
|
533
626
|
const output = [];
|
|
534
627
|
for (const token of shellCommandAbsolutePathTokens(input.command)) {
|
|
535
628
|
const normalizedPath = path.resolve(token);
|
|
536
629
|
if (isInsideAllowedRoots(normalizedPath, input.allowedRoots))
|
|
537
630
|
continue;
|
|
538
|
-
output.push(
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
631
|
+
output.push({
|
|
632
|
+
...workspacePathMetadata({
|
|
633
|
+
ok: false,
|
|
634
|
+
reason: "OUTSIDE_ALLOWED_ROOTS",
|
|
635
|
+
message: "shell command references an absolute path outside runtime allowed roots",
|
|
636
|
+
requestedPath: token,
|
|
637
|
+
normalizedPath,
|
|
638
|
+
workspaceRoot: input.workspaceRoot,
|
|
639
|
+
allowedRoots: input.allowedRoots,
|
|
640
|
+
pathWasMapped: false,
|
|
641
|
+
mappingSource: "absolute",
|
|
642
|
+
suggestedCwd: input.workspaceRoot,
|
|
643
|
+
}, "path"),
|
|
644
|
+
workspacePathAccess: shellCommandPathAccess(input.command, token),
|
|
645
|
+
});
|
|
550
646
|
}
|
|
551
647
|
return output;
|
|
552
648
|
}
|
|
@@ -557,7 +653,6 @@ function normalizeWorkspacePathContract(input) {
|
|
|
557
653
|
const allowedRoots = normalizeAllowedRoots({ workspaceRoot, allowedRoots: input.allowedRoots });
|
|
558
654
|
const nextArgs = { ...input.args };
|
|
559
655
|
const normalizations = [];
|
|
560
|
-
const pathAccess = input.toolId === "patch.apply" ? "write" : "read";
|
|
561
656
|
const allowOutsideAllowedRoots = input.profile !== undefined;
|
|
562
657
|
if (input.toolId === "file.read" || input.toolId === "skill.load" || input.toolId === "media.viewImage") {
|
|
563
658
|
for (const field of ["path", "filePath", "imagePath"]) {
|
|
@@ -596,12 +691,15 @@ function normalizeWorkspacePathContract(input) {
|
|
|
596
691
|
}
|
|
597
692
|
}
|
|
598
693
|
const workspaceOutsideAllowedRoots = normalizations.some((item) => item.workspaceOutsideAllowedRoots === true || item.reason === "OUTSIDE_ALLOWED_ROOTS");
|
|
694
|
+
const workspacePathAccess = input.toolId === "patch.apply" || normalizations.some((item) => item.workspacePathAccess === "write")
|
|
695
|
+
? "write"
|
|
696
|
+
: "read";
|
|
599
697
|
return {
|
|
600
698
|
ok: true,
|
|
601
699
|
args: withWorkspaceNormalizationMetadata(nextArgs, normalizations, workspaceOutsideAllowedRoots
|
|
602
700
|
? {
|
|
603
701
|
workspaceOutsideAllowedRoots: true,
|
|
604
|
-
workspacePathAccess
|
|
702
|
+
workspacePathAccess,
|
|
605
703
|
}
|
|
606
704
|
: {}),
|
|
607
705
|
metadata: normalizations[0] === undefined
|
|
@@ -2132,6 +2230,7 @@ async function prepareKernelSandbox(input) {
|
|
|
2132
2230
|
const sandbox = await prepareSandboxRuntime(input.manifest.sandbox, {
|
|
2133
2231
|
cwd: input.options.sandbox?.cwd ?? input.storageRuntime.layout.workspace.root,
|
|
2134
2232
|
runSmoke: input.options.sandbox?.runSmoke ?? false,
|
|
2233
|
+
providerReady: input.options.sandbox?.provider !== undefined,
|
|
2135
2234
|
});
|
|
2136
2235
|
input.events.push(...sandbox.events);
|
|
2137
2236
|
await input.store.appendEvent(event(input.sessionId, "event:sandbox.prepared", "runtime.sandboxPlane.prepared", input.now(), { sandbox }));
|
|
@@ -2456,6 +2555,48 @@ function compactRequestMaterials(input) {
|
|
|
2456
2555
|
return [...originalMaterials, ...governedSessionSummaryMaterial, ...governedProjectContext];
|
|
2457
2556
|
}
|
|
2458
2557
|
async function executeBaseToolDecision(input) {
|
|
2558
|
+
const dynamicToolSpec = input.manifest.harness.tools.find((tool) => tool.toolId === input.toolId);
|
|
2559
|
+
const dynamicRuntimeToolId = typeof dynamicToolSpec?.metadata?.runtimeToolId === "string"
|
|
2560
|
+
? dynamicToolSpec.metadata.runtimeToolId
|
|
2561
|
+
: undefined;
|
|
2562
|
+
const dynamicRuntimeArguments = isRecord(dynamicToolSpec?.metadata?.runtimeArguments)
|
|
2563
|
+
? dynamicToolSpec.metadata.runtimeArguments
|
|
2564
|
+
: undefined;
|
|
2565
|
+
if (dynamicRuntimeToolId !== undefined && dynamicRuntimeToolId !== input.toolId) {
|
|
2566
|
+
const delegatedArgs = dynamicRuntimeToolId === "mcp.use"
|
|
2567
|
+
? {
|
|
2568
|
+
...(dynamicRuntimeArguments ?? {}),
|
|
2569
|
+
arguments: input.args,
|
|
2570
|
+
}
|
|
2571
|
+
: {
|
|
2572
|
+
...(dynamicRuntimeArguments ?? {}),
|
|
2573
|
+
...input.args,
|
|
2574
|
+
};
|
|
2575
|
+
const delegated = await executeBaseToolDecision({
|
|
2576
|
+
...input,
|
|
2577
|
+
toolId: dynamicRuntimeToolId,
|
|
2578
|
+
args: delegatedArgs,
|
|
2579
|
+
});
|
|
2580
|
+
return {
|
|
2581
|
+
...delegated,
|
|
2582
|
+
record: {
|
|
2583
|
+
...delegated.record,
|
|
2584
|
+
toolId: input.toolId,
|
|
2585
|
+
arguments: input.args,
|
|
2586
|
+
},
|
|
2587
|
+
observation: {
|
|
2588
|
+
...delegated.observation,
|
|
2589
|
+
material: {
|
|
2590
|
+
...delegated.observation.material,
|
|
2591
|
+
metadata: {
|
|
2592
|
+
...(delegated.observation.material.metadata ?? {}),
|
|
2593
|
+
dynamicRuntimeToolId,
|
|
2594
|
+
dynamicMcpToolId: input.toolId,
|
|
2595
|
+
},
|
|
2596
|
+
},
|
|
2597
|
+
},
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2459
2600
|
let toolArguments = enrichToolArguments(input.manifest, input.toolId, input.args, {
|
|
2460
2601
|
runtimeId: input.runtimeId,
|
|
2461
2602
|
sessionId: input.sessionId,
|
|
@@ -3383,6 +3524,7 @@ export class PraxisRuntimeKernel {
|
|
|
3383
3524
|
}),
|
|
3384
3525
|
});
|
|
3385
3526
|
const dryRun = options.dryRun !== false;
|
|
3527
|
+
manifest = withRuntimeMcpModule(manifest, options.mcpModule);
|
|
3386
3528
|
const defaultBaseToolPolicy = {
|
|
3387
3529
|
workspaceRoot: toolWorkspaceRoot,
|
|
3388
3530
|
allowedRoots: toolAllowedRoots,
|
|
@@ -3413,7 +3555,15 @@ export class PraxisRuntimeKernel {
|
|
|
3413
3555
|
sandboxSpec: manifest.sandbox,
|
|
3414
3556
|
preparedSandbox: sandboxPrepared.sandbox,
|
|
3415
3557
|
policyProfile: manifest.toolPolicy.profile,
|
|
3558
|
+
sandboxProvider: options.sandbox?.provider,
|
|
3559
|
+
sandboxAudit: async (sandboxEvent) => {
|
|
3560
|
+
await store.appendEvent(event(sessionId, `event:sandbox:${sandboxEvent.actionId}:${sandboxEvent.type}`, sandboxEvent.type, now(), { sandbox: sandboxEvent }));
|
|
3561
|
+
},
|
|
3416
3562
|
remoteSandboxWorker: options.sandbox?.remoteWorker,
|
|
3563
|
+
mcpServers: [
|
|
3564
|
+
...buildMcpServerProfilesFromManifest(manifest),
|
|
3565
|
+
...(options.mcpServers ?? []),
|
|
3566
|
+
],
|
|
3417
3567
|
emitEvent: (runtimeEvent) => {
|
|
3418
3568
|
events.push(runtimeEvent.type);
|
|
3419
3569
|
},
|
|
@@ -3423,6 +3573,7 @@ export class PraxisRuntimeKernel {
|
|
|
3423
3573
|
id: "praxis-runtime-kernel",
|
|
3424
3574
|
sessionId,
|
|
3425
3575
|
};
|
|
3576
|
+
manifest = withRuntimeHarnessTools(manifest, await discoverRuntimeMcpDynamicTools(manifest, executor));
|
|
3426
3577
|
const maxModelTurns = manifest.harness.loop.maxModelTurns ?? 2;
|
|
3427
3578
|
const maxToolCalls = manifest.harness.loop.maxToolCalls ?? 4;
|
|
3428
3579
|
const toolMappings = providerToolMappings(manifest);
|
|
@@ -3,7 +3,7 @@ import type { RuntimeComponentSpec } from "./componentTypes.js";
|
|
|
3
3
|
export declare const officialRuntimeComponents: readonly [{
|
|
4
4
|
readonly componentId: "component.sandbox.bubblewrap";
|
|
5
5
|
readonly kind: "sandbox";
|
|
6
|
-
readonly title: "Linux
|
|
6
|
+
readonly title: "Linux Raxcell sandbox provider";
|
|
7
7
|
readonly dependencies: readonly [DependencyDeclaration];
|
|
8
8
|
readonly fallbackComponentIds: readonly ["component.sandbox.workspaceRollback"];
|
|
9
9
|
readonly supportedPlatforms: readonly ["linux"];
|
|
@@ -9,8 +9,8 @@ export const officialRuntimeComponents = [
|
|
|
9
9
|
{
|
|
10
10
|
componentId: "component.sandbox.bubblewrap",
|
|
11
11
|
kind: "sandbox",
|
|
12
|
-
title: "Linux
|
|
13
|
-
dependencies: [dependency("dependency.binary.
|
|
12
|
+
title: "Linux Raxcell sandbox provider",
|
|
13
|
+
dependencies: [dependency("dependency.binary.raxcell", { kind: "binary", required: true })],
|
|
14
14
|
fallbackComponentIds: ["component.sandbox.workspaceRollback"],
|
|
15
15
|
supportedPlatforms: ["linux"],
|
|
16
16
|
},
|
|
@@ -10,7 +10,7 @@ export type DependencySourceRegistry = {
|
|
|
10
10
|
sources: readonly DependencySource[];
|
|
11
11
|
warnings: readonly string[];
|
|
12
12
|
};
|
|
13
|
-
export declare const officialDependencySources: readonly [DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource];
|
|
13
|
+
export declare const officialDependencySources: readonly [DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource, DependencySource];
|
|
14
14
|
export declare function defaultManagedRoot(input?: {
|
|
15
15
|
raxToolDepsRoot?: string;
|
|
16
16
|
env?: Readonly<Record<string, string | undefined>>;
|
|
@@ -125,6 +125,18 @@ export const officialDependencySources = [
|
|
|
125
125
|
executableName: "rg",
|
|
126
126
|
versionCommand: { command: "rg", args: ["--version"] },
|
|
127
127
|
}),
|
|
128
|
+
source({
|
|
129
|
+
dependencyId: "dependency.binary.raxcell",
|
|
130
|
+
sourceId: "official:detect:raxcell",
|
|
131
|
+
displayName: "Raxcell sandbox provider",
|
|
132
|
+
kind: "binary",
|
|
133
|
+
safety: "trusted-detect-only",
|
|
134
|
+
packageManager: "detect-only",
|
|
135
|
+
executableName: "raxcell",
|
|
136
|
+
versionCommand: { command: "raxcell", args: ["--version"] },
|
|
137
|
+
supportedPlatforms: ["linux"],
|
|
138
|
+
installInstructions: "Install @praxis-ai/raxcell with Praxis/Raxode, or set RAXCELL_BIN to an explicit provider binary path.",
|
|
139
|
+
}),
|
|
128
140
|
source({
|
|
129
141
|
dependencyId: "dependency.binary.bwrap",
|
|
130
142
|
sourceId: "official:detect:bwrap",
|
|
@@ -7,6 +7,7 @@ export function canonicalDependencyId(input) {
|
|
|
7
7
|
const value = input.trim();
|
|
8
8
|
const legacy = {
|
|
9
9
|
"binary:bwrap": "dependency.binary.bwrap",
|
|
10
|
+
"binary:raxcell": "dependency.binary.raxcell",
|
|
10
11
|
"binary:podman|docker": "dependency.binary.podmanOrDocker",
|
|
11
12
|
"windows:Windows-Sandbox": "dependency.windows.sandbox",
|
|
12
13
|
"macos:containerization": "dependency.macos.containerization",
|
|
@@ -60,6 +61,7 @@ export function legacyDependencyIds(input) {
|
|
|
60
61
|
const canonical = canonicalDependencyId(input);
|
|
61
62
|
const reverse = {
|
|
62
63
|
"dependency.binary.bwrap": ["binary:bwrap"],
|
|
64
|
+
"dependency.binary.raxcell": ["binary:raxcell"],
|
|
63
65
|
"dependency.binary.podmanOrDocker": ["binary:podman|docker"],
|
|
64
66
|
"dependency.windows.sandbox": ["windows:Windows-Sandbox"],
|
|
65
67
|
"dependency.macos.containerization": ["macos:containerization"],
|
|
@@ -2,6 +2,7 @@ import type { BaseToolExecutorPort } from "../../basetool/types.js";
|
|
|
2
2
|
import { type BaseToolPolicyProfile, type SandboxSpec } from "../runtimeAgentManifest.js";
|
|
3
3
|
import type { SandboxRuntimePrepareResult } from "../runtime.sandboxPlane/sandboxRuntimeProvider.js";
|
|
4
4
|
import { type SandboxRemoteWorkerAdapter } from "../runtime.sandboxPlane/sandboxCommandRunner.js";
|
|
5
|
+
import type { SandboxExecutionProviderPort, SandboxPolicyMiddlewareAuditEvent } from "../runtime.sandboxPlane/sandboxPolicyMiddleware.js";
|
|
5
6
|
import { type McpRuntimeServerProfile } from "./mcpRuntimeAdapter.js";
|
|
6
7
|
export type RuntimeBaseToolExecutorEvent = {
|
|
7
8
|
type: string;
|
|
@@ -60,6 +61,8 @@ export type RuntimeBaseToolExecutorContext = {
|
|
|
60
61
|
sandboxSpec?: SandboxSpec;
|
|
61
62
|
preparedSandbox?: SandboxRuntimePrepareResult;
|
|
62
63
|
policyProfile?: BaseToolPolicyProfile;
|
|
64
|
+
sandboxProvider?: SandboxExecutionProviderPort;
|
|
65
|
+
sandboxAudit?: (event: SandboxPolicyMiddlewareAuditEvent) => Promise<void> | void;
|
|
63
66
|
remoteSandboxWorker?: SandboxRemoteWorkerAdapter;
|
|
64
67
|
mcpServers?: readonly McpRuntimeServerProfile[];
|
|
65
68
|
environment?: Readonly<Record<string, string | undefined>>;
|
|
@@ -159,8 +159,6 @@ function legacyPreparedSandbox(value) {
|
|
|
159
159
|
}
|
|
160
160
|
function sandboxModeForContext(context) {
|
|
161
161
|
const profile = policyProfileForContext(context);
|
|
162
|
-
if (profile === "bapr")
|
|
163
|
-
return "none";
|
|
164
162
|
const explicitProviderFamily = context.sandboxSpec?.providerFamily ?? context.sandbox?.providerFamily;
|
|
165
163
|
const prepared = context.preparedSandbox ?? legacyPreparedSandbox(context.sandbox);
|
|
166
164
|
if (strongSandboxFamily(explicitProviderFamily)) {
|
|
@@ -314,6 +312,10 @@ async function runCommand(context, command, args = [], cwd, input = {}) {
|
|
|
314
312
|
if (!resolvedCwd.ok)
|
|
315
313
|
return resolvedCwd;
|
|
316
314
|
const commandCwd = String(resolvedCwd.output);
|
|
315
|
+
const root = workspaceRoot(context);
|
|
316
|
+
const approvedWriteRoots = input.approved === true
|
|
317
|
+
? context.policy?.allowedWriteRoots ?? [root]
|
|
318
|
+
: context.policy?.allowedWriteRoots;
|
|
317
319
|
if (spec !== undefined) {
|
|
318
320
|
const result = await runSandboxCommand({
|
|
319
321
|
runtimeId: context.runtimeId,
|
|
@@ -331,13 +333,17 @@ async function runCommand(context, command, args = [], cwd, input = {}) {
|
|
|
331
333
|
policyProfile: profile,
|
|
332
334
|
sandboxMode: sandboxModeForContext(context),
|
|
333
335
|
filesystem: {
|
|
334
|
-
workspaceRoot:
|
|
335
|
-
allowedReadRoots: context.policy?.allowedRoots ?? [
|
|
336
|
-
...(
|
|
336
|
+
workspaceRoot: root,
|
|
337
|
+
allowedReadRoots: context.policy?.allowedRoots ?? [root],
|
|
338
|
+
...(approvedWriteRoots === undefined ? {} : { allowedWriteRoots: approvedWriteRoots }),
|
|
339
|
+
...(input.approved === true ? { readonlyRoot: false } : {}),
|
|
337
340
|
},
|
|
338
341
|
network: input.network,
|
|
342
|
+
approval: input.approved === true ? { accepted: true, grantedBy: "praxis-human-approval" } : undefined,
|
|
339
343
|
}, {
|
|
340
344
|
remoteWorker: context.remoteSandboxWorker,
|
|
345
|
+
sandboxProvider: context.sandboxProvider,
|
|
346
|
+
audit: context.sandboxAudit,
|
|
341
347
|
});
|
|
342
348
|
if (!result.ok) {
|
|
343
349
|
return fail(result.error.code, result.error.message, {
|
|
@@ -423,6 +429,7 @@ function createShellExecutor(context) {
|
|
|
423
429
|
invocationId: typeof request?.toolCallId === "string" ? request.toolCallId : undefined,
|
|
424
430
|
shellScript: true,
|
|
425
431
|
timeoutMs: typeof request?.timeoutMs === "number" ? request.timeoutMs : undefined,
|
|
432
|
+
approved: approvedByRuntimeContext(request?.context),
|
|
426
433
|
});
|
|
427
434
|
}),
|
|
428
435
|
};
|
|
@@ -436,6 +443,7 @@ function createProcessExecutor(context) {
|
|
|
436
443
|
toolId: "process.run",
|
|
437
444
|
invocationId: typeof request?.toolCallId === "string" ? request.toolCallId : undefined,
|
|
438
445
|
timeoutMs: typeof request?.timeoutMs === "number" ? request.timeoutMs : undefined,
|
|
446
|
+
approved: approvedByRuntimeContext(request?.context),
|
|
439
447
|
});
|
|
440
448
|
}),
|
|
441
449
|
wait: withAdapter(context, "process", "wait", async (request) => {
|
|
@@ -630,7 +638,22 @@ function createMcpExecutor(context) {
|
|
|
630
638
|
const configured = context.mcpServers !== undefined && context.mcpServers.length > 0
|
|
631
639
|
? createMcpRuntimeAdapter({ servers: context.mcpServers })
|
|
632
640
|
: undefined;
|
|
633
|
-
const base = configured ?? createUnavailableNamespace("mcp", [
|
|
641
|
+
const base = configured ?? createUnavailableNamespace("mcp", [
|
|
642
|
+
"connect",
|
|
643
|
+
"ping",
|
|
644
|
+
"listTools",
|
|
645
|
+
"call",
|
|
646
|
+
"stream",
|
|
647
|
+
"listResources",
|
|
648
|
+
"readResource",
|
|
649
|
+
"listPrompts",
|
|
650
|
+
"getPrompt",
|
|
651
|
+
"setRoots",
|
|
652
|
+
"reportProgress",
|
|
653
|
+
"createSamplingMessage",
|
|
654
|
+
"elicit",
|
|
655
|
+
"setLoggingLevel",
|
|
656
|
+
]);
|
|
634
657
|
const callTool = base.callTool ?? base.call;
|
|
635
658
|
const streamTool = base.streamTool ?? base.stream;
|
|
636
659
|
return {
|
|
@@ -643,7 +666,21 @@ function createMcpExecutor(context) {
|
|
|
643
666
|
export function listRuntimeBaseToolImplementedPortPaths(context = {}) {
|
|
644
667
|
const ports = new Set(baseToolExecutorPortFactoryDescriptor.implementedAdapters);
|
|
645
668
|
if (context.mcpServers !== undefined && context.mcpServers.length > 0) {
|
|
646
|
-
for (const portPath of [
|
|
669
|
+
for (const portPath of [
|
|
670
|
+
"mcp.connect",
|
|
671
|
+
"mcp.call",
|
|
672
|
+
"mcp.callTool",
|
|
673
|
+
"mcp.listTools",
|
|
674
|
+
"mcp.listResources",
|
|
675
|
+
"mcp.readResource",
|
|
676
|
+
"mcp.listPrompts",
|
|
677
|
+
"mcp.getPrompt",
|
|
678
|
+
"mcp.setRoots",
|
|
679
|
+
"mcp.reportProgress",
|
|
680
|
+
"mcp.createSamplingMessage",
|
|
681
|
+
"mcp.elicit",
|
|
682
|
+
"mcp.setLoggingLevel",
|
|
683
|
+
]) {
|
|
647
684
|
ports.add(portPath);
|
|
648
685
|
}
|
|
649
686
|
}
|
|
@@ -694,6 +731,7 @@ export function createRuntimeBaseToolExecutorPort(context) {
|
|
|
694
731
|
toolId: typeof request?.toolId === "string" ? request.toolId : "sandbox.run",
|
|
695
732
|
invocationId: typeof request?.invocationId === "string" ? request.invocationId : undefined,
|
|
696
733
|
network: request?.network === "allow" ? "allow" : undefined,
|
|
734
|
+
approved: approvedByRuntimeContext(request?.context),
|
|
697
735
|
});
|
|
698
736
|
}),
|
|
699
737
|
},
|
|
@@ -324,6 +324,62 @@ export function createMcpRuntimeAdapter(options) {
|
|
|
324
324
|
})) : [];
|
|
325
325
|
return success({ uri: requestInput.resourceUri, contents, truncated: false, providerMetadata: metadata(connected.output.profile, { method: "resources/read" }), raw: read.output });
|
|
326
326
|
},
|
|
327
|
+
async listPrompts(requestInput) {
|
|
328
|
+
const connected = await getConnection(requestInput.serverId);
|
|
329
|
+
if (!connected.ok)
|
|
330
|
+
return connected;
|
|
331
|
+
const listed = await request(connected.output, "prompts/list", requestInput.cursor === undefined ? {} : { cursor: requestInput.cursor });
|
|
332
|
+
if (!listed.ok)
|
|
333
|
+
return listed;
|
|
334
|
+
const raw = resultObject(listed.output);
|
|
335
|
+
const prompts = Array.isArray(raw.prompts) ? raw.prompts.filter(isObject).map((prompt) => ({
|
|
336
|
+
name: String(prompt.name ?? ""),
|
|
337
|
+
title: typeof prompt.title === "string" ? prompt.title : undefined,
|
|
338
|
+
description: typeof prompt.description === "string" ? prompt.description : undefined,
|
|
339
|
+
arguments: Array.isArray(prompt.arguments) ? prompt.arguments : undefined,
|
|
340
|
+
raw: prompt,
|
|
341
|
+
})).filter((prompt) => prompt.name.length > 0) : [];
|
|
342
|
+
return success({ prompts, nextCursor: typeof raw.nextCursor === "string" ? raw.nextCursor : undefined, providerMetadata: metadata(connected.output.profile, { method: "prompts/list" }), raw: listed.output });
|
|
343
|
+
},
|
|
344
|
+
async getPrompt(requestInput) {
|
|
345
|
+
const connected = await getConnection(requestInput.serverId);
|
|
346
|
+
if (!connected.ok)
|
|
347
|
+
return connected;
|
|
348
|
+
const read = await request(connected.output, "prompts/get", { name: requestInput.name, arguments: requestInput.arguments ?? {} });
|
|
349
|
+
if (!read.ok)
|
|
350
|
+
return read;
|
|
351
|
+
return success(read.output, metadata(connected.output.profile, { method: "prompts/get", promptName: requestInput.name }));
|
|
352
|
+
},
|
|
353
|
+
async setRoots(requestInput) {
|
|
354
|
+
const profile = getProfile(requestInput.serverId);
|
|
355
|
+
if (profile === undefined)
|
|
356
|
+
return failure("MCP_SERVER_NOT_CONFIGURED", `MCP server '${requestInput.serverId}' is not configured.`);
|
|
357
|
+
return success({ serverId: requestInput.serverId, roots: requestInput.roots ?? [], status: "registered", providerMetadata: metadata(profile, { hostSemantic: "roots" }) });
|
|
358
|
+
},
|
|
359
|
+
async reportProgress(requestInput) {
|
|
360
|
+
const profile = getProfile(requestInput.serverId);
|
|
361
|
+
if (profile === undefined)
|
|
362
|
+
return failure("MCP_SERVER_NOT_CONFIGURED", `MCP server '${requestInput.serverId}' is not configured.`);
|
|
363
|
+
return success({ serverId: requestInput.serverId, progressToken: requestInput.progressToken, progress: requestInput.progress, total: requestInput.total, status: "reported", providerMetadata: metadata(profile, { hostSemantic: "progress" }) });
|
|
364
|
+
},
|
|
365
|
+
async createSamplingMessage(requestInput) {
|
|
366
|
+
const profile = getProfile(requestInput.serverId);
|
|
367
|
+
if (profile === undefined)
|
|
368
|
+
return failure("MCP_SERVER_NOT_CONFIGURED", `MCP server '${requestInput.serverId}' is not configured.`);
|
|
369
|
+
return success({ serverId: requestInput.serverId, status: "accepted", request: requestInput, providerMetadata: metadata(profile, { hostSemantic: "sampling" }) });
|
|
370
|
+
},
|
|
371
|
+
async elicit(requestInput) {
|
|
372
|
+
const profile = getProfile(requestInput.serverId);
|
|
373
|
+
if (profile === undefined)
|
|
374
|
+
return failure("MCP_SERVER_NOT_CONFIGURED", `MCP server '${requestInput.serverId}' is not configured.`);
|
|
375
|
+
return success({ serverId: requestInput.serverId, status: "pending", request: requestInput, providerMetadata: metadata(profile, { hostSemantic: "elicitation" }) });
|
|
376
|
+
},
|
|
377
|
+
async setLoggingLevel(requestInput) {
|
|
378
|
+
const profile = getProfile(requestInput.serverId);
|
|
379
|
+
if (profile === undefined)
|
|
380
|
+
return failure("MCP_SERVER_NOT_CONFIGURED", `MCP server '${requestInput.serverId}' is not configured.`);
|
|
381
|
+
return success({ serverId: requestInput.serverId, level: requestInput.level ?? "info", status: "configured", providerMetadata: metadata(profile, { hostSemantic: "logging" }) });
|
|
382
|
+
},
|
|
327
383
|
async createResource(requestInput) {
|
|
328
384
|
const profile = getProfile(requestInput.serverId);
|
|
329
385
|
if (profile === undefined)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { type ExposureState, type McpCompatibleSurface, type McpPlusManifest, type NativeToolDeclaration } from "@praxis-ai/mcp-plus";
|
|
2
|
+
import type { ToolSpec } from "../runtimeAgentManifest.js";
|
|
3
|
+
import type { McpRuntimeServerProfile } from "../runtime.execEngine/mcpRuntimeAdapter.js";
|
|
4
|
+
export type McpHarnessServerMode = "native" | "mcp-plus";
|
|
5
|
+
export type McpTransportSpec = {
|
|
6
|
+
transport: "stdio";
|
|
7
|
+
command: string;
|
|
8
|
+
args?: readonly string[];
|
|
9
|
+
cwd?: string;
|
|
10
|
+
env?: Readonly<Record<string, string | undefined>>;
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
framing?: "content-length" | "line-json";
|
|
13
|
+
} | {
|
|
14
|
+
transport: "http" | "sse";
|
|
15
|
+
url: string;
|
|
16
|
+
sseUrl?: string;
|
|
17
|
+
headers?: Readonly<Record<string, string>>;
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
};
|
|
20
|
+
export type McpHarnessServerSpec = McpTransportSpec & {
|
|
21
|
+
serverId: string;
|
|
22
|
+
mode: McpHarnessServerMode;
|
|
23
|
+
title?: string;
|
|
24
|
+
summary?: string;
|
|
25
|
+
manifest?: McpPlusManifest;
|
|
26
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
27
|
+
};
|
|
28
|
+
export type McpApplicationServerInput = McpTransportSpec & {
|
|
29
|
+
serverId: string;
|
|
30
|
+
mode?: McpHarnessServerMode;
|
|
31
|
+
title?: string;
|
|
32
|
+
summary?: string;
|
|
33
|
+
manifest?: McpPlusManifest;
|
|
34
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
35
|
+
};
|
|
36
|
+
type HttpMcpHelperInput = {
|
|
37
|
+
url: string;
|
|
38
|
+
sseUrl?: string;
|
|
39
|
+
headers?: Readonly<Record<string, string>>;
|
|
40
|
+
timeoutMs?: number;
|
|
41
|
+
} & Partial<Pick<McpHarnessServerSpec, "mode" | "title" | "summary" | "manifest" | "metadata">>;
|
|
42
|
+
export type McpHarnessModuleSpec = {
|
|
43
|
+
kind: "praxis.mcp.module";
|
|
44
|
+
version: "praxis.mcp.v1";
|
|
45
|
+
servers: readonly McpHarnessServerSpec[];
|
|
46
|
+
recommended: true;
|
|
47
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
48
|
+
};
|
|
49
|
+
export type McpApplicationServerView = {
|
|
50
|
+
serverId: string;
|
|
51
|
+
mode: McpHarnessServerMode;
|
|
52
|
+
transport: McpHarnessServerSpec["transport"];
|
|
53
|
+
title?: string;
|
|
54
|
+
summary?: string;
|
|
55
|
+
manifestPresent: boolean;
|
|
56
|
+
status: "declared" | "mounted" | "error";
|
|
57
|
+
toolCount?: number;
|
|
58
|
+
visibleToolCount?: number;
|
|
59
|
+
indexedToolCount?: number;
|
|
60
|
+
publicSafe: true;
|
|
61
|
+
};
|
|
62
|
+
export type McpApplicationStateView = {
|
|
63
|
+
servers: readonly McpApplicationServerView[];
|
|
64
|
+
recommendedMode: "mcp-plus";
|
|
65
|
+
nativeCompatible: true;
|
|
66
|
+
publicSafe: true;
|
|
67
|
+
};
|
|
68
|
+
export type McpExposurePlanServer = {
|
|
69
|
+
serverId: string;
|
|
70
|
+
mode: McpHarnessServerMode;
|
|
71
|
+
surface: McpCompatibleSurface;
|
|
72
|
+
dynamicToolSpecs: readonly ToolSpec[];
|
|
73
|
+
};
|
|
74
|
+
export type McpHarnessExposurePlan = {
|
|
75
|
+
servers: readonly McpExposurePlanServer[];
|
|
76
|
+
};
|
|
77
|
+
export type McpPlusApplicationServerInput = McpTransportSpec & {
|
|
78
|
+
serverId: string;
|
|
79
|
+
manifest: McpPlusManifest;
|
|
80
|
+
title?: string;
|
|
81
|
+
summary?: string;
|
|
82
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
83
|
+
};
|
|
84
|
+
export declare function mcpServer(serverId: string, input: McpTransportSpec & Partial<Pick<McpHarnessServerSpec, "mode" | "title" | "summary" | "manifest" | "metadata">>): McpHarnessServerSpec;
|
|
85
|
+
export declare const mcp: {
|
|
86
|
+
readonly module: (input: {
|
|
87
|
+
servers: readonly McpHarnessServerSpec[];
|
|
88
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
89
|
+
}) => McpHarnessModuleSpec;
|
|
90
|
+
readonly stdio: (serverId: string, input: Omit<Extract<McpTransportSpec, {
|
|
91
|
+
transport: "stdio";
|
|
92
|
+
}>, "transport"> & Partial<Pick<McpHarnessServerSpec, "mode" | "title" | "summary" | "manifest" | "metadata">>) => McpHarnessServerSpec;
|
|
93
|
+
readonly http: (serverId: string, input: HttpMcpHelperInput) => McpHarnessServerSpec;
|
|
94
|
+
readonly sse: (serverId: string, input: HttpMcpHelperInput) => McpHarnessServerSpec;
|
|
95
|
+
readonly recommendedTools: () => readonly ToolSpec[];
|
|
96
|
+
};
|
|
97
|
+
export declare function isMcpHarnessModuleSpec(value: unknown): value is McpHarnessModuleSpec;
|
|
98
|
+
export declare function mcpHarnessModuleFrom(input: {
|
|
99
|
+
modules?: Readonly<Record<string, unknown>>;
|
|
100
|
+
}): McpHarnessModuleSpec | undefined;
|
|
101
|
+
export declare function runtimeRequirementsForMcpModule(module: McpHarnessModuleSpec | undefined): readonly string[];
|
|
102
|
+
export declare function toMcpRuntimeServerProfile(server: McpHarnessServerSpec): McpRuntimeServerProfile;
|
|
103
|
+
export declare function buildMcpServerProfilesFromManifest(input: {
|
|
104
|
+
harness: {
|
|
105
|
+
modules: Readonly<Record<string, unknown>>;
|
|
106
|
+
};
|
|
107
|
+
}): readonly McpRuntimeServerProfile[];
|
|
108
|
+
export declare function createMcpApplicationStateView(module: McpHarnessModuleSpec | undefined): McpApplicationStateView;
|
|
109
|
+
export declare function planMcpHarnessExposure(manifest: {
|
|
110
|
+
harness: {
|
|
111
|
+
modules: Readonly<Record<string, unknown>>;
|
|
112
|
+
};
|
|
113
|
+
}, nativeToolInventoryByServerId: Readonly<Record<string, readonly NativeToolDeclaration[]>>, stateByServerId?: Readonly<Record<string, Partial<ExposureState>>>): McpHarnessExposurePlan;
|
|
114
|
+
export {};
|