@tangle-network/agent-knowledge 1.12.1 → 2.0.1
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 +32 -12
- package/dist/benchmarks/index.d.ts +3 -3
- package/dist/benchmarks/index.js +1 -1
- package/dist/chunk-R7ADUA44.js +2119 -0
- package/dist/chunk-R7ADUA44.js.map +1 -0
- package/dist/{chunk-ULXZI235.js → chunk-RIHIYCX2.js} +65 -67
- package/dist/chunk-RIHIYCX2.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/{index-Cj5jRXOz.d.ts → index-BHQk7jOT.d.ts} +6 -3
- package/dist/index.d.ts +1313 -1161
- package/dist/index.js +4113 -3041
- package/dist/index.js.map +1 -1
- package/dist/memory/index.d.ts +3 -3
- package/dist/{types-C17sAROL.d.ts → types-6x0OpfW6.d.ts} +1 -1
- package/dist/{types-CjqPcTTK.d.ts → types-BFRyr390.d.ts} +1 -1
- package/dist/viz/index.d.ts +1 -1
- package/package.json +11 -4
- package/dist/chunk-ULXZI235.js.map +0 -1
- package/dist/chunk-W6VWYTNH.js +0 -958
- package/dist/chunk-W6VWYTNH.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { S as SourceRecord, c as KnowledgeIndex, d as KnowledgeSearchResult, e as SourceRegistry, f as KnowledgeEvent, g as
|
|
2
|
-
export { C as ClaimRef, n as KnowledgeBaseCandidate, K as KnowledgeGraphEdge, a as KnowledgeGraphNode, o as KnowledgeId, p as KnowledgePolicy, q as KnowledgeRelation, r as KnowledgeUnit, s as SourceAnchor } from './types-
|
|
3
|
-
import { KnowledgeRequirementCategory, KnowledgeAcquisitionMode, KnowledgeImportance, KnowledgeFreshness, KnowledgeSensitivity, KnowledgeRequirement, KnowledgeBundle, KnowledgeReadinessReport, UserQuestion, DataAcquisitionPlan, ControlRuntimeConfig, ControlEvalResult, AnalystSeverity, AnalystFinding,
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { S as SourceRecord, c as KnowledgeIndex, d as KnowledgeSearchResult, e as SourceRegistry, f as KnowledgeEvent, g as KnowledgeLintFinding, h as KnowledgeEventType, i as KnowledgePage, b as KnowledgeGraph, j as KnowledgeWriteBlock, k as KnowledgeClaim, l as KnowledgeRelease, m as KnowledgeWriteParseResult } from './types-6x0OpfW6.js';
|
|
2
|
+
export { C as ClaimRef, n as KnowledgeBaseCandidate, K as KnowledgeGraphEdge, a as KnowledgeGraphNode, o as KnowledgeId, p as KnowledgePolicy, q as KnowledgeRelation, r as KnowledgeUnit, s as SourceAnchor } from './types-6x0OpfW6.js';
|
|
3
|
+
import { KnowledgeRequirementCategory, KnowledgeAcquisitionMode, KnowledgeImportance, KnowledgeFreshness, KnowledgeSensitivity, KnowledgeRequirement, KnowledgeBundle, KnowledgeReadinessReport, UserQuestion, DataAcquisitionPlan, ControlRuntimeConfig, ControlEvalResult, RunRecord, AnalystSeverity, AnalystFinding, ReleaseTraceEvidence, GateDecision, ReleaseConfidenceScorecard } from '@tangle-network/agent-eval';
|
|
4
|
+
import { AgentCandidateKnowledgeRef } from '@tangle-network/agent-interface';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { JsonValue, Scenario, JudgeConfig } from '@tangle-network/agent-eval/campaign';
|
|
7
|
+
import { R as RunRetrievalImprovementLoopResult, a as RunRetrievalImprovementLoopOptions } from './index-BHQk7jOT.js';
|
|
8
|
+
export { B as BuildRetrievalBenchmarkCasesFromQrelsOptions, b as BuildRetrievalEvalDispatchOptions, c as BuildRetrievalParameterCandidatesOptions, I as INDUSTRY_MEMORY_BENCHMARKS, d as INDUSTRY_RAG_BENCHMARKS, K as KnowledgeAnswerBenchmarkCase, e as KnowledgeAnswerBenchmarkTaskKind, f as KnowledgeBenchmarkArtifact, g as KnowledgeBenchmarkCase, h as KnowledgeBenchmarkCaseBase, i as KnowledgeBenchmarkDistribution, j as KnowledgeBenchmarkEvaluation, k as KnowledgeBenchmarkFamily, l as KnowledgeBenchmarkReport, m as KnowledgeBenchmarkResponder, n as KnowledgeBenchmarkScenario, o as KnowledgeBenchmarkSliceSummary, p as KnowledgeBenchmarkSource, q as KnowledgeBenchmarkSpec, r as KnowledgeBenchmarkSplit, s as KnowledgeBenchmarkTaskKind, t as KnowledgeClaimMatcher, u as KnowledgeMemoryBenchmarkCase, v as KnowledgeMemoryBenchmarkTaskKind, w as KnowledgeMemoryEvent, x as KnowledgeMemoryFactMatcher, y as KnowledgeRetrievalBenchmarkCase, z as KnowledgeRetrievalBenchmarkQrel, A as KnowledgeRetrievalBenchmarkQuery, M as MemoryAdapterBenchmarkCandidate, C as MemoryAdapterBenchmarkRankingRow, D as RetrievalConfig, E as RetrievalEvalArtifact, F as RetrievalEvalRetriever, G as RetrievalEvalRetrieverInput, H as RetrievalEvalRetrieverResult, J as RetrievalEvalScenario, L as RetrievalGoldTarget, N as RetrievalMetricSummary, O as RetrievalMetricWeights, P as RetrievalParameterSearchSpace, Q as RetrievalParameterSweepProposerOptions, S as RetrievalRecallJudgeOptions, T as RetrievedKnowledgeHit, U as RetrievedSourceSpan, V as RunKnowledgeBenchmarkSuiteOptions, W as RunKnowledgeBenchmarkSuiteResult, X as RunMemoryAdapterBenchmarkOptions, Y as RunMemoryAdapterBenchmarkResult, Z as buildFirstPartyMemoryLifecycleBenchmarkCases, _ as buildIndustryMemoryBenchmarkSmokeCases, $ as buildIndustryRagBenchmarkSmokeCases, a0 as buildKnowledgeBenchmarkScenarios, a1 as buildRetrievalBenchmarkCasesFromQrels, a2 as buildRetrievalEvalDispatch, a3 as buildRetrievalParameterCandidates, a4 as createInMemoryBenchmarkAdapter, a5 as createMemoryAdapterBenchmarkResponder, a6 as createNoopMemoryBenchmarkAdapter, a7 as isKnowledgeMemoryBenchmarkCase, a8 as knowledgeBenchmarkJudge, a9 as parseKnowledgeBenchmarkJsonl, aa as parseKnowledgeBenchmarkQrels, ab as renderKnowledgeBenchmarkReportMarkdown, ac as respondToIndustryMemoryBenchmarkSmokeCase, ad as respondToIndustryRagBenchmarkSmokeCase, ae as retrievalConfigFromSurface, af as retrievalConfigSurface, ag as retrievalParameterSweepProposer, ah as retrievalRecallJudge, ai as runKnowledgeBenchmarkSuite, aj as runMemoryAdapterBenchmark, ak as runRetrievalImprovementLoop, al as scoreKnowledgeBenchmarkArtifact, am as scoreMemoryBenchmarkArtifact, an as scoreRetrievalArtifact, ao as summarizeKnowledgeBenchmarkCampaign } from './index-BHQk7jOT.js';
|
|
6
9
|
import { KnowledgeFragment } from './sources/index.js';
|
|
7
10
|
export { CornellLiiSelector, CornellLiiSourceOptions, FetchOpts, FragmentProvenance, IRS_DIMENSION_HINTS, IrsPublicationsSourceOptions, KnowledgeSource, MAX_RESPONSE_BYTES, MIN_REQUEST_GAP_MS, POLITE_USER_AGENT, PoliteFetchOptions, PoliteFetchResult, StateSosEntity, StateSosSourceConfig, __resetHttpThrottle, createCornellLiiSource, createIrsPublicationsSource, createStateSosSource, extractLinks, firstMatch, htmlToText, innerHtmlById, looksLikeBlockPage, politeFetch } from './sources/index.js';
|
|
8
|
-
import { JsonValue, Scenario, JudgeConfig } from '@tangle-network/agent-eval/campaign';
|
|
9
11
|
export { AgentMemoryHitSchema, AgentMemoryKindSchema, AgentMemoryScopeSchema, AgentMemoryWriteInputSchema, Neo4jAgentMemoryAdapterOptions, createNeo4jAgentMemoryAdapter, defaultGetMemoryContext, memoryHitToSourceRecord, memoryWriteResultToSourceRecord, renderMemoryContext } from './memory/index.js';
|
|
10
|
-
export { A as AgentMemoryAdapter, b as AgentMemoryContext, c as AgentMemoryHit, d as AgentMemoryKind, a as AgentMemoryScope, e as AgentMemorySearchOptions, f as AgentMemoryWriteInput, g as AgentMemoryWriteResult, R as RetrievalHoldoutBypassReason, h as RetrievalHoldoutCallContext, i as RetrievalHoldoutConfig, j as RetrievalHoldoutEligibleItem, k as RetrievalHoldoutEvent, l as RetrievalHoldoutOffPolicyOptions, m as RetrievalHoldoutOffPolicyResult, n as RetrievalHoldoutResult, o as RetrievalHoldoutSessionState, p as RetrievalHoldoutSessionSummary, q as applyRetrievalHoldout, r as applySessionStickyRetrievalHoldout, s as deterministicRng, t as emitRetrievalHoldoutBypass, u as resetRetrievalHoldoutRegistry, v as retrievalHoldoutConfigHash, w as toOffPolicyTrajectory } from './types-
|
|
11
|
-
import { z } from 'zod';
|
|
12
|
+
export { A as AgentMemoryAdapter, b as AgentMemoryContext, c as AgentMemoryHit, d as AgentMemoryKind, a as AgentMemoryScope, e as AgentMemorySearchOptions, f as AgentMemoryWriteInput, g as AgentMemoryWriteResult, R as RetrievalHoldoutBypassReason, h as RetrievalHoldoutCallContext, i as RetrievalHoldoutConfig, j as RetrievalHoldoutEligibleItem, k as RetrievalHoldoutEvent, l as RetrievalHoldoutOffPolicyOptions, m as RetrievalHoldoutOffPolicyResult, n as RetrievalHoldoutResult, o as RetrievalHoldoutSessionState, p as RetrievalHoldoutSessionSummary, q as applyRetrievalHoldout, r as applySessionStickyRetrievalHoldout, s as deterministicRng, t as emitRetrievalHoldoutBypass, u as resetRetrievalHoldoutRegistry, v as retrievalHoldoutConfigHash, w as toOffPolicyTrajectory } from './types-BFRyr390.js';
|
|
12
13
|
import '@tangle-network/agent-eval/rl';
|
|
13
14
|
|
|
14
15
|
interface SourceAdapterInput {
|
|
@@ -632,1265 +633,1388 @@ interface AdaptiveResearchDriver {
|
|
|
632
633
|
*/
|
|
633
634
|
declare function createAdaptiveResearchDriver(options?: AdaptiveDriverOptions): AdaptiveResearchDriver;
|
|
634
635
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
*
|
|
638
|
-
* The output drives the continuous-ingestion loop: each `KnowledgeChange`
|
|
639
|
-
* carries the eval dimensions affected (`affectedDimensions`), which an
|
|
640
|
-
* agent-eval campaign scheduler consumes to decide which campaigns to
|
|
641
|
-
* re-run. Three change kinds:
|
|
642
|
-
*
|
|
643
|
-
* - `added` — fragment id appears in `next` but not `prev`.
|
|
644
|
-
* - `removed` — fragment id appears in `prev` but not `next`. Typical
|
|
645
|
-
* trigger: an authority retires a Wex slug, or a state SOS reorganises
|
|
646
|
-
* its forms catalogue.
|
|
647
|
-
* - `modified` — fragment id appears in both, body hash differs. This
|
|
648
|
-
* is the dominant change kind in practice — the Ryan-LLC v. FTC
|
|
649
|
-
* vacatur case manifests as a `modified` on the Wex non-compete
|
|
650
|
-
* fragment, NOT as a removed one.
|
|
651
|
-
*
|
|
652
|
-
* Unverifiable fragments are filtered out before diffing — comparing a
|
|
653
|
-
* captcha-blocked snapshot against a real one would falsely fire every
|
|
654
|
-
* fragment as removed. The caller can inspect the raw lists if they want
|
|
655
|
-
* to surface block-page failures.
|
|
656
|
-
*
|
|
657
|
-
* Within-snapshot duplicate ids are an upstream bug; this function picks
|
|
658
|
-
* the LAST one and emits a diagnostic via the `warnings` field.
|
|
659
|
-
*
|
|
660
|
-
* @stable
|
|
661
|
-
*/
|
|
662
|
-
type KnowledgeChangeKind = 'added' | 'removed' | 'modified';
|
|
663
|
-
interface KnowledgeChange {
|
|
664
|
-
/** Source-scoped id (matches `KnowledgeFragment.id`). */
|
|
665
|
-
fragmentId: string;
|
|
666
|
-
kind: KnowledgeChangeKind;
|
|
667
|
-
/**
|
|
668
|
-
* For `added`: full body of the new fragment.
|
|
669
|
-
* For `removed`: full body of the prior fragment.
|
|
670
|
-
* For `modified`: unified-diff-style payload `{ before, after }` body strings.
|
|
671
|
-
*/
|
|
672
|
-
diff?: {
|
|
673
|
-
before?: string;
|
|
674
|
-
after?: string;
|
|
675
|
-
};
|
|
676
|
-
/**
|
|
677
|
-
* Eval dimensions to re-score. Computed as the union of both fragments'
|
|
678
|
-
* `dimensionHints`. The eval cron treats this as a set of campaign tags.
|
|
679
|
-
*/
|
|
680
|
-
affectedDimensions: string[];
|
|
681
|
-
/** URL of the affected authority page (from whichever side has it). */
|
|
682
|
-
url?: string;
|
|
683
|
-
/**
|
|
684
|
-
* Source-attested change time. For `modified`, takes the NEXT fragment's
|
|
685
|
-
* `sourceUpdatedAt`. For `removed`, takes the PRIOR fragment's
|
|
686
|
-
* `sourceUpdatedAt`. For `added`, takes the NEXT fragment's
|
|
687
|
-
* `sourceUpdatedAt`. Consumers index changes by this date.
|
|
688
|
-
*/
|
|
689
|
-
detectedAt: string;
|
|
690
|
-
}
|
|
691
|
-
interface DetectChangesResult {
|
|
692
|
-
changes: KnowledgeChange[];
|
|
693
|
-
/** Counts by kind — handy for dashboards. */
|
|
694
|
-
summary: {
|
|
695
|
-
added: number;
|
|
696
|
-
removed: number;
|
|
697
|
-
modified: number;
|
|
698
|
-
};
|
|
699
|
-
/** Non-fatal diagnostics (duplicate ids, dropped unverifiable fragments). */
|
|
636
|
+
interface ApplyWriteBlocksResult {
|
|
637
|
+
written: string[];
|
|
700
638
|
warnings: string[];
|
|
701
639
|
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
* When true (default), unverifiable fragments are dropped from both
|
|
705
|
-
* sides before comparison. Set false ONLY when debugging block-page
|
|
706
|
-
* issues — comparing against unverifiable content emits false
|
|
707
|
-
* `removed`/`modified` changes.
|
|
708
|
-
*/
|
|
709
|
-
skipUnverifiable?: boolean;
|
|
710
|
-
/**
|
|
711
|
-
* When provided, only changes whose `affectedDimensions` intersect this
|
|
712
|
-
* set are returned. Useful for cron loops that schedule per-dimension
|
|
713
|
-
* eval campaigns and only care about a subset.
|
|
714
|
-
*/
|
|
715
|
-
filterDimensions?: string[];
|
|
716
|
-
}
|
|
717
|
-
declare function detectChanges(prev: KnowledgeFragment[], next: KnowledgeFragment[], options?: DetectChangesOptions): DetectChangesResult;
|
|
640
|
+
declare function applyKnowledgeWriteBlocks(root: string, proposalText: string): Promise<ApplyWriteBlocksResult>;
|
|
641
|
+
declare function applyKnowledgeWriteBlocksFile(root: string, proposalPath: string): Promise<ApplyWriteBlocksResult>;
|
|
718
642
|
|
|
719
|
-
interface
|
|
720
|
-
|
|
721
|
-
maxChars: number;
|
|
722
|
-
minChars: number;
|
|
723
|
-
overlapChars: number;
|
|
643
|
+
interface ValidateKnowledgeOptions {
|
|
644
|
+
strict?: boolean;
|
|
724
645
|
}
|
|
725
|
-
interface
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
headingPath: string;
|
|
729
|
-
charStart: number;
|
|
730
|
-
charEnd: number;
|
|
731
|
-
oversized: boolean;
|
|
646
|
+
interface ValidateKnowledgeResult {
|
|
647
|
+
ok: boolean;
|
|
648
|
+
findings: KnowledgeLintFinding[];
|
|
732
649
|
}
|
|
733
|
-
declare function
|
|
734
|
-
declare function stripFrontmatter(content: string): {
|
|
735
|
-
body: string;
|
|
736
|
-
bodyOffset: number;
|
|
737
|
-
};
|
|
738
|
-
|
|
739
|
-
/**
|
|
740
|
-
* Claim-grounding mode for `runVerifiedResearchLoop`.
|
|
741
|
-
*
|
|
742
|
-
* The two-agent loop's existing verifier judges a source's on-topic RELEVANCE
|
|
743
|
-
* (is this page about the goal?). On the topic sets we have measured, its
|
|
744
|
-
* cleanliness win is dominated by DE-DUPLICATION — which a deterministic
|
|
745
|
-
* content-hash / canonical-URL check captures at ~none of the LLM premium (see
|
|
746
|
-
* `docs/results/cost-quality.md`). That makes the LLM verifier look expensive
|
|
747
|
-
* for what a cheap rule already does.
|
|
748
|
-
*
|
|
749
|
-
* Claim-grounding targets a DIFFERENT, harder error band: a citation that is
|
|
750
|
-
* relevant and unique but **misattributed** — the page is on-topic, the URL is
|
|
751
|
-
* real, yet the specific CLAIM the source is cited for does NOT actually appear
|
|
752
|
-
* in the page. This is the citation-fabrication failure mode of LLM research:
|
|
753
|
-
* the model writes a plausible sentence and hangs a real URL off it that never
|
|
754
|
-
* says any such thing. Neither de-dup nor a relevance judge catches it (both can
|
|
755
|
-
* pass a misattributed-but-on-topic page); only checking the claim against the
|
|
756
|
-
* fetched text does.
|
|
757
|
-
*
|
|
758
|
-
* The check is EXECUTABLE GROUND TRUTH, not another LLM opinion: the worker
|
|
759
|
-
* attaches the specific claim it is citing the source for, and the verifier
|
|
760
|
-
* tests whether that claim is PRESENT (verbatim, normalized, or as a sufficient
|
|
761
|
-
* content-word overlap / close paraphrase) in the `htmlToText` output of the
|
|
762
|
-
* page the worker actually fetched. A claim that is not grounded is rejected as
|
|
763
|
-
* misattributed. Because the oracle is deterministic text presence — not a model
|
|
764
|
-
* call — it is a deployable, non-oracle verifier: it can run in production with
|
|
765
|
-
* zero inference cost, OR be composed with the LLM relevance verifier so the
|
|
766
|
-
* loop rejects BOTH off-topic AND misattributed sources.
|
|
767
|
-
*
|
|
768
|
-
* This module is content-free and any-topic: it adds (1) a way for a proposal to
|
|
769
|
-
* carry the claim it is cited for, (2) the `groundClaimInText` oracle, and (3) a
|
|
770
|
-
* `ResearchDriver` that gates on grounding. It composes the existing
|
|
771
|
-
* `ResearchDriver` / `ResearchSourceProposal` contracts and the shipped
|
|
772
|
-
* `htmlToText`; it reinvents none of them.
|
|
773
|
-
*/
|
|
650
|
+
declare function validateKnowledgeIndex(index: KnowledgeIndex, options?: ValidateKnowledgeOptions): ValidateKnowledgeResult;
|
|
774
651
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
grounded: boolean;
|
|
788
|
-
/** How the claim matched (or why it didn't). For audit/notes. */
|
|
789
|
-
mode: 'verbatim' | 'normalized' | 'overlap' | 'absent' | 'empty-claim' | 'empty-text';
|
|
652
|
+
interface KnowledgeResearchLoopContext {
|
|
653
|
+
root: string;
|
|
654
|
+
goal: string;
|
|
655
|
+
iteration: number;
|
|
656
|
+
index: KnowledgeIndex;
|
|
657
|
+
lintFindings: KnowledgeLintFinding[];
|
|
658
|
+
validation: ValidateKnowledgeResult;
|
|
659
|
+
readiness?: EvalKnowledgeBundleBuildResult;
|
|
660
|
+
previousSteps: KnowledgeResearchLoopStep[];
|
|
661
|
+
signal?: AbortSignal;
|
|
662
|
+
}
|
|
663
|
+
interface KnowledgeResearchLoopDecision {
|
|
790
664
|
/**
|
|
791
|
-
*
|
|
792
|
-
*
|
|
665
|
+
* Free-form notes from the researcher. Keep this human-readable; products can
|
|
666
|
+
* store it as the research transcript.
|
|
793
667
|
*/
|
|
794
|
-
|
|
795
|
-
/** Content words present in the claim but NOT in the page text. */
|
|
796
|
-
missingWords: string[];
|
|
797
|
-
}
|
|
798
|
-
interface GroundClaimOptions {
|
|
668
|
+
notes?: string;
|
|
799
669
|
/**
|
|
800
|
-
*
|
|
801
|
-
* text to count as a close paraphrase when there is no verbatim/normalized
|
|
802
|
-
* hit. Default 0.7 — a high bar, because a misattribution is exactly a claim
|
|
803
|
-
* whose specific words the page does not contain.
|
|
670
|
+
* Local files to register as immutable sources before applying proposals.
|
|
804
671
|
*/
|
|
805
|
-
|
|
672
|
+
sourcePaths?: string[];
|
|
806
673
|
/**
|
|
807
|
-
*
|
|
808
|
-
*
|
|
674
|
+
* Textual source artifacts discovered by an agent, browser worker, connector,
|
|
675
|
+
* or deep-research process.
|
|
809
676
|
*/
|
|
810
|
-
|
|
811
|
-
}
|
|
812
|
-
/**
|
|
813
|
-
* THE ORACLE. Is `claim` grounded in `pageText` (the `htmlToText` output of the
|
|
814
|
-
* page the worker fetched)? Deterministic, no model call:
|
|
815
|
-
*
|
|
816
|
-
* 1. verbatim — the claim string appears as-is (case-insensitive).
|
|
817
|
-
* 2. normalized — the claim appears after collapsing punctuation/whitespace
|
|
818
|
-
* on both sides (so "5.4x" vs "5.4 x", smart quotes, etc. still match).
|
|
819
|
-
* 3. overlap — a close paraphrase: at least `minOverlap` of the claim's
|
|
820
|
-
* substantive content words appear in the page text. A misattributed page
|
|
821
|
-
* fails here because the SPECIFIC words the claim asserts are absent.
|
|
822
|
-
*
|
|
823
|
-
* Returns the match mode, the measured overlap, and the missing content words —
|
|
824
|
-
* enough for the driver to give a precise rejection reason and for a test/doc to
|
|
825
|
-
* audit WHY a claim grounded or didn't.
|
|
826
|
-
*/
|
|
827
|
-
declare function groundClaimInText(claim: string, pageText: string, options?: GroundClaimOptions): GroundingResult;
|
|
828
|
-
interface ClaimGroundingDriverOptions extends GroundClaimOptions {
|
|
677
|
+
sourceTexts?: AddSourceTextInput[];
|
|
829
678
|
/**
|
|
830
|
-
*
|
|
831
|
-
*
|
|
832
|
-
* relevance driver's `verifySource`). Lets the loop reject off-topic AND
|
|
833
|
-
* misattributed sources in one driver. Omit for the pure, zero-inference
|
|
834
|
-
* grounding gate.
|
|
679
|
+
* Safe write protocol text. The loop parses and applies only accepted
|
|
680
|
+
* `---FILE: knowledge/...---` blocks.
|
|
835
681
|
*/
|
|
836
|
-
|
|
682
|
+
proposalText?: string;
|
|
837
683
|
/**
|
|
838
|
-
*
|
|
839
|
-
*
|
|
840
|
-
* cited for, so an un-annotated source is treated as ungrounded. `'accept'`
|
|
841
|
-
* lets un-annotated sources through to the relevance verifier (if any) —
|
|
842
|
-
* useful when mixing annotated and legacy proposals.
|
|
684
|
+
* The researcher decides when the wiki is good enough. The loop deliberately
|
|
685
|
+
* does not encode a domain-specific definition of "done".
|
|
843
686
|
*/
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
/**
|
|
847
|
-
* A `ResearchDriver`-shaped verifier (just the `verifySource` arm) that gates on
|
|
848
|
-
* CLAIM GROUNDING: it rejects a source whose cited claim is not present in its
|
|
849
|
-
* fetched page text — a misattributed / fabricated citation — and (optionally)
|
|
850
|
-
* composes a relevance verifier after grounding passes.
|
|
851
|
-
*
|
|
852
|
-
* The returned function matches `ResearchDriver['verifySource']`, so it drops
|
|
853
|
-
* straight into `runVerifiedResearchLoop` as `{ verifySource: createClaimGroundingVerifier(...) }`.
|
|
854
|
-
*/
|
|
855
|
-
declare function createClaimGroundingVerifier(options?: ClaimGroundingDriverOptions): (source: ResearchSourceProposal, ctx: SourceVerificationContext) => Promise<SourceVerdict>;
|
|
856
|
-
interface WorkerClaimDecorationOptions {
|
|
857
|
-
router?: RouterClient;
|
|
858
|
-
router_options?: TangleRouterOptions;
|
|
859
|
-
/** Max output tokens for the claim-extraction call. Default 1200 (glm floor). */
|
|
860
|
-
maxTokens?: number;
|
|
687
|
+
done?: boolean;
|
|
688
|
+
metadata?: Record<string, unknown>;
|
|
861
689
|
}
|
|
690
|
+
interface KnowledgeResearchLoopStep {
|
|
691
|
+
iteration: number;
|
|
692
|
+
notes?: string;
|
|
693
|
+
addedSources: SourceRecord[];
|
|
694
|
+
applied?: ApplyWriteBlocksResult;
|
|
695
|
+
lintFindings: KnowledgeLintFinding[];
|
|
696
|
+
validation: ValidateKnowledgeResult;
|
|
697
|
+
readiness?: EvalKnowledgeBundleBuildResult;
|
|
698
|
+
event: KnowledgeEvent;
|
|
699
|
+
done: boolean;
|
|
700
|
+
metadata?: Record<string, unknown>;
|
|
701
|
+
}
|
|
702
|
+
interface RunKnowledgeResearchLoopOptions {
|
|
703
|
+
root: string;
|
|
704
|
+
goal: string;
|
|
705
|
+
maxIterations?: number;
|
|
706
|
+
actor?: string;
|
|
707
|
+
strict?: ValidateKnowledgeOptions['strict'];
|
|
708
|
+
readinessSpecs?: KnowledgeReadinessSpec[];
|
|
709
|
+
readinessTaskId?: string;
|
|
710
|
+
readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>;
|
|
711
|
+
sourceOptions?: Pick<AddSourceOptions, 'adapters' | 'now'>;
|
|
712
|
+
signal?: AbortSignal;
|
|
713
|
+
step(context: KnowledgeResearchLoopContext): Promise<KnowledgeResearchLoopDecision> | KnowledgeResearchLoopDecision;
|
|
714
|
+
onStep?: (step: KnowledgeResearchLoopStep) => Promise<void> | void;
|
|
715
|
+
}
|
|
716
|
+
interface KnowledgeResearchLoopResult {
|
|
717
|
+
root: string;
|
|
718
|
+
goal: string;
|
|
719
|
+
iterations: number;
|
|
720
|
+
done: boolean;
|
|
721
|
+
index: KnowledgeIndex;
|
|
722
|
+
lintFindings: KnowledgeLintFinding[];
|
|
723
|
+
validation: ValidateKnowledgeResult;
|
|
724
|
+
readiness?: EvalKnowledgeBundleBuildResult;
|
|
725
|
+
steps: KnowledgeResearchLoopStep[];
|
|
726
|
+
}
|
|
727
|
+
type KnowledgeControlLoopState = KnowledgeResearchLoopContext;
|
|
728
|
+
type KnowledgeControlLoopAction = KnowledgeResearchLoopDecision;
|
|
729
|
+
type KnowledgeControlLoopActionResult = KnowledgeResearchLoopStep;
|
|
730
|
+
interface KnowledgeControlLoopAdapterOptions {
|
|
731
|
+
root: string;
|
|
732
|
+
goal: string;
|
|
733
|
+
actor?: string;
|
|
734
|
+
strict?: ValidateKnowledgeOptions['strict'];
|
|
735
|
+
readinessSpecs?: KnowledgeReadinessSpec[];
|
|
736
|
+
readinessTaskId?: string;
|
|
737
|
+
readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>;
|
|
738
|
+
sourceOptions?: Pick<AddSourceOptions, 'adapters' | 'now'>;
|
|
739
|
+
}
|
|
740
|
+
type KnowledgeControlLoopAdapter = Pick<ControlRuntimeConfig<KnowledgeControlLoopState, KnowledgeControlLoopAction, KnowledgeControlLoopActionResult, ControlEvalResult>, 'intent' | 'observe' | 'validate' | 'act' | 'shouldStop'>;
|
|
862
741
|
/**
|
|
863
|
-
*
|
|
864
|
-
*
|
|
865
|
-
*
|
|
866
|
-
* so the claim-grounding verifier has something executable to check. The model
|
|
867
|
-
* is told to ground the claim in the provided excerpt; the verifier then checks
|
|
868
|
-
* it against the FULL page text independently — the model does not get to mark
|
|
869
|
-
* its own homework.
|
|
870
|
-
*
|
|
871
|
-
* Returns the proposal annotated via `withCitedClaim`, or the original proposal
|
|
872
|
-
* unchanged if the model returns nothing parseable (the verifier's
|
|
873
|
-
* `onMissingClaim` policy then decides).
|
|
874
|
-
*/
|
|
875
|
-
declare function createClaimDecorator(options?: WorkerClaimDecorationOptions): (source: ResearchSourceProposal, goal: string) => Promise<ResearchSourceProposal>;
|
|
876
|
-
|
|
877
|
-
/**
|
|
878
|
-
* The SINGLE-AGENT COLLECTION driver — the blind-collection baseline (Arm A).
|
|
879
|
-
*
|
|
880
|
-
* This is the honest null the depth A/B is measured against. The other drivers
|
|
881
|
-
* spend extra inference to do something differentiated:
|
|
882
|
-
* - `createVerifyingResearchDriver` runs an LLM gate per source (Arm B),
|
|
883
|
-
* - `createResearchDrivingDriver` extracts claims, tracks corroboration, and
|
|
884
|
-
* synthesizes deep follow-up questions to drive depth (Arm C).
|
|
885
|
-
*
|
|
886
|
-
* This driver does NONE of that. It is a pass-through: it accepts every source
|
|
887
|
-
* the worker proposes and contributes no research, no gating, and no steering of
|
|
888
|
-
* its own. The loop still dedups exact-uri duplicates before calling
|
|
889
|
-
* `verifySource` (that is the loop's job, not the driver's), and the default
|
|
890
|
-
* `foldGaps` (a plain bulleted list of the still-open readiness gaps) still folds
|
|
891
|
-
* the gaps into the worker's next prompt — so the worker keeps researching, but
|
|
892
|
-
* NOTHING intelligent sits between the worker and the knowledge base.
|
|
893
|
-
*
|
|
894
|
-
* In other words: ONE agent (the worker) collects sources round after round, and
|
|
895
|
-
* the "driver" is an inert rubber stamp. That is exactly what "single-agent
|
|
896
|
-
* collection" means — the topology with zero coordinator intelligence — so its
|
|
897
|
-
* material-facts score is the floor every other arm must beat to justify its
|
|
898
|
-
* extra inference cost.
|
|
899
|
-
*
|
|
900
|
-
* It adds NO router calls of its own: `verifySource` is a synchronous accept and
|
|
901
|
-
* `foldGaps` is omitted so the loop uses its built-in gap list. So Arm A's cost
|
|
902
|
-
* is the worker's cost alone — the cleanest possible blind-collection baseline.
|
|
903
|
-
*/
|
|
904
|
-
|
|
905
|
-
/**
|
|
906
|
-
* Build the single-agent collection driver. Accepts every source; never gates,
|
|
907
|
-
* never researches, never steers beyond the loop's default open-gap list. The
|
|
908
|
-
* worker is the only agent that thinks.
|
|
742
|
+
* Adapter for running knowledge growth through `agent-eval`'s generic control
|
|
743
|
+
* runtime. The caller still owns `decide`: that can be a proposer agent,
|
|
744
|
+
* reviewer agent, deterministic policy, or a composition of all three.
|
|
909
745
|
*/
|
|
910
|
-
declare function
|
|
746
|
+
declare function createKnowledgeControlLoopAdapter(options: KnowledgeControlLoopAdapterOptions): KnowledgeControlLoopAdapter;
|
|
747
|
+
declare function runKnowledgeResearchLoop(options: RunKnowledgeResearchLoopOptions): Promise<KnowledgeResearchLoopResult>;
|
|
911
748
|
|
|
912
|
-
|
|
749
|
+
type RagKnowledgeImprovementPhase = 'retrieval-tuning' | 'gap-diagnosis' | 'knowledge-acquisition' | 'knowledge-update' | 'answer-quality' | 'promotion';
|
|
750
|
+
type RagKnowledgeImprovementPhaseStatus = 'completed' | 'skipped' | 'failed';
|
|
751
|
+
type RagGapKind = 'missing-source' | 'stale-source' | 'retrieval-miss' | 'retrieval-noise' | 'chunking-mismatch' | 'missing-multihop-evidence' | 'generator-unsupported-claim' | 'citation-mismatch' | 'incorrect-abstention' | 'unknown';
|
|
752
|
+
type RagGapSeverity = 'info' | 'warning' | 'error' | 'critical';
|
|
753
|
+
interface RagGapFinding {
|
|
913
754
|
id: string;
|
|
755
|
+
kind: RagGapKind;
|
|
756
|
+
severity: RagGapSeverity;
|
|
757
|
+
message: string;
|
|
758
|
+
scenarioId?: string;
|
|
759
|
+
evidence?: Record<string, JsonValue>;
|
|
760
|
+
}
|
|
761
|
+
interface RagKnowledgeImprovementPhaseResult {
|
|
762
|
+
phase: RagKnowledgeImprovementPhase;
|
|
763
|
+
status: RagKnowledgeImprovementPhaseStatus;
|
|
764
|
+
summary: string;
|
|
765
|
+
startedAt: string;
|
|
766
|
+
finishedAt: string;
|
|
767
|
+
metadata?: Record<string, JsonValue>;
|
|
768
|
+
}
|
|
769
|
+
interface RagPhaseInputBase {
|
|
914
770
|
goal: string;
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
metadata?: Record<string, unknown>;
|
|
771
|
+
phases: readonly RagKnowledgeImprovementPhaseResult[];
|
|
772
|
+
signal?: AbortSignal;
|
|
918
773
|
}
|
|
919
|
-
interface
|
|
920
|
-
|
|
774
|
+
interface RagDiagnosisInput extends RagPhaseInputBase {
|
|
775
|
+
retrieval?: RunRetrievalImprovementLoopResult;
|
|
776
|
+
}
|
|
777
|
+
interface RagKnowledgeAcquisitionInput extends RagPhaseInputBase {
|
|
778
|
+
retrieval?: RunRetrievalImprovementLoopResult;
|
|
779
|
+
findings: readonly RagGapFinding[];
|
|
780
|
+
}
|
|
781
|
+
interface RagKnowledgeUpdateInput extends RagPhaseInputBase {
|
|
782
|
+
retrieval?: RunRetrievalImprovementLoopResult;
|
|
783
|
+
findings: readonly RagGapFinding[];
|
|
784
|
+
acquisition?: KnowledgeResearchLoopDecision;
|
|
785
|
+
}
|
|
786
|
+
interface RagKnowledgeUpdateResult {
|
|
787
|
+
applied: boolean;
|
|
921
788
|
summary: string;
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
text: string;
|
|
925
|
-
sourceUri?: string;
|
|
926
|
-
confidence?: number;
|
|
927
|
-
}>;
|
|
928
|
-
followUpTasks?: DiscoveryTask[];
|
|
929
|
-
metadata?: Record<string, unknown>;
|
|
789
|
+
research?: KnowledgeResearchLoopResult;
|
|
790
|
+
metadata?: Record<string, JsonValue>;
|
|
930
791
|
}
|
|
931
|
-
interface
|
|
932
|
-
|
|
792
|
+
interface RagAnswerQualityInput extends RagPhaseInputBase {
|
|
793
|
+
retrieval?: RunRetrievalImprovementLoopResult;
|
|
794
|
+
findings: readonly RagGapFinding[];
|
|
795
|
+
acquisition?: KnowledgeResearchLoopDecision;
|
|
796
|
+
knowledgeUpdate?: RagKnowledgeUpdateResult;
|
|
933
797
|
}
|
|
934
|
-
interface
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
798
|
+
interface RagAnswerQualityResult {
|
|
799
|
+
passed: boolean;
|
|
800
|
+
metrics: Record<string, number>;
|
|
801
|
+
findings?: readonly RagGapFinding[];
|
|
802
|
+
metadata?: Record<string, JsonValue>;
|
|
939
803
|
}
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
804
|
+
interface RagPromotionInput extends RagPhaseInputBase {
|
|
805
|
+
retrieval?: RunRetrievalImprovementLoopResult;
|
|
806
|
+
findings: readonly RagGapFinding[];
|
|
807
|
+
acquisition?: KnowledgeResearchLoopDecision;
|
|
808
|
+
knowledgeUpdate?: RagKnowledgeUpdateResult;
|
|
809
|
+
answerQuality?: RagAnswerQualityResult;
|
|
946
810
|
}
|
|
947
|
-
interface
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
rounds: DiscoveryLoopRound[];
|
|
952
|
-
/** Tasks retained, not dropped, when a configured limit stops the loop. */
|
|
953
|
-
pendingTasks: DiscoveryTask[];
|
|
954
|
-
/** Structurally identical task identities ignored to prevent cycles. */
|
|
955
|
-
duplicateTaskIds: string[];
|
|
811
|
+
interface RagPromotionResult {
|
|
812
|
+
promoted: boolean;
|
|
813
|
+
reason: string;
|
|
814
|
+
metadata?: Record<string, JsonValue>;
|
|
956
815
|
}
|
|
957
|
-
interface
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
816
|
+
interface RagKnowledgeResearchOptions extends Omit<RunKnowledgeResearchLoopOptions, 'goal' | 'signal' | 'step'> {
|
|
817
|
+
goal?: string;
|
|
818
|
+
step?: RunKnowledgeResearchLoopOptions['step'];
|
|
819
|
+
}
|
|
820
|
+
interface RunRagKnowledgeImprovementLoopOptions {
|
|
821
|
+
goal: string;
|
|
822
|
+
retrieval?: RunRetrievalImprovementLoopOptions;
|
|
823
|
+
diagnose?: (input: RagDiagnosisInput) => MaybePromise$1<readonly RagGapFinding[]>;
|
|
824
|
+
acquireKnowledge?: (input: RagKnowledgeAcquisitionInput) => MaybePromise$1<KnowledgeResearchLoopDecision>;
|
|
825
|
+
knowledgeResearch?: RagKnowledgeResearchOptions;
|
|
826
|
+
updateKnowledge?: (input: RagKnowledgeUpdateInput) => MaybePromise$1<RagKnowledgeUpdateResult>;
|
|
827
|
+
evaluateAnswers?: (input: RagAnswerQualityInput) => MaybePromise$1<RagAnswerQualityResult>;
|
|
828
|
+
promote?: (input: RagPromotionInput) => MaybePromise$1<RagPromotionResult>;
|
|
829
|
+
enabledPhases?: readonly RagKnowledgeImprovementPhase[];
|
|
830
|
+
requiredPhases?: readonly RagKnowledgeImprovementPhase[];
|
|
966
831
|
signal?: AbortSignal;
|
|
967
|
-
|
|
832
|
+
now?: () => Date;
|
|
968
833
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
interface KnowledgeEventQuery {
|
|
979
|
-
type?: KnowledgeEventType;
|
|
980
|
-
target?: string;
|
|
981
|
-
limit?: number;
|
|
834
|
+
interface RunRagKnowledgeImprovementLoopResult {
|
|
835
|
+
goal: string;
|
|
836
|
+
phases: readonly RagKnowledgeImprovementPhaseResult[];
|
|
837
|
+
retrieval?: RunRetrievalImprovementLoopResult;
|
|
838
|
+
findings: readonly RagGapFinding[];
|
|
839
|
+
acquisition?: KnowledgeResearchLoopDecision;
|
|
840
|
+
knowledgeUpdate?: RagKnowledgeUpdateResult;
|
|
841
|
+
answerQuality?: RagAnswerQualityResult;
|
|
842
|
+
promotion?: RagPromotionResult;
|
|
982
843
|
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
actor?: string;
|
|
986
|
-
target?: string;
|
|
987
|
-
metadata?: Record<string, unknown>;
|
|
988
|
-
now?: () => Date;
|
|
989
|
-
}): KnowledgeEvent;
|
|
844
|
+
type MaybePromise$1<T> = T | Promise<T>;
|
|
845
|
+
declare function runRagKnowledgeImprovementLoop(options: RunRagKnowledgeImprovementLoopOptions): Promise<RunRagKnowledgeImprovementLoopResult>;
|
|
990
846
|
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
* await store.mark({ workspaceId, sourceId: source.id, when: new Date() })
|
|
1004
|
-
* }
|
|
1005
|
-
* }
|
|
1006
|
-
* ```
|
|
1007
|
-
*
|
|
1008
|
-
* Per-tenant isolation is enforced by `workspaceId` keying — there is no
|
|
1009
|
-
* global mutable state across workspaces.
|
|
1010
|
-
*
|
|
1011
|
-
* Two adapters ship in-package:
|
|
1012
|
-
*
|
|
1013
|
-
* - `createFileSystemFreshnessStore` — JSON file under the knowledge root,
|
|
1014
|
-
* mirrors the layout convention already used by `sources.json`.
|
|
1015
|
-
* - `createD1FreshnessStoreStub` — adapter scaffold for Cloudflare D1 /
|
|
1016
|
-
* Postgres. Production consumers should implement the `D1Adapter`
|
|
1017
|
-
* interface inside their own app; this stub exists to anchor the shape.
|
|
1018
|
-
*
|
|
1019
|
-
* @stable contract — interface is frozen at 0.x within this major.
|
|
1020
|
-
* @stable filesystem adapter
|
|
1021
|
-
* @experimental D1 stub — interface will evolve as real consumers wire it.
|
|
1022
|
-
*/
|
|
1023
|
-
/** Identity for one freshness record. */
|
|
1024
|
-
interface FreshnessKey {
|
|
1025
|
-
workspaceId: string;
|
|
1026
|
-
sourceId: string;
|
|
847
|
+
type RagEvalProvider = 'agent-knowledge' | 'ragas' | 'deepeval' | 'trulens' | 'ragchecker' | 'custom';
|
|
848
|
+
type RagEvalMetricKey = 'context_precision' | 'context_recall' | 'context_relevance' | 'context_sufficiency' | 'faithfulness' | 'groundedness' | 'answer_relevance' | 'answer_correctness' | 'citation_support' | 'abstention' | 'unsupported_answer_rate';
|
|
849
|
+
type RagEvalSlice = 'known-answer' | 'paraphrase' | 'distractor' | 'freshness' | 'multi-source' | 'unanswerable' | 'long-tail' | 'custom';
|
|
850
|
+
interface RagEvalContext {
|
|
851
|
+
id: string;
|
|
852
|
+
text: string;
|
|
853
|
+
rank?: number;
|
|
854
|
+
pageId?: string;
|
|
855
|
+
sourceId?: string;
|
|
856
|
+
anchorId?: string;
|
|
857
|
+
stale?: boolean;
|
|
858
|
+
metadata?: Record<string, JsonValue>;
|
|
1027
859
|
}
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
860
|
+
interface RagEvalCitation {
|
|
861
|
+
id: string;
|
|
862
|
+
claimId?: string;
|
|
863
|
+
contextId?: string;
|
|
864
|
+
pageId?: string;
|
|
865
|
+
sourceId?: string;
|
|
866
|
+
anchorId?: string;
|
|
867
|
+
quote?: string;
|
|
868
|
+
metadata?: Record<string, JsonValue>;
|
|
1034
869
|
}
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
870
|
+
interface RagEvalClaim {
|
|
871
|
+
id: string;
|
|
872
|
+
text: string;
|
|
873
|
+
citationIds?: readonly string[];
|
|
874
|
+
metadata?: Record<string, JsonValue>;
|
|
1040
875
|
}
|
|
1041
|
-
interface
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
stale(input: FreshnessTtl): Promise<boolean>;
|
|
1048
|
-
/** All records for a workspace — useful for dashboards / debugging. */
|
|
1049
|
-
list(workspaceId: string): Promise<FreshnessRecord[]>;
|
|
876
|
+
interface RagRequiredContext {
|
|
877
|
+
id?: string;
|
|
878
|
+
text?: string;
|
|
879
|
+
pageId?: string;
|
|
880
|
+
sourceId?: string;
|
|
881
|
+
anchorId?: string;
|
|
1050
882
|
}
|
|
1051
|
-
interface
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
883
|
+
interface RagAnswerEvalScenario extends Scenario {
|
|
884
|
+
kind: 'rag-answer-eval';
|
|
885
|
+
query: string;
|
|
886
|
+
referenceAnswer?: string;
|
|
887
|
+
expectedClaims?: readonly string[];
|
|
888
|
+
forbiddenClaims?: readonly string[];
|
|
889
|
+
requiredContext?: readonly RagRequiredContext[];
|
|
890
|
+
unanswerable?: boolean;
|
|
891
|
+
requireCitations?: boolean;
|
|
892
|
+
slices?: readonly RagEvalSlice[];
|
|
893
|
+
thresholds?: Partial<Record<RagEvalMetricKey, number>>;
|
|
1056
894
|
}
|
|
1057
|
-
interface
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
root: string;
|
|
895
|
+
interface ExternalRagEvalScore {
|
|
896
|
+
provider: RagEvalProvider | string;
|
|
897
|
+
scores: Record<string, number>;
|
|
898
|
+
reasons?: Record<string, string>;
|
|
899
|
+
metadata?: Record<string, JsonValue>;
|
|
1063
900
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
* D1 / Postgres adapter scaffold. Production consumers implement
|
|
1076
|
-
* `D1Adapter` against their own driver (better-sqlite3, postgres,
|
|
1077
|
-
* Cloudflare D1 binding, ...). This factory wires the adapter to the
|
|
1078
|
-
* `KnowledgeFreshnessStore` interface.
|
|
1079
|
-
*
|
|
1080
|
-
* The expected schema:
|
|
1081
|
-
*
|
|
1082
|
-
* ```sql
|
|
1083
|
-
* CREATE TABLE knowledge_freshness (
|
|
1084
|
-
* workspace_id TEXT NOT NULL,
|
|
1085
|
-
* source_id TEXT NOT NULL,
|
|
1086
|
-
* last_refreshed_at TEXT NOT NULL,
|
|
1087
|
-
* content_hash TEXT,
|
|
1088
|
-
* PRIMARY KEY (workspace_id, source_id)
|
|
1089
|
-
* );
|
|
1090
|
-
* ```
|
|
1091
|
-
*/
|
|
1092
|
-
interface D1Adapter {
|
|
1093
|
-
get(workspaceId: string, sourceId: string): Promise<FreshnessRecord | null>;
|
|
1094
|
-
upsert(record: FreshnessRecord): Promise<void>;
|
|
1095
|
-
listByWorkspace(workspaceId: string): Promise<FreshnessRecord[]>;
|
|
901
|
+
interface RagAnswerEvalArtifact {
|
|
902
|
+
query: string;
|
|
903
|
+
answer: string;
|
|
904
|
+
contexts: readonly RagEvalContext[];
|
|
905
|
+
claims?: readonly RagEvalClaim[];
|
|
906
|
+
citations?: readonly RagEvalCitation[];
|
|
907
|
+
abstained?: boolean;
|
|
908
|
+
durationMs?: number;
|
|
909
|
+
costUsd?: number;
|
|
910
|
+
externalScores?: readonly ExternalRagEvalScore[];
|
|
911
|
+
metadata?: Record<string, JsonValue>;
|
|
1096
912
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
913
|
+
interface RagAnswerMetricSummary {
|
|
914
|
+
metrics: Record<RagEvalMetricKey, number>;
|
|
915
|
+
composite: number;
|
|
916
|
+
passed: boolean;
|
|
917
|
+
findings: readonly RagGapFinding[];
|
|
918
|
+
claimCount: number;
|
|
919
|
+
supportedClaimCount: number;
|
|
920
|
+
citedClaimCount: number;
|
|
921
|
+
supportedCitationCount: number;
|
|
922
|
+
matchedRequiredContextCount: number;
|
|
923
|
+
requiredContextCount: number;
|
|
924
|
+
providerScores: Record<string, Record<RagEvalMetricKey, number>>;
|
|
1102
925
|
}
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
declare function slugify(input: string): string;
|
|
1110
|
-
declare function stableId(prefix: string, content: string): string;
|
|
1111
|
-
|
|
1112
|
-
declare function buildKnowledgeIndex(root: string): Promise<KnowledgeIndex>;
|
|
1113
|
-
declare function writeKnowledgeIndex(root: string): Promise<KnowledgeIndex>;
|
|
1114
|
-
|
|
1115
|
-
interface KnowledgeInspection {
|
|
1116
|
-
pageCount: number;
|
|
1117
|
-
sourceCount: number;
|
|
1118
|
-
expiredSourceCount: number;
|
|
1119
|
-
staleSourceCount: number;
|
|
1120
|
-
edgeCount: number;
|
|
1121
|
-
findingCount: number;
|
|
1122
|
-
blockingFindingCount: number;
|
|
1123
|
-
topPages: Array<{
|
|
1124
|
-
path: string;
|
|
1125
|
-
title: string;
|
|
1126
|
-
degree: number;
|
|
1127
|
-
sources: number;
|
|
1128
|
-
}>;
|
|
1129
|
-
sourceFreshness: SourceFreshnessInspection[];
|
|
1130
|
-
findings: KnowledgeLintFinding[];
|
|
926
|
+
interface RagAnswerQualityJudgeOptions {
|
|
927
|
+
name?: string;
|
|
928
|
+
thresholds?: Partial<Record<RagEvalMetricKey, number>>;
|
|
929
|
+
weights?: Partial<Record<RagEvalMetricKey, number>>;
|
|
930
|
+
externalScorePolicy?: 'prefer-external' | 'deterministic-first';
|
|
931
|
+
minClaimSupport?: number;
|
|
1131
932
|
}
|
|
1132
|
-
interface
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
uri: string;
|
|
1136
|
-
status: 'fresh' | 'expired' | 'unknown';
|
|
1137
|
-
validUntil?: string;
|
|
1138
|
-
lastVerifiedAt?: string;
|
|
933
|
+
interface RagAnswerEvalCase {
|
|
934
|
+
scenario: RagAnswerEvalScenario;
|
|
935
|
+
artifact: RagAnswerEvalArtifact;
|
|
1139
936
|
}
|
|
1140
|
-
|
|
937
|
+
interface RagAnswerQualityHookOptions {
|
|
938
|
+
scenarios: readonly RagAnswerEvalScenario[];
|
|
939
|
+
run: (scenario: RagAnswerEvalScenario) => MaybePromise<RagAnswerEvalArtifact>;
|
|
940
|
+
externalEvaluator?: (item: RagAnswerEvalCase) => MaybePromise<ExternalRagEvalScore | readonly ExternalRagEvalScore[] | undefined>;
|
|
941
|
+
thresholds?: Partial<Record<RagEvalMetricKey, number>>;
|
|
942
|
+
weights?: Partial<Record<RagEvalMetricKey, number>>;
|
|
943
|
+
}
|
|
944
|
+
interface RagCalibrationOptions {
|
|
945
|
+
scenario: RagAnswerEvalScenario;
|
|
946
|
+
strong: RagAnswerEvalArtifact;
|
|
947
|
+
weak: RagAnswerEvalArtifact;
|
|
948
|
+
judge?: JudgeConfig<RagAnswerEvalArtifact, RagAnswerEvalScenario>;
|
|
949
|
+
minStrongScore?: number;
|
|
950
|
+
maxWeakScore?: number;
|
|
951
|
+
signal?: AbortSignal;
|
|
952
|
+
}
|
|
953
|
+
interface RagCalibrationResult {
|
|
954
|
+
passed: boolean;
|
|
955
|
+
strongScore: number;
|
|
956
|
+
weakScore: number;
|
|
957
|
+
gap: number;
|
|
958
|
+
}
|
|
959
|
+
interface KnowledgeBaseQualityOptions {
|
|
1141
960
|
now?: Date;
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
page?: KnowledgePage;
|
|
1146
|
-
sources: Array<{
|
|
1147
|
-
id: string;
|
|
1148
|
-
title?: string;
|
|
1149
|
-
uri: string;
|
|
1150
|
-
}>;
|
|
1151
|
-
links: string[];
|
|
1152
|
-
inbound: string[];
|
|
1153
|
-
related: Array<{
|
|
1154
|
-
path: string;
|
|
1155
|
-
title: string;
|
|
1156
|
-
score: number;
|
|
1157
|
-
}>;
|
|
961
|
+
strict?: boolean;
|
|
962
|
+
minCitationRate?: number;
|
|
963
|
+
maxStaleSourceRate?: number;
|
|
1158
964
|
}
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
965
|
+
interface KnowledgeBaseQualityReport {
|
|
966
|
+
ok: boolean;
|
|
967
|
+
metrics: {
|
|
968
|
+
page_count: number;
|
|
969
|
+
source_count: number;
|
|
970
|
+
citation_rate: number;
|
|
971
|
+
source_backed_page_rate: number;
|
|
972
|
+
stale_source_rate: number;
|
|
973
|
+
duplicate_source_hash_rate: number;
|
|
974
|
+
lint_error_count: number;
|
|
975
|
+
lint_warning_count: number;
|
|
976
|
+
};
|
|
977
|
+
findings: readonly RagGapFinding[];
|
|
978
|
+
}
|
|
979
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
980
|
+
declare function ragAnswerQualityJudge(options?: RagAnswerQualityJudgeOptions): JudgeConfig<RagAnswerEvalArtifact, RagAnswerEvalScenario>;
|
|
981
|
+
declare function scoreRagAnswerArtifact(artifact: RagAnswerEvalArtifact, scenario: RagAnswerEvalScenario, options?: RagAnswerQualityJudgeOptions): RagAnswerMetricSummary;
|
|
982
|
+
declare function diagnoseRagAnswerFailure(metrics: Record<RagEvalMetricKey, number>, scenario: RagAnswerEvalScenario, thresholds?: Partial<Record<RagEvalMetricKey, number>>): RagGapFinding[];
|
|
983
|
+
declare function createRagAnswerQualityHook(options: RagAnswerQualityHookOptions): () => Promise<RagAnswerQualityResult>;
|
|
984
|
+
declare function calibrateRagAnswerJudge(options: RagCalibrationOptions): Promise<RagCalibrationResult>;
|
|
985
|
+
declare function normalizeExternalRagScores(scores: readonly ExternalRagEvalScore[]): Record<string, Record<RagEvalMetricKey, number>>;
|
|
986
|
+
declare function toRagasEvaluationRows(cases: readonly RagAnswerEvalCase[]): {
|
|
987
|
+
user_input: string;
|
|
988
|
+
response: string;
|
|
989
|
+
retrieved_contexts: string[];
|
|
990
|
+
reference: string | undefined;
|
|
991
|
+
reference_contexts: string[];
|
|
992
|
+
}[];
|
|
993
|
+
declare function toDeepEvalTestCases(cases: readonly RagAnswerEvalCase[]): {
|
|
994
|
+
input: string;
|
|
995
|
+
actual_output: string;
|
|
996
|
+
expected_output: string | undefined;
|
|
997
|
+
retrieval_context: string[];
|
|
998
|
+
context: string[];
|
|
999
|
+
}[];
|
|
1000
|
+
declare function toTruLensRecords(cases: readonly RagAnswerEvalCase[]): {
|
|
1001
|
+
input: string;
|
|
1002
|
+
output: string;
|
|
1003
|
+
context: string;
|
|
1004
|
+
}[];
|
|
1005
|
+
declare function toRagCheckerRecords(cases: readonly RagAnswerEvalCase[]): {
|
|
1006
|
+
query_id: string;
|
|
1007
|
+
query: string;
|
|
1008
|
+
gt_answer: string | undefined;
|
|
1009
|
+
response: string;
|
|
1010
|
+
retrieved_context: {
|
|
1011
|
+
doc_id: string;
|
|
1012
|
+
text: string;
|
|
1013
|
+
}[];
|
|
1014
|
+
claims: string[];
|
|
1015
|
+
}[];
|
|
1016
|
+
declare function scoreKnowledgeBaseIndex(index: KnowledgeIndex, options?: KnowledgeBaseQualityOptions): KnowledgeBaseQualityReport;
|
|
1017
|
+
|
|
1018
|
+
type KnowledgeImprovementStatus = 'running' | 'candidate-ready' | 'promoted' | 'rejected' | 'blocked';
|
|
1019
|
+
interface KnowledgeImprovementMetricProvenanceBase {
|
|
1020
|
+
evaluator: string;
|
|
1021
|
+
version: string;
|
|
1022
|
+
}
|
|
1023
|
+
type KnowledgeImprovementMetricProvenance = (KnowledgeImprovementMetricProvenanceBase & {
|
|
1024
|
+
method: 'deterministic';
|
|
1025
|
+
}) | (KnowledgeImprovementMetricProvenanceBase & {
|
|
1026
|
+
method: 'sampled' | 'composite';
|
|
1027
|
+
corpusHash: string;
|
|
1028
|
+
runRecords: RunRecord[];
|
|
1029
|
+
}) | (KnowledgeImprovementMetricProvenanceBase & {
|
|
1030
|
+
method: 'model';
|
|
1031
|
+
model: string;
|
|
1032
|
+
corpusHash: string;
|
|
1033
|
+
runRecords: RunRecord[];
|
|
1034
|
+
});
|
|
1035
|
+
interface KnowledgeImprovementMetric {
|
|
1036
|
+
score: number;
|
|
1037
|
+
passed: boolean;
|
|
1038
|
+
dimensions?: Record<string, number>;
|
|
1039
|
+
notes?: string;
|
|
1040
|
+
provenance: KnowledgeImprovementMetricProvenance;
|
|
1041
|
+
}
|
|
1042
|
+
interface KnowledgeImprovementEvaluationInput {
|
|
1043
|
+
runId: string;
|
|
1044
|
+
iteration: number;
|
|
1045
|
+
root: string;
|
|
1046
|
+
baselineRoot: string;
|
|
1047
|
+
candidateRoot: string;
|
|
1048
|
+
baselineIndex: KnowledgeIndex;
|
|
1049
|
+
candidateIndex: KnowledgeIndex;
|
|
1050
|
+
baseHash: string;
|
|
1051
|
+
candidateHash: string;
|
|
1052
|
+
validation: ValidateKnowledgeResult;
|
|
1053
|
+
readiness?: EvalKnowledgeBundleBuildResult;
|
|
1054
|
+
kbQuality: KnowledgeBaseQualityReport;
|
|
1055
|
+
lifecycle?: RunRagKnowledgeImprovementLoopResult;
|
|
1056
|
+
signal?: AbortSignal;
|
|
1057
|
+
}
|
|
1058
|
+
type KnowledgeImprovementEvaluator = (input: KnowledgeImprovementEvaluationInput) => Promise<KnowledgeImprovementMetric> | KnowledgeImprovementMetric;
|
|
1059
|
+
interface KnowledgeImprovementCandidateRecord {
|
|
1060
|
+
iteration: number;
|
|
1061
|
+
candidateId: string;
|
|
1062
|
+
baseHash: string;
|
|
1063
|
+
candidateHash?: string;
|
|
1064
|
+
evidenceHash?: string;
|
|
1065
|
+
promotionPlanHash?: string;
|
|
1066
|
+
status: KnowledgeImprovementStatus;
|
|
1067
|
+
createdAt: string;
|
|
1068
|
+
updatedAt: string;
|
|
1069
|
+
}
|
|
1070
|
+
interface KnowledgeImprovementRunState {
|
|
1071
|
+
schemaVersion: 1;
|
|
1072
|
+
runId: string;
|
|
1073
|
+
root: string;
|
|
1074
|
+
goal: string;
|
|
1075
|
+
status: KnowledgeImprovementStatus;
|
|
1076
|
+
baseHash: string;
|
|
1077
|
+
createdAt: string;
|
|
1078
|
+
updatedAt: string;
|
|
1079
|
+
ownerId?: string;
|
|
1080
|
+
candidates: KnowledgeImprovementCandidateRecord[];
|
|
1081
|
+
promotedCandidateId?: string;
|
|
1082
|
+
blockedReason?: string;
|
|
1083
|
+
}
|
|
1084
|
+
interface KnowledgeImprovementResult {
|
|
1085
|
+
runId: string;
|
|
1086
|
+
state: KnowledgeImprovementRunState;
|
|
1087
|
+
candidate?: KnowledgeImprovementCandidateRecord;
|
|
1088
|
+
evaluation?: KnowledgeImprovementMetric;
|
|
1089
|
+
lifecycle?: RunRagKnowledgeImprovementLoopResult;
|
|
1090
|
+
promoted: boolean;
|
|
1091
|
+
blocked: boolean;
|
|
1092
|
+
}
|
|
1093
|
+
declare const KnowledgeImprovementRunStateSchema: z.ZodObject<{
|
|
1094
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
1095
|
+
runId: z.ZodString;
|
|
1096
|
+
root: z.ZodString;
|
|
1097
|
+
goal: z.ZodString;
|
|
1098
|
+
status: z.ZodEnum<{
|
|
1099
|
+
rejected: "rejected";
|
|
1100
|
+
promoted: "promoted";
|
|
1101
|
+
running: "running";
|
|
1102
|
+
"candidate-ready": "candidate-ready";
|
|
1103
|
+
blocked: "blocked";
|
|
1104
|
+
}>;
|
|
1105
|
+
baseHash: z.ZodString;
|
|
1106
|
+
createdAt: z.ZodISODateTime;
|
|
1107
|
+
updatedAt: z.ZodISODateTime;
|
|
1108
|
+
ownerId: z.ZodOptional<z.ZodString>;
|
|
1109
|
+
candidates: z.ZodArray<z.ZodObject<{
|
|
1110
|
+
iteration: z.ZodNumber;
|
|
1111
|
+
candidateId: z.ZodString;
|
|
1112
|
+
baseHash: z.ZodString;
|
|
1113
|
+
candidateHash: z.ZodOptional<z.ZodString>;
|
|
1114
|
+
evidenceHash: z.ZodOptional<z.ZodString>;
|
|
1115
|
+
promotionPlanHash: z.ZodOptional<z.ZodString>;
|
|
1116
|
+
status: z.ZodEnum<{
|
|
1117
|
+
rejected: "rejected";
|
|
1118
|
+
promoted: "promoted";
|
|
1119
|
+
running: "running";
|
|
1120
|
+
"candidate-ready": "candidate-ready";
|
|
1121
|
+
blocked: "blocked";
|
|
1122
|
+
}>;
|
|
1123
|
+
createdAt: z.ZodISODateTime;
|
|
1124
|
+
updatedAt: z.ZodISODateTime;
|
|
1125
|
+
}, z.core.$strict>>;
|
|
1126
|
+
promotedCandidateId: z.ZodOptional<z.ZodString>;
|
|
1127
|
+
blockedReason: z.ZodOptional<z.ZodString>;
|
|
1128
|
+
}, z.core.$strict>;
|
|
1129
|
+
declare const KnowledgeImprovementEvidenceSchema: z.ZodObject<{
|
|
1130
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
1131
|
+
kind: z.ZodLiteral<"knowledge-improvement-evidence">;
|
|
1132
|
+
runId: z.ZodString;
|
|
1133
|
+
candidateId: z.ZodString;
|
|
1134
|
+
iteration: z.ZodNumber;
|
|
1135
|
+
goalHash: z.ZodString;
|
|
1136
|
+
baseHash: z.ZodString;
|
|
1137
|
+
candidateHash: z.ZodString;
|
|
1138
|
+
promotionPlanHash: z.ZodString;
|
|
1139
|
+
validation: z.ZodUnknown;
|
|
1140
|
+
readiness: z.ZodNullable<z.ZodUnknown>;
|
|
1141
|
+
kbQuality: z.ZodUnknown;
|
|
1142
|
+
evaluation: z.ZodObject<{
|
|
1143
|
+
score: z.ZodNumber;
|
|
1144
|
+
passed: z.ZodBoolean;
|
|
1145
|
+
dimensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
1146
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
1147
|
+
provenance: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1148
|
+
evaluator: z.ZodString;
|
|
1149
|
+
version: z.ZodString;
|
|
1150
|
+
method: z.ZodLiteral<"deterministic">;
|
|
1151
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1152
|
+
evaluator: z.ZodString;
|
|
1153
|
+
version: z.ZodString;
|
|
1154
|
+
method: z.ZodEnum<{
|
|
1155
|
+
composite: "composite";
|
|
1156
|
+
sampled: "sampled";
|
|
1157
|
+
}>;
|
|
1158
|
+
corpusHash: z.ZodString;
|
|
1159
|
+
runRecords: z.ZodArray<z.ZodCustom<RunRecord, RunRecord>>;
|
|
1160
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1161
|
+
evaluator: z.ZodString;
|
|
1162
|
+
version: z.ZodString;
|
|
1163
|
+
method: z.ZodLiteral<"model">;
|
|
1164
|
+
model: z.ZodString;
|
|
1165
|
+
corpusHash: z.ZodString;
|
|
1166
|
+
runRecords: z.ZodArray<z.ZodCustom<RunRecord, RunRecord>>;
|
|
1167
|
+
}, z.core.$strict>], "method">;
|
|
1168
|
+
}, z.core.$strict>;
|
|
1169
|
+
lifecycle: z.ZodNullable<z.ZodUnknown>;
|
|
1170
|
+
}, z.core.$strict>;
|
|
1171
|
+
type KnowledgeImprovementEvidence = z.infer<typeof KnowledgeImprovementEvidenceSchema>;
|
|
1172
|
+
/** Portable identity of one measured candidate. Paths and mutable run state are deliberately excluded. */
|
|
1173
|
+
declare const KnowledgeImprovementCandidateRefSchema: z.ZodObject<{
|
|
1174
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
1175
|
+
kind: z.ZodLiteral<"knowledge-improvement-candidate">;
|
|
1176
|
+
runId: z.ZodString;
|
|
1177
|
+
candidateId: z.ZodString;
|
|
1178
|
+
goalHash: z.ZodString;
|
|
1179
|
+
baseHash: z.ZodString;
|
|
1180
|
+
candidateHash: z.ZodString;
|
|
1181
|
+
evidenceHash: z.ZodString;
|
|
1182
|
+
promotionPlanHash: z.ZodString;
|
|
1183
|
+
}, z.core.$strict>;
|
|
1184
|
+
type KnowledgeImprovementCandidateRef = z.infer<typeof KnowledgeImprovementCandidateRefSchema>;
|
|
1185
|
+
interface PromoteKnowledgeCandidateOptions {
|
|
1186
|
+
root: string;
|
|
1187
|
+
candidate: KnowledgeImprovementCandidateRef;
|
|
1188
|
+
ownerId?: string;
|
|
1189
|
+
leaseTtlMs?: number;
|
|
1190
|
+
now?: () => Date;
|
|
1191
|
+
onState?: (state: KnowledgeImprovementRunState) => Promise<void> | void;
|
|
1192
|
+
}
|
|
1193
|
+
interface UseKnowledgeImprovementCandidateOptions {
|
|
1194
|
+
root: string;
|
|
1195
|
+
candidate: KnowledgeImprovementCandidateRef;
|
|
1196
|
+
}
|
|
1197
|
+
interface ResolvedKnowledgeImprovementCandidate {
|
|
1198
|
+
root: string;
|
|
1199
|
+
candidate: KnowledgeImprovementCandidateRef;
|
|
1200
|
+
evaluation: KnowledgeImprovementMetric;
|
|
1201
|
+
}
|
|
1202
|
+
interface KnowledgeImprovementRetrievalOptions extends Omit<RunRetrievalImprovementLoopOptions, 'index' | 'runDir'> {
|
|
1203
|
+
runDir?: RunRetrievalImprovementLoopOptions['runDir'];
|
|
1204
|
+
}
|
|
1205
|
+
interface KnowledgeImprovementUpdateInput extends RagKnowledgeUpdateInput {
|
|
1206
|
+
runId: string;
|
|
1207
|
+
iteration: number;
|
|
1208
|
+
candidateId: string;
|
|
1209
|
+
root: string;
|
|
1210
|
+
baselineRoot: string;
|
|
1211
|
+
candidateRoot: string;
|
|
1212
|
+
baseHash: string;
|
|
1213
|
+
}
|
|
1214
|
+
type KnowledgeImprovementUpdate = (input: KnowledgeImprovementUpdateInput) => Promise<RagKnowledgeUpdateResult> | RagKnowledgeUpdateResult;
|
|
1215
|
+
interface KnowledgeImprovementOptions {
|
|
1216
|
+
root: string;
|
|
1217
|
+
goal: string;
|
|
1218
|
+
runId?: string;
|
|
1219
|
+
ownerId?: string;
|
|
1220
|
+
leaseTtlMs?: number;
|
|
1221
|
+
resume?: boolean;
|
|
1222
|
+
maxCandidates?: number;
|
|
1223
|
+
candidateResearchIterations?: number;
|
|
1224
|
+
strict?: ValidateKnowledgeOptions['strict'];
|
|
1225
|
+
readinessSpecs?: KnowledgeReadinessSpec[];
|
|
1226
|
+
readinessTaskId?: string;
|
|
1227
|
+
readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>;
|
|
1228
|
+
kbQuality?: KnowledgeBaseQualityOptions;
|
|
1229
|
+
step?: RunKnowledgeResearchLoopOptions['step'];
|
|
1230
|
+
knowledgeResearch?: Omit<RagKnowledgeResearchOptions, 'root'>;
|
|
1231
|
+
retrieval?: KnowledgeImprovementRetrievalOptions;
|
|
1232
|
+
diagnose?: NonNullable<RunRagKnowledgeImprovementLoopOptions['diagnose']>;
|
|
1233
|
+
acquireKnowledge?: NonNullable<RunRagKnowledgeImprovementLoopOptions['acquireKnowledge']>;
|
|
1234
|
+
updateKnowledge?: KnowledgeImprovementUpdate;
|
|
1235
|
+
evaluateAnswers?: NonNullable<RunRagKnowledgeImprovementLoopOptions['evaluateAnswers']>;
|
|
1236
|
+
decidePromotion?: NonNullable<RunRagKnowledgeImprovementLoopOptions['promote']>;
|
|
1237
|
+
enabledPhases?: readonly RagKnowledgeImprovementPhase[];
|
|
1238
|
+
requiredPhases?: readonly RagKnowledgeImprovementPhase[];
|
|
1239
|
+
evaluate?: KnowledgeImprovementEvaluator;
|
|
1240
|
+
signal?: AbortSignal;
|
|
1241
|
+
now?: () => Date;
|
|
1242
|
+
onState?: (state: KnowledgeImprovementRunState) => Promise<void> | void;
|
|
1243
|
+
}
|
|
1244
|
+
declare function knowledgeImprovementRunId(root: string, goal: string): string;
|
|
1245
|
+
declare function knowledgeImprovementRunDir(root: string, runId: string): string;
|
|
1246
|
+
declare function loadKnowledgeImprovementState(root: string, runId: string): Promise<KnowledgeImprovementRunState | null>;
|
|
1247
|
+
/** Freeze the exact knowledge bytes and measured evidence a later approval may promote. */
|
|
1248
|
+
declare function knowledgeImprovementCandidateRef(result: Pick<KnowledgeImprovementResult, 'runId' | 'state' | 'candidate'>): KnowledgeImprovementCandidateRef;
|
|
1249
|
+
/** Use one measured snapshot while its directory identity remains open and stable. */
|
|
1250
|
+
declare function withKnowledgeImprovementCandidate<T>(options: UseKnowledgeImprovementCandidateOptions, use: (candidate: ResolvedKnowledgeImprovementCandidate) => Promise<T> | T): Promise<T>;
|
|
1251
|
+
/** Promote one previously measured candidate without rerunning research or evaluation. */
|
|
1252
|
+
declare function promoteKnowledgeCandidate(options: PromoteKnowledgeCandidateOptions): Promise<KnowledgeImprovementResult>;
|
|
1253
|
+
declare function improveKnowledgeBase(options: KnowledgeImprovementOptions): Promise<KnowledgeImprovementResult>;
|
|
1254
|
+
interface KnowledgeImprovementEvent extends Record<string, unknown> {
|
|
1255
|
+
at: string;
|
|
1256
|
+
type: string;
|
|
1257
|
+
}
|
|
1258
|
+
declare function loadKnowledgeImprovementEvents(root: string, runId: string): Promise<KnowledgeImprovementEvent[]>;
|
|
1259
|
+
declare function hashKnowledgeBase(root: string): Promise<string>;
|
|
1260
|
+
|
|
1261
|
+
/** Convert a measured knowledge candidate into the shared review and execution identity. */
|
|
1262
|
+
declare function toAgentCandidateKnowledgeRef(candidate: KnowledgeImprovementCandidateRef): AgentCandidateKnowledgeRef;
|
|
1263
|
+
/** Recover agent-knowledge's candidate identity from the shared contract. */
|
|
1264
|
+
declare function fromAgentCandidateKnowledgeRef(candidate: AgentCandidateKnowledgeRef): KnowledgeImprovementCandidateRef;
|
|
1265
|
+
|
|
1266
|
+
/**
|
|
1267
|
+
* Change detection across snapshots of one source's fragments.
|
|
1178
1268
|
*
|
|
1179
|
-
*
|
|
1180
|
-
*
|
|
1181
|
-
*
|
|
1269
|
+
* The output drives the continuous-ingestion loop: each `KnowledgeChange`
|
|
1270
|
+
* carries the eval dimensions affected (`affectedDimensions`), which an
|
|
1271
|
+
* agent-eval campaign scheduler consumes to decide which campaigns to
|
|
1272
|
+
* re-run. Three change kinds:
|
|
1182
1273
|
*
|
|
1183
|
-
*
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1187
|
-
*
|
|
1274
|
+
* - `added` — fragment id appears in `next` but not `prev`.
|
|
1275
|
+
* - `removed` — fragment id appears in `prev` but not `next`. Typical
|
|
1276
|
+
* trigger: an authority retires a Wex slug, or a state SOS reorganises
|
|
1277
|
+
* its forms catalogue.
|
|
1278
|
+
* - `modified` — fragment id appears in both, body hash differs. This
|
|
1279
|
+
* is the dominant change kind in practice — the Ryan-LLC v. FTC
|
|
1280
|
+
* vacatur case manifests as a `modified` on the Wex non-compete
|
|
1281
|
+
* fragment, NOT as a removed one.
|
|
1188
1282
|
*
|
|
1189
|
-
*
|
|
1190
|
-
*
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
* is in the doc).
|
|
1283
|
+
* Unverifiable fragments are filtered out before diffing — comparing a
|
|
1284
|
+
* captcha-blocked snapshot against a real one would falsely fire every
|
|
1285
|
+
* fragment as removed. The caller can inspect the raw lists if they want
|
|
1286
|
+
* to surface block-page failures.
|
|
1194
1287
|
*
|
|
1195
|
-
*
|
|
1196
|
-
*
|
|
1197
|
-
* hindsight (the eventual bankruptcy / collapse) is NOT a checklist item —
|
|
1198
|
-
* it is recorded separately as `knownOutcome`, purely for the reader, and is
|
|
1199
|
-
* never graded.
|
|
1288
|
+
* Within-snapshot duplicate ids are an upstream bug; this function picks
|
|
1289
|
+
* the LAST one and emits a diagnostic via the `warnings` field.
|
|
1200
1290
|
*
|
|
1201
|
-
*
|
|
1202
|
-
* thesis text contains at least `minGroups` of its expected groups; a group is
|
|
1203
|
-
* satisfied when ANY of its `anyOf` fragments appears (case-insensitive
|
|
1204
|
-
* substring), so a faithful thesis phrased in its own words still grades as a
|
|
1205
|
-
* hit. `anyOf` groups model synonyms; the load-bearing tokens are the specific
|
|
1206
|
-
* numbers / names.
|
|
1291
|
+
* @stable
|
|
1207
1292
|
*/
|
|
1208
|
-
|
|
1209
|
-
interface
|
|
1210
|
-
/**
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
anyOf: string[];
|
|
1214
|
-
}
|
|
1215
|
-
/** Lens the fact belongs to — so a set can be checked for category coverage. */
|
|
1216
|
-
type MaterialFactLens = 'concentration' | 'leverage' | 'margin-trend' | 'liquidity' | 'capital-return' | 'governance' | 'off-balance-sheet' | 'regulatory';
|
|
1217
|
-
/** One held-out material fact with a checkable expected answer + its provenance. */
|
|
1218
|
-
interface MaterialFact {
|
|
1219
|
-
/** Stable id, `ticker/fN`. */
|
|
1220
|
-
id: string;
|
|
1221
|
-
/** Which analyst lens this fact exercises. For coverage + the doc. */
|
|
1222
|
-
lens: MaterialFactLens;
|
|
1223
|
-
/**
|
|
1224
|
-
* The material fact, in plain words — for the doc/audit. NEVER shown to a loop.
|
|
1225
|
-
* This is the thing a thorough analyst would flag and a ticker search misses.
|
|
1226
|
-
*/
|
|
1227
|
-
fact: string;
|
|
1228
|
-
/**
|
|
1229
|
-
* The checkable answer as required keyword GROUPS. The thesis text must contain
|
|
1230
|
-
* at least `minGroups` of these groups (default: all). A group is satisfied
|
|
1231
|
-
* when ANY of its `anyOf` fragments appears (case-insensitive substring).
|
|
1232
|
-
*/
|
|
1233
|
-
expected: ExpectedGroup[];
|
|
1293
|
+
type KnowledgeChangeKind = 'added' | 'removed' | 'modified';
|
|
1294
|
+
interface KnowledgeChange {
|
|
1295
|
+
/** Source-scoped id (matches `KnowledgeFragment.id`). */
|
|
1296
|
+
fragmentId: string;
|
|
1297
|
+
kind: KnowledgeChangeKind;
|
|
1234
1298
|
/**
|
|
1235
|
-
*
|
|
1236
|
-
*
|
|
1237
|
-
*
|
|
1299
|
+
* For `added`: full body of the new fragment.
|
|
1300
|
+
* For `removed`: full body of the prior fragment.
|
|
1301
|
+
* For `modified`: unified-diff-style payload `{ before, after }` body strings.
|
|
1238
1302
|
*/
|
|
1239
|
-
|
|
1303
|
+
diff?: {
|
|
1304
|
+
before?: string;
|
|
1305
|
+
after?: string;
|
|
1306
|
+
};
|
|
1240
1307
|
/**
|
|
1241
|
-
*
|
|
1242
|
-
*
|
|
1308
|
+
* Eval dimensions to re-score. Computed as the union of both fragments'
|
|
1309
|
+
* `dimensionHints`. The eval cron treats this as a set of campaign tags.
|
|
1243
1310
|
*/
|
|
1244
|
-
|
|
1311
|
+
affectedDimensions: string[];
|
|
1312
|
+
/** URL of the affected authority page (from whichever side has it). */
|
|
1313
|
+
url?: string;
|
|
1245
1314
|
/**
|
|
1246
|
-
*
|
|
1247
|
-
*
|
|
1248
|
-
*
|
|
1315
|
+
* Source-attested change time. For `modified`, takes the NEXT fragment's
|
|
1316
|
+
* `sourceUpdatedAt`. For `removed`, takes the PRIOR fragment's
|
|
1317
|
+
* `sourceUpdatedAt`. For `added`, takes the NEXT fragment's
|
|
1318
|
+
* `sourceUpdatedAt`. Consumers index changes by this date.
|
|
1249
1319
|
*/
|
|
1250
|
-
|
|
1320
|
+
detectedAt: string;
|
|
1251
1321
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
/**
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1322
|
+
interface DetectChangesResult {
|
|
1323
|
+
changes: KnowledgeChange[];
|
|
1324
|
+
/** Counts by kind — handy for dashboards. */
|
|
1325
|
+
summary: {
|
|
1326
|
+
added: number;
|
|
1327
|
+
removed: number;
|
|
1328
|
+
modified: number;
|
|
1329
|
+
};
|
|
1330
|
+
/** Non-fatal diagnostics (duplicate ids, dropped unverifiable fragments). */
|
|
1331
|
+
warnings: string[];
|
|
1332
|
+
}
|
|
1333
|
+
interface DetectChangesOptions {
|
|
1260
1334
|
/**
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1263
|
-
*
|
|
1335
|
+
* When true (default), unverifiable fragments are dropped from both
|
|
1336
|
+
* sides before comparison. Set false ONLY when debugging block-page
|
|
1337
|
+
* issues — comparing against unverifiable content emits false
|
|
1338
|
+
* `removed`/`modified` changes.
|
|
1264
1339
|
*/
|
|
1265
|
-
|
|
1266
|
-
/** Sector, for coverage / the curation-bias disclosure. */
|
|
1267
|
-
sector: string;
|
|
1340
|
+
skipUnverifiable?: boolean;
|
|
1268
1341
|
/**
|
|
1269
|
-
*
|
|
1270
|
-
*
|
|
1342
|
+
* When provided, only changes whose `affectedDimensions` intersect this
|
|
1343
|
+
* set are returned. Useful for cron loops that schedule per-dimension
|
|
1344
|
+
* eval campaigns and only care about a subset.
|
|
1271
1345
|
*/
|
|
1272
|
-
|
|
1273
|
-
/** The held-out material facts for this company. */
|
|
1274
|
-
facts: MaterialFact[];
|
|
1346
|
+
filterDimensions?: string[];
|
|
1275
1347
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
declare function gradeFactAgainstText(fact: MaterialFact, thesisText: string): {
|
|
1297
|
-
surfaced: boolean;
|
|
1298
|
-
groupsFound: number;
|
|
1299
|
-
groupsTotal: number;
|
|
1300
|
-
foundLabels: string[];
|
|
1301
|
-
};
|
|
1302
|
-
/** Grade a whole company's thesis text: how many of its held-out facts it surfaces. */
|
|
1303
|
-
declare function gradeCompanyAgainstText(company: CompanyEvalCase, thesisText: string): {
|
|
1304
|
-
surfaced: number;
|
|
1305
|
-
total: number;
|
|
1306
|
-
perFact: ReturnType<typeof gradeFactAgainstText>[];
|
|
1348
|
+
declare function detectChanges(prev: KnowledgeFragment[], next: KnowledgeFragment[], options?: DetectChangesOptions): DetectChangesResult;
|
|
1349
|
+
|
|
1350
|
+
interface ChunkingOptions {
|
|
1351
|
+
targetChars: number;
|
|
1352
|
+
maxChars: number;
|
|
1353
|
+
minChars: number;
|
|
1354
|
+
overlapChars: number;
|
|
1355
|
+
}
|
|
1356
|
+
interface KnowledgeChunk {
|
|
1357
|
+
index: number;
|
|
1358
|
+
text: string;
|
|
1359
|
+
headingPath: string;
|
|
1360
|
+
charStart: number;
|
|
1361
|
+
charEnd: number;
|
|
1362
|
+
oversized: boolean;
|
|
1363
|
+
}
|
|
1364
|
+
declare function chunkMarkdown(content: string, options?: Partial<ChunkingOptions>): KnowledgeChunk[];
|
|
1365
|
+
declare function stripFrontmatter(content: string): {
|
|
1366
|
+
body: string;
|
|
1367
|
+
bodyOffset: number;
|
|
1307
1368
|
};
|
|
1308
|
-
/** Total held-out facts across the set (the denominator the doc reports). */
|
|
1309
|
-
declare function totalMaterialFacts(set?: CompanyEvalCase[]): number;
|
|
1310
|
-
/** Count facts per lens across the set — used to report (and bound) curation bias. */
|
|
1311
|
-
declare function lensDistribution(set?: CompanyEvalCase[]): Record<MaterialFactLens, number>;
|
|
1312
1369
|
|
|
1313
1370
|
/**
|
|
1314
|
-
*
|
|
1371
|
+
* Claim-grounding mode for `runVerifiedResearchLoop`.
|
|
1315
1372
|
*
|
|
1316
|
-
*
|
|
1317
|
-
*
|
|
1318
|
-
*
|
|
1319
|
-
*
|
|
1320
|
-
*
|
|
1373
|
+
* The two-agent loop's existing verifier judges a source's on-topic RELEVANCE
|
|
1374
|
+
* (is this page about the goal?). On the topic sets we have measured, its
|
|
1375
|
+
* cleanliness win is dominated by DE-DUPLICATION — which a deterministic
|
|
1376
|
+
* content-hash / canonical-URL check captures at ~none of the LLM premium (see
|
|
1377
|
+
* `docs/results/cost-quality.md`). That makes the LLM verifier look expensive
|
|
1378
|
+
* for what a cheap rule already does.
|
|
1321
1379
|
*
|
|
1322
|
-
*
|
|
1323
|
-
*
|
|
1324
|
-
*
|
|
1325
|
-
* the
|
|
1380
|
+
* Claim-grounding targets a DIFFERENT, harder error band: a citation that is
|
|
1381
|
+
* relevant and unique but **misattributed** — the page is on-topic, the URL is
|
|
1382
|
+
* real, yet the specific CLAIM the source is cited for does NOT actually appear
|
|
1383
|
+
* in the page. This is the citation-fabrication failure mode of LLM research:
|
|
1384
|
+
* the model writes a plausible sentence and hangs a real URL off it that never
|
|
1385
|
+
* says any such thing. Neither de-dup nor a relevance judge catches it (both can
|
|
1386
|
+
* pass a misattributed-but-on-topic page); only checking the claim against the
|
|
1387
|
+
* fetched text does.
|
|
1326
1388
|
*
|
|
1327
|
-
*
|
|
1328
|
-
*
|
|
1329
|
-
*
|
|
1330
|
-
*
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
company: string;
|
|
1337
|
-
/** Ticker as of the cutoff. */
|
|
1338
|
-
ticker: string;
|
|
1339
|
-
/** SEC Central Index Key (CIK), zero-stripped — the EDGAR filer id. */
|
|
1340
|
-
cik: string;
|
|
1341
|
-
/** Research-as-of date (ISO). The loop must reason as if it is this date. */
|
|
1342
|
-
cutoff: string;
|
|
1343
|
-
/** Sector, for the readiness query context (NOT a checklist hint). */
|
|
1344
|
-
sector?: string;
|
|
1345
|
-
}
|
|
1346
|
-
/**
|
|
1347
|
-
* The generic analyst-lens readiness specs every company gets. They are the ONLY
|
|
1348
|
-
* thing the loop is told about WHAT to look for, and they name the LENSES a
|
|
1349
|
-
* thorough analyst checks (balance-sheet risk, concentration, leverage, margins,
|
|
1350
|
-
* liquidity, governance, regulatory) and where they live (the latest SEC 10-K) —
|
|
1351
|
-
* NOT the answers. They steer the worker's web/EDGAR search toward the filing,
|
|
1352
|
-
* not toward the held-out facts (which the loop never sees).
|
|
1389
|
+
* The check is EXECUTABLE GROUND TRUTH, not another LLM opinion: the worker
|
|
1390
|
+
* attaches the specific claim it is citing the source for, and the verifier
|
|
1391
|
+
* tests whether that claim is PRESENT (verbatim, normalized, or as a sufficient
|
|
1392
|
+
* content-word overlap / close paraphrase) in the `htmlToText` output of the
|
|
1393
|
+
* page the worker actually fetched. A claim that is not grounded is rejected as
|
|
1394
|
+
* misattributed. Because the oracle is deterministic text presence — not a model
|
|
1395
|
+
* call — it is a deployable, non-oracle verifier: it can run in production with
|
|
1396
|
+
* zero inference cost, OR be composed with the LLM relevance verifier so the
|
|
1397
|
+
* loop rejects BOTH off-topic AND misattributed sources.
|
|
1353
1398
|
*
|
|
1354
|
-
*
|
|
1355
|
-
*
|
|
1356
|
-
*
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
/** The KB root the loop writes into. */
|
|
1361
|
-
root: string;
|
|
1362
|
-
/** Shared router client (web search + chat). Defaults to env creds. */
|
|
1363
|
-
router: RouterClient;
|
|
1364
|
-
/** The driver — verify/dedup or research-driving. The loop's coordinator. */
|
|
1365
|
-
driver: ResearchDriver;
|
|
1366
|
-
/** Round budget. Default 3 (the depth-driving driver needs >1). */
|
|
1367
|
-
maxRounds?: number;
|
|
1368
|
-
/** Worker tuning forwarded to `createWebResearchWorker`. */
|
|
1369
|
-
workerOptions?: Omit<WebResearchWorkerOptions, 'router'>;
|
|
1370
|
-
/** Max tokens for the synthesis pass. Default 1600 (above glm-5.2's reasoning floor). */
|
|
1371
|
-
synthesisMaxTokens?: number;
|
|
1372
|
-
signal?: AbortSignal;
|
|
1373
|
-
}
|
|
1374
|
-
interface ThesisRunResult {
|
|
1375
|
-
loop: VerifiedResearchLoopResult;
|
|
1376
|
-
/** The synthesized thesis text. */
|
|
1377
|
-
thesis: string;
|
|
1378
|
-
/** Path of the thesis page written into the KB. */
|
|
1379
|
-
thesisPath: string;
|
|
1380
|
-
}
|
|
1381
|
-
/**
|
|
1382
|
-
* Run the full thesis task: drive the two-agent loop to research the company AS
|
|
1383
|
-
* OF the cutoff, then synthesize + write the thesis page. Returns the loop result
|
|
1384
|
-
* + the thesis text + the page path. The caller grades the KB with
|
|
1385
|
-
* `materialFactsSurfaced(root, checklist)` — the checklist is never passed here.
|
|
1386
|
-
*/
|
|
1387
|
-
declare function runInvestmentThesisTask(input: ThesisTaskInput, options: ThesisRunOptions): Promise<ThesisRunResult>;
|
|
1388
|
-
|
|
1389
|
-
interface ApplyWriteBlocksResult {
|
|
1390
|
-
written: string[];
|
|
1391
|
-
warnings: string[];
|
|
1392
|
-
}
|
|
1393
|
-
declare function applyKnowledgeWriteBlocks(root: string, proposalText: string): Promise<ApplyWriteBlocksResult>;
|
|
1394
|
-
declare function applyKnowledgeWriteBlocksFile(root: string, proposalPath: string): Promise<ApplyWriteBlocksResult>;
|
|
1395
|
-
|
|
1396
|
-
interface ValidateKnowledgeOptions {
|
|
1397
|
-
strict?: boolean;
|
|
1398
|
-
}
|
|
1399
|
-
interface ValidateKnowledgeResult {
|
|
1400
|
-
ok: boolean;
|
|
1401
|
-
findings: KnowledgeLintFinding[];
|
|
1402
|
-
}
|
|
1403
|
-
declare function validateKnowledgeIndex(index: KnowledgeIndex, options?: ValidateKnowledgeOptions): ValidateKnowledgeResult;
|
|
1399
|
+
* This module is content-free and any-topic: it adds (1) a way for a proposal to
|
|
1400
|
+
* carry the claim it is cited for, (2) the `groundClaimInText` oracle, and (3) a
|
|
1401
|
+
* `ResearchDriver` that gates on grounding. It composes the existing
|
|
1402
|
+
* `ResearchDriver` / `ResearchSourceProposal` contracts and the shipped
|
|
1403
|
+
* `htmlToText`; it reinvents none of them.
|
|
1404
|
+
*/
|
|
1404
1405
|
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
*/
|
|
1421
|
-
notes?: string;
|
|
1422
|
-
/**
|
|
1423
|
-
* Local files to register as immutable sources before applying proposals.
|
|
1424
|
-
*/
|
|
1425
|
-
sourcePaths?: string[];
|
|
1406
|
+
/**
|
|
1407
|
+
* Metadata key under which a proposal carries the specific claim it is cited
|
|
1408
|
+
* for. The worker sets `metadata[citedClaimKey] = '<the claim>'`; the
|
|
1409
|
+
* claim-grounding driver reads it and checks it against the fetched page text.
|
|
1410
|
+
*/
|
|
1411
|
+
declare const citedClaimKey = "citedClaim";
|
|
1412
|
+
/** Read the cited claim a proposal carries, if any. */
|
|
1413
|
+
declare function citedClaimOf(source: ResearchSourceProposal): string | undefined;
|
|
1414
|
+
/** Attach a cited claim to a proposal (immutably returns a new proposal). */
|
|
1415
|
+
declare function withCitedClaim(source: ResearchSourceProposal, claim: string): ResearchSourceProposal;
|
|
1416
|
+
interface GroundingResult {
|
|
1417
|
+
/** True when the claim is sufficiently present in the page text. */
|
|
1418
|
+
grounded: boolean;
|
|
1419
|
+
/** How the claim matched (or why it didn't). For audit/notes. */
|
|
1420
|
+
mode: 'verbatim' | 'normalized' | 'overlap' | 'absent' | 'empty-claim' | 'empty-text';
|
|
1426
1421
|
/**
|
|
1427
|
-
*
|
|
1428
|
-
*
|
|
1422
|
+
* Fraction of the claim's content words found in the page text. 1 for a
|
|
1423
|
+
* verbatim/normalized hit; the measured overlap otherwise.
|
|
1429
1424
|
*/
|
|
1430
|
-
|
|
1425
|
+
overlap: number;
|
|
1426
|
+
/** Content words present in the claim but NOT in the page text. */
|
|
1427
|
+
missingWords: string[];
|
|
1428
|
+
}
|
|
1429
|
+
interface GroundClaimOptions {
|
|
1431
1430
|
/**
|
|
1432
|
-
*
|
|
1433
|
-
*
|
|
1431
|
+
* Minimum fraction of the claim's content words that must appear in the page
|
|
1432
|
+
* text to count as a close paraphrase when there is no verbatim/normalized
|
|
1433
|
+
* hit. Default 0.7 — a high bar, because a misattribution is exactly a claim
|
|
1434
|
+
* whose specific words the page does not contain.
|
|
1434
1435
|
*/
|
|
1435
|
-
|
|
1436
|
+
minOverlap?: number;
|
|
1436
1437
|
/**
|
|
1437
|
-
*
|
|
1438
|
-
*
|
|
1438
|
+
* Content words shorter than this are ignored (drops "the", "of", "is", …)
|
|
1439
|
+
* and never count toward overlap. Default 3.
|
|
1439
1440
|
*/
|
|
1440
|
-
|
|
1441
|
-
metadata?: Record<string, unknown>;
|
|
1442
|
-
}
|
|
1443
|
-
interface KnowledgeResearchLoopStep {
|
|
1444
|
-
iteration: number;
|
|
1445
|
-
notes?: string;
|
|
1446
|
-
addedSources: SourceRecord[];
|
|
1447
|
-
applied?: ApplyWriteBlocksResult;
|
|
1448
|
-
lintFindings: KnowledgeLintFinding[];
|
|
1449
|
-
validation: ValidateKnowledgeResult;
|
|
1450
|
-
readiness?: EvalKnowledgeBundleBuildResult;
|
|
1451
|
-
event: KnowledgeEvent;
|
|
1452
|
-
done: boolean;
|
|
1453
|
-
metadata?: Record<string, unknown>;
|
|
1454
|
-
}
|
|
1455
|
-
interface RunKnowledgeResearchLoopOptions {
|
|
1456
|
-
root: string;
|
|
1457
|
-
goal: string;
|
|
1458
|
-
maxIterations?: number;
|
|
1459
|
-
actor?: string;
|
|
1460
|
-
strict?: ValidateKnowledgeOptions['strict'];
|
|
1461
|
-
readinessSpecs?: KnowledgeReadinessSpec[];
|
|
1462
|
-
readinessTaskId?: string;
|
|
1463
|
-
readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>;
|
|
1464
|
-
sourceOptions?: Pick<AddSourceOptions, 'adapters' | 'now'>;
|
|
1465
|
-
signal?: AbortSignal;
|
|
1466
|
-
step(context: KnowledgeResearchLoopContext): Promise<KnowledgeResearchLoopDecision> | KnowledgeResearchLoopDecision;
|
|
1467
|
-
onStep?: (step: KnowledgeResearchLoopStep) => Promise<void> | void;
|
|
1468
|
-
}
|
|
1469
|
-
interface KnowledgeResearchLoopResult {
|
|
1470
|
-
root: string;
|
|
1471
|
-
goal: string;
|
|
1472
|
-
iterations: number;
|
|
1473
|
-
done: boolean;
|
|
1474
|
-
index: KnowledgeIndex;
|
|
1475
|
-
lintFindings: KnowledgeLintFinding[];
|
|
1476
|
-
validation: ValidateKnowledgeResult;
|
|
1477
|
-
readiness?: EvalKnowledgeBundleBuildResult;
|
|
1478
|
-
steps: KnowledgeResearchLoopStep[];
|
|
1479
|
-
}
|
|
1480
|
-
type KnowledgeControlLoopState = KnowledgeResearchLoopContext;
|
|
1481
|
-
type KnowledgeControlLoopAction = KnowledgeResearchLoopDecision;
|
|
1482
|
-
type KnowledgeControlLoopActionResult = KnowledgeResearchLoopStep;
|
|
1483
|
-
interface KnowledgeControlLoopAdapterOptions {
|
|
1484
|
-
root: string;
|
|
1485
|
-
goal: string;
|
|
1486
|
-
actor?: string;
|
|
1487
|
-
strict?: ValidateKnowledgeOptions['strict'];
|
|
1488
|
-
readinessSpecs?: KnowledgeReadinessSpec[];
|
|
1489
|
-
readinessTaskId?: string;
|
|
1490
|
-
readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>;
|
|
1491
|
-
sourceOptions?: Pick<AddSourceOptions, 'adapters' | 'now'>;
|
|
1441
|
+
minWordLength?: number;
|
|
1492
1442
|
}
|
|
1493
|
-
type KnowledgeControlLoopAdapter = Pick<ControlRuntimeConfig<KnowledgeControlLoopState, KnowledgeControlLoopAction, KnowledgeControlLoopActionResult, ControlEvalResult>, 'intent' | 'observe' | 'validate' | 'act' | 'shouldStop'>;
|
|
1494
1443
|
/**
|
|
1495
|
-
*
|
|
1496
|
-
*
|
|
1497
|
-
*
|
|
1444
|
+
* THE ORACLE. Is `claim` grounded in `pageText` (the `htmlToText` output of the
|
|
1445
|
+
* page the worker fetched)? Deterministic, no model call:
|
|
1446
|
+
*
|
|
1447
|
+
* 1. verbatim — the claim string appears as-is (case-insensitive).
|
|
1448
|
+
* 2. normalized — the claim appears after collapsing punctuation/whitespace
|
|
1449
|
+
* on both sides (so "5.4x" vs "5.4 x", smart quotes, etc. still match).
|
|
1450
|
+
* 3. overlap — a close paraphrase: at least `minOverlap` of the claim's
|
|
1451
|
+
* substantive content words appear in the page text. A misattributed page
|
|
1452
|
+
* fails here because the SPECIFIC words the claim asserts are absent.
|
|
1453
|
+
*
|
|
1454
|
+
* Returns the match mode, the measured overlap, and the missing content words —
|
|
1455
|
+
* enough for the driver to give a precise rejection reason and for a test/doc to
|
|
1456
|
+
* audit WHY a claim grounded or didn't.
|
|
1498
1457
|
*/
|
|
1499
|
-
declare function
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
summary: string;
|
|
1518
|
-
startedAt: string;
|
|
1519
|
-
finishedAt: string;
|
|
1520
|
-
metadata?: Record<string, JsonValue>;
|
|
1521
|
-
}
|
|
1522
|
-
interface RagPhaseInputBase {
|
|
1523
|
-
goal: string;
|
|
1524
|
-
phases: readonly RagKnowledgeImprovementPhaseResult[];
|
|
1525
|
-
signal?: AbortSignal;
|
|
1526
|
-
}
|
|
1527
|
-
interface RagDiagnosisInput extends RagPhaseInputBase {
|
|
1528
|
-
retrieval?: RunRetrievalImprovementLoopResult;
|
|
1529
|
-
}
|
|
1530
|
-
interface RagKnowledgeAcquisitionInput extends RagPhaseInputBase {
|
|
1531
|
-
retrieval?: RunRetrievalImprovementLoopResult;
|
|
1532
|
-
findings: readonly RagGapFinding[];
|
|
1533
|
-
}
|
|
1534
|
-
interface RagKnowledgeUpdateInput extends RagPhaseInputBase {
|
|
1535
|
-
retrieval?: RunRetrievalImprovementLoopResult;
|
|
1536
|
-
findings: readonly RagGapFinding[];
|
|
1537
|
-
acquisition?: KnowledgeResearchLoopDecision;
|
|
1538
|
-
}
|
|
1539
|
-
interface RagKnowledgeUpdateResult {
|
|
1540
|
-
applied: boolean;
|
|
1541
|
-
summary: string;
|
|
1542
|
-
research?: KnowledgeResearchLoopResult;
|
|
1543
|
-
metadata?: Record<string, JsonValue>;
|
|
1544
|
-
}
|
|
1545
|
-
interface RagAnswerQualityInput extends RagPhaseInputBase {
|
|
1546
|
-
retrieval?: RunRetrievalImprovementLoopResult;
|
|
1547
|
-
findings: readonly RagGapFinding[];
|
|
1548
|
-
acquisition?: KnowledgeResearchLoopDecision;
|
|
1549
|
-
knowledgeUpdate?: RagKnowledgeUpdateResult;
|
|
1550
|
-
}
|
|
1551
|
-
interface RagAnswerQualityResult {
|
|
1552
|
-
passed: boolean;
|
|
1553
|
-
metrics: Record<string, number>;
|
|
1554
|
-
findings?: readonly RagGapFinding[];
|
|
1555
|
-
metadata?: Record<string, JsonValue>;
|
|
1556
|
-
}
|
|
1557
|
-
interface RagPromotionInput extends RagPhaseInputBase {
|
|
1558
|
-
retrieval?: RunRetrievalImprovementLoopResult;
|
|
1559
|
-
findings: readonly RagGapFinding[];
|
|
1560
|
-
acquisition?: KnowledgeResearchLoopDecision;
|
|
1561
|
-
knowledgeUpdate?: RagKnowledgeUpdateResult;
|
|
1562
|
-
answerQuality?: RagAnswerQualityResult;
|
|
1563
|
-
}
|
|
1564
|
-
interface RagPromotionResult {
|
|
1565
|
-
promoted: boolean;
|
|
1566
|
-
reason: string;
|
|
1567
|
-
metadata?: Record<string, JsonValue>;
|
|
1568
|
-
}
|
|
1569
|
-
interface RagKnowledgeResearchOptions extends Omit<RunKnowledgeResearchLoopOptions, 'goal' | 'signal' | 'step'> {
|
|
1570
|
-
goal?: string;
|
|
1571
|
-
step?: RunKnowledgeResearchLoopOptions['step'];
|
|
1572
|
-
}
|
|
1573
|
-
interface RunRagKnowledgeImprovementLoopOptions {
|
|
1574
|
-
goal: string;
|
|
1575
|
-
retrieval?: RunRetrievalImprovementLoopOptions;
|
|
1576
|
-
diagnose?: (input: RagDiagnosisInput) => MaybePromise$1<readonly RagGapFinding[]>;
|
|
1577
|
-
acquireKnowledge?: (input: RagKnowledgeAcquisitionInput) => MaybePromise$1<KnowledgeResearchLoopDecision>;
|
|
1578
|
-
knowledgeResearch?: RagKnowledgeResearchOptions;
|
|
1579
|
-
updateKnowledge?: (input: RagKnowledgeUpdateInput) => MaybePromise$1<RagKnowledgeUpdateResult>;
|
|
1580
|
-
evaluateAnswers?: (input: RagAnswerQualityInput) => MaybePromise$1<RagAnswerQualityResult>;
|
|
1581
|
-
promote?: (input: RagPromotionInput) => MaybePromise$1<RagPromotionResult>;
|
|
1582
|
-
enabledPhases?: readonly RagKnowledgeImprovementPhase[];
|
|
1583
|
-
requiredPhases?: readonly RagKnowledgeImprovementPhase[];
|
|
1584
|
-
signal?: AbortSignal;
|
|
1585
|
-
now?: () => Date;
|
|
1586
|
-
}
|
|
1587
|
-
interface RunRagKnowledgeImprovementLoopResult {
|
|
1588
|
-
goal: string;
|
|
1589
|
-
phases: readonly RagKnowledgeImprovementPhaseResult[];
|
|
1590
|
-
retrieval?: RunRetrievalImprovementLoopResult;
|
|
1591
|
-
findings: readonly RagGapFinding[];
|
|
1592
|
-
acquisition?: KnowledgeResearchLoopDecision;
|
|
1593
|
-
knowledgeUpdate?: RagKnowledgeUpdateResult;
|
|
1594
|
-
answerQuality?: RagAnswerQualityResult;
|
|
1595
|
-
promotion?: RagPromotionResult;
|
|
1596
|
-
}
|
|
1597
|
-
type MaybePromise$1<T> = T | Promise<T>;
|
|
1598
|
-
declare function runRagKnowledgeImprovementLoop(options: RunRagKnowledgeImprovementLoopOptions): Promise<RunRagKnowledgeImprovementLoopResult>;
|
|
1599
|
-
|
|
1600
|
-
type RagEvalProvider = 'agent-knowledge' | 'ragas' | 'deepeval' | 'trulens' | 'ragchecker' | 'custom';
|
|
1601
|
-
type RagEvalMetricKey = 'context_precision' | 'context_recall' | 'context_relevance' | 'context_sufficiency' | 'faithfulness' | 'groundedness' | 'answer_relevance' | 'answer_correctness' | 'citation_support' | 'abstention' | 'unsupported_answer_rate';
|
|
1602
|
-
type RagEvalSlice = 'known-answer' | 'paraphrase' | 'distractor' | 'freshness' | 'multi-source' | 'unanswerable' | 'long-tail' | 'custom';
|
|
1603
|
-
interface RagEvalContext {
|
|
1604
|
-
id: string;
|
|
1605
|
-
text: string;
|
|
1606
|
-
rank?: number;
|
|
1607
|
-
pageId?: string;
|
|
1608
|
-
sourceId?: string;
|
|
1609
|
-
anchorId?: string;
|
|
1610
|
-
stale?: boolean;
|
|
1611
|
-
metadata?: Record<string, JsonValue>;
|
|
1458
|
+
declare function groundClaimInText(claim: string, pageText: string, options?: GroundClaimOptions): GroundingResult;
|
|
1459
|
+
interface ClaimGroundingDriverOptions extends GroundClaimOptions {
|
|
1460
|
+
/**
|
|
1461
|
+
* Optional second verifier to compose AFTER grounding passes. When set, a
|
|
1462
|
+
* source must BOTH ground its claim AND pass this verifier (e.g. the LLM
|
|
1463
|
+
* relevance driver's `verifySource`). Lets the loop reject off-topic AND
|
|
1464
|
+
* misattributed sources in one driver. Omit for the pure, zero-inference
|
|
1465
|
+
* grounding gate.
|
|
1466
|
+
*/
|
|
1467
|
+
relevanceVerifier?: (source: ResearchSourceProposal, ctx: SourceVerificationContext) => Promise<SourceVerdict> | SourceVerdict;
|
|
1468
|
+
/**
|
|
1469
|
+
* What to do when a proposal carries NO cited claim. `'reject'` (default) is
|
|
1470
|
+
* fail-closed: in claim-grounding mode every source must declare what it is
|
|
1471
|
+
* cited for, so an un-annotated source is treated as ungrounded. `'accept'`
|
|
1472
|
+
* lets un-annotated sources through to the relevance verifier (if any) —
|
|
1473
|
+
* useful when mixing annotated and legacy proposals.
|
|
1474
|
+
*/
|
|
1475
|
+
onMissingClaim?: 'reject' | 'accept';
|
|
1612
1476
|
}
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1477
|
+
/**
|
|
1478
|
+
* A `ResearchDriver`-shaped verifier (just the `verifySource` arm) that gates on
|
|
1479
|
+
* CLAIM GROUNDING: it rejects a source whose cited claim is not present in its
|
|
1480
|
+
* fetched page text — a misattributed / fabricated citation — and (optionally)
|
|
1481
|
+
* composes a relevance verifier after grounding passes.
|
|
1482
|
+
*
|
|
1483
|
+
* The returned function matches `ResearchDriver['verifySource']`, so it drops
|
|
1484
|
+
* straight into `runVerifiedResearchLoop` as `{ verifySource: createClaimGroundingVerifier(...) }`.
|
|
1485
|
+
*/
|
|
1486
|
+
declare function createClaimGroundingVerifier(options?: ClaimGroundingDriverOptions): (source: ResearchSourceProposal, ctx: SourceVerificationContext) => Promise<SourceVerdict>;
|
|
1487
|
+
interface WorkerClaimDecorationOptions {
|
|
1488
|
+
router?: RouterClient;
|
|
1489
|
+
router_options?: TangleRouterOptions;
|
|
1490
|
+
/** Max output tokens for the claim-extraction call. Default 1200 (glm floor). */
|
|
1491
|
+
maxTokens?: number;
|
|
1622
1492
|
}
|
|
1623
|
-
|
|
1493
|
+
/**
|
|
1494
|
+
* Ask an LLM to state, for one source, the single specific factual claim a
|
|
1495
|
+
* researcher would cite THIS page for toward the goal. Used to DECORATE the
|
|
1496
|
+
* sources a relevance-only worker produced with the claim a citation would make,
|
|
1497
|
+
* so the claim-grounding verifier has something executable to check. The model
|
|
1498
|
+
* is told to ground the claim in the provided excerpt; the verifier then checks
|
|
1499
|
+
* it against the FULL page text independently — the model does not get to mark
|
|
1500
|
+
* its own homework.
|
|
1501
|
+
*
|
|
1502
|
+
* Returns the proposal annotated via `withCitedClaim`, or the original proposal
|
|
1503
|
+
* unchanged if the model returns nothing parseable (the verifier's
|
|
1504
|
+
* `onMissingClaim` policy then decides).
|
|
1505
|
+
*/
|
|
1506
|
+
declare function createClaimDecorator(options?: WorkerClaimDecorationOptions): (source: ResearchSourceProposal, goal: string) => Promise<ResearchSourceProposal>;
|
|
1507
|
+
|
|
1508
|
+
/**
|
|
1509
|
+
* The SINGLE-AGENT COLLECTION driver — the blind-collection baseline (Arm A).
|
|
1510
|
+
*
|
|
1511
|
+
* This is the honest null the depth A/B is measured against. The other drivers
|
|
1512
|
+
* spend extra inference to do something differentiated:
|
|
1513
|
+
* - `createVerifyingResearchDriver` runs an LLM gate per source (Arm B),
|
|
1514
|
+
* - `createResearchDrivingDriver` extracts claims, tracks corroboration, and
|
|
1515
|
+
* synthesizes deep follow-up questions to drive depth (Arm C).
|
|
1516
|
+
*
|
|
1517
|
+
* This driver does NONE of that. It is a pass-through: it accepts every source
|
|
1518
|
+
* the worker proposes and contributes no research, no gating, and no steering of
|
|
1519
|
+
* its own. The loop still dedups exact-uri duplicates before calling
|
|
1520
|
+
* `verifySource` (that is the loop's job, not the driver's), and the default
|
|
1521
|
+
* `foldGaps` (a plain bulleted list of the still-open readiness gaps) still folds
|
|
1522
|
+
* the gaps into the worker's next prompt — so the worker keeps researching, but
|
|
1523
|
+
* NOTHING intelligent sits between the worker and the knowledge base.
|
|
1524
|
+
*
|
|
1525
|
+
* In other words: ONE agent (the worker) collects sources round after round, and
|
|
1526
|
+
* the "driver" is an inert rubber stamp. That is exactly what "single-agent
|
|
1527
|
+
* collection" means — the topology with zero coordinator intelligence — so its
|
|
1528
|
+
* material-facts score is the floor every other arm must beat to justify its
|
|
1529
|
+
* extra inference cost.
|
|
1530
|
+
*
|
|
1531
|
+
* It adds NO router calls of its own: `verifySource` is a synchronous accept and
|
|
1532
|
+
* `foldGaps` is omitted so the loop uses its built-in gap list. So Arm A's cost
|
|
1533
|
+
* is the worker's cost alone — the cleanest possible blind-collection baseline.
|
|
1534
|
+
*/
|
|
1535
|
+
|
|
1536
|
+
/**
|
|
1537
|
+
* Build the single-agent collection driver. Accepts every source; never gates,
|
|
1538
|
+
* never researches, never steers beyond the loop's default open-gap list. The
|
|
1539
|
+
* worker is the only agent that thinks.
|
|
1540
|
+
*/
|
|
1541
|
+
declare function createCollectionResearchDriver(): ResearchDriver;
|
|
1542
|
+
|
|
1543
|
+
interface DiscoveryTask {
|
|
1624
1544
|
id: string;
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
interface RagRequiredContext {
|
|
1630
|
-
id?: string;
|
|
1631
|
-
text?: string;
|
|
1632
|
-
pageId?: string;
|
|
1633
|
-
sourceId?: string;
|
|
1634
|
-
anchorId?: string;
|
|
1635
|
-
}
|
|
1636
|
-
interface RagAnswerEvalScenario extends Scenario {
|
|
1637
|
-
kind: 'rag-answer-eval';
|
|
1638
|
-
query: string;
|
|
1639
|
-
referenceAnswer?: string;
|
|
1640
|
-
expectedClaims?: readonly string[];
|
|
1641
|
-
forbiddenClaims?: readonly string[];
|
|
1642
|
-
requiredContext?: readonly RagRequiredContext[];
|
|
1643
|
-
unanswerable?: boolean;
|
|
1644
|
-
requireCitations?: boolean;
|
|
1645
|
-
slices?: readonly RagEvalSlice[];
|
|
1646
|
-
thresholds?: Partial<Record<RagEvalMetricKey, number>>;
|
|
1647
|
-
}
|
|
1648
|
-
interface ExternalRagEvalScore {
|
|
1649
|
-
provider: RagEvalProvider | string;
|
|
1650
|
-
scores: Record<string, number>;
|
|
1651
|
-
reasons?: Record<string, string>;
|
|
1652
|
-
metadata?: Record<string, JsonValue>;
|
|
1545
|
+
goal: string;
|
|
1546
|
+
query?: string;
|
|
1547
|
+
sourceHints?: string[];
|
|
1548
|
+
metadata?: Record<string, unknown>;
|
|
1653
1549
|
}
|
|
1654
|
-
interface
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
claims?:
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
metadata?: Record<string,
|
|
1550
|
+
interface DiscoveryResult {
|
|
1551
|
+
taskId: string;
|
|
1552
|
+
summary: string;
|
|
1553
|
+
sourceUris?: string[];
|
|
1554
|
+
claims?: Array<{
|
|
1555
|
+
text: string;
|
|
1556
|
+
sourceUri?: string;
|
|
1557
|
+
confidence?: number;
|
|
1558
|
+
}>;
|
|
1559
|
+
followUpTasks?: DiscoveryTask[];
|
|
1560
|
+
metadata?: Record<string, unknown>;
|
|
1665
1561
|
}
|
|
1666
|
-
interface
|
|
1667
|
-
|
|
1668
|
-
composite: number;
|
|
1669
|
-
passed: boolean;
|
|
1670
|
-
findings: readonly RagGapFinding[];
|
|
1671
|
-
claimCount: number;
|
|
1672
|
-
supportedClaimCount: number;
|
|
1673
|
-
citedClaimCount: number;
|
|
1674
|
-
supportedCitationCount: number;
|
|
1675
|
-
matchedRequiredContextCount: number;
|
|
1676
|
-
requiredContextCount: number;
|
|
1677
|
-
providerScores: Record<string, Record<RagEvalMetricKey, number>>;
|
|
1562
|
+
interface KnowledgeDiscoveryWorker {
|
|
1563
|
+
run(task: DiscoveryTask, signal?: AbortSignal): Promise<DiscoveryResult> | DiscoveryResult;
|
|
1678
1564
|
}
|
|
1679
|
-
interface
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
minClaimSupport?: number;
|
|
1565
|
+
interface KnowledgeDiscoveryDispatcher {
|
|
1566
|
+
dispatch(tasks: DiscoveryTask[], options?: {
|
|
1567
|
+
concurrency?: number;
|
|
1568
|
+
signal?: AbortSignal;
|
|
1569
|
+
}): Promise<DiscoveryResult[]>;
|
|
1685
1570
|
}
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1571
|
+
type DiscoveryLoopStopReason = 'complete' | 'max-rounds' | 'max-tasks' | 'aborted';
|
|
1572
|
+
interface DiscoveryLoopRound {
|
|
1573
|
+
round: number;
|
|
1574
|
+
tasks: DiscoveryTask[];
|
|
1575
|
+
results: DiscoveryResult[];
|
|
1576
|
+
queuedFollowUps: DiscoveryTask[];
|
|
1689
1577
|
}
|
|
1690
|
-
interface
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1578
|
+
interface DiscoveryLoopResult {
|
|
1579
|
+
stopReason: DiscoveryLoopStopReason;
|
|
1580
|
+
tasksDispatched: number;
|
|
1581
|
+
results: DiscoveryResult[];
|
|
1582
|
+
rounds: DiscoveryLoopRound[];
|
|
1583
|
+
/** Tasks retained, not dropped, when a configured limit stops the loop. */
|
|
1584
|
+
pendingTasks: DiscoveryTask[];
|
|
1585
|
+
/** Structurally identical task identities ignored to prevent cycles. */
|
|
1586
|
+
duplicateTaskIds: string[];
|
|
1696
1587
|
}
|
|
1697
|
-
interface
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1588
|
+
interface RunDiscoveryLoopOptions {
|
|
1589
|
+
dispatcher: KnowledgeDiscoveryDispatcher;
|
|
1590
|
+
initialTasks: readonly DiscoveryTask[];
|
|
1591
|
+
/** Maximum follow-up depth including the initial dispatch. Default 3. */
|
|
1592
|
+
maxRounds?: number;
|
|
1593
|
+
/** Maximum tasks dispatched across all rounds. Default 24. */
|
|
1594
|
+
maxTasks?: number;
|
|
1595
|
+
/** Forwarded to the dispatcher. Default 4. */
|
|
1596
|
+
concurrency?: number;
|
|
1704
1597
|
signal?: AbortSignal;
|
|
1598
|
+
onRound?: (round: DiscoveryLoopRound) => Promise<void> | void;
|
|
1705
1599
|
}
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1600
|
+
/**
|
|
1601
|
+
* Dispatch discovery tasks and recursively pursue worker-proposed follow-ups.
|
|
1602
|
+
*
|
|
1603
|
+
* The runner owns only bounded scheduling and accounting. Workers own search,
|
|
1604
|
+
* source verification, and domain-specific candidate shapes.
|
|
1605
|
+
*/
|
|
1606
|
+
declare function runDiscoveryLoop(options: RunDiscoveryLoopOptions): Promise<DiscoveryLoopResult>;
|
|
1607
|
+
declare function createLocalDiscoveryDispatcher(worker: KnowledgeDiscoveryWorker): KnowledgeDiscoveryDispatcher;
|
|
1608
|
+
|
|
1609
|
+
interface KnowledgeEventQuery {
|
|
1610
|
+
type?: KnowledgeEventType;
|
|
1611
|
+
target?: string;
|
|
1612
|
+
limit?: number;
|
|
1613
|
+
}
|
|
1614
|
+
declare function createKnowledgeEvent(input: {
|
|
1615
|
+
type: KnowledgeEventType;
|
|
1616
|
+
actor?: string;
|
|
1617
|
+
target?: string;
|
|
1618
|
+
metadata?: Record<string, unknown>;
|
|
1619
|
+
now?: () => Date;
|
|
1620
|
+
}): KnowledgeEvent;
|
|
1621
|
+
|
|
1622
|
+
/**
|
|
1623
|
+
* Knowledge freshness store: tracks when each `(workspaceId, sourceId)` pair
|
|
1624
|
+
* was last successfully refreshed, and reports staleness against a TTL.
|
|
1625
|
+
*
|
|
1626
|
+
* The contract is intentionally minimal — just enough to drive a cron loop:
|
|
1627
|
+
*
|
|
1628
|
+
* ```ts
|
|
1629
|
+
* const store = createFileSystemFreshnessStore({ root: '.agent-knowledge' })
|
|
1630
|
+
* for (const source of sources) {
|
|
1631
|
+
* if (await store.stale({ workspaceId, sourceId: source.id, ttlMs: DAY })) {
|
|
1632
|
+
* const fragments = await source.fetch({ cacheDir })
|
|
1633
|
+
* await persistFragments(fragments)
|
|
1634
|
+
* await store.mark({ workspaceId, sourceId: source.id, when: new Date() })
|
|
1635
|
+
* }
|
|
1636
|
+
* }
|
|
1637
|
+
* ```
|
|
1638
|
+
*
|
|
1639
|
+
* Per-tenant isolation is enforced by `workspaceId` keying — there is no
|
|
1640
|
+
* global mutable state across workspaces.
|
|
1641
|
+
*
|
|
1642
|
+
* Two adapters ship in-package:
|
|
1643
|
+
*
|
|
1644
|
+
* - `createFileSystemFreshnessStore` — JSON file under the knowledge root,
|
|
1645
|
+
* mirrors the layout convention already used by `sources.json`.
|
|
1646
|
+
* - `createD1FreshnessStoreStub` — adapter scaffold for Cloudflare D1 /
|
|
1647
|
+
* Postgres. Production consumers should implement the `D1Adapter`
|
|
1648
|
+
* interface inside their own app; this stub exists to anchor the shape.
|
|
1649
|
+
*
|
|
1650
|
+
* @stable contract — interface is frozen at 0.x within this major.
|
|
1651
|
+
* @stable filesystem adapter
|
|
1652
|
+
* @experimental D1 stub — interface will evolve as real consumers wire it.
|
|
1653
|
+
*/
|
|
1654
|
+
/** Identity for one freshness record. */
|
|
1655
|
+
interface FreshnessKey {
|
|
1656
|
+
workspaceId: string;
|
|
1657
|
+
sourceId: string;
|
|
1711
1658
|
}
|
|
1712
|
-
|
|
1659
|
+
/** TTL bound for staleness checks. */
|
|
1660
|
+
interface FreshnessTtl extends FreshnessKey {
|
|
1661
|
+
/** Milliseconds — `Date.now() - last() > ttlMs` ⇒ stale. */
|
|
1662
|
+
ttlMs: number;
|
|
1663
|
+
/** Injected clock for deterministic tests; defaults to system time. */
|
|
1713
1664
|
now?: Date;
|
|
1714
|
-
strict?: boolean;
|
|
1715
|
-
minCitationRate?: number;
|
|
1716
|
-
maxStaleSourceRate?: number;
|
|
1717
1665
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
citation_rate: number;
|
|
1724
|
-
source_backed_page_rate: number;
|
|
1725
|
-
stale_source_rate: number;
|
|
1726
|
-
duplicate_source_hash_rate: number;
|
|
1727
|
-
lint_error_count: number;
|
|
1728
|
-
lint_warning_count: number;
|
|
1729
|
-
};
|
|
1730
|
-
findings: readonly RagGapFinding[];
|
|
1666
|
+
/** Mark argument. */
|
|
1667
|
+
interface FreshnessMark extends FreshnessKey {
|
|
1668
|
+
when: Date;
|
|
1669
|
+
/** Optional content hash captured at refresh time; aids debugging. */
|
|
1670
|
+
contentHash?: string;
|
|
1731
1671
|
}
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
response: string;
|
|
1742
|
-
retrieved_contexts: string[];
|
|
1743
|
-
reference: string | undefined;
|
|
1744
|
-
reference_contexts: string[];
|
|
1745
|
-
}[];
|
|
1746
|
-
declare function toDeepEvalTestCases(cases: readonly RagAnswerEvalCase[]): {
|
|
1747
|
-
input: string;
|
|
1748
|
-
actual_output: string;
|
|
1749
|
-
expected_output: string | undefined;
|
|
1750
|
-
retrieval_context: string[];
|
|
1751
|
-
context: string[];
|
|
1752
|
-
}[];
|
|
1753
|
-
declare function toTruLensRecords(cases: readonly RagAnswerEvalCase[]): {
|
|
1754
|
-
input: string;
|
|
1755
|
-
output: string;
|
|
1756
|
-
context: string;
|
|
1757
|
-
}[];
|
|
1758
|
-
declare function toRagCheckerRecords(cases: readonly RagAnswerEvalCase[]): {
|
|
1759
|
-
query_id: string;
|
|
1760
|
-
query: string;
|
|
1761
|
-
gt_answer: string | undefined;
|
|
1762
|
-
response: string;
|
|
1763
|
-
retrieved_context: {
|
|
1764
|
-
doc_id: string;
|
|
1765
|
-
text: string;
|
|
1766
|
-
}[];
|
|
1767
|
-
claims: string[];
|
|
1768
|
-
}[];
|
|
1769
|
-
declare function scoreKnowledgeBaseIndex(index: KnowledgeIndex, options?: KnowledgeBaseQualityOptions): KnowledgeBaseQualityReport;
|
|
1770
|
-
|
|
1771
|
-
type KnowledgeImprovementStatus = 'running' | 'candidate-ready' | 'promoted' | 'rejected' | 'blocked';
|
|
1772
|
-
interface KnowledgeImprovementMetric {
|
|
1773
|
-
score: number;
|
|
1774
|
-
passed: boolean;
|
|
1775
|
-
dimensions?: Record<string, number>;
|
|
1776
|
-
notes?: string;
|
|
1672
|
+
interface KnowledgeFreshnessStore {
|
|
1673
|
+
/** Last refresh time, or null if never refreshed. */
|
|
1674
|
+
last(key: FreshnessKey): Promise<Date | null>;
|
|
1675
|
+
/** Record a successful refresh. */
|
|
1676
|
+
mark(input: FreshnessMark): Promise<void>;
|
|
1677
|
+
/** True iff `last(key)` is null or older than `ttlMs`. */
|
|
1678
|
+
stale(input: FreshnessTtl): Promise<boolean>;
|
|
1679
|
+
/** All records for a workspace — useful for dashboards / debugging. */
|
|
1680
|
+
list(workspaceId: string): Promise<FreshnessRecord[]>;
|
|
1777
1681
|
}
|
|
1778
|
-
interface
|
|
1779
|
-
|
|
1780
|
-
|
|
1682
|
+
interface FreshnessRecord {
|
|
1683
|
+
workspaceId: string;
|
|
1684
|
+
sourceId: string;
|
|
1685
|
+
lastRefreshedAt: string;
|
|
1686
|
+
contentHash?: string;
|
|
1687
|
+
}
|
|
1688
|
+
interface FileSystemFreshnessStoreOptions {
|
|
1689
|
+
/**
|
|
1690
|
+
* Knowledge root. The store writes to `<root>/.agent-knowledge/freshness.json`,
|
|
1691
|
+
* mirroring the convention used by `sources.json`.
|
|
1692
|
+
*/
|
|
1781
1693
|
root: string;
|
|
1782
|
-
baselineRoot: string;
|
|
1783
|
-
candidateRoot: string;
|
|
1784
|
-
baselineIndex: KnowledgeIndex;
|
|
1785
|
-
candidateIndex: KnowledgeIndex;
|
|
1786
|
-
baseHash: string;
|
|
1787
|
-
candidateHash: string;
|
|
1788
|
-
validation: ValidateKnowledgeResult;
|
|
1789
|
-
readiness?: EvalKnowledgeBundleBuildResult;
|
|
1790
|
-
kbQuality: KnowledgeBaseQualityReport;
|
|
1791
|
-
lifecycle?: RunRagKnowledgeImprovementLoopResult;
|
|
1792
|
-
signal?: AbortSignal;
|
|
1793
1694
|
}
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1695
|
+
/**
|
|
1696
|
+
* Filesystem-backed implementation. Single JSON file per knowledge root,
|
|
1697
|
+
* indexed by `${workspaceId}::${sourceId}`. Reads parse on every call —
|
|
1698
|
+
* cron tick rate is well below the cost of one JSON parse.
|
|
1699
|
+
*
|
|
1700
|
+
* Writes share the package-wide filesystem lock, so multiple workers cannot
|
|
1701
|
+
* overwrite one another or run through an interrupted knowledge promotion.
|
|
1702
|
+
*/
|
|
1703
|
+
declare function createFileSystemFreshnessStore(options: FileSystemFreshnessStoreOptions): KnowledgeFreshnessStore;
|
|
1704
|
+
/**
|
|
1705
|
+
* D1 / Postgres adapter scaffold. Production consumers implement
|
|
1706
|
+
* `D1Adapter` against their own driver (better-sqlite3, postgres,
|
|
1707
|
+
* Cloudflare D1 binding, ...). This factory wires the adapter to the
|
|
1708
|
+
* `KnowledgeFreshnessStore` interface.
|
|
1709
|
+
*
|
|
1710
|
+
* The expected schema:
|
|
1711
|
+
*
|
|
1712
|
+
* ```sql
|
|
1713
|
+
* CREATE TABLE knowledge_freshness (
|
|
1714
|
+
* workspace_id TEXT NOT NULL,
|
|
1715
|
+
* source_id TEXT NOT NULL,
|
|
1716
|
+
* last_refreshed_at TEXT NOT NULL,
|
|
1717
|
+
* content_hash TEXT,
|
|
1718
|
+
* PRIMARY KEY (workspace_id, source_id)
|
|
1719
|
+
* );
|
|
1720
|
+
* ```
|
|
1721
|
+
*/
|
|
1722
|
+
interface D1Adapter {
|
|
1723
|
+
get(workspaceId: string, sourceId: string): Promise<FreshnessRecord | null>;
|
|
1724
|
+
upsert(record: FreshnessRecord): Promise<void>;
|
|
1725
|
+
listByWorkspace(workspaceId: string): Promise<FreshnessRecord[]>;
|
|
1726
|
+
}
|
|
1727
|
+
declare function createD1FreshnessStoreStub(adapter: D1Adapter): KnowledgeFreshnessStore;
|
|
1728
|
+
|
|
1729
|
+
interface ParsedFrontmatter {
|
|
1730
|
+
frontmatter: Record<string, unknown>;
|
|
1731
|
+
body: string;
|
|
1732
|
+
}
|
|
1733
|
+
declare function parseFrontmatter(content: string): ParsedFrontmatter;
|
|
1734
|
+
declare function formatFrontmatter(frontmatter: Record<string, unknown>, body: string): string;
|
|
1735
|
+
|
|
1736
|
+
declare function buildKnowledgeGraph(pages: KnowledgePage[]): KnowledgeGraph;
|
|
1737
|
+
|
|
1738
|
+
declare function sha256(text: string): string;
|
|
1739
|
+
declare function slugify(input: string): string;
|
|
1740
|
+
declare function stableId(prefix: string, content: string): string;
|
|
1741
|
+
|
|
1742
|
+
declare function buildKnowledgeIndex(root: string): Promise<KnowledgeIndex>;
|
|
1743
|
+
declare function writeKnowledgeIndex(root: string): Promise<KnowledgeIndex>;
|
|
1744
|
+
|
|
1745
|
+
interface KnowledgeInspection {
|
|
1746
|
+
pageCount: number;
|
|
1747
|
+
sourceCount: number;
|
|
1748
|
+
expiredSourceCount: number;
|
|
1749
|
+
staleSourceCount: number;
|
|
1750
|
+
edgeCount: number;
|
|
1798
1751
|
findingCount: number;
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1752
|
+
blockingFindingCount: number;
|
|
1753
|
+
topPages: Array<{
|
|
1754
|
+
path: string;
|
|
1755
|
+
title: string;
|
|
1756
|
+
degree: number;
|
|
1757
|
+
sources: number;
|
|
1758
|
+
}>;
|
|
1759
|
+
sourceFreshness: SourceFreshnessInspection[];
|
|
1760
|
+
findings: KnowledgeLintFinding[];
|
|
1802
1761
|
}
|
|
1803
|
-
interface
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
createdAt: string;
|
|
1811
|
-
updatedAt: string;
|
|
1812
|
-
validation?: ValidateKnowledgeResult;
|
|
1813
|
-
kbQuality?: KnowledgeBaseQualityReport;
|
|
1814
|
-
readinessBlockingMissing?: number;
|
|
1815
|
-
evaluation?: KnowledgeImprovementMetric;
|
|
1816
|
-
lifecycle?: readonly KnowledgeImprovementLifecycleRecord[];
|
|
1817
|
-
retrievalWinnerConfig?: RetrievalConfig;
|
|
1818
|
-
answerQuality?: RagAnswerQualityResult;
|
|
1819
|
-
promotionDecision?: RagPromotionResult;
|
|
1820
|
-
notes?: string;
|
|
1762
|
+
interface SourceFreshnessInspection {
|
|
1763
|
+
id: string;
|
|
1764
|
+
title?: string;
|
|
1765
|
+
uri: string;
|
|
1766
|
+
status: 'fresh' | 'expired' | 'unknown';
|
|
1767
|
+
validUntil?: string;
|
|
1768
|
+
lastVerifiedAt?: string;
|
|
1821
1769
|
}
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1770
|
+
declare function inspectKnowledgeIndex(index: KnowledgeIndex, options?: {
|
|
1771
|
+
now?: Date;
|
|
1772
|
+
}): KnowledgeInspection;
|
|
1773
|
+
interface KnowledgeExplanation {
|
|
1774
|
+
target: string;
|
|
1775
|
+
page?: KnowledgePage;
|
|
1776
|
+
sources: Array<{
|
|
1777
|
+
id: string;
|
|
1778
|
+
title?: string;
|
|
1779
|
+
uri: string;
|
|
1780
|
+
}>;
|
|
1781
|
+
links: string[];
|
|
1782
|
+
inbound: string[];
|
|
1783
|
+
related: Array<{
|
|
1784
|
+
path: string;
|
|
1785
|
+
title: string;
|
|
1786
|
+
score: number;
|
|
1787
|
+
}>;
|
|
1788
|
+
}
|
|
1789
|
+
declare function explainKnowledgeTarget(index: KnowledgeIndex, target: string): KnowledgeExplanation;
|
|
1790
|
+
|
|
1791
|
+
/**
|
|
1792
|
+
* HELD-OUT INVESTMENT-RESEARCH EVAL SET.
|
|
1793
|
+
*
|
|
1794
|
+
* The point of this file is the same FIREWALL the deep-question exam uses
|
|
1795
|
+
* (`tests/loops/held-out-exam.ts`): the material facts and their checkable
|
|
1796
|
+
* fragments are NEVER shown to a research loop. A loop is told only the company
|
|
1797
|
+
* + ticker + a research-as-of CUTOFF date, and asked to write an investment
|
|
1798
|
+
* thesis. AFTER it finishes, we grade the thesis it produced against THESE
|
|
1799
|
+
* facts — facts it never saw — so a high score is thesis QUALITY (it surfaced
|
|
1800
|
+
* the buried, material, non-obvious drivers) and not teaching-to-the-test.
|
|
1801
|
+
*
|
|
1802
|
+
* Each fact is a DEPTH fact by construction: a single ticker / company-name web
|
|
1803
|
+
* search does NOT surface it. They are the things buried in the filings or
|
|
1804
|
+
* knowable from then-available primary sources that a thorough analyst flags and
|
|
1805
|
+
* a one-shot search misses — customer/revenue/deposit concentration, a debt
|
|
1806
|
+
* maturity wall, a margin-trend reversal, a governance / related-party item, a
|
|
1807
|
+
* specific competitive or regulatory risk, an off-balance-sheet loss.
|
|
1808
|
+
*
|
|
1809
|
+
* THREE HARD RULES, enforced by how the data was gathered (see
|
|
1810
|
+
* docs/eval/investment-material-facts.md for the per-item provenance + the
|
|
1811
|
+
* curation-bias disclosure):
|
|
1812
|
+
*
|
|
1813
|
+
* 1. SPECIFIC + CHECKABLE. Each fact carries `expected` keyword groups — the
|
|
1814
|
+
* specific number / name / phrase — so a deterministic, model-free
|
|
1815
|
+
* substring grader (`gradeFactAgainstText`) can score "did the thesis
|
|
1816
|
+
* surface it". $0, reproducible, and it cannot leak the answer key into a
|
|
1817
|
+
* model the loop could observe.
|
|
1818
|
+
*
|
|
1819
|
+
* 2. DERIVED FROM REAL FETCHED EVIDENCE. Every fact records the primary source
|
|
1820
|
+
* it came from (`sourceUrl`, an SEC EDGAR 10-K) and the literal `evidence`
|
|
1821
|
+
* value read out of that document. Nothing here is invented; an item that
|
|
1822
|
+
* could not be independently sourced was DROPPED, not guessed (the drop log
|
|
1823
|
+
* is in the doc).
|
|
1824
|
+
*
|
|
1825
|
+
* 3. KNOWABLE AT THE CUTOFF. Every fact was disclosed in, or computable from, a
|
|
1826
|
+
* document available on or before the company's `cutoff` date. Post-cutoff
|
|
1827
|
+
* hindsight (the eventual bankruptcy / collapse) is NOT a checklist item —
|
|
1828
|
+
* it is recorded separately as `knownOutcome`, purely for the reader, and is
|
|
1829
|
+
* never graded.
|
|
1830
|
+
*
|
|
1831
|
+
* Grading mirrors the deep-question exam exactly: a fact is SURFACED when the
|
|
1832
|
+
* thesis text contains at least `minGroups` of its expected groups; a group is
|
|
1833
|
+
* satisfied when ANY of its `anyOf` fragments appears (case-insensitive
|
|
1834
|
+
* substring), so a faithful thesis phrased in its own words still grades as a
|
|
1835
|
+
* hit. `anyOf` groups model synonyms; the load-bearing tokens are the specific
|
|
1836
|
+
* numbers / names.
|
|
1837
|
+
*/
|
|
1838
|
+
/** A required answer component: satisfied when any synonym fragment is present. */
|
|
1839
|
+
interface ExpectedGroup {
|
|
1840
|
+
/** Human label for the component (for the doc / audit). */
|
|
1841
|
+
label: string;
|
|
1842
|
+
/** Case-insensitive substring fragments; any one present satisfies the group. */
|
|
1843
|
+
anyOf: string[];
|
|
1835
1844
|
}
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1845
|
+
/** Lens the fact belongs to — so a set can be checked for category coverage. */
|
|
1846
|
+
type MaterialFactLens = 'concentration' | 'leverage' | 'margin-trend' | 'liquidity' | 'capital-return' | 'governance' | 'off-balance-sheet' | 'regulatory';
|
|
1847
|
+
/** One held-out material fact with a checkable expected answer + its provenance. */
|
|
1848
|
+
interface MaterialFact {
|
|
1849
|
+
/** Stable id, `ticker/fN`. */
|
|
1850
|
+
id: string;
|
|
1851
|
+
/** Which analyst lens this fact exercises. For coverage + the doc. */
|
|
1852
|
+
lens: MaterialFactLens;
|
|
1853
|
+
/**
|
|
1854
|
+
* The material fact, in plain words — for the doc/audit. NEVER shown to a loop.
|
|
1855
|
+
* This is the thing a thorough analyst would flag and a ticker search misses.
|
|
1856
|
+
*/
|
|
1857
|
+
fact: string;
|
|
1858
|
+
/**
|
|
1859
|
+
* The checkable answer as required keyword GROUPS. The thesis text must contain
|
|
1860
|
+
* at least `minGroups` of these groups (default: all). A group is satisfied
|
|
1861
|
+
* when ANY of its `anyOf` fragments appears (case-insensitive substring).
|
|
1862
|
+
*/
|
|
1863
|
+
expected: ExpectedGroup[];
|
|
1864
|
+
/**
|
|
1865
|
+
* Minimum number of `expected` groups the thesis must contain to count the
|
|
1866
|
+
* fact SURFACED. Default = all groups (the strict bar). Lowered (and documented
|
|
1867
|
+
* inline) only when the fact is genuinely satisfiable by a subset.
|
|
1868
|
+
*/
|
|
1869
|
+
minGroups?: number;
|
|
1870
|
+
/**
|
|
1871
|
+
* PROVENANCE. The primary source URL this fact was read from — an SEC EDGAR
|
|
1872
|
+
* 10-K primary document, fetched live during curation.
|
|
1873
|
+
*/
|
|
1874
|
+
sourceUrl: string;
|
|
1875
|
+
/**
|
|
1876
|
+
* The literal value / phrase read out of `sourceUrl` that grounds the fact.
|
|
1877
|
+
* This is the "cite the actual filing + the value" requirement — verbatim or
|
|
1878
|
+
* near-verbatim from the filing, with the figure.
|
|
1879
|
+
*/
|
|
1880
|
+
evidence: string;
|
|
1844
1881
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1882
|
+
/** A company + the cutoff a loop researches as-of + its held-out material facts. */
|
|
1883
|
+
interface CompanyEvalCase {
|
|
1884
|
+
/** Ticker as of the cutoff. */
|
|
1885
|
+
ticker: string;
|
|
1886
|
+
/** Legal name as of the cutoff (what the loop is told to research). */
|
|
1887
|
+
company: string;
|
|
1888
|
+
/** SEC Central Index Key (CIK), zero-stripped — the EDGAR filer id. */
|
|
1889
|
+
cik: string;
|
|
1890
|
+
/**
|
|
1891
|
+
* Research-as-of date (ISO). The loop must reason as if it is this date; every
|
|
1892
|
+
* `evidence` value was knowable on or before it. >= 18 months before this set
|
|
1893
|
+
* was curated, so the outcome is known but is NOT a checklist item.
|
|
1894
|
+
*/
|
|
1895
|
+
cutoff: string;
|
|
1896
|
+
/** Sector, for coverage / the curation-bias disclosure. */
|
|
1897
|
+
sector: string;
|
|
1898
|
+
/**
|
|
1899
|
+
* The known POST-cutoff outcome — recorded for the reader ONLY, never graded.
|
|
1900
|
+
* Keeping it out of `facts` is what makes the set hindsight-free.
|
|
1901
|
+
*/
|
|
1902
|
+
knownOutcome: string;
|
|
1903
|
+
/** The held-out material facts for this company. */
|
|
1904
|
+
facts: MaterialFact[];
|
|
1847
1905
|
}
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1906
|
+
/**
|
|
1907
|
+
* The eval set. 5 public companies, 5-8 held-out material facts each, every fact
|
|
1908
|
+
* grounded in a primary SEC EDGAR 10-K filed on or before the cutoff.
|
|
1909
|
+
*
|
|
1910
|
+
* CURATION-BIAS DISCLOSURE (full version in the doc): all five are companies
|
|
1911
|
+
* whose buried risks later materialized, because that is where the material-vs-
|
|
1912
|
+
* surface distinction is sharpest AND where the figures are easy to verify after
|
|
1913
|
+
* the fact. This biases the set toward downside risks (two of the eight lenses,
|
|
1914
|
+
* concentration + leverage, dominate) and toward distressed names. A production
|
|
1915
|
+
* eval would balance these with companies whose buried facts were POSITIVE
|
|
1916
|
+
* drivers and with survivors. This set is honest about that and reports the lens
|
|
1917
|
+
* distribution so the bias is measurable, not hidden.
|
|
1918
|
+
*/
|
|
1919
|
+
declare const investmentThesisSet: CompanyEvalCase[];
|
|
1920
|
+
/**
|
|
1921
|
+
* Grade ONE material fact against an investment thesis's full text. Returns
|
|
1922
|
+
* whether the thesis SURFACED it plus which expected groups were found. The
|
|
1923
|
+
* check is a deterministic case-insensitive substring scan — $0, model-free,
|
|
1924
|
+
* reproducible — so the eval never leaks into a model the loop could observe.
|
|
1925
|
+
*/
|
|
1926
|
+
declare function gradeFactAgainstText(fact: MaterialFact, thesisText: string): {
|
|
1927
|
+
surfaced: boolean;
|
|
1928
|
+
groupsFound: number;
|
|
1929
|
+
groupsTotal: number;
|
|
1930
|
+
foundLabels: string[];
|
|
1931
|
+
};
|
|
1932
|
+
/** Grade a whole company's thesis text: how many of its held-out facts it surfaces. */
|
|
1933
|
+
declare function gradeCompanyAgainstText(company: CompanyEvalCase, thesisText: string): {
|
|
1934
|
+
surfaced: number;
|
|
1935
|
+
total: number;
|
|
1936
|
+
perFact: ReturnType<typeof gradeFactAgainstText>[];
|
|
1937
|
+
};
|
|
1938
|
+
/** Total held-out facts across the set (the denominator the doc reports). */
|
|
1939
|
+
declare function totalMaterialFacts(set?: CompanyEvalCase[]): number;
|
|
1940
|
+
/** Count facts per lens across the set — used to report (and bound) curation bias. */
|
|
1941
|
+
declare function lensDistribution(set?: CompanyEvalCase[]): Record<MaterialFactLens, number>;
|
|
1942
|
+
|
|
1943
|
+
/**
|
|
1944
|
+
* The INVESTMENT-THESIS research task.
|
|
1945
|
+
*
|
|
1946
|
+
* Given `{ company, ticker, cik, cutoff }`, drive the SAME two-agent research
|
|
1947
|
+
* loop the ML deep-question A/B uses (`runVerifiedResearchLoop` + the real web
|
|
1948
|
+
* worker) to research the company AS OF the cutoff — web + SEC EDGAR, both public
|
|
1949
|
+
* — and produce an investment-thesis PAGE in the knowledge base: a judgment, the
|
|
1950
|
+
* drivers, and the risks, grounded in what it fetched.
|
|
1951
|
+
*
|
|
1952
|
+
* This file builds NOTHING new for the loop: it composes the existing worker +
|
|
1953
|
+
* driver + loop, supplies the readiness specs that steer the worker toward the
|
|
1954
|
+
* filing-level evidence (the analyst lenses), then writes a synthesis thesis page
|
|
1955
|
+
* the metric (`materialFactsSurfaced`) grades against the HELD-OUT checklist.
|
|
1956
|
+
*
|
|
1957
|
+
* THE FIREWALL: the task is told ONLY company + ticker + cutoff (+ the generic
|
|
1958
|
+
* analyst-lens readiness specs every company gets). It is NEVER shown the
|
|
1959
|
+
* checklist. The checklist is read only afterward, by the metric. So a high score
|
|
1960
|
+
* is research depth, not teaching-to-the-test.
|
|
1961
|
+
*/
|
|
1962
|
+
|
|
1963
|
+
/** The minimal brief a thesis run is given — the firewall boundary. */
|
|
1964
|
+
interface ThesisTaskInput {
|
|
1965
|
+
/** Legal name as of the cutoff — what the loop researches. */
|
|
1966
|
+
company: string;
|
|
1967
|
+
/** Ticker as of the cutoff. */
|
|
1968
|
+
ticker: string;
|
|
1969
|
+
/** SEC Central Index Key (CIK), zero-stripped — the EDGAR filer id. */
|
|
1970
|
+
cik: string;
|
|
1971
|
+
/** Research-as-of date (ISO). The loop must reason as if it is this date. */
|
|
1972
|
+
cutoff: string;
|
|
1973
|
+
/** Sector, for the readiness query context (NOT a checklist hint). */
|
|
1974
|
+
sector?: string;
|
|
1856
1975
|
}
|
|
1857
|
-
|
|
1858
|
-
|
|
1976
|
+
/**
|
|
1977
|
+
* The generic analyst-lens readiness specs every company gets. They are the ONLY
|
|
1978
|
+
* thing the loop is told about WHAT to look for, and they name the LENSES a
|
|
1979
|
+
* thorough analyst checks (balance-sheet risk, concentration, leverage, margins,
|
|
1980
|
+
* liquidity, governance, regulatory) and where they live (the latest SEC 10-K) —
|
|
1981
|
+
* NOT the answers. They steer the worker's web/EDGAR search toward the filing,
|
|
1982
|
+
* not toward the held-out facts (which the loop never sees).
|
|
1983
|
+
*
|
|
1984
|
+
* `minSources` is set above 1 so the readiness gate stays UNMET after a single
|
|
1985
|
+
* fetch and the loop runs multiple rounds — the depth-driving driver needs >1
|
|
1986
|
+
* round to steer, exactly as the ML-exam multi-round probe established.
|
|
1987
|
+
*/
|
|
1988
|
+
declare function thesisReadinessSpecs(input: ThesisTaskInput): KnowledgeReadinessSpec[];
|
|
1989
|
+
interface ThesisRunOptions {
|
|
1990
|
+
/** The KB root the loop writes into. */
|
|
1859
1991
|
root: string;
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
readinessSpecs?: KnowledgeReadinessSpec[];
|
|
1871
|
-
readinessTaskId?: string;
|
|
1872
|
-
readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>;
|
|
1873
|
-
kbQuality?: KnowledgeBaseQualityOptions;
|
|
1874
|
-
step?: RunKnowledgeResearchLoopOptions['step'];
|
|
1875
|
-
knowledgeResearch?: Omit<RagKnowledgeResearchOptions, 'root'>;
|
|
1876
|
-
retrieval?: KnowledgeImprovementRetrievalOptions;
|
|
1877
|
-
diagnose?: NonNullable<RunRagKnowledgeImprovementLoopOptions['diagnose']>;
|
|
1878
|
-
acquireKnowledge?: NonNullable<RunRagKnowledgeImprovementLoopOptions['acquireKnowledge']>;
|
|
1879
|
-
updateKnowledge?: KnowledgeImprovementUpdate;
|
|
1880
|
-
evaluateAnswers?: NonNullable<RunRagKnowledgeImprovementLoopOptions['evaluateAnswers']>;
|
|
1881
|
-
decidePromotion?: NonNullable<RunRagKnowledgeImprovementLoopOptions['promote']>;
|
|
1882
|
-
enabledPhases?: readonly RagKnowledgeImprovementPhase[];
|
|
1883
|
-
requiredPhases?: readonly RagKnowledgeImprovementPhase[];
|
|
1884
|
-
evaluate?: KnowledgeImprovementEvaluator;
|
|
1992
|
+
/** Shared router client (web search + chat). Defaults to env creds. */
|
|
1993
|
+
router: RouterClient;
|
|
1994
|
+
/** The driver — verify/dedup or research-driving. The loop's coordinator. */
|
|
1995
|
+
driver: ResearchDriver;
|
|
1996
|
+
/** Round budget. Default 3 (the depth-driving driver needs >1). */
|
|
1997
|
+
maxRounds?: number;
|
|
1998
|
+
/** Worker tuning forwarded to `createWebResearchWorker`. */
|
|
1999
|
+
workerOptions?: Omit<WebResearchWorkerOptions, 'router'>;
|
|
2000
|
+
/** Max tokens for the synthesis pass. Default 1600 (above glm-5.2's reasoning floor). */
|
|
2001
|
+
synthesisMaxTokens?: number;
|
|
1885
2002
|
signal?: AbortSignal;
|
|
1886
|
-
now?: () => Date;
|
|
1887
|
-
onState?: (state: KnowledgeImprovementRunState) => Promise<void> | void;
|
|
1888
2003
|
}
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
2004
|
+
interface ThesisRunResult {
|
|
2005
|
+
loop: VerifiedResearchLoopResult;
|
|
2006
|
+
/** The synthesized thesis text. */
|
|
2007
|
+
thesis: string;
|
|
2008
|
+
/** Path of the thesis page written into the KB. */
|
|
2009
|
+
thesisPath: string;
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* Run the full thesis task: drive the two-agent loop to research the company AS
|
|
2013
|
+
* OF the cutoff, then synthesize + write the thesis page. Returns the loop result
|
|
2014
|
+
* + the thesis text + the page path. The caller grades the KB with
|
|
2015
|
+
* `materialFactsSurfaced(root, checklist)` — the checklist is never passed here.
|
|
2016
|
+
*/
|
|
2017
|
+
declare function runInvestmentThesisTask(input: ThesisTaskInput, options: ThesisRunOptions): Promise<ThesisRunResult>;
|
|
1894
2018
|
|
|
1895
2019
|
interface KbStore {
|
|
1896
2020
|
putSource(source: SourceRecord): Promise<void>;
|
|
@@ -1920,12 +2044,22 @@ declare class MemoryKbStore implements KbStore {
|
|
|
1920
2044
|
putEvent(event: KnowledgeEvent): Promise<void>;
|
|
1921
2045
|
listEvents(query?: KnowledgeEventQuery): Promise<KnowledgeEvent[]>;
|
|
1922
2046
|
}
|
|
1923
|
-
declare class FileSystemKbStore
|
|
2047
|
+
declare class FileSystemKbStore implements KbStore {
|
|
1924
2048
|
private readonly dir;
|
|
1925
2049
|
constructor(dir: string);
|
|
2050
|
+
putSource(source: SourceRecord): Promise<void>;
|
|
2051
|
+
getSource(id: string): Promise<SourceRecord | null>;
|
|
2052
|
+
listSources(): Promise<SourceRecord[]>;
|
|
2053
|
+
putPage(page: KnowledgePage): Promise<void>;
|
|
2054
|
+
getPage(idOrPath: string): Promise<KnowledgePage | null>;
|
|
2055
|
+
listPages(): Promise<KnowledgePage[]>;
|
|
1926
2056
|
putIndex(index: KnowledgeIndex): Promise<void>;
|
|
1927
2057
|
getIndex(): Promise<KnowledgeIndex | null>;
|
|
1928
2058
|
putEvent(event: KnowledgeEvent): Promise<void>;
|
|
2059
|
+
listEvents(query?: KnowledgeEventQuery): Promise<KnowledgeEvent[]>;
|
|
2060
|
+
private updateIndex;
|
|
2061
|
+
private readIndex;
|
|
2062
|
+
private readEvents;
|
|
1929
2063
|
}
|
|
1930
2064
|
|
|
1931
2065
|
declare function lintKnowledgeIndex(index: KnowledgeIndex): KnowledgeLintFinding[];
|
|
@@ -2004,6 +2138,20 @@ declare function materialFactsSurfacedInText(company: CompanyEvalCase, kbText: s
|
|
|
2004
2138
|
*/
|
|
2005
2139
|
declare function materialFactsSurfaced(kb: string | KnowledgeIndex, checklist: CompanyEvalCase): Promise<MaterialFactsResult>;
|
|
2006
2140
|
|
|
2141
|
+
interface PendingKnowledgeMutation {
|
|
2142
|
+
transactionId: string;
|
|
2143
|
+
purpose: string;
|
|
2144
|
+
createdAt: string;
|
|
2145
|
+
direction: 'apply' | 'rollback';
|
|
2146
|
+
paths: string[];
|
|
2147
|
+
}
|
|
2148
|
+
interface RecoverPendingKnowledgeMutationOptions {
|
|
2149
|
+
transactionId: string;
|
|
2150
|
+
action: 'apply' | 'rollback';
|
|
2151
|
+
}
|
|
2152
|
+
declare function inspectPendingKnowledgeMutation(root: string): Promise<PendingKnowledgeMutation | null>;
|
|
2153
|
+
declare function recoverPendingKnowledgeMutation(root: string, options: RecoverPendingKnowledgeMutationOptions): Promise<void>;
|
|
2154
|
+
|
|
2007
2155
|
/**
|
|
2008
2156
|
* Bridge from `AnalystFinding` (agent-eval) to knowledge proposals.
|
|
2009
2157
|
*
|
|
@@ -2335,6 +2483,8 @@ declare const SourceRecordSchema: z.ZodObject<{
|
|
|
2335
2483
|
timestampMs: z.ZodOptional<z.ZodNumber>;
|
|
2336
2484
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
2337
2485
|
}, z.core.$strip>>>;
|
|
2486
|
+
validUntil: z.ZodOptional<z.ZodISODateTime>;
|
|
2487
|
+
lastVerifiedAt: z.ZodOptional<z.ZodISODateTime>;
|
|
2338
2488
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
2339
2489
|
createdAt: z.ZodString;
|
|
2340
2490
|
}, z.core.$strip>;
|
|
@@ -2385,6 +2535,8 @@ declare const KnowledgeIndexSchema: z.ZodObject<{
|
|
|
2385
2535
|
timestampMs: z.ZodOptional<z.ZodNumber>;
|
|
2386
2536
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
2387
2537
|
}, z.core.$strip>>>;
|
|
2538
|
+
validUntil: z.ZodOptional<z.ZodISODateTime>;
|
|
2539
|
+
lastVerifiedAt: z.ZodOptional<z.ZodISODateTime>;
|
|
2388
2540
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
2389
2541
|
createdAt: z.ZodString;
|
|
2390
2542
|
}, z.core.$strip>>;
|
|
@@ -2516,4 +2668,4 @@ declare function normalizeLinkTarget(target: string): string;
|
|
|
2516
2668
|
declare function isSafeKnowledgePath(path: string, allowedPrefixes?: string[]): boolean;
|
|
2517
2669
|
declare function parseKnowledgeWriteBlocks(text: string, allowedPrefixes?: string[]): KnowledgeWriteParseResult;
|
|
2518
2670
|
|
|
2519
|
-
export { type AdaptiveDecision, type AdaptiveDriverOptions, type AdaptiveResearchDriver, type AdaptiveStats, type AddSourceOptions, type AddSourceTextInput, type ApplyWriteBlocksResult, type BuildEvalKnowledgeBundleOptions, type ChunkingOptions, type ClaimGroundingDriverOptions, type CompanyEvalCase, type D1Adapter, type DedupReason, type DeepQuestion, type DeepQuestionKind, type DefineReadinessSpecInput, type DetectChangesOptions, type DetectChangesResult, type DiscoveryLoopResult, type DiscoveryLoopRound, type DiscoveryLoopStopReason, type DiscoveryResult, type DiscoveryTask, type DriverResearchContext, type EvalKnowledgeBundleBuildResult, type EvaluateKnowledgeBaseReadinessOptions, type ExpectedGroup, type ExternalRagEvalScore, type FactResult, type FileSystemFreshnessStoreOptions, FileSystemKbStore, type FreshnessKey, type FreshnessMark, type FreshnessRecord, type FreshnessTtl, type GroundClaimOptions, type GroundingResult, type KbStore, KnowledgeBaseCandidateSchema, type KnowledgeBaseQualityOptions, type KnowledgeBaseQualityReport, type KnowledgeBaseReadinessEvaluation, type KnowledgeChange, type KnowledgeChangeKind, type KnowledgeChunk, KnowledgeClaim, type KnowledgeControlLoopAction, type KnowledgeControlLoopActionResult, type KnowledgeControlLoopAdapter, type KnowledgeControlLoopAdapterOptions, type KnowledgeControlLoopState, type KnowledgeDiscoveryDispatcher, type KnowledgeDiscoveryWorker, KnowledgeEvent, type KnowledgeEventQuery, KnowledgeEventSchema, KnowledgeEventType, type KnowledgeExplanation, KnowledgeFragment, type KnowledgeFreshnessStore, type KnowledgeGap, KnowledgeGraph, KnowledgeGraphEdgeSchema, KnowledgeGraphNodeSchema, type KnowledgeImprovementCandidateRecord, type KnowledgeImprovementEvaluationInput, type KnowledgeImprovementEvaluator, type
|
|
2671
|
+
export { type AdaptiveDecision, type AdaptiveDriverOptions, type AdaptiveResearchDriver, type AdaptiveStats, type AddSourceOptions, type AddSourceTextInput, type ApplyWriteBlocksResult, type BuildEvalKnowledgeBundleOptions, type ChunkingOptions, type ClaimGroundingDriverOptions, type CompanyEvalCase, type D1Adapter, type DedupReason, type DeepQuestion, type DeepQuestionKind, type DefineReadinessSpecInput, type DetectChangesOptions, type DetectChangesResult, type DiscoveryLoopResult, type DiscoveryLoopRound, type DiscoveryLoopStopReason, type DiscoveryResult, type DiscoveryTask, type DriverResearchContext, type EvalKnowledgeBundleBuildResult, type EvaluateKnowledgeBaseReadinessOptions, type ExpectedGroup, type ExternalRagEvalScore, type FactResult, type FileSystemFreshnessStoreOptions, FileSystemKbStore, type FreshnessKey, type FreshnessMark, type FreshnessRecord, type FreshnessTtl, type GroundClaimOptions, type GroundingResult, type KbStore, KnowledgeBaseCandidateSchema, type KnowledgeBaseQualityOptions, type KnowledgeBaseQualityReport, type KnowledgeBaseReadinessEvaluation, type KnowledgeChange, type KnowledgeChangeKind, type KnowledgeChunk, KnowledgeClaim, type KnowledgeControlLoopAction, type KnowledgeControlLoopActionResult, type KnowledgeControlLoopAdapter, type KnowledgeControlLoopAdapterOptions, type KnowledgeControlLoopState, type KnowledgeDiscoveryDispatcher, type KnowledgeDiscoveryWorker, KnowledgeEvent, type KnowledgeEventQuery, KnowledgeEventSchema, KnowledgeEventType, type KnowledgeExplanation, KnowledgeFragment, type KnowledgeFreshnessStore, type KnowledgeGap, KnowledgeGraph, KnowledgeGraphEdgeSchema, KnowledgeGraphNodeSchema, type KnowledgeImprovementCandidateRecord, type KnowledgeImprovementCandidateRef, KnowledgeImprovementCandidateRefSchema, type KnowledgeImprovementEvaluationInput, type KnowledgeImprovementEvaluator, type KnowledgeImprovementEvent, type KnowledgeImprovementEvidence, KnowledgeImprovementEvidenceSchema, type KnowledgeImprovementMetric, type KnowledgeImprovementMetricProvenance, type KnowledgeImprovementOptions, type KnowledgeImprovementResult, type KnowledgeImprovementRetrievalOptions, type KnowledgeImprovementRunState, KnowledgeImprovementRunStateSchema, type KnowledgeImprovementStatus, type KnowledgeImprovementUpdate, type KnowledgeImprovementUpdateInput, KnowledgeIndex, KnowledgeIndexSchema, type KnowledgeInspection, type KnowledgeLayout, KnowledgeLintFinding, KnowledgePage, KnowledgePageSchema, type KnowledgeProposal, KnowledgeProposalParseError, type KnowledgeReadinessSpec, KnowledgeRelease, type KnowledgeReleaseInput, type KnowledgeReleaseReport, type KnowledgeResearchLoopContext, type KnowledgeResearchLoopDecision, type KnowledgeResearchLoopResult, type KnowledgeResearchLoopStep, KnowledgeSearchResult, KnowledgeWriteBlock, KnowledgeWriteParseResult, type MaterialFact, type MaterialFactLens, type MaterialFactsResult, MemoryKbStore, type ParsedFrontmatter, type PendingKnowledgeMutation, type PromoteKnowledgeCandidateOptions, type ProposeFromFindingsResult, READINESS_SPEC_DEFAULTS, type RagAnswerEvalArtifact, type RagAnswerEvalCase, type RagAnswerEvalScenario, type RagAnswerMetricSummary, type RagAnswerQualityHookOptions, type RagAnswerQualityInput, type RagAnswerQualityJudgeOptions, type RagAnswerQualityResult, type RagCalibrationOptions, type RagCalibrationResult, type RagDiagnosisInput, type RagEvalCitation, type RagEvalClaim, type RagEvalContext, type RagEvalMetricKey, type RagEvalProvider, type RagEvalSlice, type RagGapFinding, type RagGapKind, type RagGapSeverity, type RagKnowledgeAcquisitionInput, type RagKnowledgeImprovementPhase, type RagKnowledgeImprovementPhaseResult, type RagKnowledgeImprovementPhaseStatus, type RagKnowledgeResearchOptions, type RagKnowledgeUpdateInput, type RagKnowledgeUpdateResult, type RagPhaseInputBase, type RagPromotionInput, type RagPromotionResult, type RagRequiredContext, type RecoverPendingKnowledgeMutationOptions, type RejectedSource, type ResearchContribution, type ResearchDriver, type ResearchDrivingDriver, type ResearchDrivingDriverOptions, type ResearchDrivingState, type ResearchDrivingSteer, type ResearchSourceProposal, type ResearchWorker, type ResolvedKnowledgeImprovementCandidate, type RouterClient, RouterError, type RouterUsage, type RunDiscoveryLoopOptions, type RunKnowledgeResearchLoopOptions, type RunRagKnowledgeImprovementLoopOptions, type RunRagKnowledgeImprovementLoopResult, RunRetrievalImprovementLoopOptions, RunRetrievalImprovementLoopResult, SCAFFOLD_PAGE_BASENAMES, type SourceAdapter, type SourceAdapterInput, type SourceAdapterOutput, SourceAnchorSchema, type SourceFreshnessInspection, SourceRecord, SourceRecordSchema, SourceRegistry, type SourceVerdict, type SourceVerificationContext, type TangleRouterOptions, type ThesisRunOptions, type ThesisRunResult, type ThesisTaskInput, type TrackedClaim, type TriageClass, type TwoAgentResearchLoopOptions, type TwoAgentResearchLoopResult, type TwoAgentResearchRound, type UseKnowledgeImprovementCandidateOptions, type ValidateKnowledgeOptions, type ValidateKnowledgeResult, type VerifiedResearchLoopOptions, type VerifiedResearchLoopResult, type VerifiedResearchRound, type VerifyingDriverOptions, WIKILINK_REGEX, type WebResearchWorkerOptions, type WebSearchHit, type WorkerClaimDecorationOptions, type WorkerResearchContext, addSourcePath, addSourceText, applyKnowledgeWriteBlocks, applyKnowledgeWriteBlocksFile, buildEvalKnowledgeBundle, buildKnowledgeGraph, buildKnowledgeIndex, calibrateRagAnswerJudge, canonicalizeUrl, chunkMarkdown, citedClaimKey, citedClaimOf, contentKey, createAdaptiveResearchDriver, createClaimDecorator, createClaimGroundingVerifier, createCollectionResearchDriver, createD1FreshnessStoreStub, createFileSystemFreshnessStore, createKnowledgeControlLoopAdapter, createKnowledgeEvent, createLocalDiscoveryDispatcher, createRagAnswerQualityHook, createResearchDrivingDriver, createTangleRouterClient, createVerifyingResearchDriver, createWebResearchWorker, defineReadinessSpec, detectChanges, diagnoseRagAnswerFailure, evaluateKnowledgeBaseReadiness, explainKnowledgeTarget, extractWikilinks, formatFrontmatter, fromAgentCandidateKnowledgeRef, gradeCompanyAgainstText, gradeFactAgainstText, groundClaimInText, hashKnowledgeBase, improveKnowledgeBase, initKnowledgeBase, inspectKnowledgeIndex, inspectPendingKnowledgeMutation, investmentThesisSet, isSafeKnowledgePath, isScaffoldPath, kbIndexToText, knowledgeImprovementCandidateRef, knowledgeImprovementRunDir, knowledgeImprovementRunId, knowledgeReleaseReport, layoutFor, lensDistribution, lintKnowledgeIndex, loadKnowledgeImprovementEvents, loadKnowledgeImprovementState, loadKnowledgePages, loadSourceRegistry, materialFactsSurfaced, materialFactsSurfacedInText, mediaTypeFor, normalizeExternalRagScores, normalizeLinkTarget, parseFrontmatter, parseKnowledgeWriteBlocks, promoteKnowledgeCandidate, proposeFromFinding, proposeFromFindings, ragAnswerQualityJudge, reciprocalRankFusion, recoverPendingKnowledgeMutation, runDiscoveryLoop, runInvestmentThesisTask, runKnowledgeResearchLoop, runRagKnowledgeImprovementLoop, runTwoAgentResearchLoop, runVerifiedResearchLoop, scoreKnowledgeBaseIndex, scoreRagAnswerArtifact, searchKnowledge, sha256, slugify, sourceMatchesGaps, sourceRegistryPath, stableId, stripFrontmatter, textSourceAdapter, thesisReadinessSpecs, toAgentCandidateKnowledgeRef, toDeepEvalTestCases, toRagCheckerRecords, toRagasEvaluationRows, toTruLensRecords, tokenizeQuery, totalMaterialFacts, triageSource, validateKnowledgeIndex, withCitedClaim, withKnowledgeImprovementCandidate, writeJson, writeKnowledgeIndex, writeSourceRegistry };
|