freshcontext-mcp 0.3.20 → 0.3.21
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 +55 -9
- package/SECURITY.md +9 -7
- package/dist/adapters/arxiv.d.ts +15 -0
- package/dist/adapters/arxiv.js +1 -1
- package/dist/adapters/changelog.d.ts +2 -0
- package/dist/adapters/finance.d.ts +2 -0
- package/dist/adapters/finance.js +1 -1
- package/dist/adapters/gdelt.d.ts +2 -0
- package/dist/adapters/gdelt.js +1 -1
- package/dist/adapters/gebiz.d.ts +2 -0
- package/dist/adapters/gebiz.js +1 -1
- package/dist/adapters/github.d.ts +2 -0
- package/dist/adapters/govcontracts.d.ts +2 -0
- package/dist/adapters/hackernews.d.ts +2 -0
- package/dist/adapters/jobs.d.ts +2 -0
- package/dist/adapters/jobs.js +6 -6
- package/dist/adapters/packageTrends.d.ts +2 -0
- package/dist/adapters/productHunt.d.ts +2 -0
- package/dist/adapters/reddit.d.ts +8 -0
- package/dist/adapters/reddit.js +1 -1
- package/dist/adapters/registry.d.ts +19 -0
- package/dist/adapters/repoSearch.d.ts +2 -0
- package/dist/adapters/repoSearch.js +1 -1
- package/dist/adapters/scholar.d.ts +2 -0
- package/dist/adapters/secFilings.d.ts +2 -0
- package/dist/adapters/secFilings.js +1 -1
- package/dist/adapters/yc.d.ts +2 -0
- package/dist/core/decay.d.ts +5 -0
- package/dist/core/decision.d.ts +3 -0
- package/dist/core/decision.js +1 -3
- package/dist/core/envelope.d.ts +5 -0
- package/dist/core/explain.d.ts +12 -0
- package/dist/core/guards.d.ts +1 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.js +2 -0
- package/dist/core/pipeline.d.ts +3 -0
- package/dist/core/pipeline.js +8 -0
- package/dist/core/provenance.d.ts +5 -0
- package/dist/core/provenanceReadiness.d.ts +2 -0
- package/dist/core/provenanceReadiness.js +220 -0
- package/dist/core/rank.d.ts +4 -0
- package/dist/core/readable.d.ts +2 -0
- package/dist/core/readable.js +75 -0
- package/dist/core/signal.d.ts +3 -0
- package/dist/core/sourceProfiles.d.ts +4 -0
- package/dist/core/types.d.ts +239 -0
- package/dist/core/utility.d.ts +2 -0
- package/dist/rest/handler.d.ts +1 -0
- package/dist/security.d.ts +15 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +1 -1
- package/dist/tools/evaluateContext.d.ts +21 -0
- package/dist/tools/evaluateContext.js +3 -1
- package/dist/tools/freshnessStamp.d.ts +1 -0
- package/dist/types.d.ts +1 -0
- package/docs/API_DESIGN.md +28 -1
- package/docs/CLIENT_SETUP.md +4 -4
- package/docs/CODEX_MCP_USAGE.md +3 -3
- package/docs/CORE_API.md +74 -12
- package/docs/CORE_MCP_BOUNDARY.md +13 -4
- package/docs/FUTURE_LANES.md +43 -43
- package/docs/HUMAN_READABLE_OUTPUT_CONTRACT.md +293 -0
- package/docs/RELEASE_NOTES.md +33 -5
- package/docs/SIGNAL_CONTRACT.md +215 -213
- package/package-script-guard.mjs +84 -75
- package/package.json +31 -16
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -87,6 +87,22 @@ The production Cloudflare Worker now uses Core-backed envelope generation. Worke
|
|
|
87
87
|
|
|
88
88
|
See [Core / MCP Boundary](./docs/CORE_MCP_BOUNDARY.md) for the current package boundary and the staged path toward a future standalone Core package.
|
|
89
89
|
|
|
90
|
+
### Core import path
|
|
91
|
+
|
|
92
|
+
FreshContext Core is also available directly from the current MCP package:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import {
|
|
96
|
+
evaluateSignals,
|
|
97
|
+
interpretEvaluations,
|
|
98
|
+
getSourceProfile,
|
|
99
|
+
normalizeSignal,
|
|
100
|
+
calculateHaPriV2,
|
|
101
|
+
} from "freshcontext-mcp/core";
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
This is a Core subpath export inside `freshcontext-mcp`, not a standalone `freshcontext-core` package yet. The root package and `freshcontext-mcp` binary remain the MCP reference host.
|
|
105
|
+
|
|
90
106
|
---
|
|
91
107
|
|
|
92
108
|
## Primary MCP interface
|
|
@@ -126,9 +142,39 @@ FreshContext returns decision-first output:
|
|
|
126
142
|
- Confidence
|
|
127
143
|
- Why
|
|
128
144
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
145
|
+
Structured results also include a `readable` object for humans:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"decision": "cite_as_primary",
|
|
150
|
+
"label": "Cite as primary",
|
|
151
|
+
"readable": {
|
|
152
|
+
"label": "Primary source",
|
|
153
|
+
"summary": "This source is strong enough to use as main evidence.",
|
|
154
|
+
"why": [
|
|
155
|
+
"Strong semantic match and current freshness for arxiv.",
|
|
156
|
+
"source profile academic_research uses lenient date policy",
|
|
157
|
+
"intent profile citation_check selected"
|
|
158
|
+
],
|
|
159
|
+
"action": "Use this as main evidence while preserving citation and provenance.",
|
|
160
|
+
"warnings": [
|
|
161
|
+
"FreshContext judges citation readiness and context usefulness; it does not certify truth."
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The readable object translates Core decisions into user-facing language. It does not change ranking, decision labels, utility scoring, or source intake. Utility helps explain usefulness for the current question; it remains explanatory and does not control default decision labels or ranking.
|
|
168
|
+
|
|
169
|
+
FreshContext does not certify truth. It records why context was used, supported, questioned, refreshed, watched, or excluded before it reaches a model.
|
|
170
|
+
|
|
171
|
+
`evaluate_context` does not fetch URLs, crawl, scrape, browse, read folders, or call adapters. It only evaluates candidate context the caller provides.
|
|
172
|
+
|
|
173
|
+
Current boundary: `evaluate_context` is part of the npm/local stdio MCP server prepared for `0.3.21`. The hosted Cloudflare Worker MCP endpoint was last verified separately at `0.3.20 / 22 tools`. The Worker remains a separate deployment surface, so future package interfaces should be re-verified remotely before being claimed live.
|
|
174
|
+
|
|
175
|
+
### Network Boundary
|
|
176
|
+
|
|
177
|
+
FreshContext's primary `evaluate_context` path does not fetch, crawl, scrape, browse, read folders, or call adapters. The MCP package also includes read-only reference adapters that use network access only when those adapter tools are invoked. Supply-chain scanners may therefore report package network access; that applies to the optional adapter surface, not to caller-provided context evaluation.
|
|
132
178
|
|
|
133
179
|
---
|
|
134
180
|
|
|
@@ -389,7 +435,7 @@ The reference implementation runs on Cloudflare's global edge:
|
|
|
389
435
|
| `/` | GET | Service info + endpoint list |
|
|
390
436
|
| `/health` | GET | Liveness check |
|
|
391
437
|
| `/mcp` | POST | MCP JSON-RPC transport |
|
|
392
|
-
| `/demo` | GET | Live before/after demo (no auth token required) |
|
|
438
|
+
| `/demo` | GET | Live before/after demo (no auth token required) |
|
|
393
439
|
| `/briefing` | GET | Latest stored briefing |
|
|
394
440
|
| `/v1/intel/feed/:profile_id` | GET | DAR-scored intelligence feed |
|
|
395
441
|
| `/watched-queries` | GET | List all watched queries |
|
|
@@ -407,19 +453,19 @@ Production: `https://freshcontext-mcp.gimmanuel73.workers.dev`
|
|
|
407
453
|
## Roadmap
|
|
408
454
|
|
|
409
455
|
- [x] FreshContext Specification v1.2 published (MIT, open standard)
|
|
410
|
-
- [x] DAR engine with source-specific lambda constants
|
|
456
|
+
- [x] DAR engine with source-specific lambda constants
|
|
411
457
|
- [x] Ha-Pri v1 provenance signatures on stored signals
|
|
412
458
|
- [x] Semantic deduplication via fingerprinting
|
|
413
459
|
- [x] Live before/after demo at `/demo`
|
|
414
|
-
- [x] METHODOLOGY.md — methodology and engineering documentation
|
|
460
|
+
- [x] METHODOLOGY.md — methodology and engineering documentation
|
|
415
461
|
- [x] Named reference adapters across intelligence, competitive research, market data, and composites
|
|
416
462
|
- [x] Generic MCP `evaluate_context` tool for caller-provided candidate context
|
|
417
463
|
- [x] Core-backed envelope generation shared by npm/MCP and the Cloudflare Worker
|
|
418
464
|
- [x] Cloudflare Workers deployment — global edge, KV cache, KV rate limiting
|
|
419
465
|
- [x] Published on npm and listed for MCP usage; Apify/feed assets are separated from the normal MCP runtime package
|
|
420
|
-
- [x] Ha-Pri v2 Core helper and deterministic golden vectors
|
|
421
|
-
- [x] Ha-Pri v2 production-enforcement design document
|
|
422
|
-
- [ ] Ha-Pri v2 Worker/D1 production enforcement
|
|
466
|
+
- [x] Ha-Pri v2 Core helper and deterministic golden vectors
|
|
467
|
+
- [x] Ha-Pri v2 production-enforcement design document
|
|
468
|
+
- [ ] Ha-Pri v2 Worker/D1 production enforcement
|
|
423
469
|
- [x] GitHub Actions release workflow — manual or `v*` tag-triggered npm publish path
|
|
424
470
|
- [ ] Webhook triggers — push high-entropy signals on threshold
|
|
425
471
|
- [ ] Dashboard — React frontend for the D1 intelligence pipeline
|
package/SECURITY.md
CHANGED
|
@@ -25,10 +25,12 @@ For a useful report, include:
|
|
|
25
25
|
|
|
26
26
|
Public GitHub issues are fine for non-sensitive bugs, documentation mistakes, stale claims, build failures, and feature requests.
|
|
27
27
|
|
|
28
|
-
## Scope Notes
|
|
29
|
-
|
|
30
|
-
FreshContext does not currently offer a formal bug bounty program.
|
|
31
|
-
|
|
32
|
-
Please do not send live production tokens, private Cloudflare logs, npm tokens, GitHub tokens, MCP registry tokens, customer data, or private account data. If a report requires sensitive evidence, describe the issue first by email so a safer exchange path can be agreed.
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
## Scope Notes
|
|
29
|
+
|
|
30
|
+
FreshContext does not currently offer a formal bug bounty program.
|
|
31
|
+
|
|
32
|
+
Please do not send live production tokens, private Cloudflare logs, npm tokens, GitHub tokens, MCP registry tokens, customer data, or private account data. If a report requires sensitive evidence, describe the issue first by email so a safer exchange path can be agreed.
|
|
33
|
+
|
|
34
|
+
FreshContext's primary `evaluate_context` path evaluates caller-provided candidate context and does not fetch, crawl, browse, read folders, or call adapters. The published MCP package also includes read-only reference adapters that use network access only when those adapter tools are invoked.
|
|
35
|
+
|
|
36
|
+
This policy does not make claims of certification, compliance, guaranteed response time, or security warranty.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AdapterResult, ExtractOptions } from "../types.js";
|
|
2
|
+
import type { FreshContextSignalInput } from "../core/types.js";
|
|
3
|
+
export type ArxivSignalSearchInput = {
|
|
4
|
+
query: string;
|
|
5
|
+
maxResults?: number;
|
|
6
|
+
retrievedAt?: string;
|
|
7
|
+
semanticScore?: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* arXiv adapter uses the official arXiv API.
|
|
11
|
+
* Accepts a search query or a direct arXiv API URL.
|
|
12
|
+
* Docs: https://arxiv.org/help/api/user-manual
|
|
13
|
+
*/
|
|
14
|
+
export declare function arxivAdapter(options: ExtractOptions): Promise<AdapterResult>;
|
|
15
|
+
export declare function searchArxivSignals(input: ArxivSignalSearchInput): Promise<FreshContextSignalInput[]>;
|
package/dist/adapters/arxiv.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { validateUrl } from "../security.js";
|
|
2
|
-
const USER_AGENT = "freshcontext-mcp/0.
|
|
2
|
+
const USER_AGENT = "freshcontext-mcp/0.3.21 (https://github.com/PrinceGabriel-lgtm/freshcontext-mcp)";
|
|
3
3
|
const DEFAULT_ARXIV_SIGNAL_SCORE = 0.8;
|
|
4
4
|
function buildArxivApiUrl(input, maxResults = 10) {
|
|
5
5
|
const trimmed = input.trim();
|
package/dist/adapters/finance.js
CHANGED
|
@@ -30,7 +30,7 @@ async function fetchStooqQuote(ticker) {
|
|
|
30
30
|
const url = `https://stooq.com/q/l/?s=${encodeURIComponent(stooqSymbol.toLowerCase())}&f=sd2t2ohlcv&h&e=json`;
|
|
31
31
|
const res = await fetch(url, {
|
|
32
32
|
headers: {
|
|
33
|
-
"User-Agent": "freshcontext-mcp/0.3.
|
|
33
|
+
"User-Agent": "freshcontext-mcp/0.3.21",
|
|
34
34
|
"Accept": "application/json",
|
|
35
35
|
},
|
|
36
36
|
});
|
package/dist/adapters/gdelt.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
const HEADERS = {
|
|
13
13
|
"Accept": "application/json",
|
|
14
|
-
"User-Agent": "freshcontext-mcp/0.3.
|
|
14
|
+
"User-Agent": "freshcontext-mcp/0.3.21 (https://github.com/PrinceGabriel-lgtm/freshcontext-mcp)",
|
|
15
15
|
};
|
|
16
16
|
function parseGdeltDate(raw) {
|
|
17
17
|
if (!raw)
|
package/dist/adapters/gebiz.js
CHANGED
|
@@ -20,7 +20,7 @@ const DATASET_ID = "d_acde1106003906a75c3fa052592f2fcb";
|
|
|
20
20
|
const BASE_URL = "https://data.gov.sg/api/action/datastore_search";
|
|
21
21
|
const HEADERS = {
|
|
22
22
|
"Accept": "application/json",
|
|
23
|
-
"User-Agent": "freshcontext-mcp/0.3.
|
|
23
|
+
"User-Agent": "freshcontext-mcp/0.3.21 (https://github.com/PrinceGabriel-lgtm/freshcontext-mcp)",
|
|
24
24
|
};
|
|
25
25
|
function formatDate(raw) {
|
|
26
26
|
if (!raw)
|
package/dist/adapters/jobs.js
CHANGED
|
@@ -131,7 +131,7 @@ export async function jobsAdapter(options) {
|
|
|
131
131
|
async function fetchRemotive(query, location, maxAgeDays, keywords) {
|
|
132
132
|
const url = `https://remotive.com/api/remote-jobs?search=${encodeURIComponent(query)}&limit=15`;
|
|
133
133
|
const res = await fetch(url, {
|
|
134
|
-
headers: { "User-Agent": "freshcontext-mcp/0.3.
|
|
134
|
+
headers: { "User-Agent": "freshcontext-mcp/0.3.21", "Accept": "application/json" },
|
|
135
135
|
});
|
|
136
136
|
if (!res.ok)
|
|
137
137
|
throw new Error(`Remotive ${res.status}`);
|
|
@@ -161,7 +161,7 @@ async function fetchRemoteOK(query, location, maxAgeDays, keywords) {
|
|
|
161
161
|
const tag = query.toLowerCase().replace(/\s+/g, "-");
|
|
162
162
|
const url = `https://remoteok.com/api?tag=${encodeURIComponent(tag)}`;
|
|
163
163
|
const res = await fetch(url, {
|
|
164
|
-
headers: { "User-Agent": "freshcontext-mcp/0.3.
|
|
164
|
+
headers: { "User-Agent": "freshcontext-mcp/0.3.21", "Accept": "application/json" },
|
|
165
165
|
});
|
|
166
166
|
if (!res.ok)
|
|
167
167
|
throw new Error(`RemoteOK ${res.status}`);
|
|
@@ -199,7 +199,7 @@ async function fetchArbeitnow(query, location, maxAgeDays, keywords, remoteOnly)
|
|
|
199
199
|
params.set("remote", "true");
|
|
200
200
|
const url = `https://arbeitnow.com/api/job-board-api?${params.toString()}`;
|
|
201
201
|
const res = await fetch(url, {
|
|
202
|
-
headers: { "User-Agent": "freshcontext-mcp/0.3.
|
|
202
|
+
headers: { "User-Agent": "freshcontext-mcp/0.3.21", "Accept": "application/json" },
|
|
203
203
|
});
|
|
204
204
|
if (!res.ok)
|
|
205
205
|
throw new Error(`Arbeitnow ${res.status}`);
|
|
@@ -233,7 +233,7 @@ async function fetchMuse(query, location, maxAgeDays, keywords) {
|
|
|
233
233
|
: "&location=Flexible%20%2F%20Remote";
|
|
234
234
|
const url = `https://www.themuse.com/api/public/jobs?name=${encodeURIComponent(query)}${locParam}&page=0&descending=true`;
|
|
235
235
|
const res = await fetch(url, {
|
|
236
|
-
headers: { "User-Agent": "freshcontext-mcp/0.3.
|
|
236
|
+
headers: { "User-Agent": "freshcontext-mcp/0.3.21", "Accept": "application/json" },
|
|
237
237
|
});
|
|
238
238
|
if (!res.ok)
|
|
239
239
|
throw new Error(`The Muse ${res.status}`);
|
|
@@ -263,7 +263,7 @@ async function fetchMuse(query, location, maxAgeDays, keywords) {
|
|
|
263
263
|
// instead of all HN comments. Uses the parent_id filter to target the thread.
|
|
264
264
|
async function fetchHNHiring(query, location, maxAgeDays, keywords) {
|
|
265
265
|
// Step 1: Find the most recent "Ask HN: Who is hiring?" thread
|
|
266
|
-
const threadRes = await fetch(`https://hn.algolia.com/api/v1/search?query=Ask+HN+Who+is+hiring&tags=story&hitsPerPage=5`, { headers: { "User-Agent": "freshcontext-mcp/0.3.
|
|
266
|
+
const threadRes = await fetch(`https://hn.algolia.com/api/v1/search?query=Ask+HN+Who+is+hiring&tags=story&hitsPerPage=5`, { headers: { "User-Agent": "freshcontext-mcp/0.3.21" } });
|
|
267
267
|
if (!threadRes.ok)
|
|
268
268
|
throw new Error(`HN thread search ${threadRes.status}`);
|
|
269
269
|
const threadData = await threadRes.json();
|
|
@@ -273,7 +273,7 @@ async function fetchHNHiring(query, location, maxAgeDays, keywords) {
|
|
|
273
273
|
throw new Error("HN hiring thread not found");
|
|
274
274
|
// Step 2: Search comments within that thread for the query
|
|
275
275
|
const searchTerms = [query, location].filter(Boolean).join(" ");
|
|
276
|
-
const commentsRes = await fetch(`https://hn.algolia.com/api/v1/search?query=${encodeURIComponent(searchTerms)}&tags=comment,story_${hiringThread.objectID}&hitsPerPage=10`, { headers: { "User-Agent": "freshcontext-mcp/0.3.
|
|
276
|
+
const commentsRes = await fetch(`https://hn.algolia.com/api/v1/search?query=${encodeURIComponent(searchTerms)}&tags=comment,story_${hiringThread.objectID}&hitsPerPage=10`, { headers: { "User-Agent": "freshcontext-mcp/0.3.21" } });
|
|
277
277
|
if (!commentsRes.ok)
|
|
278
278
|
throw new Error(`HN comments ${commentsRes.status}`);
|
|
279
279
|
const commentsData = await commentsRes.json();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AdapterResult, ExtractOptions } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Reddit adapter — public JSON API, no auth required.
|
|
4
|
+
* Accepts subreddit URLs or search queries.
|
|
5
|
+
* e.g. https://www.reddit.com/r/MachineLearning/.json
|
|
6
|
+
* https://www.reddit.com/search.json?q=mcp+server&sort=hot
|
|
7
|
+
*/
|
|
8
|
+
export declare function redditAdapter(options: ExtractOptions): Promise<AdapterResult>;
|
package/dist/adapters/reddit.js
CHANGED
|
@@ -28,7 +28,7 @@ export async function redditAdapter(options) {
|
|
|
28
28
|
const safeUrl = validateUrl(apiUrl, "reddit");
|
|
29
29
|
const res = await fetch(safeUrl, {
|
|
30
30
|
headers: {
|
|
31
|
-
"User-Agent": "freshcontext-mcp/0.
|
|
31
|
+
"User-Agent": "freshcontext-mcp/0.3.21 (https://github.com/PrinceGabriel-lgtm/freshcontext-mcp)",
|
|
32
32
|
"Accept": "application/json",
|
|
33
33
|
},
|
|
34
34
|
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SourceProfileId } from "../core/index.js";
|
|
2
|
+
export type AdapterRisk = "low" | "medium" | "high";
|
|
3
|
+
export type AdapterOutputMode = "single" | "batch" | "composite";
|
|
4
|
+
export type AdapterRuntimeKind = "api" | "browser" | "composite" | "mixed" | "local";
|
|
5
|
+
export interface FreshContextAdapterDescriptor {
|
|
6
|
+
adapter_id: string;
|
|
7
|
+
tool_name: string;
|
|
8
|
+
source_profile: SourceProfileId;
|
|
9
|
+
secondary_source_profiles?: SourceProfileId[];
|
|
10
|
+
output_mode: AdapterOutputMode;
|
|
11
|
+
runtime_kind: AdapterRuntimeKind;
|
|
12
|
+
risk: AdapterRisk;
|
|
13
|
+
notes?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const BUILT_IN_ADAPTER_REGISTRY: readonly FreshContextAdapterDescriptor[];
|
|
16
|
+
export declare function listAdapterDescriptors(): FreshContextAdapterDescriptor[];
|
|
17
|
+
export declare function getAdapterDescriptor(adapterIdOrToolName: string): FreshContextAdapterDescriptor | undefined;
|
|
18
|
+
export declare function listAdaptersBySourceProfile(profileId: SourceProfileId): FreshContextAdapterDescriptor[];
|
|
19
|
+
export declare function listAdaptersByRisk(risk: AdapterRisk): FreshContextAdapterDescriptor[];
|
|
@@ -22,7 +22,7 @@ export async function repoSearchAdapter(options) {
|
|
|
22
22
|
const res = await fetch(apiUrl, {
|
|
23
23
|
headers: {
|
|
24
24
|
Accept: "application/vnd.github.v3+json",
|
|
25
|
-
"User-Agent": "freshcontext-mcp/0.3.
|
|
25
|
+
"User-Agent": "freshcontext-mcp/0.3.21 (https://github.com/PrinceGabriel-lgtm/freshcontext-mcp)",
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
28
|
if (!res.ok) {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
const HEADERS = {
|
|
14
14
|
"Accept": "application/json",
|
|
15
|
-
"User-Agent": "freshcontext-mcp/0.3.
|
|
15
|
+
"User-Agent": "freshcontext-mcp/0.3.21 (https://github.com/PrinceGabriel-lgtm/freshcontext-mcp)",
|
|
16
16
|
};
|
|
17
17
|
async function fetchSecFilings(query, maxResults = 10) {
|
|
18
18
|
const today = new Date().toISOString().slice(0, 10);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const LAMBDA: Record<string, number>;
|
|
2
|
+
export declare const FUTURE_CLOCK_SKEW_TOLERANCE_MS: number;
|
|
3
|
+
export declare function isMeaningfullyFutureDate(content_date: string | null, retrieved_at: string): boolean;
|
|
4
|
+
export declare function calculateFreshnessScore(content_date: string | null, retrieved_at: string, adapter: string): number | null;
|
|
5
|
+
export declare function scoreLabel(score: number | null): string;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ContextDecisionOptions, ContextDecisionResult, CoreSignalEvaluationResult } from "./types.js";
|
|
2
|
+
export declare function interpretEvaluation(evaluation: CoreSignalEvaluationResult, options?: ContextDecisionOptions): ContextDecisionResult;
|
|
3
|
+
export declare function interpretEvaluations(evaluations: CoreSignalEvaluationResult[], options?: ContextDecisionOptions): ContextDecisionResult[];
|
package/dist/core/decision.js
CHANGED
|
@@ -125,7 +125,6 @@ export function interpretEvaluation(evaluation, options = {}) {
|
|
|
125
125
|
]);
|
|
126
126
|
const warnings = [...nonAdviceWarnings(intentProfile)];
|
|
127
127
|
const finalScore = evaluation.ranked.final_score;
|
|
128
|
-
const utilityScore = evaluation.utility.score;
|
|
129
128
|
const freshnessScore = evaluation.freshness_score;
|
|
130
129
|
const confidence = evaluation.ranked.confidence;
|
|
131
130
|
const isFailed = evaluation.signal.status === "failed"
|
|
@@ -153,7 +152,6 @@ export function interpretEvaluation(evaluation, options = {}) {
|
|
|
153
152
|
if (finalScore >= 0.85
|
|
154
153
|
&& freshnessScore !== null
|
|
155
154
|
&& freshnessScore >= 70
|
|
156
|
-
&& utilityScore >= 60
|
|
157
155
|
&& confidence === "high") {
|
|
158
156
|
if (sourceProfile?.authority_hint === "high" && isCitationIntent(intentProfile)) {
|
|
159
157
|
return decisionResult("cite_as_primary", reasons, warnings);
|
|
@@ -163,7 +161,7 @@ export function interpretEvaluation(evaluation, options = {}) {
|
|
|
163
161
|
if (finalScore >= 0.55 && freshnessScore !== null && freshnessScore < 50) {
|
|
164
162
|
return decisionResult(isCitationIntent(intentProfile) ? "cite_as_supporting" : "use_as_background", reasons, warnings);
|
|
165
163
|
}
|
|
166
|
-
if (finalScore < 0.35
|
|
164
|
+
if (finalScore < 0.35) {
|
|
167
165
|
return decisionResult(confidence === "low" ? "exclude" : "watch_only", reasons, warnings);
|
|
168
166
|
}
|
|
169
167
|
if (finalScore >= 0.55) {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FreshContext, AdapterResult, ExtractOptions, EnvelopeFormatOptions } from "./types.js";
|
|
2
|
+
export declare const MAX_ENVELOPE_CONTENT_LENGTH = 20000;
|
|
3
|
+
export declare function stampFreshness(result: AdapterResult, options: ExtractOptions, adapter: string): FreshContext;
|
|
4
|
+
export declare function toStructuredJSON(ctx: FreshContext): object;
|
|
5
|
+
export declare function formatForLLM(ctx: FreshContext, options?: EnvelopeFormatOptions): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SignalConfidence } from "./types.js";
|
|
2
|
+
interface ExplainSignalInput {
|
|
3
|
+
source?: string;
|
|
4
|
+
source_type?: string;
|
|
5
|
+
semantic_score: number;
|
|
6
|
+
freshness_score: number | null;
|
|
7
|
+
final_score: number;
|
|
8
|
+
confidence: SignalConfidence;
|
|
9
|
+
published_at?: string | null;
|
|
10
|
+
}
|
|
11
|
+
export declare function explainSignal(input: ExplainSignalInput): string;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function looksLikeFailedAdapterContent(raw: string): boolean;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { LAMBDA, calculateFreshnessScore, scoreLabel } from "./decay.js";
|
|
2
|
+
export { looksLikeFailedAdapterContent } from "./guards.js";
|
|
3
|
+
export { stampFreshness, toStructuredJSON, formatForLLM } from "./envelope.js";
|
|
4
|
+
export { explainSignal } from "./explain.js";
|
|
5
|
+
export { rankSignals, rankSignal, clampScore } from "./rank.js";
|
|
6
|
+
export { calculateContextUtility } from "./utility.js";
|
|
7
|
+
export { SIGNAL_CONTRACT_VERSION, normalizeSignal } from "./signal.js";
|
|
8
|
+
export { evaluateSignal, evaluateSignals } from "./pipeline.js";
|
|
9
|
+
export { interpretEvaluation, interpretEvaluations } from "./decision.js";
|
|
10
|
+
export { toReadableContextResult } from "./readable.js";
|
|
11
|
+
export { prepareProvenanceReadiness } from "./provenanceReadiness.js";
|
|
12
|
+
export { BUILT_IN_SOURCE_PROFILES, getSourceProfile, listSourceProfiles } from "./sourceProfiles.js";
|
|
13
|
+
export { canonicalizeHaPriContent, sha256Hex, calculateHaPriV2, verifyHaPriV2, } from "./provenance.js";
|
|
14
|
+
export type { FreshContext, ExtractOptions, AdapterResult, EnvelopeFormatOptions, SignalConfidence, SignalDateConfidence, SignalContractVersion, SourceAuthorityHint, SourceDatePolicy, SourceFailurePolicy, SourceProfile, SourceProfileId, SourceSurface, ContextDecision, IntentProfileId, ContextDecisionOptions, ContextDecisionResult, HumanReadableHandoffResult, HumanReadableContextResult, SignalNormalizeOptions, FreshContextSignalInput, FreshContextSignal, FreshSignal, RankedSignal, RankOptions, ContextUtilityStatus, ContextUtilityInput, ContextUtilityResult, HaPriV2Input, HaPriV2Material, HaPriV2Result, HaPriVerificationStatus, HaPriV2VerificationResult, ProvenanceReadinessState, ProvenanceSourceIdentityCompleteness, ProvenanceTimingCompleteness, ProvenanceReadinessInput, ProvenanceReadinessOptions, ProvenanceSourceIdentityResult, ProvenanceReadinessResult, CoreSignalProvenanceOptions, CoreSignalEnvelopeResult, CoreSignalEvaluationOptions, CoreSignalEvaluationResult, } from "./types.js";
|
package/dist/core/index.js
CHANGED
|
@@ -7,5 +7,7 @@ export { calculateContextUtility } from "./utility.js";
|
|
|
7
7
|
export { SIGNAL_CONTRACT_VERSION, normalizeSignal } from "./signal.js";
|
|
8
8
|
export { evaluateSignal, evaluateSignals } from "./pipeline.js";
|
|
9
9
|
export { interpretEvaluation, interpretEvaluations } from "./decision.js";
|
|
10
|
+
export { toReadableContextResult } from "./readable.js";
|
|
11
|
+
export { prepareProvenanceReadiness } from "./provenanceReadiness.js";
|
|
10
12
|
export { BUILT_IN_SOURCE_PROFILES, getSourceProfile, listSourceProfiles } from "./sourceProfiles.js";
|
|
11
13
|
export { canonicalizeHaPriContent, sha256Hex, calculateHaPriV2, verifyHaPriV2, } from "./provenance.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CoreSignalEvaluationOptions, CoreSignalEvaluationResult, FreshContextSignalInput } from "./types.js";
|
|
2
|
+
export declare function evaluateSignal(input: FreshContextSignalInput, options?: CoreSignalEvaluationOptions): CoreSignalEvaluationResult;
|
|
3
|
+
export declare function evaluateSignals(inputs: FreshContextSignalInput[], options?: CoreSignalEvaluationOptions): CoreSignalEvaluationResult[];
|
package/dist/core/pipeline.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LAMBDA, calculateFreshnessScore } from "./decay.js";
|
|
2
2
|
import { formatForLLM, toStructuredJSON } from "./envelope.js";
|
|
3
3
|
import { calculateHaPriV2 } from "./provenance.js";
|
|
4
|
+
import { prepareProvenanceReadiness } from "./provenanceReadiness.js";
|
|
4
5
|
import { rankSignal } from "./rank.js";
|
|
5
6
|
import { normalizeSignal } from "./signal.js";
|
|
6
7
|
import { calculateContextUtility } from "./utility.js";
|
|
@@ -79,6 +80,12 @@ export function evaluateSignal(input, options = {}) {
|
|
|
79
80
|
const reasons = [...signal.reasons, ...utility.reasons];
|
|
80
81
|
const envelope = createEnvelope(signal, freshness_score, options);
|
|
81
82
|
const provenance = createProvenance(signal, options, reasons);
|
|
83
|
+
const provenance_readiness = prepareProvenanceReadiness(signal, {
|
|
84
|
+
now: options.now,
|
|
85
|
+
resultId: options.provenance?.resultId ?? signal.id,
|
|
86
|
+
semanticFingerprint: options.provenance?.semanticFingerprint ?? null,
|
|
87
|
+
engineVersion: options.provenance?.engineVersion,
|
|
88
|
+
});
|
|
82
89
|
return {
|
|
83
90
|
signal,
|
|
84
91
|
freshness_score,
|
|
@@ -87,6 +94,7 @@ export function evaluateSignal(input, options = {}) {
|
|
|
87
94
|
explanation: ranked.reason,
|
|
88
95
|
envelope,
|
|
89
96
|
provenance,
|
|
97
|
+
provenance_readiness,
|
|
90
98
|
reasons,
|
|
91
99
|
};
|
|
92
100
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { HaPriV2Input, HaPriV2Result, HaPriV2VerificationResult } from "./types.js";
|
|
2
|
+
export declare function canonicalizeHaPriContent(input: string): string;
|
|
3
|
+
export declare function sha256Hex(input: string): string;
|
|
4
|
+
export declare function calculateHaPriV2(input: HaPriV2Input): HaPriV2Result;
|
|
5
|
+
export declare function verifyHaPriV2(input: HaPriV2Input, actualSig: string | null | undefined): HaPriV2VerificationResult;
|