@relvehq/agent-ready 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -3
- package/SETUP.md +354 -354
- package/dist/core/report.d.ts +9 -3
- package/dist/core/report.js +30 -10
- package/dist/core/version.d.ts +1 -0
- package/dist/core/version.js +8 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -1
- package/dist/refine/check.d.ts +3 -1
- package/dist/refine/check.js +43 -0
- package/dist/refine/remote.d.ts +3 -2
- package/dist/refine/remote.js +3 -2
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-admin.php +560 -550
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-converter.php +762 -762
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-llms.php +192 -192
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-markdown-builder.php +455 -455
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-negotiation.php +334 -334
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-refiner.php +894 -894
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-reporter.php +147 -0
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-response.php +226 -226
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-router.php +422 -421
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-settings.php +210 -201
- package/dist/wp/relve-agent-ready/includes/class-relve-ar-store.php +583 -583
- package/dist/wp/relve-agent-ready/includes/index.php +2 -2
- package/dist/wp/relve-agent-ready/index.php +2 -2
- package/dist/wp/relve-agent-ready/readme.txt +119 -108
- package/dist/wp/relve-agent-ready/relve-agent-ready.php +82 -81
- package/dist/wp/relve-agent-ready/uninstall.php +35 -35
- package/package.json +1 -1
package/dist/core/report.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { HitEvent } from "./config";
|
|
2
|
+
/** Relve's ingest URL, used when AGENT_READY_ENDPOINT is not set. */
|
|
3
|
+
export declare const DEFAULT_HITS_ENDPOINT = "https://relvehq.com/api/agent-ready/v1/hits";
|
|
2
4
|
export interface ReporterOptions {
|
|
3
5
|
/** The venture's dashboard key. */
|
|
4
6
|
key: string;
|
|
5
|
-
/** Ingest URL that receives { key, event }. */
|
|
6
|
-
endpoint
|
|
7
|
+
/** Ingest URL that receives { key, client, event }. Default: Relve's. */
|
|
8
|
+
endpoint?: string;
|
|
7
9
|
/** Give up after this long. Default 2000 ms. */
|
|
8
10
|
timeoutMs?: number;
|
|
9
11
|
/** Injected for tests. */
|
|
@@ -11,5 +13,9 @@ export interface ReporterOptions {
|
|
|
11
13
|
}
|
|
12
14
|
/** An `onHit` that sends each event to the dashboard. */
|
|
13
15
|
export declare function reporter(opts: ReporterOptions): (event: HitEvent) => Promise<void>;
|
|
14
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* A reporter from env, or null when AGENT_READY_KEY is missing.
|
|
18
|
+
* AGENT_READY_ENDPOINT is optional (Relve's by default); when set it must be
|
|
19
|
+
* http(s), else null.
|
|
20
|
+
*/
|
|
15
21
|
export declare function reporterFromEnv(env: Record<string, string | undefined>): ((event: HitEvent) => Promise<void>) | null;
|
package/dist/core/report.js
CHANGED
|
@@ -2,28 +2,42 @@
|
|
|
2
2
|
// Measure, the easy way: send every agent visit to a dashboard with one key
|
|
3
3
|
// (changes/agent-ready-engine, "easy setup"). Replaces writing an `onHit`.
|
|
4
4
|
//
|
|
5
|
-
// AGENT_READY_KEY=
|
|
6
|
-
// AGENT_READY_ENDPOINT=https://.../hits
|
|
5
|
+
// AGENT_READY_KEY=ar_live_yoursite (your key: ar_ + 3-64 of A-Z a-z 0-9 _ -)
|
|
6
|
+
// AGENT_READY_ENDPOINT=https://.../hits (optional: another dashboard)
|
|
7
7
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
8
|
+
// With only AGENT_READY_KEY set, visits go to Relve's dashboard
|
|
9
|
+
// (DEFAULT_HITS_ENDPOINT, changes/agent-ready-telemetry). Nothing is sent
|
|
10
|
+
// unless the key is set: reporting is opt-in.
|
|
11
|
+
//
|
|
12
|
+
// What one report holds: the key, the package version and the HitEvent
|
|
13
|
+
// (time, host, path, how the Markdown was asked for and where it came from,
|
|
14
|
+
// status, tokens, bytes, the visitor's user agent, duration). Never the
|
|
15
|
+
// Markdown, never the visitor's IP.
|
|
16
|
+
//
|
|
17
|
+
// `reporter()` returns an `onHit` that POSTs { key, client, event } as JSON,
|
|
18
|
+
// with a short timeout and keepalive. Fire-and-forget like every `onHit`: it
|
|
19
|
+
// never throws and the response never waits for it.
|
|
11
20
|
//
|
|
12
21
|
// EDGE-SAFE. No Node APIs.
|
|
13
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.DEFAULT_HITS_ENDPOINT = void 0;
|
|
14
24
|
exports.reporter = reporter;
|
|
15
25
|
exports.reporterFromEnv = reporterFromEnv;
|
|
26
|
+
const version_1 = require("./version");
|
|
27
|
+
/** Relve's ingest URL, used when AGENT_READY_ENDPOINT is not set. */
|
|
28
|
+
exports.DEFAULT_HITS_ENDPOINT = "https://relvehq.com/api/agent-ready/v1/hits";
|
|
16
29
|
/** An `onHit` that sends each event to the dashboard. */
|
|
17
30
|
function reporter(opts) {
|
|
18
31
|
const f = opts.fetch ?? fetch;
|
|
32
|
+
const endpoint = opts.endpoint ?? exports.DEFAULT_HITS_ENDPOINT;
|
|
19
33
|
return async (event) => {
|
|
20
34
|
const ctl = new AbortController();
|
|
21
35
|
const timer = setTimeout(() => ctl.abort(), opts.timeoutMs ?? 2000);
|
|
22
36
|
try {
|
|
23
|
-
await f(
|
|
37
|
+
await f(endpoint, {
|
|
24
38
|
method: "POST",
|
|
25
39
|
headers: { "content-type": "application/json", authorization: `Bearer ${opts.key}` },
|
|
26
|
-
body: JSON.stringify({ key: opts.key, event }),
|
|
40
|
+
body: JSON.stringify({ key: opts.key, client: `npm/${version_1.PACKAGE_VERSION}`, event }),
|
|
27
41
|
keepalive: true,
|
|
28
42
|
signal: ctl.signal,
|
|
29
43
|
});
|
|
@@ -36,11 +50,17 @@ function reporter(opts) {
|
|
|
36
50
|
}
|
|
37
51
|
};
|
|
38
52
|
}
|
|
39
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* A reporter from env, or null when AGENT_READY_KEY is missing.
|
|
55
|
+
* AGENT_READY_ENDPOINT is optional (Relve's by default); when set it must be
|
|
56
|
+
* http(s), else null.
|
|
57
|
+
*/
|
|
40
58
|
function reporterFromEnv(env) {
|
|
41
59
|
const key = env.AGENT_READY_KEY?.trim();
|
|
42
60
|
const endpoint = env.AGENT_READY_ENDPOINT?.trim();
|
|
43
|
-
if (!key
|
|
61
|
+
if (!key)
|
|
62
|
+
return null;
|
|
63
|
+
if (endpoint && !/^https?:\/\//.test(endpoint))
|
|
44
64
|
return null;
|
|
45
|
-
return reporter({ key, endpoint });
|
|
65
|
+
return reporter({ key, endpoint: endpoint || undefined });
|
|
46
66
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PACKAGE_VERSION = "0.4.0";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The package version, in one place: the refine user agent and the visit
|
|
3
|
+
// reporter both send it, so Relve can tell which release a venture runs
|
|
4
|
+
// (changes/agent-ready-telemetry). Keep in step with package.json.
|
|
5
|
+
// EDGE-SAFE.
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.PACKAGE_VERSION = void 0;
|
|
8
|
+
exports.PACKAGE_VERSION = "0.4.0";
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ export { buildLlmsTxt, type BuildLlmsOptions } from "./core/llms";
|
|
|
6
6
|
export { byteLength, etagFor, ifNoneMatchHits, markdownResponse, MARKDOWN_CONTENT_TYPE, type RespondOptions } from "./core/respond";
|
|
7
7
|
export { COMMON_PRIVATE_PATHS, createAgentReady, enabledFromEnv, siteFromEnv, type EasyOptions, type Env } from "./core/easy";
|
|
8
8
|
export { entriesFromUrls, humanize, parseSitemap, sitemapEntries, type ParsedSitemap, type SitemapEntriesOptions } from "./core/sitemap";
|
|
9
|
-
export { reporter, reporterFromEnv, type ReporterOptions } from "./core/report";
|
|
9
|
+
export { DEFAULT_HITS_ENDPOINT, reporter, reporterFromEnv, type ReporterOptions } from "./core/report";
|
|
10
|
+
export { PACKAGE_VERSION } from "./core/version";
|
|
10
11
|
export { ANSWER_BOT_TOKENS, classifyAgent, isAnswerBot, type Bot, type BotKind } from "./proof/bots";
|
|
11
12
|
export { filterHits, memoryHitStore, teeHits, type HitQuery, type HitStore } from "./proof/hits";
|
|
12
13
|
export { formatSummary, summarize, type Count, type HitSummary } from "./proof/stats";
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
// @relvehq/agent-ready/next/route Next.js route handler
|
|
9
9
|
// and the Next.js middleware adapter lives at @relvehq/agent-ready/next.
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.
|
|
11
|
+
exports.blockedBots = exports.auditSite = exports.renderDashboard = exports.summarize = exports.formatSummary = exports.teeHits = exports.memoryHitStore = exports.filterHits = exports.isAnswerBot = exports.classifyAgent = exports.ANSWER_BOT_TOKENS = exports.PACKAGE_VERSION = exports.reporterFromEnv = exports.reporter = exports.DEFAULT_HITS_ENDPOINT = exports.sitemapEntries = exports.parseSitemap = exports.humanize = exports.entriesFromUrls = exports.siteFromEnv = exports.enabledFromEnv = exports.createAgentReady = exports.COMMON_PRIVATE_PATHS = exports.MARKDOWN_CONTENT_TYPE = exports.markdownResponse = exports.ifNoneMatchHits = exports.etagFor = exports.byteLength = exports.buildLlmsTxt = exports.jsonLdFacts = exports.hasFrontMatter = exports.frontMatter = exports.estimateTokens = exports.enrich = exports.wantsMarkdown = exports.stripMdSuffix = exports.normalizePath = exports.mdUrlPath = exports.isExcluded = exports.isEnabled = exports.emitHit = exports.defineAgentReady = exports.VIA_HEADER = exports.DEFAULT_NEGOTIATED_CACHE_CONTROL = exports.DEFAULT_INTERNAL_PREFIX = exports.DEFAULT_INTERNAL_HEADER = exports.DEFAULT_CACHE_CONTROL = exports.ALWAYS_EXCLUDE = exports.parseAccept = exports.chooseFormat = void 0;
|
|
12
|
+
exports.formatAudit = void 0;
|
|
12
13
|
var accept_1 = require("./core/accept");
|
|
13
14
|
Object.defineProperty(exports, "chooseFormat", { enumerable: true, get: function () { return accept_1.chooseFormat; } });
|
|
14
15
|
Object.defineProperty(exports, "parseAccept", { enumerable: true, get: function () { return accept_1.parseAccept; } });
|
|
@@ -54,8 +55,11 @@ Object.defineProperty(exports, "humanize", { enumerable: true, get: function ()
|
|
|
54
55
|
Object.defineProperty(exports, "parseSitemap", { enumerable: true, get: function () { return sitemap_1.parseSitemap; } });
|
|
55
56
|
Object.defineProperty(exports, "sitemapEntries", { enumerable: true, get: function () { return sitemap_1.sitemapEntries; } });
|
|
56
57
|
var report_1 = require("./core/report");
|
|
58
|
+
Object.defineProperty(exports, "DEFAULT_HITS_ENDPOINT", { enumerable: true, get: function () { return report_1.DEFAULT_HITS_ENDPOINT; } });
|
|
57
59
|
Object.defineProperty(exports, "reporter", { enumerable: true, get: function () { return report_1.reporter; } });
|
|
58
60
|
Object.defineProperty(exports, "reporterFromEnv", { enumerable: true, get: function () { return report_1.reporterFromEnv; } });
|
|
61
|
+
var version_1 = require("./core/version");
|
|
62
|
+
Object.defineProperty(exports, "PACKAGE_VERSION", { enumerable: true, get: function () { return version_1.PACKAGE_VERSION; } });
|
|
59
63
|
// Proof: who reads, how much, and how agent-ready a site is.
|
|
60
64
|
var bots_1 = require("./proof/bots");
|
|
61
65
|
Object.defineProperty(exports, "ANSWER_BOT_TOKENS", { enumerable: true, get: function () { return bots_1.ANSWER_BOT_TOKENS; } });
|
package/dist/refine/check.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PageInput } from "./types";
|
|
2
2
|
import type { PromptSettings } from "./prompts";
|
|
3
|
-
export type IssueKind = "number" | "url" | "frontmatter" | "hash" | "section" | "h1" | "html" | "placeholder" | "tokens" | "empty";
|
|
3
|
+
export type IssueKind = "number" | "url" | "frontmatter" | "hash" | "section" | "h1" | "html" | "placeholder" | "tokens" | "empty" | "plan";
|
|
4
4
|
export interface CheckIssue {
|
|
5
5
|
kind: IssueKind;
|
|
6
6
|
detail: string;
|
|
@@ -15,3 +15,5 @@ export interface CheckOptions {
|
|
|
15
15
|
countTokens?: (text: string) => number;
|
|
16
16
|
}
|
|
17
17
|
export declare function checkDoc(doc: string, input: PageInput, settings: PromptSettings, opts?: CheckOptions): CheckResult;
|
|
18
|
+
/** First-column names of the tables under "## Pricing" / "## Plans" headings. */
|
|
19
|
+
export declare function planNames(prose: string): string[];
|
package/dist/refine/check.js
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
// h1 not exactly one H1
|
|
13
13
|
// html HTML tags in the document
|
|
14
14
|
// placeholder a {{PLACEHOLDER}} or <Template field> left in
|
|
15
|
+
// plan a plan named in a "## Pricing" / "## Plans" table that the
|
|
16
|
+
// input never names (e.g. a made-up "Basic" built from the
|
|
17
|
+
// prices of other products shown on the page; 2026-10-29)
|
|
15
18
|
// tokens over the prompt's token budget
|
|
16
19
|
// empty no real body
|
|
17
20
|
//
|
|
@@ -20,6 +23,7 @@
|
|
|
20
23
|
// EDGE-SAFE (pure). It cannot catch a reworded claim; people still read.
|
|
21
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
25
|
exports.checkDoc = checkDoc;
|
|
26
|
+
exports.planNames = planNames;
|
|
23
27
|
const enrich_1 = require("../core/enrich");
|
|
24
28
|
const URL_RE = /https?:\/\/[^\s<>()[\]|"'`]+/g;
|
|
25
29
|
const NUM_RE = /\d+(?:[.,]\d+)*/g;
|
|
@@ -100,8 +104,47 @@ function checkDoc(doc, input, settings, opts = {}) {
|
|
|
100
104
|
seen.add(c);
|
|
101
105
|
add("number", n);
|
|
102
106
|
}
|
|
107
|
+
// Plans: every plan a Pricing / Plans table names must be named in the
|
|
108
|
+
// input. The number check alone passes a plan stitched together from
|
|
109
|
+
// prices that are on the page but belong to something else.
|
|
110
|
+
for (const name of planNames(prose)) {
|
|
111
|
+
if (!namedIn(haystack, name))
|
|
112
|
+
add("plan", name);
|
|
113
|
+
}
|
|
103
114
|
return { ok: issues.length === 0, issues, tokens };
|
|
104
115
|
}
|
|
116
|
+
/** First-column names of the tables under "## Pricing" / "## Plans" headings. */
|
|
117
|
+
function planNames(prose) {
|
|
118
|
+
const names = [];
|
|
119
|
+
for (const section of prose.split(/^(?=##\s)/m)) {
|
|
120
|
+
const heading = /^##\s+(.+)$/m.exec(section);
|
|
121
|
+
if (!heading || !/^(pricing|plans)\b/i.test(heading[1].trim()))
|
|
122
|
+
continue;
|
|
123
|
+
let header = true;
|
|
124
|
+
for (const line of section.split("\n")) {
|
|
125
|
+
if (!line.trim().startsWith("|")) {
|
|
126
|
+
header = true; // a new table starts with its own header row
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (/^\|[\s:|-]+\|?\s*$/.test(line.trim()))
|
|
130
|
+
continue; // separator row
|
|
131
|
+
if (header) {
|
|
132
|
+
header = false;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const cell = line.trim().replace(/^\|/, "").split("|")[0] ?? "";
|
|
136
|
+
const name = cell.replace(/[*_`]/g, "").replace(/\s+/g, " ").trim();
|
|
137
|
+
if (name)
|
|
138
|
+
names.push(name);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return names;
|
|
142
|
+
}
|
|
143
|
+
/** The name appears in the text as a whole word or phrase, ignoring case and spacing. */
|
|
144
|
+
function namedIn(text, name) {
|
|
145
|
+
const words = name.split(" ").map(escapeRe).join("\\s+");
|
|
146
|
+
return new RegExp(`(?<![A-Za-z0-9])${words}(?![A-Za-z0-9])`, "i").test(text);
|
|
147
|
+
}
|
|
105
148
|
/** "1,400" = "1400", "0.10" = "0.1", "05" = "5". */
|
|
106
149
|
function canonNum(s) {
|
|
107
150
|
const plain = s.replace(/,(?=\d{3}\b)/g, "");
|
package/dist/refine/remote.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { PACKAGE_VERSION } from "../core/version";
|
|
2
|
+
export { PACKAGE_VERSION };
|
|
2
3
|
export declare const DEFAULT_REFINE_ENDPOINT = "https://relvehq.com/api/agent-ready/v1/refine";
|
|
3
4
|
export declare const REFINE_MODELS: readonly ["gpt-4o", "gpt-4o-mini", "gpt-4.1", "gpt-4.1-mini"];
|
|
4
|
-
export declare const USER_AGENT = "agent-ready/0.
|
|
5
|
+
export declare const USER_AGENT = "agent-ready/0.4.0 (+https://relvehq.com/agent-ready)";
|
|
5
6
|
export type RemoteStatus = "ok" | "unchanged" | "rejected" | "error" | "skipped";
|
|
6
7
|
export interface RemoteItem {
|
|
7
8
|
path: string;
|
package/dist/refine/remote.js
CHANGED
|
@@ -52,10 +52,11 @@ exports.savedFingerprint = savedFingerprint;
|
|
|
52
52
|
exports.refineRemote = refineRemote;
|
|
53
53
|
exports.stopMessage = stopMessage;
|
|
54
54
|
const file_store_1 = require("./file-store");
|
|
55
|
-
|
|
55
|
+
const version_1 = require("../core/version");
|
|
56
|
+
Object.defineProperty(exports, "PACKAGE_VERSION", { enumerable: true, get: function () { return version_1.PACKAGE_VERSION; } });
|
|
56
57
|
exports.DEFAULT_REFINE_ENDPOINT = "https://relvehq.com/api/agent-ready/v1/refine";
|
|
57
58
|
exports.REFINE_MODELS = ["gpt-4o", "gpt-4o-mini", "gpt-4.1", "gpt-4.1-mini"];
|
|
58
|
-
exports.USER_AGENT = `agent-ready/${
|
|
59
|
+
exports.USER_AGENT = `agent-ready/${version_1.PACKAGE_VERSION} (+https://relvehq.com/agent-ready)`;
|
|
59
60
|
/** Errors that mean every later call would fail the same way: the run stops. */
|
|
60
61
|
const FATAL = new Set(["openai_auth", "openai_quota", "missing_key"]);
|
|
61
62
|
/** The saved JSON's fingerprint, else one built from a local run's sourceHash, else null. */
|