prism-mcp-server 20.21.21 → 20.21.23
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/README.md +25 -0
- package/dist/config.js +3 -3
- package/dist/connect.js +7 -0
- package/dist/darkfactory/actionExecutor.js +327 -0
- package/dist/darkfactory/backendReadiness.js +12 -0
- package/dist/darkfactory/clawInvocation.js +18 -6
- package/dist/darkfactory/enablement.js +29 -0
- package/dist/darkfactory/executionAuthority.js +11 -0
- package/dist/darkfactory/hostPolicy.js +12 -0
- package/dist/darkfactory/promptRouting.js +59 -0
- package/dist/darkfactory/runner.js +179 -31
- package/dist/darkfactory/safetyController.js +10 -1
- package/dist/dashboard/server.js +5 -4
- package/dist/dashboard/settingsPolicy.js +2 -0
- package/dist/dashboard/ui.js +37 -1
- package/dist/onboarding/wizard.js +1 -1
- package/dist/server.js +12 -10
- package/dist/storage/configStorage.js +49 -0
- package/dist/storage/index.js +38 -7
- package/dist/storage/portalContracts.js +55 -0
- package/dist/storage/sqlite.js +13 -4
- package/dist/storage/supabase.js +27 -5
- package/dist/storage/synalux.js +77 -1
- package/dist/tools/ledgerHandlers.js +24 -2
- package/dist/tools/pipelineDefinitions.js +7 -1
- package/dist/tools/pipelineHandlers.js +18 -1
- package/dist/tools/sessionMemoryDefinitions.js +7 -1
- package/dist/utils/llm/adapters/anthropic.js +11 -3
- package/dist/utils/llm/adapters/gemini.js +3 -2
- package/dist/utils/llm/adapters/openai.js +3 -3
- package/dist/utils/llm/adapters/traced.js +2 -2
- package/dist/verification/runner.js +11 -2
- package/package.json +1 -1
|
@@ -61,20 +61,28 @@ export class AnthropicAdapter {
|
|
|
61
61
|
debugLog("[AnthropicAdapter] Initialized");
|
|
62
62
|
}
|
|
63
63
|
// ─── Text Generation ─────────────────────────────────────────────────────
|
|
64
|
-
async generateText(prompt, systemInstruction) {
|
|
65
|
-
const model = getSettingSync("anthropic_model", getDefaultModel());
|
|
64
|
+
async generateText(prompt, systemInstruction, options) {
|
|
65
|
+
const model = options?.model || getSettingSync("anthropic_model", getDefaultModel());
|
|
66
66
|
debugLog(`[AnthropicAdapter] generateText — model=${model}`);
|
|
67
67
|
// Anthropic's Messages API uses system as a top-level field (not a message role).
|
|
68
68
|
// This maps cleanly to LLMProvider's systemInstruction parameter.
|
|
69
69
|
const response = await this.client.messages.create({
|
|
70
70
|
model,
|
|
71
|
-
max_tokens: getMaxTokens(),
|
|
71
|
+
max_tokens: options?.maxOutputTokens || getMaxTokens(),
|
|
72
72
|
...(systemInstruction ? { system: systemInstruction } : {}),
|
|
73
73
|
messages: [{ role: "user", content: prompt }],
|
|
74
|
+
...(options?.json ? {
|
|
75
|
+
tools: [{ name: "emit_json", description: "Return the requested JSON object.", input_schema: { type: "object", additionalProperties: true } }],
|
|
76
|
+
tool_choice: { type: "tool", name: "emit_json" },
|
|
77
|
+
} : {}),
|
|
74
78
|
});
|
|
75
79
|
// Extract text from the first ContentBlock.
|
|
76
80
|
// Anthropic returns an array of content blocks; we only use text blocks.
|
|
77
81
|
const block = response.content[0];
|
|
82
|
+
if (options?.json && block?.type === "tool_use")
|
|
83
|
+
return JSON.stringify(block.input);
|
|
84
|
+
if (options?.json)
|
|
85
|
+
throw new Error("[AnthropicAdapter] Structured response missing emit_json tool use");
|
|
78
86
|
if (!block || block.type !== "text") {
|
|
79
87
|
throw new Error(`[AnthropicAdapter] Unexpected response content type: ${block?.type ?? "empty"}`);
|
|
80
88
|
}
|
|
@@ -62,14 +62,15 @@ export class GeminiAdapter {
|
|
|
62
62
|
this.ai = new GoogleGenerativeAI(GOOGLE_API_KEY);
|
|
63
63
|
}
|
|
64
64
|
// ─── Text Generation ─────────────────────────────────────────────────────
|
|
65
|
-
async generateText(prompt, systemInstruction) {
|
|
65
|
+
async generateText(prompt, systemInstruction, options) {
|
|
66
66
|
// getGenerativeModel() is lightweight — it just binds model name + options.
|
|
67
67
|
// The HTTP call happens inside generateContent() below.
|
|
68
68
|
const model = this.ai.getGenerativeModel({
|
|
69
|
-
model: TEXT_MODEL,
|
|
69
|
+
model: options?.model || TEXT_MODEL,
|
|
70
70
|
// Only spread systemInstruction if provided — avoids sending an empty field
|
|
71
71
|
// which could confuse some model versions.
|
|
72
72
|
...(systemInstruction ? { systemInstruction } : {}),
|
|
73
|
+
...(options?.json || options?.maxOutputTokens ? { generationConfig: { ...(options?.json ? { responseMimeType: "application/json" } : {}), ...(options?.maxOutputTokens ? { maxOutputTokens: options.maxOutputTokens } : {}) } } : {}),
|
|
73
74
|
});
|
|
74
75
|
const result = await model.generateContent(prompt);
|
|
75
76
|
// result.response.text() extracts the first candidate's text content.
|
|
@@ -84,10 +84,10 @@ export class OpenAIAdapter {
|
|
|
84
84
|
debugLog(`[OpenAIAdapter] Initialized — baseURL=${baseURL}, keyless=${!apiKey}`);
|
|
85
85
|
}
|
|
86
86
|
// ─── Text Generation ─────────────────────────────────────────────────────
|
|
87
|
-
async generateText(prompt, systemInstruction) {
|
|
87
|
+
async generateText(prompt, systemInstruction, options) {
|
|
88
88
|
// Read model at call time (not constructor) so the user can hot-swap
|
|
89
89
|
// the model setting without restarting the server.
|
|
90
|
-
const model = getSettingSync("openai_model", "gpt-4o-mini");
|
|
90
|
+
const model = options?.model || getSettingSync("openai_model", "gpt-4o-mini");
|
|
91
91
|
// Build message array: optional system message first, then user prompt.
|
|
92
92
|
// This maps cleanly to Gemini's systemInstruction + user prompt pattern.
|
|
93
93
|
const messages = [];
|
|
@@ -96,7 +96,7 @@ export class OpenAIAdapter {
|
|
|
96
96
|
}
|
|
97
97
|
messages.push({ role: "user", content: prompt });
|
|
98
98
|
debugLog(`[OpenAIAdapter] generateText — model=${model}, messages=${messages.length}`);
|
|
99
|
-
const response = await this.client.chat.completions.create({ model, messages });
|
|
99
|
+
const response = await this.client.chat.completions.create({ model, messages, ...(options?.json ? { response_format: { type: "json_object" } } : {}), ...(options?.maxOutputTokens ? { max_tokens: options.maxOutputTokens } : {}) });
|
|
100
100
|
// choices[0] is always the primary completion. ?? "" returns empty string
|
|
101
101
|
// on null content (e.g. if the model returned a function call instead).
|
|
102
102
|
return response.choices[0]?.message?.content ?? "";
|
|
@@ -115,7 +115,7 @@ export class TracingLLMProvider {
|
|
|
115
115
|
// will correctly evaluate to false.
|
|
116
116
|
}
|
|
117
117
|
// ── generateText ──────────────────────────────────────────────────────────
|
|
118
|
-
async generateText(prompt, systemInstruction) {
|
|
118
|
+
async generateText(prompt, systemInstruction, options) {
|
|
119
119
|
/**
|
|
120
120
|
* Span: llm.generate_text
|
|
121
121
|
*
|
|
@@ -130,7 +130,7 @@ export class TracingLLMProvider {
|
|
|
130
130
|
});
|
|
131
131
|
return context.with(trace.setSpan(context.active(), span), async () => {
|
|
132
132
|
try {
|
|
133
|
-
const result = await this.inner.generateText(prompt, systemInstruction);
|
|
133
|
+
const result = options ? await this.inner.generateText(prompt, systemInstruction, options) : await this.inner.generateText(prompt, systemInstruction);
|
|
134
134
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
135
135
|
return result;
|
|
136
136
|
}
|
|
@@ -54,7 +54,14 @@ function isPrivateIpv4(hostname) {
|
|
|
54
54
|
return PRIVATE_IPV4_CIDRS.some(([start, end]) => value >= start && value <= end);
|
|
55
55
|
}
|
|
56
56
|
function isDisallowedIpv6(hostname) {
|
|
57
|
-
const normalized = hostname.toLowerCase();
|
|
57
|
+
const normalized = hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
58
|
+
// URL normalizes dotted IPv4-mapped addresses into two hexadecimal groups.
|
|
59
|
+
const mapped = normalized.match(/^::ffff:([a-f0-9]{1,4}):([a-f0-9]{1,4})$/);
|
|
60
|
+
if (mapped) {
|
|
61
|
+
const high = parseInt(mapped[1], 16);
|
|
62
|
+
const low = parseInt(mapped[2], 16);
|
|
63
|
+
return isPrivateIpv4(`${high >> 8}.${high & 255}.${low >> 8}.${low & 255}`);
|
|
64
|
+
}
|
|
58
65
|
return (normalized === "::1" ||
|
|
59
66
|
normalized.startsWith("fc") || // fc00::/7
|
|
60
67
|
normalized.startsWith("fd") || // fc00::/7
|
|
@@ -227,7 +234,9 @@ export class VerificationRunner {
|
|
|
227
234
|
const parsed = JSON.parse(jsonContent);
|
|
228
235
|
const suite = TestSuiteSchema.parse(parsed);
|
|
229
236
|
if (harness) {
|
|
230
|
-
|
|
237
|
+
// The frozen hash covers the submitted JSON, including its key order.
|
|
238
|
+
// Schema parsing may reorder keys or supply defaults for execution.
|
|
239
|
+
VerificationRunner.verifyRubricHash(parsed.tests, harness);
|
|
231
240
|
}
|
|
232
241
|
const { preparedById, orderedIds, precomputed } = prepareAssertions(suite.tests, filterLayers, minSeverity, config);
|
|
233
242
|
const outcomes = new Map();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prism-mcp-server",
|
|
3
|
-
"version": "20.21.
|
|
3
|
+
"version": "20.21.23",
|
|
4
4
|
"mcpName": "io.github.dcostenco/prism-coder",
|
|
5
5
|
"description": "Persistent session memory for AI coding agents that never leaves your machine — including the on-device model that reasons over it. Restores your prior decisions, open TODOs, and changed files across sessions; adds associative recall of related past work, semantic drift detection, and local inference. Local-first by default. Works with Claude Code, Cursor, and Codex.",
|
|
6
6
|
"module": "index.ts",
|