predicate-skill 2.0.4 → 2.0.5
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/package.json +1 -1
- package/server.bundle.mjs +112 -32
package/package.json
CHANGED
package/server.bundle.mjs
CHANGED
|
@@ -46295,8 +46295,37 @@ Anthropic.Beta = Beta;
|
|
|
46295
46295
|
var { HUMAN_PROMPT, AI_PROMPT } = Anthropic;
|
|
46296
46296
|
var sdk_default = Anthropic;
|
|
46297
46297
|
|
|
46298
|
+
// ../predicate-agent/src/completion-provider.ts
|
|
46299
|
+
var ANTHROPIC_MODEL = "claude-haiku-4-5-20251001";
|
|
46300
|
+
var AnthropicSdkProvider = class {
|
|
46301
|
+
kind = "anthropic-sdk";
|
|
46302
|
+
isAvailable() {
|
|
46303
|
+
return Boolean(process.env["ANTHROPIC_API_KEY"]);
|
|
46304
|
+
}
|
|
46305
|
+
async complete(req) {
|
|
46306
|
+
const client = new sdk_default();
|
|
46307
|
+
const response = await client.messages.create({
|
|
46308
|
+
model: ANTHROPIC_MODEL,
|
|
46309
|
+
max_tokens: req.maxTokens,
|
|
46310
|
+
system: [
|
|
46311
|
+
{ type: "text", text: req.systemPrompt },
|
|
46312
|
+
{
|
|
46313
|
+
type: "text",
|
|
46314
|
+
text: `<tbox-slice>
|
|
46315
|
+
${req.tboxSlice}
|
|
46316
|
+
</tbox-slice>`,
|
|
46317
|
+
cache_control: { type: "ephemeral" }
|
|
46318
|
+
}
|
|
46319
|
+
],
|
|
46320
|
+
messages: [{ role: "user", content: `Question: ${req.question}
|
|
46321
|
+
|
|
46322
|
+
Return the JSON.` }]
|
|
46323
|
+
});
|
|
46324
|
+
return response.content.filter((b2) => b2.type === "text").map((b2) => b2.text).join("\n");
|
|
46325
|
+
}
|
|
46326
|
+
};
|
|
46327
|
+
|
|
46298
46328
|
// ../predicate-agent/src/semantic-decomposer.ts
|
|
46299
|
-
var MODEL = "claude-haiku-4-5-20251001";
|
|
46300
46329
|
var VALID_INTENTS = [
|
|
46301
46330
|
"why-broken",
|
|
46302
46331
|
"find-callers",
|
|
@@ -46335,33 +46364,31 @@ Output strict JSON, no prose:
|
|
|
46335
46364
|
}`;
|
|
46336
46365
|
var SemanticDecomposer = class {
|
|
46337
46366
|
deterministic = new Decomposer();
|
|
46338
|
-
|
|
46367
|
+
providers;
|
|
46368
|
+
fallbackOnEmpty;
|
|
46369
|
+
/** Set to the provider actually used on the last decompose() call (for telemetry). */
|
|
46370
|
+
lastProviderUsed = null;
|
|
46339
46371
|
constructor(options = {}) {
|
|
46340
|
-
this.
|
|
46372
|
+
this.providers = options.providers ?? [new AnthropicSdkProvider()];
|
|
46373
|
+
this.fallbackOnEmpty = options.fallbackOnEmpty ?? true;
|
|
46341
46374
|
}
|
|
46342
46375
|
async decompose(question, tboxSlice = "") {
|
|
46376
|
+
this.lastProviderUsed = null;
|
|
46343
46377
|
const deterministicResult = this.deterministic.decompose(question);
|
|
46344
46378
|
const allUnknown = deterministicResult.every((sq) => sq.intent.kind === "unknown");
|
|
46345
46379
|
if (!allUnknown) return deterministicResult;
|
|
46346
|
-
|
|
46347
|
-
|
|
46380
|
+
const provider = this.providers.find((p2) => p2.isAvailable());
|
|
46381
|
+
if (!provider) {
|
|
46382
|
+
return this.fallbackOnEmpty ? deterministicResult : [];
|
|
46348
46383
|
}
|
|
46349
46384
|
try {
|
|
46350
|
-
const
|
|
46351
|
-
|
|
46352
|
-
|
|
46353
|
-
|
|
46354
|
-
|
|
46355
|
-
{ type: "text", text: SYSTEM_PROMPT },
|
|
46356
|
-
{ type: "text", text: `<tbox-slice>
|
|
46357
|
-
${tboxSlice}
|
|
46358
|
-
</tbox-slice>`, cache_control: { type: "ephemeral" } }
|
|
46359
|
-
],
|
|
46360
|
-
messages: [{ role: "user", content: `Question: ${question}
|
|
46361
|
-
|
|
46362
|
-
Return the JSON.` }]
|
|
46385
|
+
const text = await provider.complete({
|
|
46386
|
+
systemPrompt: SYSTEM_PROMPT,
|
|
46387
|
+
tboxSlice,
|
|
46388
|
+
question,
|
|
46389
|
+
maxTokens: 1024
|
|
46363
46390
|
});
|
|
46364
|
-
|
|
46391
|
+
this.lastProviderUsed = provider.kind;
|
|
46365
46392
|
const stripped = text.replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/i, "").trim();
|
|
46366
46393
|
const parsed = JSON.parse(stripped);
|
|
46367
46394
|
if (!Array.isArray(parsed.subQuestions)) return deterministicResult;
|
|
@@ -46373,10 +46400,10 @@ Return the JSON.` }]
|
|
|
46373
46400
|
payload: sq.intent.payload ?? {}
|
|
46374
46401
|
}
|
|
46375
46402
|
}));
|
|
46376
|
-
if (validated.length === 0) return this.
|
|
46403
|
+
if (validated.length === 0) return this.fallbackOnEmpty ? deterministicResult : [];
|
|
46377
46404
|
return validated;
|
|
46378
46405
|
} catch {
|
|
46379
|
-
return this.
|
|
46406
|
+
return this.fallbackOnEmpty ? deterministicResult : [];
|
|
46380
46407
|
}
|
|
46381
46408
|
}
|
|
46382
46409
|
};
|
|
@@ -47214,18 +47241,22 @@ async function buildTBoxSlice(client) {
|
|
|
47214
47241
|
);
|
|
47215
47242
|
return r2.results.bindings.map((b2) => `${b2["p"].value} a ${b2["kind"].value} .`).join("\n");
|
|
47216
47243
|
}
|
|
47217
|
-
async function kgResearchGoal(client, input) {
|
|
47244
|
+
async function kgResearchGoal(client, input, deps = {}) {
|
|
47218
47245
|
const baseInput = {
|
|
47219
47246
|
goal: input.goal,
|
|
47220
47247
|
source: input.source ?? "user",
|
|
47221
47248
|
parentGoal: input.parentGoal
|
|
47222
47249
|
};
|
|
47223
|
-
const
|
|
47224
|
-
|
|
47250
|
+
const providers = [
|
|
47251
|
+
...deps.extraCompletionProviders ?? [],
|
|
47252
|
+
new AnthropicSdkProvider()
|
|
47253
|
+
];
|
|
47254
|
+
const hasAvailableLlmProvider = providers.some((p2) => p2.isAvailable());
|
|
47255
|
+
const useSemantic = Boolean(input.useLlmDecomposer) && hasAvailableLlmProvider;
|
|
47225
47256
|
if (useSemantic) {
|
|
47226
47257
|
const store = new GoalStore(client);
|
|
47227
47258
|
const detector = new GapDetector(client);
|
|
47228
|
-
const semantic = new SemanticDecomposer();
|
|
47259
|
+
const semantic = new SemanticDecomposer({ providers });
|
|
47229
47260
|
const goal = await store.create({
|
|
47230
47261
|
statement: baseInput.goal,
|
|
47231
47262
|
source: baseInput.source,
|
|
@@ -47235,8 +47266,9 @@ async function kgResearchGoal(client, input) {
|
|
|
47235
47266
|
const subQuestions = await semantic.decompose(baseInput.goal, tboxSlice);
|
|
47236
47267
|
const gaps = await Promise.all(subQuestions.map((sq) => detector.detect(sq)));
|
|
47237
47268
|
const plan2 = { goalId: goal.id, subQuestions, gaps };
|
|
47269
|
+
const decomposerProvider = semantic.lastProviderUsed ?? void 0;
|
|
47238
47270
|
if (!input.executeResearch) {
|
|
47239
|
-
return { ...plan2, decomposerKind };
|
|
47271
|
+
return { ...plan2, decomposerKind: "semantic", ...decomposerProvider && { decomposerProvider } };
|
|
47240
47272
|
}
|
|
47241
47273
|
if (!input.corpusRoot) {
|
|
47242
47274
|
throw new Error(
|
|
@@ -47260,7 +47292,7 @@ async function kgResearchGoal(client, input) {
|
|
|
47260
47292
|
}
|
|
47261
47293
|
if (!input.executeResearch) {
|
|
47262
47294
|
const plan2 = await researchGoal(client, baseInput);
|
|
47263
|
-
return { ...plan2, decomposerKind };
|
|
47295
|
+
return { ...plan2, decomposerKind: "deterministic" };
|
|
47264
47296
|
}
|
|
47265
47297
|
if (!input.corpusRoot) {
|
|
47266
47298
|
throw new Error(
|
|
@@ -47280,7 +47312,7 @@ async function kgResearchGoal(client, input) {
|
|
|
47280
47312
|
new EnvVarExtractor()
|
|
47281
47313
|
]
|
|
47282
47314
|
});
|
|
47283
|
-
return { ...plan, decomposerKind };
|
|
47315
|
+
return { ...plan, decomposerKind: "deterministic" };
|
|
47284
47316
|
}
|
|
47285
47317
|
|
|
47286
47318
|
// ../predicate-mcp/src/tools/kg-propose-schema.ts
|
|
@@ -47522,7 +47554,8 @@ var schemaDeltaSchema = external_exports.discriminatedUnion("kind", [
|
|
|
47522
47554
|
shapes: external_exports.array(deltaQuadSchema).optional()
|
|
47523
47555
|
})
|
|
47524
47556
|
]);
|
|
47525
|
-
function buildTools(client) {
|
|
47557
|
+
function buildTools(client, options = {}) {
|
|
47558
|
+
const extraCompletionProviders = options.extraCompletionProviders ?? [];
|
|
47526
47559
|
return [
|
|
47527
47560
|
{
|
|
47528
47561
|
name: "kg_explore_schema",
|
|
@@ -47606,7 +47639,7 @@ function buildTools(client) {
|
|
|
47606
47639
|
},
|
|
47607
47640
|
{
|
|
47608
47641
|
name: "kg_research_goal",
|
|
47609
|
-
description: "Decompose a goal and report which predicates the live TBox can/cannot answer. When executeResearch=true and corpusRoot is provided, also fetch artifacts from that directory, extract candidate triples, and assert them via kg_assert. Set useLlmDecomposer=true to enable
|
|
47642
|
+
description: "Decompose a goal and report which predicates the live TBox can/cannot answer. When executeResearch=true and corpusRoot is provided, also fetch artifacts from that directory, extract candidate triples, and assert them via kg_assert. Set useLlmDecomposer=true to enable LLM-augmented decomposition for questions that do not match a built-in pattern; the decomposer prefers MCP sampling (no API key needed) and falls back to ANTHROPIC_API_KEY, then to deterministic.",
|
|
47610
47643
|
inputSchema: external_exports.object({
|
|
47611
47644
|
goal: external_exports.string().min(1),
|
|
47612
47645
|
source: external_exports.enum(["user", "inferred"]).optional(),
|
|
@@ -47624,7 +47657,7 @@ function buildTools(client) {
|
|
|
47624
47657
|
corpusRoot: external_exports.string().optional(),
|
|
47625
47658
|
useLlmDecomposer: external_exports.boolean().optional()
|
|
47626
47659
|
}).parse(raw);
|
|
47627
|
-
return kgResearchGoal(client, args);
|
|
47660
|
+
return kgResearchGoal(client, args, { extraCompletionProviders });
|
|
47628
47661
|
}
|
|
47629
47662
|
},
|
|
47630
47663
|
{
|
|
@@ -47708,15 +47741,62 @@ function stubs() {
|
|
|
47708
47741
|
return [];
|
|
47709
47742
|
}
|
|
47710
47743
|
|
|
47744
|
+
// ../predicate-mcp/src/sampling-provider.ts
|
|
47745
|
+
var SAMPLING_MODEL_HINT = "claude-haiku";
|
|
47746
|
+
var SamplingProvider = class {
|
|
47747
|
+
constructor(server) {
|
|
47748
|
+
this.server = server;
|
|
47749
|
+
}
|
|
47750
|
+
server;
|
|
47751
|
+
kind = "mcp-sampling";
|
|
47752
|
+
isAvailable() {
|
|
47753
|
+
const caps = this.server.getClientCapabilities();
|
|
47754
|
+
return Boolean(caps?.sampling);
|
|
47755
|
+
}
|
|
47756
|
+
async complete(req) {
|
|
47757
|
+
const result = await this.server.createMessage({
|
|
47758
|
+
systemPrompt: `${req.systemPrompt}
|
|
47759
|
+
|
|
47760
|
+
<tbox-slice>
|
|
47761
|
+
${req.tboxSlice}
|
|
47762
|
+
</tbox-slice>`,
|
|
47763
|
+
maxTokens: req.maxTokens,
|
|
47764
|
+
modelPreferences: {
|
|
47765
|
+
hints: [{ name: SAMPLING_MODEL_HINT }],
|
|
47766
|
+
intelligencePriority: 0.3,
|
|
47767
|
+
speedPriority: 0.7
|
|
47768
|
+
},
|
|
47769
|
+
messages: [
|
|
47770
|
+
{
|
|
47771
|
+
role: "user",
|
|
47772
|
+
content: { type: "text", text: `Question: ${req.question}
|
|
47773
|
+
|
|
47774
|
+
Return the JSON.` }
|
|
47775
|
+
}
|
|
47776
|
+
]
|
|
47777
|
+
});
|
|
47778
|
+
const content = result.content;
|
|
47779
|
+
if (Array.isArray(content)) {
|
|
47780
|
+
return content.filter((b2) => b2.type === "text").map((b2) => b2.text).join("\n");
|
|
47781
|
+
}
|
|
47782
|
+
if (content && typeof content === "object" && "type" in content && content.type === "text") {
|
|
47783
|
+
return content.text;
|
|
47784
|
+
}
|
|
47785
|
+
return "";
|
|
47786
|
+
}
|
|
47787
|
+
};
|
|
47788
|
+
|
|
47711
47789
|
// ../predicate-mcp/src/index.ts
|
|
47712
47790
|
async function main() {
|
|
47713
47791
|
const config2 = loadConfig();
|
|
47714
47792
|
const client = new SparqlClient(config2);
|
|
47715
|
-
const tools = buildTools(client);
|
|
47716
47793
|
const server = new Server(
|
|
47717
47794
|
{ name: "predicate-mcp", version: "0.1.0" },
|
|
47718
47795
|
{ capabilities: { tools: {} } }
|
|
47719
47796
|
);
|
|
47797
|
+
const tools = buildTools(client, {
|
|
47798
|
+
extraCompletionProviders: [new SamplingProvider(server)]
|
|
47799
|
+
});
|
|
47720
47800
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
47721
47801
|
tools: tools.map((t2) => ({
|
|
47722
47802
|
name: t2.name,
|