@praxis-ai/praxis 0.1.4 → 0.1.6
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 +29 -3
- package/dist/agentCore/index.js +3 -0
- package/dist/applicationLayer/applicationRuntime.js +7 -1
- package/dist/basetool/authoring.d.ts +2 -0
- package/dist/basetool/authoring.js +2 -0
- package/dist/basetool/catalog.d.ts +1 -1
- package/dist/basetool/catalog.js +86 -4
- package/dist/basetool/core/index.d.ts +4 -2
- package/dist/basetool/core/index.js +8 -0
- package/dist/basetool/core/mcpCompletions.d.ts +2 -0
- package/dist/basetool/core/mcpCompletions.js +70 -0
- package/dist/basetool/core/mcpPrompts.d.ts +2 -0
- package/dist/basetool/core/mcpPrompts.js +48 -0
- package/dist/basetool/core/mcpResources.js +41 -5
- package/dist/basetool/profiles.js +15 -1
- package/dist/basetool/registry.d.ts +1 -1
- package/dist/basetool/supportCatalog.js +23 -6
- package/dist/executionEngine/promptPack/promptAssembler.js +1 -0
- package/dist/executionEngine/promptPack/promptDefiner.d.ts +4 -4
- package/dist/executionEngine/promptPack/promptDefiner.js +1 -0
- package/dist/runtimeImplementation/praxisRuntimeKernel.d.ts +4 -0
- package/dist/runtimeImplementation/praxisRuntimeKernel.js +1729 -1498
- package/dist/runtimeImplementation/runtime.execEngine/baseToolApprovalScope.js +11 -0
- package/dist/runtimeImplementation/runtime.execEngine/baseToolExecutorPortFactory.js +13 -1
- package/dist/runtimeImplementation/runtime.execEngine/baseToolPolicyAdjudicator.js +14 -0
- package/dist/runtimeImplementation/runtime.execEngine/mcpRuntimeAdapter.d.ts +27 -0
- package/dist/runtimeImplementation/runtime.execEngine/mcpRuntimeAdapter.js +648 -56
- package/dist/runtimeImplementation/runtime.execEngine/promptContextAssembly.d.ts +2 -0
- package/dist/runtimeImplementation/runtime.execEngine/promptContextAssembly.js +35 -0
- package/dist/runtimeImplementation/runtime.mcpPlane/index.d.ts +20 -7
- package/dist/runtimeImplementation/runtime.mcpPlane/index.js +105 -89
- package/dist/runtimeImplementation/runtime.skillPlane/index.d.ts +119 -0
- package/dist/runtimeImplementation/runtime.skillPlane/index.js +274 -0
- package/dist/runtimeImplementation/runtimeAgentManifest.js +2 -0
- package/dist/toolBase/catalog.d.ts +24 -0
- package/dist/toolBase/catalog.js +41 -3
- package/dist/toolBase/profiles.d.ts +3 -3
- package/dist/toolBase/profiles.js +2 -0
- package/dist/toolBase/types.d.ts +1 -1
- package/examples/fullstack/agents/repoInspector/harness/repoInspectorHarness.ts +23 -0
- package/examples/raxode-mcp-plus-ten-server.config.json +229 -0
- package/examples/scripts/README.md +8 -2
- package/examples/scripts/mcp-plus-native-smoke.ts +1296 -0
- package/package.json +3 -1
- package/raxode-tui/dist/raxode-cli/backend/agents/codingAgent/prompts/tool-use.md +1 -1
- package/raxode-tui/dist/raxode-cli/backend/application/mcpConfig.d.ts +9 -0
- package/raxode-tui/dist/raxode-cli/backend/application/mcpConfig.js +65 -0
- package/raxode-tui/dist/raxode-cli/backend/application/mcpReadinessSummary.d.ts +28 -0
- package/raxode-tui/dist/raxode-cli/backend/application/mcpReadinessSummary.js +57 -0
- package/raxode-tui/dist/raxode-cli/backend/application/runtimeReadiness.d.ts +5 -1
- package/raxode-tui/dist/raxode-cli/backend/application/runtimeReadiness.js +40 -0
- package/raxode-tui/dist/raxode-cli/backend/application/stdioApplicationServer.js +6 -0
- package/raxode-tui/dist/raxode-cli/backend/directApplicationBackend.d.ts +4 -0
- package/raxode-tui/dist/raxode-cli/backend/directApplicationBackend.js +14 -0
- package/raxode-tui/dist/raxode-cli/backend/raxodeBackend.d.ts +1 -1
- package/raxode-tui/dist/raxode-cli/backend/raxodeBackend.js +16 -1
- package/raxode-tui/dist/raxode-cli/contracts.d.ts +1 -0
- package/raxode-tui/dist/raxode-cli/frontend/bridge/readiness.js +24 -0
- package/raxode-tui/dist/raxode-cli/frontend/tui/app/direct-tui.js +35 -0
- package/raxode-tui/dist/raxode-cli/frontend/tui/cli/raxode-cli.d.ts +2 -0
- package/raxode-tui/dist/raxode-cli/frontend/tui/cli/raxode-cli.js +8 -0
- package/raxode-tui/dist/raxode-cli/frontend/tui/config/raxode-config.d.ts +31 -0
- package/raxode-tui/dist/raxode-cli/frontend/tui/config/raxode-config.js +129 -0
- package/raxode-tui/dist/raxode-cli/index.d.ts +1 -0
|
@@ -36,6 +36,8 @@ export type PromptContextAssemblyRequest = {
|
|
|
36
36
|
sessionSummary?: PromptContextSessionSummary;
|
|
37
37
|
conversationWindow?: readonly PromptContextConversationMessage[];
|
|
38
38
|
projectContextGovernanceMaterials?: readonly PromptPackMaterialDraft[];
|
|
39
|
+
toolDeclarationPreludeMaterials?: readonly PromptPackMaterialDraft[];
|
|
40
|
+
skillIndexMaterials?: readonly PromptPackMaterialDraft[];
|
|
39
41
|
budget?: PromptContextAssemblyBudget;
|
|
40
42
|
toolContextSelection?: BaseToolContextSelection;
|
|
41
43
|
toolContextUsage?: readonly BaseToolContextUsageRecord[];
|
|
@@ -418,6 +418,37 @@ export function assemblePromptContextMaterials(input) {
|
|
|
418
418
|
sandboxMode: input.manifest.sandbox?.profile,
|
|
419
419
|
toolSpecificGuidance: PRAXIS_BASE_TOOL_CALLING_PROTOCOL,
|
|
420
420
|
});
|
|
421
|
+
const toolDeclarationPreludeMaterials = (input.toolDeclarationPreludeMaterials ?? []).map((material, index) => ({
|
|
422
|
+
...material,
|
|
423
|
+
id: material.id ?? `runtime:tool-declaration-prelude:${index + 1}`,
|
|
424
|
+
kind: material.kind,
|
|
425
|
+
source: material.source ?? "runtime.toolDeclarationPrelude",
|
|
426
|
+
sourceCategory: material.sourceCategory ?? "declared-built-in",
|
|
427
|
+
priority: material.priority ?? 95.5 - index,
|
|
428
|
+
trusted: material.trusted ?? true,
|
|
429
|
+
scope: material.scope ?? "runtime.toolCalling",
|
|
430
|
+
promptSegmentKind: "toolDeclarations",
|
|
431
|
+
metadata: {
|
|
432
|
+
...(material.metadata ?? {}),
|
|
433
|
+
promptSegmentKind: "toolDeclarations",
|
|
434
|
+
toolMaterialType: "policy",
|
|
435
|
+
},
|
|
436
|
+
}));
|
|
437
|
+
const skillIndexMaterials = (input.skillIndexMaterials ?? []).map((material, index) => ({
|
|
438
|
+
...material,
|
|
439
|
+
id: material.id ?? `runtime:skill-index:${index + 1}`,
|
|
440
|
+
kind: material.kind,
|
|
441
|
+
source: material.source ?? "runtime.skillPlane.index",
|
|
442
|
+
sourceCategory: material.sourceCategory ?? "declared-built-in",
|
|
443
|
+
priority: material.priority ?? 94 - index,
|
|
444
|
+
trusted: material.trusted ?? true,
|
|
445
|
+
scope: material.scope ?? "runtime.skillPlane.index",
|
|
446
|
+
promptSegmentKind: "skillIndex",
|
|
447
|
+
metadata: {
|
|
448
|
+
...(material.metadata ?? {}),
|
|
449
|
+
promptSegmentKind: "skillIndex",
|
|
450
|
+
},
|
|
451
|
+
}));
|
|
421
452
|
const sessionSummaryMaterial = input.sessionSummary === undefined
|
|
422
453
|
? []
|
|
423
454
|
: [{
|
|
@@ -445,6 +476,8 @@ export function assemblePromptContextMaterials(input) {
|
|
|
445
476
|
...projectContextGovernanceMaterials,
|
|
446
477
|
...sessionSummaryMaterial,
|
|
447
478
|
...memoryContextMaterials,
|
|
479
|
+
...toolDeclarationPreludeMaterials,
|
|
480
|
+
...skillIndexMaterials,
|
|
448
481
|
{
|
|
449
482
|
id: `task:${input.turnIndex}`,
|
|
450
483
|
kind: "user",
|
|
@@ -526,6 +559,8 @@ export function assemblePromptContextMaterials(input) {
|
|
|
526
559
|
...manifestPromptMaterials,
|
|
527
560
|
declaredRuntimeContextMaterial,
|
|
528
561
|
toolDeclarationsMaterial,
|
|
562
|
+
...toolDeclarationPreludeMaterials,
|
|
563
|
+
...skillIndexMaterials,
|
|
529
564
|
...projectContextGovernanceMaterials,
|
|
530
565
|
...sessionSummaryMaterial,
|
|
531
566
|
...memoryContextMaterials,
|
|
@@ -90,7 +90,7 @@ export type McpPlusProfileProposal = {
|
|
|
90
90
|
title: string;
|
|
91
91
|
summary: string;
|
|
92
92
|
}[];
|
|
93
|
-
rationale?: string
|
|
93
|
+
rationale?: string | Readonly<Record<string, string>>;
|
|
94
94
|
metadata?: Readonly<Record<string, unknown>>;
|
|
95
95
|
};
|
|
96
96
|
export type McpPlusLearnedProfile = {
|
|
@@ -99,7 +99,7 @@ export type McpPlusLearnedProfile = {
|
|
|
99
99
|
projectId: string;
|
|
100
100
|
exposure: NonNullable<McpPlusManifest["exposure"]>;
|
|
101
101
|
skills?: NonNullable<McpPlusManifest["skills"]>;
|
|
102
|
-
rationale?: string
|
|
102
|
+
rationale?: string | Readonly<Record<string, string>>;
|
|
103
103
|
createdAt: string;
|
|
104
104
|
updatedAt: string;
|
|
105
105
|
metadata?: Readonly<Record<string, unknown>>;
|
|
@@ -107,14 +107,26 @@ export type McpPlusLearnedProfile = {
|
|
|
107
107
|
export type McpPlusRuntimeOverlay = {
|
|
108
108
|
serverId: string;
|
|
109
109
|
sessionId: string;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
state: {
|
|
111
|
+
mode: ExposureMode;
|
|
112
|
+
activeTools: readonly string[];
|
|
113
|
+
pendingReprofile?: boolean;
|
|
114
|
+
counters: {
|
|
115
|
+
consecutiveIndexedToolCalls: Readonly<Record<string, number>>;
|
|
116
|
+
};
|
|
115
117
|
};
|
|
116
118
|
updatedAt: string;
|
|
117
119
|
metadata?: Readonly<Record<string, unknown>>;
|
|
120
|
+
/** @deprecated Read-only migration support for pre-contract Praxis overlays. */
|
|
121
|
+
mode?: ExposureMode;
|
|
122
|
+
/** @deprecated Read-only migration support for pre-contract Praxis overlays. */
|
|
123
|
+
activeTools?: readonly string[];
|
|
124
|
+
/** @deprecated Read-only migration support for pre-contract Praxis overlays. */
|
|
125
|
+
pendingReprofile?: boolean;
|
|
126
|
+
/** @deprecated Read-only migration support for pre-contract Praxis overlays. */
|
|
127
|
+
counters?: {
|
|
128
|
+
consecutiveIndexedToolCalls: Readonly<Record<string, number>>;
|
|
129
|
+
};
|
|
118
130
|
};
|
|
119
131
|
export type McpPlusProfileStoreKey = {
|
|
120
132
|
serverId: string;
|
|
@@ -206,6 +218,7 @@ export declare function learnedProfileFromProposal(input: {
|
|
|
206
218
|
projectId: string;
|
|
207
219
|
now: string;
|
|
208
220
|
existing?: McpPlusLearnedProfile;
|
|
221
|
+
protectedAlwaysIndexTools?: readonly string[];
|
|
209
222
|
}): {
|
|
210
223
|
ok: true;
|
|
211
224
|
profile: McpPlusLearnedProfile;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
7
7
|
import path from "node:path";
|
|
8
|
-
import { compileMcpPlusManifest, createExpandToolDeclaration, lowerExposurePlanToMcpSurface, planExposure, } from "@praxis-ai/mcp-plus";
|
|
8
|
+
import { compileMcpPlusManifest, createExpandToolDeclaration, createInitToolDeclaration as createMcpPlusContractInitToolDeclaration, createLearnedProfileFromProposal as createContractLearnedProfileFromProposal, createReprofileToolDeclaration as createMcpPlusContractReprofileToolDeclaration, lowerExposurePlanToMcpSurface, mergeMcpPlusPolicy, normalizeProfileProposal, planExposure, validateProfileProposal, } from "@praxis-ai/mcp-plus";
|
|
9
9
|
export function mcpServer(serverId, input) {
|
|
10
10
|
return {
|
|
11
11
|
...input,
|
|
@@ -42,6 +42,14 @@ export const mcp = {
|
|
|
42
42
|
toolId: "mcp.resources",
|
|
43
43
|
metadata: { source: "praxis.mcp.recommendedTools", toolProviderKind: "mcp-static" },
|
|
44
44
|
},
|
|
45
|
+
{
|
|
46
|
+
toolId: "mcp.prompts",
|
|
47
|
+
metadata: { source: "praxis.mcp.recommendedTools", toolProviderKind: "mcp-static" },
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
toolId: "mcp.completions",
|
|
51
|
+
metadata: { source: "praxis.mcp.recommendedTools", toolProviderKind: "mcp-static" },
|
|
52
|
+
},
|
|
45
53
|
];
|
|
46
54
|
},
|
|
47
55
|
};
|
|
@@ -113,18 +121,10 @@ function jsonObjectSchema(properties, required = []) {
|
|
|
113
121
|
};
|
|
114
122
|
}
|
|
115
123
|
export function createMcpPlusInitToolDeclaration() {
|
|
116
|
-
return
|
|
117
|
-
name: "mcp_plus.init",
|
|
118
|
-
description: "Submit the first MCP+ profile proposal for this standard MCP server after inspecting its full MCP tools/list surface.",
|
|
119
|
-
inputSchema: profileProposalInputSchema("init"),
|
|
120
|
-
};
|
|
124
|
+
return createMcpPlusContractInitToolDeclaration();
|
|
121
125
|
}
|
|
122
126
|
export function createMcpPlusReprofileToolDeclaration() {
|
|
123
|
-
return
|
|
124
|
-
name: "mcp_plus.reprofile",
|
|
125
|
-
description: "Submit an updated MCP+ profile proposal for this standard MCP server when runtime usage shows the current profile is stale.",
|
|
126
|
-
inputSchema: profileProposalInputSchema("reprofile"),
|
|
127
|
-
};
|
|
127
|
+
return createMcpPlusContractReprofileToolDeclaration();
|
|
128
128
|
}
|
|
129
129
|
export function createMcpPlusSkillReadToolDeclaration() {
|
|
130
130
|
return {
|
|
@@ -165,36 +165,6 @@ export function createMcpPlusFinishToolDeclaration() {
|
|
|
165
165
|
}, ["serverId", "outcome"]),
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
|
-
function profileProposalInputSchema(kind) {
|
|
169
|
-
return jsonObjectSchema({
|
|
170
|
-
serverId: { type: "string" },
|
|
171
|
-
pinnedTools: { type: "array", items: { type: "string" } },
|
|
172
|
-
warmTools: { type: "array", items: { type: "string" } },
|
|
173
|
-
indexedTools: { type: "array", items: { type: "string" } },
|
|
174
|
-
alwaysIndexTools: { type: "array", items: { type: "string" } },
|
|
175
|
-
toolCards: {
|
|
176
|
-
type: "object",
|
|
177
|
-
additionalProperties: {
|
|
178
|
-
type: "object",
|
|
179
|
-
properties: {
|
|
180
|
-
title: { type: "string" },
|
|
181
|
-
summary: { type: "string" },
|
|
182
|
-
keywords: { type: "array", items: { type: "string" } },
|
|
183
|
-
},
|
|
184
|
-
additionalProperties: false,
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
skillChapters: {
|
|
188
|
-
type: "array",
|
|
189
|
-
items: jsonObjectSchema({
|
|
190
|
-
id: { type: "string" },
|
|
191
|
-
title: { type: "string" },
|
|
192
|
-
summary: { type: "string" },
|
|
193
|
-
}, ["id", "title", "summary"]),
|
|
194
|
-
},
|
|
195
|
-
rationale: { type: "string", description: `${kind} rationale for the host runtime.` },
|
|
196
|
-
}, ["serverId"]);
|
|
197
|
-
}
|
|
198
168
|
function dynamicToolSpecForNativeTool(serverId, tool) {
|
|
199
169
|
return {
|
|
200
170
|
toolId: `mcp.${toolIdPart(serverId)}.${toolIdPart(tool.name)}`,
|
|
@@ -362,6 +332,47 @@ function defaultToolCard(tool) {
|
|
|
362
332
|
keywords: tool.name.split(/[^a-zA-Z0-9]+/u).filter(Boolean),
|
|
363
333
|
};
|
|
364
334
|
}
|
|
335
|
+
function profileRationaleForContract(rationale) {
|
|
336
|
+
if (typeof rationale === "string") {
|
|
337
|
+
return rationale.trim().length === 0 ? undefined : { summary: rationale };
|
|
338
|
+
}
|
|
339
|
+
if (rationale === undefined)
|
|
340
|
+
return undefined;
|
|
341
|
+
return Object.fromEntries(Object.entries(rationale).filter(([, value]) => typeof value === "string"));
|
|
342
|
+
}
|
|
343
|
+
function toContractProfileProposal(proposal) {
|
|
344
|
+
const toolCards = Object.fromEntries(Object.entries(proposal.toolCards ?? {}).map(([toolName, card]) => [toolName, {
|
|
345
|
+
title: card.title,
|
|
346
|
+
summary: card.summary,
|
|
347
|
+
keywords: card.keywords === undefined ? undefined : [...card.keywords],
|
|
348
|
+
}]));
|
|
349
|
+
const contractProposal = {
|
|
350
|
+
serverId: proposal.serverId,
|
|
351
|
+
pinnedTools: uniqueStrings(proposal.pinnedTools),
|
|
352
|
+
warmTools: proposal.warmTools === undefined ? undefined : uniqueStrings(proposal.warmTools),
|
|
353
|
+
indexedTools: uniqueStrings(proposal.indexedTools),
|
|
354
|
+
alwaysIndexTools: proposal.alwaysIndexTools === undefined ? undefined : uniqueStrings(proposal.alwaysIndexTools),
|
|
355
|
+
toolCards,
|
|
356
|
+
skillChapters: proposal.skillChapters?.map((chapter) => ({ ...chapter })),
|
|
357
|
+
rationale: profileRationaleForContract(proposal.rationale),
|
|
358
|
+
};
|
|
359
|
+
if (Object.hasOwn(proposal, "modeHint")) {
|
|
360
|
+
contractProposal.modeHint = proposal.modeHint;
|
|
361
|
+
}
|
|
362
|
+
return Object.fromEntries(Object.entries(contractProposal).filter(([, value]) => value !== undefined));
|
|
363
|
+
}
|
|
364
|
+
function profileErrorCodeFromValidationIssue(code) {
|
|
365
|
+
switch (code) {
|
|
366
|
+
case "unknown_tool":
|
|
367
|
+
return "MCP_PLUS_PROFILE_UNKNOWN_TOOL";
|
|
368
|
+
case "always_index_pinned":
|
|
369
|
+
return "MCP_PLUS_PROFILE_ALWAYS_INDEX_PINNED";
|
|
370
|
+
case "reserved_runtime_field":
|
|
371
|
+
return "MCP_PLUS_PROFILE_MODE_HINT_UNSUPPORTED";
|
|
372
|
+
default:
|
|
373
|
+
return "MCP_PLUS_PROFILE_INVALID_PROPOSAL";
|
|
374
|
+
}
|
|
375
|
+
}
|
|
365
376
|
function learnedManifestFromProfile(profile, server) {
|
|
366
377
|
return {
|
|
367
378
|
server: {
|
|
@@ -373,6 +384,28 @@ function learnedManifestFromProfile(profile, server) {
|
|
|
373
384
|
skills: profile.skills,
|
|
374
385
|
};
|
|
375
386
|
}
|
|
387
|
+
function contractLearnedProfileFromPraxisProfile(profile) {
|
|
388
|
+
const toolCards = Object.fromEntries(Object.entries(profile.exposure.toolCards ?? {}).flatMap(([toolName, card]) => {
|
|
389
|
+
if (typeof card.summary !== "string" || card.summary.trim().length === 0)
|
|
390
|
+
return [];
|
|
391
|
+
return [[toolName, {
|
|
392
|
+
title: card.title,
|
|
393
|
+
summary: card.summary,
|
|
394
|
+
keywords: card.keywords === undefined ? undefined : [...card.keywords],
|
|
395
|
+
}]];
|
|
396
|
+
}));
|
|
397
|
+
return {
|
|
398
|
+
schemaVersion: profile.schemaVersion,
|
|
399
|
+
serverId: profile.serverId,
|
|
400
|
+
pinnedTools: [...(profile.exposure.pinnedTools ?? [])],
|
|
401
|
+
warmTools: [...(profile.exposure.warmTools ?? [])],
|
|
402
|
+
indexedTools: [...(profile.exposure.indexedTools ?? [])],
|
|
403
|
+
alwaysIndexTools: [...(profile.exposure.alwaysIndexTools ?? [])],
|
|
404
|
+
toolCards,
|
|
405
|
+
skillChapters: profile.skills?.chapters?.map((chapter) => ({ ...chapter })),
|
|
406
|
+
rationale: profileRationaleForContract(profile.rationale),
|
|
407
|
+
};
|
|
408
|
+
}
|
|
376
409
|
function fallbackMcpPlusManifest(server, nativeTools) {
|
|
377
410
|
const smallServer = nativeTools.length <= 8;
|
|
378
411
|
return {
|
|
@@ -412,65 +445,41 @@ function bootstrapSurface(server, nativeTools) {
|
|
|
412
445
|
};
|
|
413
446
|
}
|
|
414
447
|
export function learnedProfileFromProposal(input) {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
const nativeToolNames = new Set(input.nativeTools.map((tool) => tool.name));
|
|
426
|
-
const referenced = [
|
|
427
|
-
...uniqueStrings(input.proposal.pinnedTools),
|
|
428
|
-
...uniqueStrings(input.proposal.warmTools),
|
|
429
|
-
...uniqueStrings(input.proposal.indexedTools),
|
|
430
|
-
...uniqueStrings(input.proposal.alwaysIndexTools),
|
|
431
|
-
...Object.keys(input.proposal.toolCards ?? {}),
|
|
432
|
-
];
|
|
433
|
-
const unknown = referenced.filter((toolName) => !nativeToolNames.has(toolName));
|
|
434
|
-
if (unknown.length > 0) {
|
|
435
|
-
return {
|
|
436
|
-
ok: false,
|
|
437
|
-
error: {
|
|
438
|
-
code: "MCP_PLUS_PROFILE_UNKNOWN_TOOL",
|
|
439
|
-
message: `MCP+ profile proposal references unknown tool(s): ${unknown.join(", ")}`,
|
|
440
|
-
publicSafe: true,
|
|
441
|
-
},
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
const alwaysIndex = new Set(uniqueStrings(input.proposal.alwaysIndexTools));
|
|
445
|
-
const pinnedAlwaysIndex = uniqueStrings(input.proposal.pinnedTools).filter((toolName) => alwaysIndex.has(toolName));
|
|
446
|
-
if (pinnedAlwaysIndex.length > 0) {
|
|
448
|
+
const contractProposal = toContractProfileProposal(input.proposal);
|
|
449
|
+
const validation = validateProfileProposal(contractProposal, input.nativeTools, {
|
|
450
|
+
serverId: input.proposal.serverId,
|
|
451
|
+
alwaysIndexTools: [
|
|
452
|
+
...(input.existing?.exposure.alwaysIndexTools ?? []),
|
|
453
|
+
...(input.protectedAlwaysIndexTools ?? []),
|
|
454
|
+
],
|
|
455
|
+
});
|
|
456
|
+
if (!validation.valid) {
|
|
457
|
+
const primary = validation.issues[0];
|
|
447
458
|
return {
|
|
448
459
|
ok: false,
|
|
449
460
|
error: {
|
|
450
|
-
code: "
|
|
451
|
-
message:
|
|
461
|
+
code: primary === undefined ? "MCP_PLUS_PROFILE_INVALID_PROPOSAL" : profileErrorCodeFromValidationIssue(primary.code),
|
|
462
|
+
message: validation.issues.map((issue) => issue.message).join(" "),
|
|
452
463
|
publicSafe: true,
|
|
453
464
|
},
|
|
454
465
|
};
|
|
455
466
|
}
|
|
467
|
+
const normalizedProposal = normalizeProfileProposal(contractProposal);
|
|
468
|
+
const contractProfile = createContractLearnedProfileFromProposal(normalizedProposal);
|
|
456
469
|
const profile = {
|
|
457
470
|
schemaVersion: "mcp-plus.profile.v1",
|
|
458
|
-
serverId:
|
|
471
|
+
serverId: contractProfile.serverId,
|
|
459
472
|
projectId: input.projectId,
|
|
460
473
|
exposure: {
|
|
461
|
-
pinnedTools:
|
|
462
|
-
warmTools:
|
|
463
|
-
indexedTools:
|
|
464
|
-
alwaysIndexTools:
|
|
465
|
-
toolCards:
|
|
466
|
-
title: card.title,
|
|
467
|
-
summary: card.summary,
|
|
468
|
-
keywords: card.keywords === undefined ? undefined : [...card.keywords],
|
|
469
|
-
}])),
|
|
474
|
+
pinnedTools: contractProfile.pinnedTools ?? [],
|
|
475
|
+
warmTools: contractProfile.warmTools ?? [],
|
|
476
|
+
indexedTools: contractProfile.indexedTools ?? [],
|
|
477
|
+
alwaysIndexTools: contractProfile.alwaysIndexTools ?? [],
|
|
478
|
+
toolCards: contractProfile.toolCards,
|
|
470
479
|
},
|
|
471
|
-
skills:
|
|
480
|
+
skills: contractProfile.skillChapters === undefined ? input.existing?.skills : {
|
|
472
481
|
...(input.existing?.skills ?? {}),
|
|
473
|
-
chapters:
|
|
482
|
+
chapters: contractProfile.skillChapters.map((chapter) => ({ ...chapter })),
|
|
474
483
|
},
|
|
475
484
|
rationale: input.proposal.rationale,
|
|
476
485
|
createdAt: input.existing?.createdAt ?? input.now,
|
|
@@ -514,9 +523,15 @@ export function planMcpHarnessExposure(manifest, nativeToolInventoryByServerId,
|
|
|
514
523
|
dynamicToolSpecs: dynamicToolSpecsForSurface(server.serverId, surface),
|
|
515
524
|
};
|
|
516
525
|
}
|
|
517
|
-
const
|
|
526
|
+
const baseManifest = server.manifest ?? (learnedProfile === undefined
|
|
518
527
|
? fallbackMcpPlusManifest(server, nativeTools)
|
|
519
528
|
: learnedManifestFromProfile(learnedProfile, server));
|
|
529
|
+
const effectiveManifest = learnedProfile === undefined
|
|
530
|
+
? baseManifest
|
|
531
|
+
: mergeMcpPlusPolicy({
|
|
532
|
+
manifest: baseManifest,
|
|
533
|
+
learnedProfile: contractLearnedProfileFromPraxisProfile(learnedProfile),
|
|
534
|
+
});
|
|
520
535
|
const graph = compileMcpPlusManifest(effectiveManifest, nativeTools);
|
|
521
536
|
const state = {
|
|
522
537
|
serverId: server.serverId,
|
|
@@ -525,10 +540,11 @@ export function planMcpHarnessExposure(manifest, nativeToolInventoryByServerId,
|
|
|
525
540
|
};
|
|
526
541
|
const plan = planExposure(graph, state);
|
|
527
542
|
const surface = lowerExposurePlanToMcpSurface(plan);
|
|
543
|
+
const shouldExposeExpandControl = state.mode === "frozen" || surface.sidecar.toolIndex.length > 0;
|
|
528
544
|
const withNativeControls = {
|
|
529
545
|
tools: [
|
|
530
546
|
...surface.tools.filter((tool) => tool.name !== "mcp_plus.expand"),
|
|
531
|
-
createExpandToolDeclaration(),
|
|
547
|
+
...(shouldExposeExpandControl ? [createExpandToolDeclaration()] : []),
|
|
532
548
|
...(stateByServerId[server.serverId]?.mode === "frozen" ? [] : [
|
|
533
549
|
createMcpPlusSkillReadToolDeclaration(),
|
|
534
550
|
createMcpPlusSkillWriteToolDeclaration(),
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { PromptPackMaterialDraft } from "../../executionEngine/promptPack/promptDefiner.js";
|
|
2
|
+
export type SkillPlaneScope = "agent" | "project" | "workspace" | "user" | "session";
|
|
3
|
+
export type SkillPlanePromotionState = "experience" | "skill" | "candidate-mcp-plus" | "mcp-plus" | "tool";
|
|
4
|
+
export type SkillHead = {
|
|
5
|
+
skillId: string;
|
|
6
|
+
title: string;
|
|
7
|
+
summary: string;
|
|
8
|
+
scope?: SkillPlaneScope;
|
|
9
|
+
whenToUse?: string;
|
|
10
|
+
why?: string;
|
|
11
|
+
keywords?: readonly string[];
|
|
12
|
+
pitfallsPreview?: readonly string[];
|
|
13
|
+
bodyRef?: string;
|
|
14
|
+
promotedFrom?: readonly string[];
|
|
15
|
+
promotionState?: SkillPlanePromotionState;
|
|
16
|
+
};
|
|
17
|
+
export type SkillBody = SkillHead & {
|
|
18
|
+
prerequisites?: readonly string[];
|
|
19
|
+
do?: readonly string[];
|
|
20
|
+
avoid?: readonly string[];
|
|
21
|
+
pitfalls?: readonly string[];
|
|
22
|
+
verification?: readonly string[];
|
|
23
|
+
examples?: readonly string[];
|
|
24
|
+
promotionSignals?: readonly string[];
|
|
25
|
+
updatedAt: string;
|
|
26
|
+
};
|
|
27
|
+
export type SkillSourceSpec = {
|
|
28
|
+
kind: "directory";
|
|
29
|
+
path: string;
|
|
30
|
+
scope?: SkillPlaneScope;
|
|
31
|
+
} | {
|
|
32
|
+
kind: "package";
|
|
33
|
+
packageName: string;
|
|
34
|
+
scope?: SkillPlaneScope;
|
|
35
|
+
} | {
|
|
36
|
+
kind: "inline";
|
|
37
|
+
heads: readonly SkillHead[];
|
|
38
|
+
};
|
|
39
|
+
export type SkillPlaneIndexPolicy = {
|
|
40
|
+
maxHeads: number;
|
|
41
|
+
includeScopes: readonly SkillPlaneScope[];
|
|
42
|
+
};
|
|
43
|
+
export type SkillPlaneBodyLoadPolicy = {
|
|
44
|
+
mode: "on-demand" | "eager" | "disabled";
|
|
45
|
+
maxBodiesPerTurn: number;
|
|
46
|
+
};
|
|
47
|
+
export type SkillPlaneLifecyclePolicy = {
|
|
48
|
+
allowWrite: boolean;
|
|
49
|
+
checkpointWrites: boolean;
|
|
50
|
+
promotion: "off" | "suggest" | "auto";
|
|
51
|
+
};
|
|
52
|
+
export type SkillPlaneModuleSpec = {
|
|
53
|
+
kind: "praxis.skill.module";
|
|
54
|
+
version: "praxis.skill.v1";
|
|
55
|
+
sources: readonly SkillSourceSpec[];
|
|
56
|
+
indexPolicy: SkillPlaneIndexPolicy;
|
|
57
|
+
bodyLoadPolicy: SkillPlaneBodyLoadPolicy;
|
|
58
|
+
lifecycle: SkillPlaneLifecyclePolicy;
|
|
59
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
60
|
+
};
|
|
61
|
+
export type SkillPlaneListHeadsQuery = {
|
|
62
|
+
scopes?: readonly SkillPlaneScope[];
|
|
63
|
+
};
|
|
64
|
+
export type SkillPlaneStore = {
|
|
65
|
+
listHeads(query?: SkillPlaneListHeadsQuery): Promise<readonly SkillHead[]>;
|
|
66
|
+
readBody(skillId: string): Promise<SkillBody | undefined>;
|
|
67
|
+
write(body: SkillBody): Promise<SkillBody>;
|
|
68
|
+
};
|
|
69
|
+
export type SkillPlaneSourceResolutionInput = {
|
|
70
|
+
workspaceRoot?: string;
|
|
71
|
+
};
|
|
72
|
+
export type SkillWriteProposal = {
|
|
73
|
+
kind: "praxis.skill.writeProposal";
|
|
74
|
+
body: SkillBody;
|
|
75
|
+
reason?: string;
|
|
76
|
+
safeForRuntimeInspection: true;
|
|
77
|
+
};
|
|
78
|
+
export type SkillPromotionAdvice = {
|
|
79
|
+
kind: "praxis.skill.promotionAdvice";
|
|
80
|
+
skillId: string;
|
|
81
|
+
from?: SkillPlanePromotionState;
|
|
82
|
+
target: "candidate-mcp-plus";
|
|
83
|
+
autoGenerateTool: false;
|
|
84
|
+
reason?: string;
|
|
85
|
+
signals?: readonly string[];
|
|
86
|
+
};
|
|
87
|
+
export declare const skill: {
|
|
88
|
+
readonly directory: (directoryPath: string, input?: {
|
|
89
|
+
scope?: SkillPlaneScope;
|
|
90
|
+
}) => SkillSourceSpec;
|
|
91
|
+
readonly package: (packageName: string, input?: {
|
|
92
|
+
scope?: SkillPlaneScope;
|
|
93
|
+
}) => SkillSourceSpec;
|
|
94
|
+
readonly inline: (heads: readonly SkillHead[]) => SkillSourceSpec;
|
|
95
|
+
readonly module: (input?: {
|
|
96
|
+
sources?: readonly SkillSourceSpec[];
|
|
97
|
+
indexPolicy?: Partial<SkillPlaneIndexPolicy>;
|
|
98
|
+
bodyLoadPolicy?: Partial<SkillPlaneBodyLoadPolicy>;
|
|
99
|
+
lifecycle?: Partial<SkillPlaneLifecyclePolicy>;
|
|
100
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
101
|
+
}) => SkillPlaneModuleSpec;
|
|
102
|
+
};
|
|
103
|
+
export declare function isSkillPlaneModuleSpec(value: unknown): value is SkillPlaneModuleSpec;
|
|
104
|
+
export declare function skillPlaneModuleFrom(input: {
|
|
105
|
+
modules?: Readonly<Record<string, unknown>>;
|
|
106
|
+
}): SkillPlaneModuleSpec | undefined;
|
|
107
|
+
export declare function runtimeRequirementsForSkillModule(module: SkillPlaneModuleSpec | undefined): readonly string[];
|
|
108
|
+
export declare function loadSkillHeadsFromSource(source: SkillSourceSpec, input?: SkillPlaneSourceResolutionInput): Promise<readonly SkillHead[]>;
|
|
109
|
+
export declare function loadSkillHeadsFromSources(sources: readonly SkillSourceSpec[], input?: SkillPlaneSourceResolutionInput): Promise<readonly SkillHead[]>;
|
|
110
|
+
export declare function createInMemorySkillPlaneStore(initialBodies?: readonly SkillBody[]): SkillPlaneStore;
|
|
111
|
+
export declare function createFileSkillPlaneStore(rootDir: string): SkillPlaneStore;
|
|
112
|
+
export declare function renderSkillIndexMaterial(heads: readonly SkillHead[]): PromptPackMaterialDraft;
|
|
113
|
+
export declare function createSkillWriteProposal(body: SkillBody, input?: {
|
|
114
|
+
reason?: string;
|
|
115
|
+
}): SkillWriteProposal;
|
|
116
|
+
export declare function adviseSkillPromotion(skillHead: SkillHead, input?: {
|
|
117
|
+
reason?: string;
|
|
118
|
+
signals?: readonly string[];
|
|
119
|
+
}): SkillPromotionAdvice;
|