loopctl-mcp-server 2.70.0 → 2.72.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 +5 -5
- package/index.js +84 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -267,7 +267,7 @@ Epic 39 Repo Coordination Bus — a lightweight, tenant-isolated channel for age
|
|
|
267
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
268
|
| `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. Last-write-wins per pair. Required: `source_article_id`, `target_article_id`, `disposition`. Optional: `authoritative_article_id`, `classification`, `evidence`, `confidence`. |
|
|
269
269
|
| `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
|
-
| `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 (
|
|
270
|
+
| `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
271
|
| `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. |
|
|
272
272
|
| `knowledge_okf_import` | **Requires `LOOPCTL_USER_KEY`.** Import an OKF v0.1 bundle from a local directory. Creates or (with `merge`) updates articles; tolerates and preserves unknown frontmatter. |
|
|
273
273
|
|
|
@@ -299,12 +299,12 @@ it is enforced server-side and a no-op for a non-superadmin key — see below.)
|
|
|
299
299
|
| `knowledge_bulk_publish` | **Requires `LOOPCTL_USER_KEY`.** Publish drafts, partial-success style: every valid draft publishes; others are reported per-id as `skipped` (already published — idempotent — or archived/superseded), `not_found`, or `errored`. No 100-id cap (auto-chunked); duplicates ignored; safe to retry. `meta.count` = published; `meta.counts`/`meta.results` give the breakdown. Required: `article_ids` (array). |
|
|
300
300
|
| `knowledge_unpublish` | **Requires `LOOPCTL_USER_KEY`.** Revert a published article back to draft (hidden from search/context, not deleted). Required: `article_id`. |
|
|
301
301
|
| `knowledge_bulk_unpublish` | **Requires `LOOPCTL_USER_KEY`.** Revert published articles to draft in bulk, partial-success style (mirror of `knowledge_bulk_publish`): per-id `unpublished`/`skipped` (already draft, or archived/superseded)/`not_found`/`errored`. No 100-id cap (auto-chunked, ≤5000); duplicates ignored; safe to retry. Not deleted (re-publish to restore; `knowledge_bulk_delete` to archive). `meta.count`/`meta.counts`/`meta.results` give the breakdown. Required: `article_ids` (array). |
|
|
302
|
-
| `knowledge_archive` | Soft-delete an article (draft or published). Row retained for audit; hidden from all reads
|
|
303
|
-
| `knowledge_delete` | Alias for `knowledge_archive` — DELETE verb on the REST API archives under the hood (soft delete, reversible,
|
|
304
|
-
| `knowledge_bulk_delete` | **Requires `LOOPCTL_USER_KEY`.** Bulk archive (default, reversible) or IRREVERSIBLE hard-delete by selector. Provide exactly one selector: `article_ids` (list), `source_type`+`source_id` (every active article from a source), or `tag`+`confirm:true` (every active article with the tag — high blast radius). Default = set-based soft archive (idempotent; `meta.count`=archived, `meta.counts`/`meta.results` give the breakdown; ≤5000). **Dry-run** (`dry_run:true`) mutates nothing, returns `meta.would_affect` (with `hard:true` also a single-use `meta.token`, or `meta.confirm_hash` for oversized selectors). **Hard delete** (irreversible): dry-run with `hard:true` for a token, then call again with `hard:true`+`token` to FK-correctly delete the frozen id-set (links first, access events cascade). |
|
|
302
|
+
| `knowledge_archive` | Soft-delete an article (draft or published). Row retained for audit; hidden from all reads. **NOT reversible by you** — `:archived` is a TERMINAL status (no unarchive call, no outbound transition), so restoring one needs a user-role PATCH with an explicit status. Nothing is destroyed, but do not reach for this as an undoable action: for a retraction you can undo, use `knowledge_unpublish` and `knowledge_publish`. Agent role — KB-content curation, visibility-scoped (another agent's private/owner memory 404s). Required: `article_id`. |
|
|
303
|
+
| `knowledge_delete` | Alias for `knowledge_archive` — DELETE verb on the REST API archives under the hood (soft delete: row retained and audited, but NOT reversible by any call you can make, since `:archived` is terminal — use `knowledge_unpublish` when you need an undoable retraction). Agent role. (Irreversible HARD delete is `knowledge_bulk_delete hard:true`, which stays `LOOPCTL_USER_KEY`.) Required: `article_id`. |
|
|
304
|
+
| `knowledge_bulk_delete` | **Requires `LOOPCTL_USER_KEY`.** Bulk archive (default — non-destructive, but NOT reversible by any call: `:archived` is terminal and restoring needs a user-role PATCH) or IRREVERSIBLE hard-delete by selector. Provide exactly one selector: `article_ids` (list), `source_type`+`source_id` (every active article from a source), or `tag`+`confirm:true` (every active article with the tag — high blast radius). Default = set-based soft archive (idempotent; `meta.count`=archived, `meta.counts`/`meta.results` give the breakdown; ≤5000). **Dry-run** (`dry_run:true`) mutates nothing, returns `meta.would_affect` (with `hard:true` also a single-use `meta.token`, or `meta.confirm_hash` for oversized selectors). **Hard delete** (irreversible): dry-run with `hard:true` for a token, then call again with `hard:true`+`token` to FK-correctly delete the frozen id-set (links first, access events cascade). |
|
|
305
305
|
| `knowledge_drafts` | List draft (unpublished) knowledge articles with pagination. Optional: `limit` (default 20, max 1000 — over-max → 400, no silent clamp), `offset` (default 0), `project_id`. Returns `meta.total_count`. |
|
|
306
306
|
| `knowledge_lint` | Run a lint check on the knowledge wiki to identify stale or low-coverage articles. Optional: `project_id`, `stale_days`, `min_coverage`, `max_per_category` (default 50, max 500). True totals returned in `summary.total_per_category`. |
|
|
307
|
-
| `knowledge_consolidation` | Read the nightly consolidation ("dream") report: NUMBERED proposals for reconciling the corpus, each naming the articles involved and quoting an excerpt from each as evidence. **
|
|
307
|
+
| `knowledge_consolidation` | Read the nightly consolidation ("dream") report: NUMBERED proposals for reconciling the corpus, each naming the articles involved and quoting an excerpt from each as evidence. **This tool** applies nothing and recomputes nothing — it returns persisted rows. **The pass** it reports on does write: since #608 the nightly run UNPUBLISHES the losers of each `duplicate_capture` group that two consecutive reports both propose (consecutive meaning the previous report is at most 2 days older, so one skipped nightly run is tolerated and a longer outage is not). That is its only write to `articles`, it is an unpublish and never an archive (archive is terminal for an article), and it still writes no links or conflict resolutions. Classes: `duplicate_capture` (titles that collide once case/punctuation normalize away, or idempotency keys that collide under the same normalization while differing verbatim — capture tag-format drift, which the novelty gate does not catch because novelty scoring and idempotency are separate paths), `generic_title` (a placeholder title that collides on active-title uniqueness and blocks hub creation). Two classes are **RETIRED** (#605) and no longer produced, though the `class` filter still accepts them so historical reports stay readable: `contradiction_candidate` (the nightly lint judges those pairs itself now) and `stale_entry` (age is not a defect signal — for stale articles call `knowledge_lint`, which computes them with a caller-chosen `stale_days`). **Denominators:** `corpus_size` = PUBLISHED articles owned by the tenant at scan time, not its total article count; `proposal_count` = the TRUE pre-cap count of PROPOSALS, not of articles (one duplicate group of three articles is ONE proposal, and one article can appear in proposals of several classes); `persisted_count` = proposal ROWS the report carries, lower than `proposal_count` exactly when a class hit `max_per_class` (`truncated` flags which); `meta.total_count` counts persisted proposals matching the `class` filter, so it is bounded by `persisted_count`, never `proposal_count`. `review_status`/`reviewed_by`/`reviewed_at` are vestigial — nothing reads them to decide anything, there is no approve/reject surface and there will not be one (#605 supersedes #594); auto-apply is gated on reversibility and two-run agreement. They still reset to pending/null whenever the nightly pass re-derives a proposal, so refreshed machine output never inherits an earlier verdict. Requires orchestrator role. Optional: `day` (ISO8601, default most recent report), `class`, `limit` (default 50, max 500), `offset`. |
|
|
308
308
|
| `knowledge_export` | Export all knowledge articles as an OKF v0.1 bundle (gzipped tar archive, unbounded, bounded-memory streaming, fail-closed). Returns a curl command for direct download — **the download requires `LOOPCTL_USER_KEY`** (an orchestrator key would 403). Pass `format=json` for buffered in-memory JSON (convenience tool for file writers; capped at `export_max_buffered_export_articles` — returns 413 if over-cap). Optional: `project_id`, `format` (`tar.gz` default or `json`). |
|
|
309
309
|
| `knowledge_ingest` | Submit a URL or raw content for knowledge extraction. Enqueues an Oban job. Extracted articles are **drafts by default** (lower-trust LLM output); pass `publish: true` to publish on extraction. **BYO:** runs on the tenant's own Anthropic key — a keyless tenant gets a 422 whose result leads with an `ACTION REQUIRED` notice pointing at `set_llm_config` (see [First-time setup](#first-time-setup--provision-your-byo-llm-keys)). Required: `source_type`. One of: `url` or `content`. Optional: `project_id`, `publish`. |
|
|
310
310
|
| `knowledge_ingest_batch` | Submit up to 50 ingestion items in a single request. Each item has the same shape as `knowledge_ingest` (incl. `publish`). Returns per-item results. Required: `items`. Optional: batch-level `project_id` / `publish` defaults. |
|
package/index.js
CHANGED
|
@@ -1786,8 +1786,9 @@ async function knowledgeUnpublish({ article_id }) {
|
|
|
1786
1786
|
return toContent(result);
|
|
1787
1787
|
}
|
|
1788
1788
|
|
|
1789
|
-
// #331: single-article archive is agent-role KB curation (
|
|
1790
|
-
// audited, visibility-scoped server-side).
|
|
1789
|
+
// #331: single-article archive is agent-role KB curation (non-destructive soft delete,
|
|
1790
|
+
// audited, visibility-scoped server-side). NOT reversible in code — #606/#605: `:archived`
|
|
1791
|
+
// is a terminal status. The row survives; nothing automated brings it back.
|
|
1791
1792
|
async function knowledgeArchive({ article_id }) {
|
|
1792
1793
|
const result = await apiCall(
|
|
1793
1794
|
"POST",
|
|
@@ -1941,12 +1942,16 @@ async function knowledgeConsolidation({ day, class: klass, limit, offset } = {})
|
|
|
1941
1942
|
return toContent(result);
|
|
1942
1943
|
}
|
|
1943
1944
|
|
|
1944
|
-
async function knowledgeIngest({ url, content, source_type, project_id, publish }) {
|
|
1945
|
+
async function knowledgeIngest({ url, content, source_type, project_id, publish, metadata }) {
|
|
1945
1946
|
const body = { source_type };
|
|
1946
1947
|
if (url) body.url = url;
|
|
1947
1948
|
if (content) body.content = content;
|
|
1948
1949
|
if (project_id) body.project_id = project_id;
|
|
1949
1950
|
if (publish) body.publish = true;
|
|
1951
|
+
// Forwarded so `metadata.source_ref` is reachable at all: the server honours it as the
|
|
1952
|
+
// source that article titles are qualified with, and declaring it in the schema above
|
|
1953
|
+
// without forwarding it here would advertise a parameter that silently does nothing.
|
|
1954
|
+
if (metadata && typeof metadata === "object") body.metadata = metadata;
|
|
1950
1955
|
const result = await apiCall("POST", "/api/v1/knowledge/ingest", body, process.env.LOOPCTL_ORCH_KEY);
|
|
1951
1956
|
// A keyless tenant gets a 422 (code no_api_key) carrying a remediation — surface it
|
|
1952
1957
|
// prominently so a first-time agent knows to call set_llm_config before ingesting.
|
|
@@ -4817,7 +4822,9 @@ const TOOLS = [
|
|
|
4817
4822
|
"project CLAUDE.mds and cross-links). Send only the fields you want to change; every " +
|
|
4818
4823
|
"field is optional except article_id. `tags` REPLACES the whole array (send the full " +
|
|
4819
4824
|
"desired set, not a delta). A changed body/tags re-triggers embedding + auto-linking. " +
|
|
4820
|
-
"Agent role — this is KB-content curation (
|
|
4825
|
+
"Agent role — this is KB-content curation (non-destructive + audited: the edit is in " +
|
|
4826
|
+
"place and there is no version-restore endpoint, but the prior body is retained in the " +
|
|
4827
|
+
"article.updated audit entry). Visibility-scoped: " +
|
|
4821
4828
|
"you can only edit an article you can see, so another agent's private/owner memory " +
|
|
4822
4829
|
"returns 404. `tenant_id` is never accepted. Returns the full updated article. To " +
|
|
4823
4830
|
"instead retire/replace an article, use knowledge_archive or knowledge_resolve_conflict.",
|
|
@@ -5201,11 +5208,15 @@ const TOOLS = [
|
|
|
5201
5208
|
{
|
|
5202
5209
|
name: "knowledge_archive",
|
|
5203
5210
|
description:
|
|
5204
|
-
"Archive an article (soft delete). The article is hidden from search, context, " +
|
|
5205
|
-
"
|
|
5206
|
-
"
|
|
5207
|
-
"
|
|
5208
|
-
"
|
|
5211
|
+
"Archive an article (soft delete). The article is hidden from search, context, and " +
|
|
5212
|
+
"the index but the row is retained for audit/history. NOT reversible by you: " +
|
|
5213
|
+
"`:archived` is a TERMINAL article status — there is no unarchive call and no " +
|
|
5214
|
+
"{archived -> anything} transition, so restoring one needs a user-role PATCH with an " +
|
|
5215
|
+
"explicit status. Nothing is destroyed, but do not reach for this as an undoable " +
|
|
5216
|
+
"action. If you want a RETRACTION you can undo, use knowledge_unpublish (published " +
|
|
5217
|
+
"-> draft) and knowledge_publish to put it back. Works for drafts and published " +
|
|
5218
|
+
"articles. Agent role — KB-content curation. Visibility-scoped: you can only archive " +
|
|
5219
|
+
"an article you can see, so another agent's private/owner memory returns 404.",
|
|
5209
5220
|
inputSchema: {
|
|
5210
5221
|
type: "object",
|
|
5211
5222
|
properties: {
|
|
@@ -5221,10 +5232,13 @@ const TOOLS = [
|
|
|
5221
5232
|
name: "knowledge_delete",
|
|
5222
5233
|
description:
|
|
5223
5234
|
"Delete an article. Under the hood this performs the same soft-delete (archive) " +
|
|
5224
|
-
"as knowledge_archive — use whichever name is clearer at the call site
|
|
5225
|
-
"
|
|
5226
|
-
"
|
|
5227
|
-
"
|
|
5235
|
+
"as knowledge_archive — use whichever name is clearer at the call site, and note " +
|
|
5236
|
+
"that it inherits archive's terminality: the row is retained for audit, but " +
|
|
5237
|
+
"`:archived` has no outbound transition, so NOTHING you can call restores it. " +
|
|
5238
|
+
"For a retraction you can undo, use knowledge_unpublish instead. There is no hard " +
|
|
5239
|
+
"delete here (that is knowledge_bulk_delete hard:true, which stays user-gated). " +
|
|
5240
|
+
"Agent role — KB-content curation: non-destructive + audited, visibility-scoped " +
|
|
5241
|
+
"(another agent's private/owner memory 404s).",
|
|
5228
5242
|
inputSchema: {
|
|
5229
5243
|
type: "object",
|
|
5230
5244
|
properties: {
|
|
@@ -5239,7 +5253,9 @@ const TOOLS = [
|
|
|
5239
5253
|
{
|
|
5240
5254
|
name: "knowledge_bulk_delete",
|
|
5241
5255
|
description:
|
|
5242
|
-
"Bulk archive (default, reversible
|
|
5256
|
+
"Bulk archive (default, non-destructive but NOT reversible by any call you can make — " +
|
|
5257
|
+
"`:archived` is terminal; restoring needs a user-role PATCH) or IRREVERSIBLE hard-delete " +
|
|
5258
|
+
"of articles by selector. " +
|
|
5243
5259
|
"REQUIRES LOOPCTL_USER_KEY (user role — orchestrator is NOT sufficient). Provide EXACTLY ONE " +
|
|
5244
5260
|
"selector: article_ids (explicit list), source_type + source_id (every active article from " +
|
|
5245
5261
|
"that source), or tag + confirm:true (every active article carrying the tag — high blast " +
|
|
@@ -5285,8 +5301,9 @@ const TOOLS = [
|
|
|
5285
5301
|
hard: {
|
|
5286
5302
|
type: "boolean",
|
|
5287
5303
|
description:
|
|
5288
|
-
"IRREVERSIBLE hard delete (vs default
|
|
5289
|
-
"
|
|
5304
|
+
"IRREVERSIBLE hard delete (vs the default soft archive, which is non-destructive but " +
|
|
5305
|
+
"terminal — `:archived` has no outbound transition, so restoring one needs a user-role " +
|
|
5306
|
+
"PATCH). Run dry_run first to get a token, then pass hard:true + token.",
|
|
5290
5307
|
},
|
|
5291
5308
|
token: {
|
|
5292
5309
|
type: "string",
|
|
@@ -5477,16 +5494,23 @@ const TOOLS = [
|
|
|
5477
5494
|
description:
|
|
5478
5495
|
"Read the nightly consolidation (\"dream\") report: NUMBERED proposals for reconciling " +
|
|
5479
5496
|
"the corpus, each naming the articles involved and quoting an excerpt from each as " +
|
|
5480
|
-
"evidence.
|
|
5481
|
-
"
|
|
5497
|
+
"evidence. THIS TOOL applies nothing and recomputes nothing — it returns persisted rows. " +
|
|
5498
|
+
"The PASS it reports on does write: since #608 the nightly run UNPUBLISHES the losers of " +
|
|
5499
|
+
"each `duplicate_capture` group that two consecutive reports both propose — consecutive " +
|
|
5500
|
+
"meaning the previous report is at most 2 days older, so ONE skipped nightly run is " +
|
|
5501
|
+
"tolerated and a longer outage is not. That is its " +
|
|
5502
|
+
"only write to articles, it is an unpublish and never an archive (archive is terminal for " +
|
|
5503
|
+
"an article), and it still writes no links or conflict resolutions. Requires orchestrator " +
|
|
5504
|
+
"role.\n\n" +
|
|
5482
5505
|
"Classes: `duplicate_capture` (titles that collide once case/punctuation normalize away, " +
|
|
5483
5506
|
"or idempotency keys that collide under the same normalization while differing verbatim — " +
|
|
5484
5507
|
"capture tag-format drift, which the novelty gate does not catch because novelty scoring " +
|
|
5485
|
-
"and idempotency are separate paths); `
|
|
5486
|
-
"
|
|
5487
|
-
"
|
|
5488
|
-
"
|
|
5489
|
-
"
|
|
5508
|
+
"and idempotency are separate paths); `generic_title` (a placeholder title that collides " +
|
|
5509
|
+
"on active-title uniqueness and blocks hub creation). Two classes are RETIRED (#605) and " +
|
|
5510
|
+
"no longer produced, though the `class` filter still accepts them so historical reports " +
|
|
5511
|
+
"stay readable: `contradiction_candidate` (the nightly lint judges those pairs itself now) " +
|
|
5512
|
+
"and `stale_entry` (age is not a defect signal — for stale articles call knowledge_lint, " +
|
|
5513
|
+
"which computes them with a caller-chosen `stale_days`).\n\n" +
|
|
5490
5514
|
"Denominators: `corpus_size` counts PUBLISHED articles owned by the tenant at scan time, " +
|
|
5491
5515
|
"not its total article count. `proposal_count` is the TRUE pre-cap count of PROPOSALS, not " +
|
|
5492
5516
|
"of articles — one duplicate group of three articles is ONE proposal, and one article can " +
|
|
@@ -5494,8 +5518,11 @@ const TOOLS = [
|
|
|
5494
5518
|
"report carries, lower than `proposal_count` exactly when a class hit `max_per_class` " +
|
|
5495
5519
|
"(`truncated` flags which). `meta.total_count` counts persisted proposals matching the " +
|
|
5496
5520
|
"`class` filter, so it is bounded by `persisted_count`, never by `proposal_count`.\n\n" +
|
|
5497
|
-
"Review state (`review_status`/`reviewed_by`/`reviewed_at`)
|
|
5498
|
-
"
|
|
5521
|
+
"Review state (`review_status`/`reviewed_by`/`reviewed_at`) is VESTIGIAL: nothing reads it " +
|
|
5522
|
+
"to decide anything, there is no approve/reject surface and there will not be one (#605 " +
|
|
5523
|
+
"supersedes #594) — auto-apply is gated on reversibility and two-run agreement, not on an " +
|
|
5524
|
+
"approval. It still RESETS to pending/null whenever the nightly pass re-derives a proposal, " +
|
|
5525
|
+
"so refreshed machine output can never inherit an earlier verdict.",
|
|
5499
5526
|
inputSchema: {
|
|
5500
5527
|
type: "object",
|
|
5501
5528
|
properties: {
|
|
@@ -5644,6 +5671,25 @@ const TOOLS = [
|
|
|
5644
5671
|
description:
|
|
5645
5672
|
"Optional: publish extracted articles immediately instead of staging them as drafts (default false).",
|
|
5646
5673
|
},
|
|
5674
|
+
metadata: {
|
|
5675
|
+
type: "object",
|
|
5676
|
+
description:
|
|
5677
|
+
"Optional metadata map. `source_ref` is the one key with behaviour: it names the " +
|
|
5678
|
+
"SPECIFIC source (a URL, repo, or document name) and is what lets extracted article " +
|
|
5679
|
+
"titles qualify themselves — without it a CHANGELOG file can only become an article " +
|
|
5680
|
+
"titled \"Changelog\", which is indistinguishable from every other document's " +
|
|
5681
|
+
"changelog once it is in the corpus. It overrides the name derived from `url`, and " +
|
|
5682
|
+
"is the ONLY way to name the source of an inline `content` ingest. Its value is " +
|
|
5683
|
+
"included in the extraction prompt POSTed to the tenant's LLM provider (reduced the " +
|
|
5684
|
+
"same way a url is: userinfo and query string stripped, host and path kept). Omit it " +
|
|
5685
|
+
"rather than passing a placeholder — a model will qualify a title WITH it.",
|
|
5686
|
+
properties: {
|
|
5687
|
+
source_ref: {
|
|
5688
|
+
type: "string",
|
|
5689
|
+
description: "The specific source that article titles are qualified with.",
|
|
5690
|
+
},
|
|
5691
|
+
},
|
|
5692
|
+
},
|
|
5647
5693
|
},
|
|
5648
5694
|
required: ["source_type"],
|
|
5649
5695
|
},
|
|
@@ -5689,7 +5735,19 @@ const TOOLS = [
|
|
|
5689
5735
|
},
|
|
5690
5736
|
metadata: {
|
|
5691
5737
|
type: "object",
|
|
5692
|
-
description:
|
|
5738
|
+
description:
|
|
5739
|
+
"Optional metadata map. Set `source_ref` to the SPECIFIC source (URL, repo, " +
|
|
5740
|
+
"or document name) so extracted titles qualify themselves — without it a " +
|
|
5741
|
+
"CHANGELOG becomes an article titled \"Changelog\", indistinguishable from " +
|
|
5742
|
+
"every other document's changelog in the corpus. Overrides the url-derived " +
|
|
5743
|
+
"name, and is the only way to name an inline `content` item. Sent to the " +
|
|
5744
|
+
"LLM provider in the extraction prompt. Omit rather than passing a placeholder.",
|
|
5745
|
+
properties: {
|
|
5746
|
+
source_ref: {
|
|
5747
|
+
type: "string",
|
|
5748
|
+
description: "The specific source that article titles are qualified with.",
|
|
5749
|
+
},
|
|
5750
|
+
},
|
|
5693
5751
|
},
|
|
5694
5752
|
},
|
|
5695
5753
|
required: ["source_type"],
|