loopctl-mcp-server 2.74.0 → 2.76.0
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 +3 -2
- package/index.js +160 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -264,8 +264,9 @@ Epic 39 Repo Coordination Bus — a lightweight, tenant-isolated channel for age
|
|
|
264
264
|
| `knowledge_distant_pairs` | Distant-but-bridgeable article pairs in the optimal-novelty embedding band (cosine distance, default 0.3–0.7) — the creative sweet spot. Sampled from **agent's visible published articles**; agent callers see only their own and `shared` articles. `bridge_path: true` requires a ≤2-hop link path. Returns `{a, b, distance}` pairs, paginated. Optional: `min_distance`, `max_distance`, `bridge_path`, `limit` (default 20, max 100), `offset`. |
|
|
265
265
|
| `knowledge_novelty` | Score ideas by novelty: embeds each idea's text, returns `novelty_score` = cosine distance to the nearest **visible** prior proposal (0 = identical, higher = more novel, up to 2.0; `null` when the idea text is blank, no visible priors exist, or embedding fails — see `meta.prior_count`). Agent callers see only their own and `shared` articles as priors. Priors default to articles tagged `proposal`. Provide ideas as `texts` (strings) OR `ideas` (strings or objects), ≤50. Optional: `prior_tag`. |
|
|
266
266
|
| `knowledge_random_walk` | Random walk through the link graph from `start_id` (no cycles, up to `length` nodes), traversing only **agent's visible published articles**, surfacing unexpected connections. Agent callers see only their own and `shared` articles. Returns `{id, title, category}` in walk order. Required: `start_id`. Optional: `length` (default 4, max 25). |
|
|
267
|
-
| `knowledge_conflicts` | List potential-conflict article pairs — published articles flagged "too similar to comfortably coexist" by the auto-linker / nightly lint sweep, highest-overlap first. The KB only FLAGS the pair; it does NOT decide redundancy-vs-contradiction — that's your call with live context. Each entry has both articles (id/title/status/category) + similarity. Then merge (supersede one, `knowledge_create` the merged article, or PATCH) or reconcile if they genuinely disagree. Paginated with `total_count` in meta. Agent role. Optional: `limit` (default 50, max 1000, clamped), `offset
|
|
268
|
-
| `
|
|
267
|
+
| `knowledge_conflicts` | List potential-conflict article pairs — published articles flagged "too similar to comfortably coexist" by the auto-linker / nightly lint sweep, highest-overlap first. The KB only FLAGS the pair; it does NOT decide redundancy-vs-contradiction — that's your call with live context. Each entry has both articles (id/title/status/category) + similarity. Then merge (supersede one, `knowledge_create` the merged article, or PATCH) or reconcile if they genuinely disagree. Paginated with `total_count` in meta. Agent role. Optional: `limit` (default 50, max 1000, clamped), `offset`, `origin` (`system` or `asserted` — asserted rows lead the default ordering, so pass `system` to review machine-flagged pairs alone). |
|
|
268
|
+
| `knowledge_assert_conflict` | **ASSERT** a conflict between two articles the system never flagged — the way to contest an article you just deliberately refuted. `knowledge_resolve_conflict` only reaches pairs the AUTO-LINKER flagged by similarity, which is exactly wrong for a correction: the pair is minutes old (the nightly linker has not run) and a good correction argues about the CONCLUSION, so it may never be similar enough to be flagged at all. The pair then appears in `knowledge_conflicts` with `origin: "asserted"` and your claim attached, and in both articles' `potential_conflicts`. **It retires, hides and down-ranks nothing**, and does not remove either article from curated answers (that still needs a system flag). **And you cannot judge your own assertion** — `knowledge_resolve_conflict` returns `409 self_asserted_conflict` to the asserting key, because you named both ids; another key decides. Idempotent per pair (`created: false` on a re-assert; never overwrites a system flag's provenance). Agent role. Required: `source_article_id`, `target_article_id`, `evidence`. Optional: `classification`, `proposed_authoritative_article_id`. |
|
|
269
|
+
| `knowledge_resolve_conflict` | Record YOUR verdict on a potential-conflict pair (from `knowledge_conflicts`). Dispositions: `dismiss` (false positive, drops from queue), `supersede` (one wins — pass `authoritative_article_id`; nightly executor links + retires loser, only at `confidence:"high"`, reversible/audited), `merge` (at high confidence an LLM synthesizes both into ONE new DRAFT, sources preserved, never auto-published). Non-destructive at agent role — you record intent, the privileged nightly job executes. Only pairs with a real flag are reachable; for a pair that was never flagged, use `knowledge_assert_conflict` first — and note that a DIFFERENT key must then record the verdict. Last-write-wins per pair. **`supersede` is the one disposition that retires an article unattended**, so its `confidence` is capped server-side: an agent-role `"high"` is recorded as `"medium"` (`data.requested_confidence` + `note` say so) and the pair stays in `knowledge_conflicts` until an orchestrator+ key records it at high; a `high` supersede also REQUIRES `evidence` (422 without it). `merge` is never capped. Sent on `LOOPCTL_AGENT_KEY`, so a pair YOU asserted answers `409 self_asserted_conflict` here by design — another principal (a second session, an orchestrator, a human operator) records that verdict. Required: `source_article_id`, `target_article_id`, `disposition`. Optional: `authoritative_article_id`, `classification`, `evidence` (required for a high supersede), `confidence`. |
|
|
269
270
|
| `knowledge_create` | Create a new knowledge article. File findings, document patterns, or record decisions. **Published immediately by default** (visible per `metadata.visibility` — default `owner` for agent authors, only visible to that agent; `shared` for visibility to all agents) — the response `note` says which outcome occurred. Pass `draft: true` to stage it for later review instead (publish afterwards with `knowledge_publish`). Pass `metadata: {visibility: "shared"}` to make the article visible to other agents; higher roles can set visibility and agent_id explicitly. Pass `idempotency_key` for idempotent capture (re-creating with the same key is a no-op returning the existing article — no partial duplicates). RESERVED TAG NAMESPACE: a tag starting with `idem-` must be `idem-<family>-<digest>` (digest = 12 or 40 lowercase hex chars, e.g. `idem-url-7ebe1ca33431`) or the write is rejected 422 — never silently rewritten; put topics outside that prefix and use `idempotency_key` for idempotent capture. Optional: `category`, `tags`, `project_id`, `draft`, `idempotency_key`, `source_type`, `source_id`, `metadata`. |
|
|
270
271
|
| `knowledge_update` | Edit an EXISTING article IN PLACE, **preserving its ID** (IDs are load-bearing — cited in project CLAUDE.mds and cross-links). Fold in a new fact, tidy a hub, retag, or reclassify without churning a new row. Send only the fields to change; `tags` REPLACES the whole array. A changed body/tags re-triggers embedding + auto-linking. Agent role — KB-content curation (non-destructive + audited; the in-place edit overwrites the prior body, so it is not reversible either); visibility-scoped, so another agent's private/owner memory 404s. The reserved `idem-` tag namespace applies here too (see `knowledge_create`). Required: `article_id`. Optional: `title`, `body`, `category`, `tags`, `metadata`. |
|
|
271
272
|
| `knowledge_okf_export` | **Requires `LOOPCTL_USER_KEY`.** Export the wiki as a portable OKF (Open Knowledge Format) v0.1 bundle of markdown files. Writes to `out_dir`, or returns `{files, meta}` inline. |
|
package/index.js
CHANGED
|
@@ -2062,6 +2062,26 @@ async function knowledgeConflicts({ limit, offset }) {
|
|
|
2062
2062
|
return toContent(result);
|
|
2063
2063
|
}
|
|
2064
2064
|
|
|
2065
|
+
async function knowledgeAssertConflict({
|
|
2066
|
+
source_article_id,
|
|
2067
|
+
target_article_id,
|
|
2068
|
+
classification,
|
|
2069
|
+
evidence,
|
|
2070
|
+
proposed_authoritative_article_id,
|
|
2071
|
+
}) {
|
|
2072
|
+
const payload = { source_article_id, target_article_id, evidence };
|
|
2073
|
+
if (classification) payload.classification = classification;
|
|
2074
|
+
if (proposed_authoritative_article_id)
|
|
2075
|
+
payload.proposed_authoritative_article_id = proposed_authoritative_article_id;
|
|
2076
|
+
const result = await apiCall(
|
|
2077
|
+
"POST",
|
|
2078
|
+
"/api/v1/knowledge/conflicts",
|
|
2079
|
+
payload,
|
|
2080
|
+
process.env.LOOPCTL_AGENT_KEY,
|
|
2081
|
+
);
|
|
2082
|
+
return toContent(result);
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2065
2085
|
async function knowledgeResolveConflict({
|
|
2066
2086
|
source_article_id,
|
|
2067
2087
|
target_article_id,
|
|
@@ -2076,6 +2096,15 @@ async function knowledgeResolveConflict({
|
|
|
2076
2096
|
if (classification) payload.classification = classification;
|
|
2077
2097
|
if (evidence) payload.evidence = evidence;
|
|
2078
2098
|
if (confidence) payload.confidence = confidence;
|
|
2099
|
+
// #730: the AGENT key, the same one every other knowledge_* verb sends. It must NOT
|
|
2100
|
+
// reach for LOOPCTL_ORCH_KEY to get past a 409 self_asserted_conflict: that 409 is the
|
|
2101
|
+
// separation working, and clearing it by handing this process a second, higher-privileged
|
|
2102
|
+
// key is the workaround this repo forbids outright ("the MCP server must NEVER hold both
|
|
2103
|
+
// implementer and reviewer keys in the same process"). It would also lift the #331
|
|
2104
|
+
// supersede confidence cap and the agent visibility scope on EVERY verdict, not just on
|
|
2105
|
+
// an asserted pair — an agent-role "high" supersede would stop being capped to "medium"
|
|
2106
|
+
// and the nightly executor would retire the loser unattended. A pair you asserted is
|
|
2107
|
+
// judged by a DIFFERENT key: another session, an orchestrator, or a human operator.
|
|
2079
2108
|
const result = await apiCall(
|
|
2080
2109
|
"POST",
|
|
2081
2110
|
"/api/v1/knowledge/conflicts/resolve",
|
|
@@ -4665,7 +4694,12 @@ const TOOLS = [
|
|
|
4665
4694
|
"trustworthy answer plus its provenance rather than a ranked list to triage yourself; " +
|
|
4666
4695
|
"use knowledge_search when you want to browse/enumerate matches. Additive — existing " +
|
|
4667
4696
|
"knowledge tools are unchanged. If semantic ranking is unavailable it degrades to " +
|
|
4668
|
-
"keyword-only (meta.fallback/fallback_reason), same as knowledge_search
|
|
4697
|
+
"keyword-only (meta.fallback/fallback_reason), same as knowledge_search.\n\n" +
|
|
4698
|
+
"TODAY THE CURATED BRANCH IS UNREACHABLE ON THIS DEPLOYMENT: a source counts as " +
|
|
4699
|
+
"curated only if its article has curated_at set, and no article does — so every " +
|
|
4700
|
+
"call returns provenance 'retrieved' and a null curated_article_id. Read a " +
|
|
4701
|
+
"'retrieved' verdict as the normal case, not as evidence that a curated answer " +
|
|
4702
|
+
"was considered and rejected. This line comes out when something actually curates.",
|
|
4669
4703
|
inputSchema: {
|
|
4670
4704
|
type: "object",
|
|
4671
4705
|
properties: {
|
|
@@ -5656,6 +5690,65 @@ const TOOLS = [
|
|
|
5656
5690
|
required: [],
|
|
5657
5691
|
},
|
|
5658
5692
|
},
|
|
5693
|
+
{
|
|
5694
|
+
name: "knowledge_assert_conflict",
|
|
5695
|
+
description:
|
|
5696
|
+
"ASSERT a conflict between two articles the system never flagged — the way to contest " +
|
|
5697
|
+
"an article you have just deliberately refuted. knowledge_resolve_conflict only " +
|
|
5698
|
+
"reaches pairs the AUTO-LINKER flagged by similarity, which is exactly wrong for a " +
|
|
5699
|
+
"correction: your pair is minutes old (the nightly linker has not run), and a good " +
|
|
5700
|
+
"correction argues about the CONCLUSION so it may never be similar enough to be " +
|
|
5701
|
+
"flagged at all. Use this the moment you write an article that contradicts an " +
|
|
5702
|
+
"existing one — do not settle for a 'SUPERSEDED' banner in the loser's body, which " +
|
|
5703
|
+
"changes no ranking and is invisible to any caller reading snippets. " +
|
|
5704
|
+
"`evidence` is REQUIRED: an assertion carries no similarity score, so your argument " +
|
|
5705
|
+
"IS what the reviewer judges. " +
|
|
5706
|
+
"WHAT THIS DOES: the pair appears in knowledge_conflicts with origin \"asserted\" and " +
|
|
5707
|
+
"your claim attached, and in both articles' potential_conflicts. " +
|
|
5708
|
+
"WHAT IT DOES NOT DO: it does not retire, hide, or down-rank either article, and it " +
|
|
5709
|
+
"does not remove either from curated answers (that still needs a system flag). AND " +
|
|
5710
|
+
"YOU CANNOT JUDGE YOUR OWN ASSERTION — knowledge_resolve_conflict returns 409 " +
|
|
5711
|
+
"self_asserted_conflict to the key that asserted the pair, because you named both " +
|
|
5712
|
+
"ids and a party that arranges a pair does not also certify the verdict on it. " +
|
|
5713
|
+
"Another key (a human, an orchestrator, a later session) decides. " +
|
|
5714
|
+
"Idempotent per pair: re-asserting returns the existing flag (created: false) and " +
|
|
5715
|
+
"never overwrites a system flag's provenance. Agent role.",
|
|
5716
|
+
inputSchema: {
|
|
5717
|
+
type: "object",
|
|
5718
|
+
properties: {
|
|
5719
|
+
source_article_id: {
|
|
5720
|
+
type: "string",
|
|
5721
|
+
description: "One article of the pair (UUID). Order does not matter.",
|
|
5722
|
+
},
|
|
5723
|
+
target_article_id: {
|
|
5724
|
+
type: "string",
|
|
5725
|
+
description: "The other article of the pair (UUID).",
|
|
5726
|
+
},
|
|
5727
|
+
classification: {
|
|
5728
|
+
type: "string",
|
|
5729
|
+
enum: ["redundant", "complementary", "contradictory"],
|
|
5730
|
+
description:
|
|
5731
|
+
"What kind of conflict you are asserting: redundant (same claim twice), " +
|
|
5732
|
+
"complementary (same topic, different facets), or contradictory (cannot both " +
|
|
5733
|
+
"be true — the usual reason to assert).",
|
|
5734
|
+
},
|
|
5735
|
+
evidence: {
|
|
5736
|
+
type: "string",
|
|
5737
|
+
description:
|
|
5738
|
+
"REQUIRED. Why these two conflict, ideally the ground truth that settles it " +
|
|
5739
|
+
"(commit, file:line, URL, measurement, observed behavior). This travels with " +
|
|
5740
|
+
"the pair in knowledge_conflicts and is what the deciding key reads.",
|
|
5741
|
+
},
|
|
5742
|
+
proposed_authoritative_article_id: {
|
|
5743
|
+
type: "string",
|
|
5744
|
+
description:
|
|
5745
|
+
"Optional: which of the two you believe should win. Recorded as your CLAIM on " +
|
|
5746
|
+
"the queue row — it applies nothing and is not a verdict.",
|
|
5747
|
+
},
|
|
5748
|
+
},
|
|
5749
|
+
required: ["source_article_id", "target_article_id", "evidence"],
|
|
5750
|
+
},
|
|
5751
|
+
},
|
|
5659
5752
|
{
|
|
5660
5753
|
name: "knowledge_resolve_conflict",
|
|
5661
5754
|
description:
|
|
@@ -5674,6 +5767,13 @@ const TOOLS = [
|
|
|
5674
5767
|
"recorded as \"medium\" (see data.requested_confidence and note in the response) and " +
|
|
5675
5768
|
"the pair STAYS in knowledge_conflicts until an orchestrator+ key records it at high. " +
|
|
5676
5769
|
"'merge' is never capped and executes normally at agent role. " +
|
|
5770
|
+
"Only pairs with a real flag are reachable here — if the pair you want was never " +
|
|
5771
|
+
"flagged (you just wrote an article refuting another), assert it first with " +
|
|
5772
|
+
"knowledge_assert_conflict; a DIFFERENT PRINCIPAL then records the verdict, since the " +
|
|
5773
|
+
"asserter of a pair may not judge it (409 self_asserted_conflict). This tool sends " +
|
|
5774
|
+
"LOOPCTL_AGENT_KEY, so a pair YOU asserted answers 409 here by design — hand it to " +
|
|
5775
|
+
"another session, an orchestrator, or a human operator rather than reaching for a " +
|
|
5776
|
+
"higher-privileged key. " +
|
|
5677
5777
|
"Last-write-wins per pair, so re-recording with fresher ground truth overrides. " +
|
|
5678
5778
|
"Resolve only conflicts material to your current task; adjudicate against the actual " +
|
|
5679
5779
|
"system, and if you can't tell which is right, LEAVE IT UNRECORDED rather than " +
|
|
@@ -6493,7 +6593,40 @@ const TOOLS = [
|
|
|
6493
6593
|
"search_follow_through carries two further biases pointing OPPOSITE ways: the 20-row " +
|
|
6494
6594
|
"recording cap hides opens of results ranked beyond it (DOWN on large pages), while " +
|
|
6495
6595
|
"one open credits EVERY search in the window that surfaced that article, not just the " +
|
|
6496
|
-
"preceding one (UP when an agent refines and re-searches)
|
|
6596
|
+
"preceding one (UP when an agent refines and re-searches).\n\n" +
|
|
6597
|
+
"Exact attribution (unit: READS — not surfaced results, not calls): attributed_opens " +
|
|
6598
|
+
"/ cross_key_opens / direct_opens count READ rows by how their originating search was " +
|
|
6599
|
+
"established, resolved server-side at write time and never accepted from a caller. " +
|
|
6600
|
+
"Not comparable with followed_through, which counts SURFACED RESULTS later opened. " +
|
|
6601
|
+
"cross_key_opens is the population followed_through cannot see: it correlates on " +
|
|
6602
|
+
"api_key_id, and the injected recall hook searches under a different key from the " +
|
|
6603
|
+
"session that reads, so that channel scores a structural ZERO there — meaning " +
|
|
6604
|
+
"UNMEASURABLE, not unread. Cross-key attribution is circumstantial (two agents in one " +
|
|
6605
|
+
"tenant can reach one article independently), hence labelled rather than folded in. " +
|
|
6606
|
+
"direct_opens is the agent going straight to an article by link or cited id, which " +
|
|
6607
|
+
"used to look identical to 'surfaced and ignored' — close to its opposite.\n\n" +
|
|
6608
|
+
"Disposition (unit: SEARCH CALLS): searches_scored_with_follow_through, " +
|
|
6609
|
+
"searches_reformulated and searches_quiet PARTITION searches_scored — NOT searches. " +
|
|
6610
|
+
"Treating every not-opened search as a failure is wrong — an agent answered by the " +
|
|
6611
|
+
"result snippet correctly opens nothing, and that is a success. A reformulation (the " +
|
|
6612
|
+
"SAME SESSION issuing a later search call with a DIFFERENT QUERY in-window, nothing " +
|
|
6613
|
+
"opened) is the closest thing to an unambiguous failure, so it is split out; what " +
|
|
6614
|
+
"remains is `quiet` and is STILL a mixture of 'snippet sufficed' and 'rows ignored'. " +
|
|
6615
|
+
"This surface does not separate them — do not read quiet as either.\n\n" +
|
|
6616
|
+
"searches_scored is SMALLER than searches and the gap is NOT quiet traffic. A search " +
|
|
6617
|
+
"is scoreable only if it carries a session identity (stamped forward-looking, so a " +
|
|
6618
|
+
"pre-migration row reports searches_scored: 0) and comes from a channel that can " +
|
|
6619
|
+
"react to a result at all — the recall hook and the session-start auto-query emit one " +
|
|
6620
|
+
"distilled query per prompt and never see what came back, so they cannot reformulate " +
|
|
6621
|
+
"by construction. They stay in every other denominator here, precision included. " +
|
|
6622
|
+
"Read searches - searches_scored as n/a, never as zero.\n\n" +
|
|
6623
|
+
"COMPARE ROWS ONLY WITHIN A metric_version. Every row carries the version of the " +
|
|
6624
|
+
"definition set that produced it. Three changes have already altered what a figure here " +
|
|
6625
|
+
"MEANS — searched went from search calls to surfaced results, infrastructure traffic " +
|
|
6626
|
+
"began being excluded, and the disposition trio was rescoped — each forward-looking and " +
|
|
6627
|
+
"each previously leaving no mark on the row, so a series read across one of those " +
|
|
6628
|
+
"boundaries compares definitions rather than days. 0 means the row predates the stamp " +
|
|
6629
|
+
"and its definitions are unknown.",
|
|
6497
6630
|
inputSchema: {
|
|
6498
6631
|
type: "object",
|
|
6499
6632
|
properties: {
|
|
@@ -6515,8 +6648,15 @@ const TOOLS = [
|
|
|
6515
6648
|
{
|
|
6516
6649
|
name: "knowledge_analytics_top",
|
|
6517
6650
|
description:
|
|
6518
|
-
"Return the top
|
|
6519
|
-
"
|
|
6651
|
+
"Return the top READ knowledge articles for the tenant — articles whose body was " +
|
|
6652
|
+
"actually delivered (get/context/drill). Requires orchestrator role.\n\n" +
|
|
6653
|
+
"access_type DEFAULTS TO READS, not to every event. `search` and `index` rows are " +
|
|
6654
|
+
"IMPRESSIONS the ranker produced — one per surfaced result — and they outnumber reads " +
|
|
6655
|
+
"roughly 50:1, so the old unfiltered default ranked ranker output while claiming to " +
|
|
6656
|
+
"show what agents read. Pass access_type:'all' if you genuinely want impressions " +
|
|
6657
|
+
"counted, or a single type to select one. unique_keys counts distinct API KEYS, not " +
|
|
6658
|
+
"agents: v2 mints one ephemeral key per dispatch, so one agent dispatched N times is " +
|
|
6659
|
+
"N keys.",
|
|
6520
6660
|
inputSchema: {
|
|
6521
6661
|
type: "object",
|
|
6522
6662
|
properties: {
|
|
@@ -6549,8 +6689,12 @@ const TOOLS = [
|
|
|
6549
6689
|
{
|
|
6550
6690
|
name: "knowledge_article_stats",
|
|
6551
6691
|
description:
|
|
6552
|
-
"Return per-article usage statistics:
|
|
6553
|
-
"
|
|
6692
|
+
"Return per-article usage statistics: total_events (impressions included), " +
|
|
6693
|
+
"total_reads (bodies actually delivered — get/context/drill), unique_keys, a by-type " +
|
|
6694
|
+
"breakdown, and the 10 most recent events. Requires orchestrator role.\n\n" +
|
|
6695
|
+
"Read total_reads, not total_events, when you want usage: impressions outnumber reads " +
|
|
6696
|
+
"roughly 50:1. unique_keys counts distinct API KEYS rather than agents — v2 mints one " +
|
|
6697
|
+
"ephemeral key per dispatch.",
|
|
6554
6698
|
inputSchema: {
|
|
6555
6699
|
type: "object",
|
|
6556
6700
|
properties: {
|
|
@@ -6565,7 +6709,8 @@ const TOOLS = [
|
|
|
6565
6709
|
{
|
|
6566
6710
|
name: "knowledge_agent_usage",
|
|
6567
6711
|
description:
|
|
6568
|
-
"Return knowledge usage for an agent:
|
|
6712
|
+
"Return knowledge usage for an agent: total_reads (bodies actually delivered), " +
|
|
6713
|
+
"total_events (impressions included), unique articles, top read articles. " +
|
|
6569
6714
|
"Pass api_key_id (api_keys.id credential) OR agent_id (agents.id logical identity) — not both. " +
|
|
6570
6715
|
"Requires orchestrator role.",
|
|
6571
6716
|
inputSchema: {
|
|
@@ -6600,8 +6745,11 @@ const TOOLS = [
|
|
|
6600
6745
|
{
|
|
6601
6746
|
name: "knowledge_unused_articles",
|
|
6602
6747
|
description:
|
|
6603
|
-
"Return published articles that have not been
|
|
6604
|
-
"
|
|
6748
|
+
"Return published articles that have not been READ in the configured time window. " +
|
|
6749
|
+
"Use to identify dead-weight knowledge. Requires orchestrator role.\n\n" +
|
|
6750
|
+
"\"Not read\" means no get/context/drill. It deliberately does NOT mean \"no event\": " +
|
|
6751
|
+
"on that definition an article the ranker surfaces constantly and nobody ever opens " +
|
|
6752
|
+
"counted as USED, which made this blind to the largest class of dead weight there is.",
|
|
6605
6753
|
inputSchema: {
|
|
6606
6754
|
type: "object",
|
|
6607
6755
|
properties: {
|
|
@@ -7350,6 +7498,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
7350
7498
|
case "knowledge_conflicts":
|
|
7351
7499
|
return await knowledgeConflicts(args);
|
|
7352
7500
|
|
|
7501
|
+
case "knowledge_assert_conflict":
|
|
7502
|
+
return await knowledgeAssertConflict(args);
|
|
7503
|
+
|
|
7353
7504
|
case "knowledge_resolve_conflict":
|
|
7354
7505
|
return await knowledgeResolveConflict(args);
|
|
7355
7506
|
|