@agentronics/sdk 0.5.0 → 0.7.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 +96 -76
- package/dist/chunk-3WPDIMJP.js +18 -0
- package/dist/chunk-3WPDIMJP.js.map +1 -0
- package/dist/chunk-6QQS26AP.js +1200 -0
- package/dist/chunk-6QQS26AP.js.map +1 -0
- package/dist/chunk-BPDWJCPY.js +2 -0
- package/dist/chunk-BPDWJCPY.js.map +1 -0
- package/dist/index.cjs +8 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -12
- package/dist/index.d.ts +51 -12
- package/dist/index.global.js +8 -7
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/{init-only-7f8_LQAI.d.ts → init-only-C80qhujz.d.ts} +227 -30
- package/dist/{init-only-Cwll8MGz.d.cts → init-only-s9E9bVC0.d.cts} +227 -30
- package/dist/init-only.cjs +8 -7
- package/dist/init-only.cjs.map +1 -1
- package/dist/init-only.d.cts +2 -2
- package/dist/init-only.d.ts +2 -2
- package/dist/init-only.global.js +8 -7
- package/dist/init-only.global.js.map +1 -1
- package/dist/init-only.js +1 -1
- package/dist/lite.cjs +1 -1
- package/dist/lite.cjs.map +1 -1
- package/dist/lite.d.cts +2 -2
- package/dist/lite.d.ts +2 -2
- package/dist/lite.global.js +1 -1
- package/dist/lite.global.js.map +1 -1
- package/dist/lite.js +1 -1
- package/dist/middleware-Dd2T772u.d.cts +429 -0
- package/dist/middleware-Dd2T772u.d.ts +429 -0
- package/dist/next.cjs +1137 -0
- package/dist/next.cjs.map +1 -0
- package/dist/next.d.cts +20 -0
- package/dist/next.d.ts +20 -0
- package/dist/next.js +20 -0
- package/dist/next.js.map +1 -0
- package/dist/server.cjs +1321 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +131 -0
- package/dist/server.d.ts +131 -0
- package/dist/server.js +95 -0
- package/dist/server.js.map +1 -0
- package/dist/webmcp-BgKzHeQ3.d.cts +97 -0
- package/dist/webmcp-BgKzHeQ3.d.ts +97 -0
- package/package.json +38 -6
- package/dist/chunk-77VJ65X2.js +0 -17
- package/dist/chunk-77VJ65X2.js.map +0 -1
- package/dist/chunk-LLD3Y2LZ.js +0 -2
- package/dist/chunk-LLD3Y2LZ.js.map +0 -1
- package/dist/webmcp-C4ikhM4g.d.cts +0 -12
- package/dist/webmcp-C4ikhM4g.d.ts +0 -12
package/dist/server.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export { AGENT_HEADERS, DIRECTORY_PATH, PROTECTED_RESOURCE_PATH, PUBLISHED_IP_RANGES, RDNS_DOMAINS, WEB_BOT_AUTH_TAG, classifyUserAgent, clientIp, createAgentAuth, createAgentAuthHandler, expressAgentAuth, generateAgentKey, hashAgentKey, ipInCidr, ipInRanges, jwkThumbprint, memoryReplayCache, oauthChallenge, protectedResourceMetadata, rangesFor, readAgentHeaders, signatureBase, staticKeyVerifier, toTraceEvent, verifyCrawler, verifyOAuthToken, verifyWebBotAuth, withAgentHeaders } from './chunk-6QQS26AP.js';
|
|
2
|
+
|
|
3
|
+
// src/observability/exporters/intel.ts
|
|
4
|
+
var INGEST_PATH = "/v1/sdk/events";
|
|
5
|
+
var createIntelExporter = ({
|
|
6
|
+
url,
|
|
7
|
+
ingestKey,
|
|
8
|
+
fetcher = fetch
|
|
9
|
+
}) => {
|
|
10
|
+
const base = url.replace(/\/$/, "");
|
|
11
|
+
const endpoint = base.endsWith(INGEST_PATH) ? base : `${base}${INGEST_PATH}`;
|
|
12
|
+
return {
|
|
13
|
+
name: "intel",
|
|
14
|
+
async export(events) {
|
|
15
|
+
const batch = { events };
|
|
16
|
+
const response = await fetcher(endpoint, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: {
|
|
19
|
+
"content-type": "application/json",
|
|
20
|
+
authorization: `Bearer ${ingestKey}`
|
|
21
|
+
},
|
|
22
|
+
body: JSON.stringify(batch)
|
|
23
|
+
});
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(`Intel exporter failed with status ${response.status}.`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// src/server/relay.ts
|
|
32
|
+
var KNOWN_TYPES = /* @__PURE__ */ new Set([
|
|
33
|
+
"agent.detected",
|
|
34
|
+
"agent.missed",
|
|
35
|
+
"auth.identity_presented",
|
|
36
|
+
"auth.identity_cleared",
|
|
37
|
+
"authz.policies_set",
|
|
38
|
+
"authz.evaluated",
|
|
39
|
+
"memory.accessed",
|
|
40
|
+
"memory.updated",
|
|
41
|
+
"tool.registered",
|
|
42
|
+
"tool.executed",
|
|
43
|
+
"tool.surfaced",
|
|
44
|
+
"tool.progressed",
|
|
45
|
+
"sdk.error"
|
|
46
|
+
]);
|
|
47
|
+
function createTraceRelay(options) {
|
|
48
|
+
const exporter = createIntelExporter({ url: options.url, ingestKey: options.ingestKey, ...options.fetcher ? { fetcher: options.fetcher } : {} });
|
|
49
|
+
const max = options.maxEvents ?? 100;
|
|
50
|
+
return async function relay(request) {
|
|
51
|
+
if (request.method !== "POST") return new Response(null, { status: 405 });
|
|
52
|
+
let body;
|
|
53
|
+
try {
|
|
54
|
+
const text = await request.text();
|
|
55
|
+
if (text.length > 512e3) return new Response(null, { status: 413 });
|
|
56
|
+
body = JSON.parse(text);
|
|
57
|
+
} catch {
|
|
58
|
+
return new Response(null, { status: 400 });
|
|
59
|
+
}
|
|
60
|
+
const events = (Array.isArray(body.events) ? body.events : []).filter((e) => typeof e === "object" && e !== null && KNOWN_TYPES.has(String(e.type))).slice(0, max).map((e) => ({ ...e, siteId: options.siteId }));
|
|
61
|
+
if (events.length) {
|
|
62
|
+
await Promise.all([
|
|
63
|
+
Promise.resolve(exporter.export(events)).catch(() => void 0),
|
|
64
|
+
options.forward ? Promise.resolve().then(() => options.forward(events)).catch(() => void 0) : void 0
|
|
65
|
+
]);
|
|
66
|
+
}
|
|
67
|
+
return new Response(null, { status: 202 });
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/server/agentContext.ts
|
|
72
|
+
function createAgentContextHandler({ sync, cacheSeconds = 300 }) {
|
|
73
|
+
let cached = null;
|
|
74
|
+
return async function agentContext() {
|
|
75
|
+
if (!cached || cached.until <= Date.now()) {
|
|
76
|
+
try {
|
|
77
|
+
const { siteMemory } = await sync.pullConfig();
|
|
78
|
+
if (siteMemory && Object.keys(siteMemory).length) cached = { body: JSON.stringify(siteMemory), until: Date.now() + cacheSeconds * 1e3 };
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (!cached) return new Response(JSON.stringify({ error: "no_site_memory" }), { status: 404, headers: { "content-type": "application/json" } });
|
|
83
|
+
return new Response(cached.body, {
|
|
84
|
+
headers: {
|
|
85
|
+
"content-type": "application/json",
|
|
86
|
+
"cache-control": `public, max-age=${cacheSeconds}`,
|
|
87
|
+
"access-control-allow-origin": "*"
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { createAgentContextHandler, createTraceRelay };
|
|
94
|
+
//# sourceMappingURL=server.js.map
|
|
95
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/observability/exporters/intel.ts","../src/server/relay.ts","../src/server/agentContext.ts"],"names":[],"mappings":"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","file":"server.js","sourcesContent":["import type { TraceBatch, TraceEvent as TraceEventRecord } from '@agentronics/protocol'\nimport type { TraceExporter } from '../tracer.js'\nimport type { GovernedTool } from '../../tools/registry.js'\nimport type { PolicyRule } from '@agentronics/protocol'\nimport { toToolDescriptor } from '../../tools/toolSync.js'\n\n/** Mirrors ApiKeyIdentity in @agentronics/sdk/server (kept structural to avoid a server import). */\nexport interface ApiKeyIdentity {\n agentId: string\n name?: string\n vendor?: string\n scopes?: string[]\n}\n\nexport interface IntelExporterOptions {\n /**\n * Agentronics API base URL (shown in the console under Settings) — the\n * `/v1/sdk/events` path is appended automatically — or the full ingest URL.\n */\n url: string\n /**\n * Per-tenant SDK ingest key (`agtx_ik_…`), minted in the dashboard Settings.\n * This is a **secret**: use this exporter in your backend only, never in the\n * browser. (The browser SDK should forward traces to your backend, which\n * relays them with the key.)\n */\n ingestKey: string\n fetcher?: typeof fetch\n}\n\nconst INGEST_PATH = '/v1/sdk/events'\n\n/**\n * Stream traces (agent sign-ins, verifications, access decisions) to the\n * Agentronics dashboard.\n * POSTs a `TraceBatch` to the intel-api ingest endpoint with the ingest key.\n * Intended for Node/server use (the existing webhook exporter is browser-bound\n * and can't send an auth header).\n */\n/** @deprecated Use createDashboardExporter (same function). */\nexport const createIntelExporter = ({\n url,\n ingestKey,\n fetcher = fetch,\n}: IntelExporterOptions): TraceExporter => {\n const base = url.replace(/\\/$/, '')\n const endpoint = base.endsWith(INGEST_PATH) ? base : `${base}${INGEST_PATH}`\n return {\n name: 'intel',\n async export(events: TraceEventRecord[]) {\n const batch: TraceBatch = { events }\n const response = await fetcher(endpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${ingestKey}`,\n },\n body: JSON.stringify(batch),\n })\n if (!response.ok) {\n throw new Error(`Intel exporter failed with status ${response.status}.`)\n }\n },\n }\n}\n\nexport interface IntelSyncOptions {\n /** Agentronics API base URL (shown in the console under Settings). */\n url: string\n /** Per-tenant SDK ingest key (`agtx_ik_…`). Backend-only — never the browser. */\n ingestKey: string\n /** The site these tools/memory belong to (matches your SDK `siteId`). */\n siteId: string\n fetcher?: typeof fetch\n}\n\n/**\n * Push the authoritative tool registry + site-memory snapshot to the\n * Agentronics console — the full data the WebMCP Tools + Knaph pages need,\n * which is too large for the lightweight trace stream. Call after `syncTools()`\n * / `provideSiteMemory(...)`. Backend/server use only (the key is secret).\n */\nexport interface IntelSync {\n /** POST the registry to /v1/sdk/tools. Returns the number of tools sent. */\n pushTools(tools: GovernedTool[]): Promise<number>\n /** POST the site-memory snapshot (+ optional quality score) to /v1/sdk/memory. */\n pushMemory(snapshot: object, score?: number): Promise<void>\n /**\n * Fetch what the console manages for this site: authorization rules and the\n * tool descriptions you approved in Procedural memory. Pass them to the\n * browser SDK — `init({ policies, toolDescriptions })`.\n */\n pullConfig(): Promise<DashboardConfig>\n /**\n * An agent-API-key verifier for `createAgentAuth({ apiKey: { verify } })`\n * that checks keys minted in the console, live — revoking a key in the\n * console takes effect within `cacheSeconds` (default 60).\n */\n keyVerifier(options?: { cacheSeconds?: number }): (key: string) => Promise<ApiKeyIdentity | null>\n}\n\nexport interface DashboardConfig {\n policies: PolicyRule[]\n /** tool name → approved description (replaces the code's description when published). */\n toolDescriptions: Record<string, string>\n /** The site-memory snapshot last pushed for this site (null if none). */\n siteMemory: Record<string, unknown> | null\n fetchedAt: string\n}\n\n/** @deprecated Use createDashboardSync (same function). */\nexport const createIntelSync = ({\n url,\n ingestKey,\n siteId,\n fetcher = fetch,\n}: IntelSyncOptions): IntelSync => {\n const base = url.replace(/\\/$/, '')\n const call = async (path: string, body: unknown): Promise<Response> => {\n const response = await fetcher(`${base}${path}`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${ingestKey}`,\n },\n body: JSON.stringify(body),\n })\n if (!response.ok) {\n throw new Error(`Intel sync ${path} failed with status ${response.status}.`)\n }\n return response\n }\n const post = async (path: string, body: unknown): Promise<void> => {\n await call(path, body)\n }\n const keyCache = new Map<string, { value: ApiKeyIdentity | null; until: number }>()\n\n return {\n async pushTools(tools: GovernedTool[]) {\n const descriptors = tools.map(toToolDescriptor)\n await post('/v1/sdk/tools', { siteId, tools: descriptors })\n return descriptors.length\n },\n async pushMemory(snapshot: object, score?: number) {\n await post('/v1/sdk/memory', {\n siteId,\n snapshot,\n ...(typeof score === 'number' ? { score } : {}),\n })\n },\n async pullConfig() {\n const body = (await (await call('/v1/sdk/config', { siteId })).json()) as Partial<DashboardConfig>\n return {\n policies: Array.isArray(body.policies) ? body.policies : [],\n toolDescriptions: body.toolDescriptions && typeof body.toolDescriptions === 'object' ? body.toolDescriptions : {},\n siteMemory: body.siteMemory && typeof body.siteMemory === 'object' ? body.siteMemory : null,\n fetchedAt: typeof body.fetchedAt === 'string' ? body.fetchedAt : new Date().toISOString(),\n }\n },\n keyVerifier({ cacheSeconds = 60 } = {}) {\n return async (key: string) => {\n const hit = keyCache.get(key)\n if (hit && hit.until > Date.now()) return hit.value\n let value: ApiKeyIdentity | null = null\n try {\n const body = (await (await call('/v1/sdk/agent-keys/verify', { key })).json()) as {\n valid?: boolean\n agentId?: string\n name?: string\n vendor?: string | null\n }\n if (body.valid && body.agentId) {\n value = { agentId: body.agentId }\n if (body.name) value.name = body.name\n if (body.vendor) value.vendor = body.vendor\n }\n } catch {\n // Console unreachable: serve a cached answer if we had one, else \"unknown key\".\n if (hit) return hit.value\n return null\n }\n if (keyCache.size > 5000) keyCache.delete(keyCache.keys().next().value as string)\n keyCache.set(key, { value, until: Date.now() + cacheSeconds * 1000 })\n return value\n }\n },\n }\n}\n\n/** Preferred name. Streams SDK traces to the Agentronics dashboard. */\nexport const createDashboardExporter = createIntelExporter\n/** Preferred name for createIntelSync. */\nexport const createDashboardSync = createIntelSync\n","/**\n * Relay browser traces to the Agentronics console.\n *\n * The browser SDK can't hold the ingest key (it's a secret), so it posts its\n * traces to a route on your own site (`init({ trace: { webhookUrl: '/api/agentronics' } })`)\n * and this handler forwards them with the key:\n *\n * // app/api/agentronics/route.ts (Next.js)\n * const relay = createTraceRelay({ url: process.env.AGENTRONICS_API_URL!, ingestKey: process.env.AGENTRONICS_INGEST_KEY!, siteId: 'shop' })\n * export const POST = relay\n *\n * Every event is pinned to your `siteId`, batches are capped, and the relay\n * always answers 202 quickly — a console outage never breaks the page.\n */\nimport { createIntelExporter } from '../observability/exporters/intel.js'\n\nexport interface TraceRelayOptions {\n url: string\n ingestKey: string\n /** Events are re-labelled with this site id, whatever the browser sent. */\n siteId: string\n /** Max events accepted per request. Default 100. */\n maxEvents?: number\n /**\n * Also hand every accepted batch to your own sink — a warehouse, a queue,\n * a webhook. Runs alongside the console export; failures are ignored.\n */\n forward?: (events: Array<Record<string, unknown>>) => unknown\n fetcher?: typeof fetch\n}\n\nconst KNOWN_TYPES = new Set([\n 'agent.detected',\n 'agent.missed',\n 'auth.identity_presented',\n 'auth.identity_cleared',\n 'authz.policies_set',\n 'authz.evaluated',\n 'memory.accessed',\n 'memory.updated',\n 'tool.registered',\n 'tool.executed',\n 'tool.surfaced',\n 'tool.progressed',\n 'sdk.error',\n])\n\nexport function createTraceRelay(options: TraceRelayOptions) {\n const exporter = createIntelExporter({ url: options.url, ingestKey: options.ingestKey, ...(options.fetcher ? { fetcher: options.fetcher } : {}) })\n const max = options.maxEvents ?? 100\n return async function relay(request: Request): Promise<Response> {\n if (request.method !== 'POST') return new Response(null, { status: 405 })\n let body: { events?: unknown }\n try {\n const text = await request.text()\n if (text.length > 512_000) return new Response(null, { status: 413 })\n body = JSON.parse(text) as { events?: unknown }\n } catch {\n return new Response(null, { status: 400 })\n }\n const events = (Array.isArray(body.events) ? body.events : [])\n .filter((e): e is Record<string, unknown> => typeof e === 'object' && e !== null && KNOWN_TYPES.has(String((e as { type?: unknown }).type)))\n .slice(0, max)\n .map((e) => ({ ...e, siteId: options.siteId })) as unknown as Parameters<typeof exporter.export>[0]\n if (events.length) {\n await Promise.all([\n Promise.resolve(exporter.export(events)).catch(() => undefined),\n options.forward ? Promise.resolve().then(() => options.forward!(events as unknown as Array<Record<string, unknown>>)).catch(() => undefined) : undefined,\n ])\n }\n return new Response(null, { status: 202 })\n }\n}\n","/**\n * Serve `/.well-known/agent-context.json` — your site memory, for any agent,\n * with no SDK on their side — from what you manage in the Agentronics console.\n *\n * // app/.well-known/agent-context.json/route.ts (Next.js)\n * export const GET = createAgentContextHandler({ sync })\n *\n * The snapshot comes from `sync.pullConfig()` (the last `pushMemory()` for this\n * site), cached in memory. If the console can't be reached, the last good\n * snapshot keeps being served; with none, the route answers 404.\n */\nimport type { IntelSync } from '../observability/exporters/intel.js'\n\nexport interface AgentContextHandlerOptions {\n sync: Pick<IntelSync, 'pullConfig'>\n /** How long to reuse a snapshot. Default 300 s. */\n cacheSeconds?: number\n}\n\nexport function createAgentContextHandler({ sync, cacheSeconds = 300 }: AgentContextHandlerOptions) {\n let cached: { body: string; until: number } | null = null\n return async function agentContext(): Promise<Response> {\n if (!cached || cached.until <= Date.now()) {\n try {\n const { siteMemory } = await sync.pullConfig()\n if (siteMemory && Object.keys(siteMemory).length) cached = { body: JSON.stringify(siteMemory), until: Date.now() + cacheSeconds * 1000 }\n } catch {\n // keep serving the last good snapshot\n }\n }\n if (!cached) return new Response(JSON.stringify({ error: 'no_site_memory' }), { status: 404, headers: { 'content-type': 'application/json' } })\n return new Response(cached.body, {\n headers: {\n 'content-type': 'application/json',\n 'cache-control': `public, max-age=${cacheSeconds}`,\n 'access-control-allow-origin': '*',\n },\n })\n }\n}\n"]}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { AgentIdentity } from '@agentronics/protocol';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The WebMCP `ModelContext` surface, per the W3C WebMCP draft (Oct 2026):
|
|
5
|
+
*
|
|
6
|
+
* await document.modelContext.registerTool(tool, { signal, exposedTo })
|
|
7
|
+
*
|
|
8
|
+
* - The getter lives on `document`. `navigator.modelContext` was the old name;
|
|
9
|
+
* Chrome 150 kept it as an alias and Chrome 152 removed it, so it's read
|
|
10
|
+
* only as a fallback.
|
|
11
|
+
* - `registerTool()` is async. There is no `unregisterTool()`; aborting the
|
|
12
|
+
* `signal` passed at registration unregisters the tool.
|
|
13
|
+
* - `toolactivated` / `toolcancel` events fire on the ModelContext when an
|
|
14
|
+
* agent starts or cancels a tool call — the only reliable "an agent is here"
|
|
15
|
+
* signal, because the API itself exists for every visitor of a WebMCP browser.
|
|
16
|
+
* - The declarative form API (`<form toolname>`) was removed from the spec
|
|
17
|
+
* (Oct 8, 2026) and lives on only as an explainer; the SDK registers every
|
|
18
|
+
* tool imperatively.
|
|
19
|
+
*/
|
|
20
|
+
interface ToolAnnotations {
|
|
21
|
+
/** The tool only reads; agents may call it without asking the user. */
|
|
22
|
+
readOnlyHint?: boolean;
|
|
23
|
+
/** The tool's output includes content the site didn't author (reviews, messages, …). */
|
|
24
|
+
untrustedContentHint?: boolean;
|
|
25
|
+
/** Payments, deletes, sends — the agent should confirm with the user first. */
|
|
26
|
+
consequentialHint?: boolean;
|
|
27
|
+
/** Exposed only to agent debugging tools. */
|
|
28
|
+
debugging?: boolean;
|
|
29
|
+
}
|
|
30
|
+
interface ToolExecuteOptions {
|
|
31
|
+
signal: AbortSignal;
|
|
32
|
+
}
|
|
33
|
+
interface ModelContextTool {
|
|
34
|
+
name: string;
|
|
35
|
+
title?: string;
|
|
36
|
+
description: string;
|
|
37
|
+
inputSchema?: Record<string, unknown>;
|
|
38
|
+
annotations?: ToolAnnotations;
|
|
39
|
+
execute: (input: Record<string, unknown>, options: ToolExecuteOptions) => Promise<unknown>;
|
|
40
|
+
}
|
|
41
|
+
interface RegisterToolOptions {
|
|
42
|
+
signal?: AbortSignal;
|
|
43
|
+
/** Origins (besides this one) whose agents may see the tool. */
|
|
44
|
+
exposedTo?: string[];
|
|
45
|
+
}
|
|
46
|
+
interface ModelContextLike {
|
|
47
|
+
registerTool(tool: ModelContextTool, options?: RegisterToolOptions): Promise<void> | void;
|
|
48
|
+
addEventListener?: (type: string, listener: (event: Event) => void) => void;
|
|
49
|
+
removeEventListener?: (type: string, listener: (event: Event) => void) => void;
|
|
50
|
+
}
|
|
51
|
+
/** Very old polyfills exposed `provideContext({ tools })` instead of `registerTool`. */
|
|
52
|
+
interface LegacyProvider {
|
|
53
|
+
provideContext(payload: {
|
|
54
|
+
tools: Array<{
|
|
55
|
+
name: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
inputSchema?: Record<string, unknown>;
|
|
58
|
+
invoke(input?: unknown): Promise<unknown>;
|
|
59
|
+
}>;
|
|
60
|
+
}): {
|
|
61
|
+
revoke: () => void;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
type ModelContextSource = 'document' | 'navigator' | 'legacy';
|
|
65
|
+
interface ResolvedModelContext {
|
|
66
|
+
source: ModelContextSource;
|
|
67
|
+
context: ModelContextLike | LegacyProvider;
|
|
68
|
+
}
|
|
69
|
+
interface HostLike {
|
|
70
|
+
document?: {
|
|
71
|
+
modelContext?: unknown;
|
|
72
|
+
} | null;
|
|
73
|
+
navigator?: {
|
|
74
|
+
modelContext?: unknown;
|
|
75
|
+
} | null;
|
|
76
|
+
}
|
|
77
|
+
/** Find the page's ModelContext: `document.modelContext`, then the legacy names. */
|
|
78
|
+
declare const resolveModelContext: (host?: HostLike | null) => ResolvedModelContext | null;
|
|
79
|
+
interface WebMcpActivity {
|
|
80
|
+
type: 'activated' | 'cancelled' | 'executed';
|
|
81
|
+
toolName: string;
|
|
82
|
+
at: number;
|
|
83
|
+
}
|
|
84
|
+
declare const onWebMcpActivity: (listener: (activity: WebMcpActivity) => void) => () => void;
|
|
85
|
+
|
|
86
|
+
interface DetectWebMcpOptions {
|
|
87
|
+
/**
|
|
88
|
+
* Wait up to this many milliseconds for an agent to act (or an extension to
|
|
89
|
+
* inject itself). 0 reads once and returns immediately.
|
|
90
|
+
*/
|
|
91
|
+
pollMs?: number;
|
|
92
|
+
}
|
|
93
|
+
/** Whether this page can serve WebMCP tools, and through which surface. */
|
|
94
|
+
declare const webMcpSupport: () => ModelContextSource | null;
|
|
95
|
+
declare const detectWebMcp: (options?: DetectWebMcpOptions) => Promise<AgentIdentity | null>;
|
|
96
|
+
|
|
97
|
+
export { type DetectWebMcpOptions as D, type LegacyProvider as L, type ModelContextTool as M, type ToolAnnotations as T, type WebMcpActivity as W, type ModelContextSource as a, type ModelContextLike as b, detectWebMcp as d, onWebMcpActivity as o, resolveModelContext as r, webMcpSupport as w };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { AgentIdentity } from '@agentronics/protocol';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The WebMCP `ModelContext` surface, per the W3C WebMCP draft (Oct 2026):
|
|
5
|
+
*
|
|
6
|
+
* await document.modelContext.registerTool(tool, { signal, exposedTo })
|
|
7
|
+
*
|
|
8
|
+
* - The getter lives on `document`. `navigator.modelContext` was the old name;
|
|
9
|
+
* Chrome 150 kept it as an alias and Chrome 152 removed it, so it's read
|
|
10
|
+
* only as a fallback.
|
|
11
|
+
* - `registerTool()` is async. There is no `unregisterTool()`; aborting the
|
|
12
|
+
* `signal` passed at registration unregisters the tool.
|
|
13
|
+
* - `toolactivated` / `toolcancel` events fire on the ModelContext when an
|
|
14
|
+
* agent starts or cancels a tool call — the only reliable "an agent is here"
|
|
15
|
+
* signal, because the API itself exists for every visitor of a WebMCP browser.
|
|
16
|
+
* - The declarative form API (`<form toolname>`) was removed from the spec
|
|
17
|
+
* (Oct 8, 2026) and lives on only as an explainer; the SDK registers every
|
|
18
|
+
* tool imperatively.
|
|
19
|
+
*/
|
|
20
|
+
interface ToolAnnotations {
|
|
21
|
+
/** The tool only reads; agents may call it without asking the user. */
|
|
22
|
+
readOnlyHint?: boolean;
|
|
23
|
+
/** The tool's output includes content the site didn't author (reviews, messages, …). */
|
|
24
|
+
untrustedContentHint?: boolean;
|
|
25
|
+
/** Payments, deletes, sends — the agent should confirm with the user first. */
|
|
26
|
+
consequentialHint?: boolean;
|
|
27
|
+
/** Exposed only to agent debugging tools. */
|
|
28
|
+
debugging?: boolean;
|
|
29
|
+
}
|
|
30
|
+
interface ToolExecuteOptions {
|
|
31
|
+
signal: AbortSignal;
|
|
32
|
+
}
|
|
33
|
+
interface ModelContextTool {
|
|
34
|
+
name: string;
|
|
35
|
+
title?: string;
|
|
36
|
+
description: string;
|
|
37
|
+
inputSchema?: Record<string, unknown>;
|
|
38
|
+
annotations?: ToolAnnotations;
|
|
39
|
+
execute: (input: Record<string, unknown>, options: ToolExecuteOptions) => Promise<unknown>;
|
|
40
|
+
}
|
|
41
|
+
interface RegisterToolOptions {
|
|
42
|
+
signal?: AbortSignal;
|
|
43
|
+
/** Origins (besides this one) whose agents may see the tool. */
|
|
44
|
+
exposedTo?: string[];
|
|
45
|
+
}
|
|
46
|
+
interface ModelContextLike {
|
|
47
|
+
registerTool(tool: ModelContextTool, options?: RegisterToolOptions): Promise<void> | void;
|
|
48
|
+
addEventListener?: (type: string, listener: (event: Event) => void) => void;
|
|
49
|
+
removeEventListener?: (type: string, listener: (event: Event) => void) => void;
|
|
50
|
+
}
|
|
51
|
+
/** Very old polyfills exposed `provideContext({ tools })` instead of `registerTool`. */
|
|
52
|
+
interface LegacyProvider {
|
|
53
|
+
provideContext(payload: {
|
|
54
|
+
tools: Array<{
|
|
55
|
+
name: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
inputSchema?: Record<string, unknown>;
|
|
58
|
+
invoke(input?: unknown): Promise<unknown>;
|
|
59
|
+
}>;
|
|
60
|
+
}): {
|
|
61
|
+
revoke: () => void;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
type ModelContextSource = 'document' | 'navigator' | 'legacy';
|
|
65
|
+
interface ResolvedModelContext {
|
|
66
|
+
source: ModelContextSource;
|
|
67
|
+
context: ModelContextLike | LegacyProvider;
|
|
68
|
+
}
|
|
69
|
+
interface HostLike {
|
|
70
|
+
document?: {
|
|
71
|
+
modelContext?: unknown;
|
|
72
|
+
} | null;
|
|
73
|
+
navigator?: {
|
|
74
|
+
modelContext?: unknown;
|
|
75
|
+
} | null;
|
|
76
|
+
}
|
|
77
|
+
/** Find the page's ModelContext: `document.modelContext`, then the legacy names. */
|
|
78
|
+
declare const resolveModelContext: (host?: HostLike | null) => ResolvedModelContext | null;
|
|
79
|
+
interface WebMcpActivity {
|
|
80
|
+
type: 'activated' | 'cancelled' | 'executed';
|
|
81
|
+
toolName: string;
|
|
82
|
+
at: number;
|
|
83
|
+
}
|
|
84
|
+
declare const onWebMcpActivity: (listener: (activity: WebMcpActivity) => void) => () => void;
|
|
85
|
+
|
|
86
|
+
interface DetectWebMcpOptions {
|
|
87
|
+
/**
|
|
88
|
+
* Wait up to this many milliseconds for an agent to act (or an extension to
|
|
89
|
+
* inject itself). 0 reads once and returns immediately.
|
|
90
|
+
*/
|
|
91
|
+
pollMs?: number;
|
|
92
|
+
}
|
|
93
|
+
/** Whether this page can serve WebMCP tools, and through which surface. */
|
|
94
|
+
declare const webMcpSupport: () => ModelContextSource | null;
|
|
95
|
+
declare const detectWebMcp: (options?: DetectWebMcpOptions) => Promise<AgentIdentity | null>;
|
|
96
|
+
|
|
97
|
+
export { type DetectWebMcpOptions as D, type LegacyProvider as L, type ModelContextTool as M, type ToolAnnotations as T, type WebMcpActivity as W, type ModelContextSource as a, type ModelContextLike as b, detectWebMcp as d, onWebMcpActivity as o, resolveModelContext as r, webMcpSupport as w };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentronics/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "Govern AI agents on your site — detect them (WebMCP, browser, vision, crawlers), authenticate them (Web Bot Auth, OAuth 2.1, agent API keys, verified crawlers), authorize every WebMCP tool call (allow / deny / review), and observe it all.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -24,6 +24,16 @@
|
|
|
24
24
|
"types": "./dist/lite.d.ts",
|
|
25
25
|
"import": "./dist/lite.js",
|
|
26
26
|
"require": "./dist/lite.cjs"
|
|
27
|
+
},
|
|
28
|
+
"./server": {
|
|
29
|
+
"types": "./dist/server.d.ts",
|
|
30
|
+
"import": "./dist/server.js",
|
|
31
|
+
"require": "./dist/server.cjs"
|
|
32
|
+
},
|
|
33
|
+
"./next": {
|
|
34
|
+
"types": "./dist/next.d.ts",
|
|
35
|
+
"import": "./dist/next.js",
|
|
36
|
+
"require": "./dist/next.cjs"
|
|
27
37
|
}
|
|
28
38
|
},
|
|
29
39
|
"files": [
|
|
@@ -31,7 +41,8 @@
|
|
|
31
41
|
"README.md"
|
|
32
42
|
],
|
|
33
43
|
"dependencies": {
|
|
34
|
-
"
|
|
44
|
+
"jose": "^6.2.3",
|
|
45
|
+
"@agentronics/protocol": "0.5.0"
|
|
35
46
|
},
|
|
36
47
|
"devDependencies": {
|
|
37
48
|
"@size-limit/preset-small-lib": "^11.1.6",
|
|
@@ -40,15 +51,16 @@
|
|
|
40
51
|
"tsup": "^8.3.5",
|
|
41
52
|
"typescript": "^5.7.2",
|
|
42
53
|
"vitest": "^2.1.8",
|
|
54
|
+
"next": "^15.5.27",
|
|
55
|
+
"@agentronics/eslint-config": "0.0.0",
|
|
43
56
|
"@agentronics/tsconfig": "0.0.0",
|
|
44
|
-
"@agentronics/tsup-config": "0.0.0"
|
|
45
|
-
"@agentronics/eslint-config": "0.0.0"
|
|
57
|
+
"@agentronics/tsup-config": "0.0.0"
|
|
46
58
|
},
|
|
47
59
|
"size-limit": [
|
|
48
60
|
{
|
|
49
61
|
"name": "Agentronics.init reachable graph (esm, brotli)",
|
|
50
62
|
"path": "dist/init-only.js",
|
|
51
|
-
"limit": "
|
|
63
|
+
"limit": "28 KB"
|
|
52
64
|
},
|
|
53
65
|
{
|
|
54
66
|
"name": "lite (esm, gzipped)",
|
|
@@ -64,6 +76,26 @@
|
|
|
64
76
|
"publishConfig": {
|
|
65
77
|
"access": "public"
|
|
66
78
|
},
|
|
79
|
+
"peerDependencies": {
|
|
80
|
+
"next": ">=14"
|
|
81
|
+
},
|
|
82
|
+
"peerDependenciesMeta": {
|
|
83
|
+
"next": {
|
|
84
|
+
"optional": true
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"keywords": [
|
|
88
|
+
"ai-agents",
|
|
89
|
+
"agent-authentication",
|
|
90
|
+
"web-bot-auth",
|
|
91
|
+
"http-message-signatures",
|
|
92
|
+
"rfc9421",
|
|
93
|
+
"webmcp",
|
|
94
|
+
"bot-verification",
|
|
95
|
+
"oauth2",
|
|
96
|
+
"mtls",
|
|
97
|
+
"spiffe"
|
|
98
|
+
],
|
|
67
99
|
"scripts": {
|
|
68
100
|
"build": "tsup",
|
|
69
101
|
"dev": "tsup --watch",
|
package/dist/chunk-77VJ65X2.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import {a,b}from'./chunk-LLD3Y2LZ.js';import {AgentClass,isHigherTrust,IdentityClaim,AgentronicsError,PolicyRule,MemoryEntry,SiteMemory,SITE_MEMORY_DEFAULT,TraceEvent,classifyApiKey,PUBLISHABLE_KEY_PREFIX,TRUST_RANK,SiteMemoryPageContext}from'@agentronics/protocol';var pe=[{name:"GPTBot",category:"ai",pattern:/GPTBot/i},{name:"OAI-SearchBot",category:"ai",pattern:/OAI-SearchBot/i},{name:"ChatGPT-User",category:"ai",pattern:/ChatGPT-User/i},{name:"ClaudeBot",category:"ai",pattern:/ClaudeBot/i},{name:"Claude-Web",category:"ai",pattern:/Claude-Web/i},{name:"anthropic-ai",category:"ai",pattern:/anthropic-ai/i},{name:"PerplexityBot",category:"ai",pattern:/PerplexityBot/i},{name:"Google-Extended",category:"ai",pattern:/Google-Extended/i},{name:"Applebot-Extended",category:"ai",pattern:/Applebot-Extended/i},{name:"Amazonbot",category:"ai",pattern:/Amazonbot/i},{name:"Bytespider",category:"ai",pattern:/Bytespider/i},{name:"CCBot",category:"ai",pattern:/CCBot/i},{name:"Meta-ExternalAgent",category:"ai",pattern:/Meta-ExternalAgent/i},{name:"cohere-ai",category:"ai",pattern:/cohere-ai/i},{name:"Googlebot",category:"search",pattern:/Googlebot/i},{name:"Bingbot",category:"search",pattern:/bingbot/i},{name:"DuckDuckBot",category:"search",pattern:/DuckDuckBot/i},{name:"YandexBot",category:"search",pattern:/YandexBot/i},{name:"Baiduspider",category:"search",pattern:/Baiduspider/i},{name:"Applebot",category:"search",pattern:/Applebot/i}],$=(e={})=>{let{signatures:t=pe,disable:r=false,confidence:n=.9}=e;if(r||typeof navigator>"u")return null;let o=navigator.userAgent??"";if(!o)return null;for(let a$1 of t)if(a$1.pattern.test(o))return {class:"crawler",trust:"detected",confidence:n,vendor:a$1.name,userAgent:o,detectionVersion:a,signals:{matched:a$1.name,category:a$1.category,ua:o}};return null};var vt=[/HeadlessChrome/i,/Headless/i,/PhantomJS/i,/SlimerJS/i],wt=()=>({hit:(typeof navigator<"u"&&navigator.webdriver)===true,weight:.6,detail:"navigator.webdriver === true"}),xt=()=>{if(typeof window>"u")return {hit:false,weight:.5};let e=Object.keys(window).filter(t=>t.startsWith("cdc_"));return {hit:e.length>0,weight:.5,detail:`window.${e[0]??"cdc_*"}`}},St=()=>{if(typeof navigator>"u"||!navigator.plugins)return {hit:false,weight:.2};let e=/Win|Mac|Linux/.test(navigator.userAgent??""),t=navigator.plugins.length===0;return {hit:e&&t,weight:.2,detail:"desktop UA with no plugins"}},bt=()=>{if(typeof navigator>"u")return {hit:false,weight:.7};let e=navigator.userAgent??"",t=vt.some(r=>r.test(e));return t?{hit:t,weight:.7,detail:`headless UA: ${e}`}:{hit:t,weight:.7}},Tt=()=>{if(typeof navigator>"u")return {hit:false,weight:.15};let e=navigator.languages;return {hit:!e||e.length===0,weight:.15,detail:"navigator.languages empty"}},At=()=>{if(typeof navigator>"u")return {hit:false,weight:.1};let e="chrome"in window,t=navigator.userAgent??"";return {hit:/Chrome\//.test(t)&&!/Edg\//.test(t)&&!e,weight:.2,detail:"Chrome UA without window.chrome"}},kt={webdriver:wt,chromedriver:xt,headlessUa:bt,languages:Tt,permissions:At,plugins:St},L=(e={})=>{let{threshold:t=.4}=e,r={},n=0,o=0;for(let[s,l]of Object.entries(kt)){let i=l();n+=i.weight,r[s]={hit:i.hit,weight:i.weight,detail:i.detail},i.hit&&(o+=i.weight);}let a$1=n===0?0:o/n;return a$1<t?null:{class:"dom",trust:"detected",confidence:a$1,vendor:null,userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:r}};var de=()=>[{id:"webmcp.model-context",status:"stable",detect:()=>b({pollMs:0})},{id:"crawler.user-agent",status:"beta",detect:()=>$()},{id:"dom.automation-heuristics",status:"beta",detect:()=>L()}],K=(e=de())=>{let t=new Map(e.map(r=>[r.id,r]));return {register(r){t.set(r.id,r);},list(r){let n=[...t.values()];return r?n.filter(o=>o.status===r):n},async detectAll(r=false){for(let n of t.values()){if(n.status==="research"&&!r)continue;let o=await n.detect();if(o)return o}return null}}};var Mt=e=>{let t=AgentClass.parse(e.class),r=e.verificationToken?"verified":"declared";return {class:t,trust:r,confidence:1,vendor:e.vendor,userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{declared:true,hasVerificationToken:!!e.verificationToken}}};var Rt=({gatewayUrl:e,fetcher:t=fetch})=>{let r=null,n=[];return {snapshot(){return [...n]},async sync(){let o=await t(`${e.replace(/\/$/,"")}/v1/detector-signatures`,{headers:r?{"if-none-match":r}:{}});if(o.status===304)return this.snapshot();if(!o.ok)throw new Error(`Detector signature sync failed with status ${o.status}.`);return n=(await o.json()).signatures??[],r=o.headers.get("etag"),this.snapshot()}}};var me=async(e={})=>{if(e.customDetectors?.length){let t=await K(e.customDetectors).detectAll(!!e.experimental);if(t)return t}if(e.webmcp!==false){let t=await b(e.webmcp??{});if(t)return t}if(e.crawler!==false){let t=$(e.crawler??{});if(t)return t}if(e.dom!==false){let t=L(e.dom??{});if(t)return t}return null};var Ct=e=>({class:e.class,trust:"declared",confidence:1,vendor:e.vendor,userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{declared:true,hasToken:true,tokenExpiresAt:e.expiresAt??null}}),ye=()=>{let e=null;return {present(t){let r=IdentityClaim.safeParse(t);if(!r.success)throw new AgentronicsError("invalid_api_key",`Invalid identity claim: ${r.error.issues[0]?.message??"unknown"}`);let n={claim:r.data,identity:Ct(r.data)};return e=n,n},clear(){e=null;},preferOver(t){return e?t?isHigherTrust(e.identity.trust,t.trust)?e.identity:t:e.identity:t},snapshot(){return e}}};var Hr=({detected:e,declared:t,verified:r,linked:n})=>n?"linked":r?"verified":t?"declared":"detected",fe=e=>{let t=null;for(let r of e)(!t||TRUST_RANK[r.trust]>TRUST_RANK[t.trust])&&(t=r);return t};var he=()=>({name:"bearer",async authenticate(e,t){if(!e.bearerToken)return null;let r=await t.verifyToken?.("bearer",e.bearerToken);return {class:e.classHint??"dom",trust:r?.trust??"verified",confidence:1,vendor:r?.vendor??e.vendorHint??"bearer",userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{bearer:true,verifiedRemotely:!!r}}}});var ve=()=>({name:"detection",async authenticate(e){return e.detected??null}});var we=()=>({name:"extensionToken",async authenticate(e,t){if(!e.extensionToken)return null;let r=await t.verifyToken?.("extensionToken",e.extensionToken);return {class:"dom",trust:r?.trust??"verified",confidence:1,vendor:r?.vendor??e.vendorHint??"browser-extension",userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{extensionToken:true,verifiedRemotely:!!r}}}});var xe=()=>({name:"mtls",async authenticate(e,t){if(!e.xfccHeader)return null;let r=await t.verifyToken?.("mtls",e.xfccHeader);return {class:e.classHint??"webmcp",trust:r?.trust??"verified",confidence:1,vendor:r?.vendor??e.vendorHint??"mtls",userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{mtls:true,subject:r?.subject??null,verifiedRemotely:!!r,...r?.signals??{}}}}});var Se=()=>({name:"oauth2",async authenticate(e,t){if(!e.oauth2AccessToken)return null;let r=await t.verifyToken?.("oauth2",e.oauth2AccessToken);return {class:e.classHint??"webmcp",trust:e.oauth2Subject?"linked":r?.trust??"verified",confidence:1,vendor:r?.vendor??e.vendorHint??"oauth2",userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{oauth2:true,subject:e.oauth2Subject??null,verifiedRemotely:!!r}}}});var $t=e=>({class:e.class,trust:"declared",confidence:1,vendor:e.vendor,userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{declared:true,hasToken:true,tokenExpiresAt:e.expiresAt??null}}),be=()=>({name:"selfDeclaration",async authenticate(e){return e.declaration?$t(IdentityClaim.parse(e.declaration)):null}});var Te=()=>({name:"sessionLink",async authenticate(e,t){if(!e.sessionLinkToken)return null;let r=await t.verifyToken?.("sessionLink",e.sessionLinkToken);return {class:e.classHint??"screenshot",trust:e.linkedUserId?"linked":r?.trust??"verified",confidence:1,vendor:r?.vendor??e.vendorHint??"session-link",userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{sessionLink:true,linkedUserId:e.linkedUserId??null,verifiedRemotely:!!r}}}});var Ae=()=>({name:"sso",async authenticate(e,t){if(!e.ssoIdToken)return null;let r=await t.verifyToken?.("sso",e.ssoIdToken);return {class:e.classHint??"dom",trust:r?.trust??"verified",confidence:1,vendor:r?.vendor??e.vendorHint??"sso",userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{sso:true,subject:r?.subject??null,verifiedRemotely:!!r,...r?.signals??{}}}}});var ke=()=>({name:"spiffe",async authenticate(e,t){if(!e.spiffeJwt)return null;let r=await t.verifyToken?.("spiffe",e.spiffeJwt),n=r?.vendor==="google";return {class:e.classHint??"webmcp",trust:r?.trust??"verified",confidence:1,vendor:r?.vendor??e.vendorHint??"spiffe",userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{spiffe:true,spiffeId:r?.subject??null,subject:r?.subject??null,verifiedRemotely:!!r,...n?{googleAgent:true}:{},...r?.signals??{}}}}});var Ie=()=>({name:"xAgentHeader",async authenticate(e){if(!e.xAgentHeader)return null;let[t="x-agent",r="dom",n]=e.xAgentHeader.split(";"),o=AgentClass.safeParse(r);return {class:o.success?o.data:"dom",trust:n?"verified":"declared",confidence:n?1:.8,vendor:t,userAgent:typeof navigator>"u"?null:navigator.userAgent,detectionVersion:a,signals:{xAgentHeader:true,hasProof:!!n}}}});var jt=()=>[ve(),be(),he(),Ie(),we(),Te(),Se(),Ae(),ke(),xe()],Bt={detection:"detection",selfDeclaration:"declaration",bearer:"bearer",xAgentHeader:"x-agent-header",extensionToken:"extension",sessionLink:"session-link",oauth2:"oauth2",sso:"sso",spiffe:"spiffe",mtls:"mtls"},Gt=(e,t)=>e==="spiffe"&&t.signals?.googleAgent===true?"google-agent":Bt[e],Me=({methods:e=jt(),context:t={},onTrace:r}={})=>({async authenticate(n){let o=[],a={};for(let m of e){let d=await m.authenticate(n,t);a[m.name]=!!d,d&&o.push({method:m.name,identity:d});}let s=fe(o.map(m=>m.identity)),l=s?o.find(m=>m.identity===s):void 0,i=l?Gt(l.method,l.identity):void 0,g=typeof s?.signals?.subject=="string"?s.signals.subject:void 0,p={type:s?"auth.identity_presented":"sdk.error",agent:s,outcome:s?"success":"error",metadata:{methods:a,...i?{protocol:i}:{},...g?{subject:g}:{}}};return s||(p.error="No auth method produced an identity."),r?.(p),s},methods(){return e.map(n=>n.name)}});var Wt={identity:null,source:"initial",updatedAt:null},Re=()=>{let e=Wt,t=new Set,r=()=>{t.size!==0&&t.forEach(n=>n(e));};return {snapshot(){return e},set(n,o){e={identity:n,source:o,updatedAt:new Date().toISOString()},r();},subscribe(n){return t.add(n),()=>{t.delete(n);}}}};var Nt=()=>{let e=new Map;return {read:t=>e.get(t)??null,write:(t,r)=>{e.set(t,r);}}},_t=()=>typeof window>"u"||!window.localStorage?Nt():{read:e=>{try{return window.localStorage.getItem(e)}catch{return null}},write:(e,t)=>{try{window.localStorage.setItem(e,t);}catch{}}},Ut=e=>{if(!e)return null;try{let t=JSON.parse(e);if(typeof t=="object"&&t!==null&&Number.isFinite(t.count)&&Number.isFinite(t.resetAt))return t}catch{return null}return null},Ee=(e=_t())=>({consume(t,r,n=Date.now()){let o=`agtx:rate:${t}`,a=Ut(e.read(o)),s=a&&a.resetAt>n?a.resetAt:n+r.windowSeconds*1e3,l=a&&a.resetAt>n?a.count+1:1;return e.write(o,JSON.stringify({count:l,resetAt:s})),{allowed:l<=r.max,remaining:Math.max(0,r.max-l),resetAt:s}}});var Kt=(e,t)=>e==="*"||e===t?true:e.includes("*")?new RegExp("^"+e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*")+"$").test(t):false,Ht=(e,t)=>{let r=e?TRUST_RANK[e.trust]:-1,n=TRUST_RANK[t.minTrust];return r>=n},zt=(e,t)=>t.allowedClasses.length===0?true:e?t.allowedClasses.includes(e.class):false,Ce="review",Vt=(e,t)=>{let r=t?.class??"unknown",n=t?.vendor??"unknown",o=t?.trust??"none";return `${e}:${r}:${n}:${o}`},De=(e=[],t={})=>{let r=e.map(o=>PolicyRule.parse(o)),n=t.rateLimiter??Ee();return {set(o){r=o.map(a=>PolicyRule.parse(a));},list(){return [...r]},evaluate({tool:o,identity:a}){for(let s of r)if(Kt(s.tool,o)){if(!Ht(a,s))return {decision:"deny",ruleId:s.id,reason:`Rule "${s.id}" requires trust >= ${s.minTrust}.`};if(!zt(a,s))return {decision:"deny",ruleId:s.id,reason:`Rule "${s.id}" restricts to classes: ${s.allowedClasses.join(", ")}.`};if(s.rateLimit){let l=n.consume(Vt(o,a),s.rateLimit);if(!l.allowed)return {decision:"deny",ruleId:s.id,reason:`Rule "${s.id}" rate limit exceeded. Resets at ${new Date(l.resetAt).toISOString()}.`}}return {decision:s.decision,ruleId:s.id,reason:`Matched rule "${s.id}".`}}return {decision:Ce,ruleId:null,reason:`No rule matched tool "${o}". Falling back to "${Ce}".`}}}};var $e=({gatewayUrl:e,siteId:t,publishableKey:r,fetcher:n=fetch})=>{let o={policies:[],etag:null};return {snapshot(){return {policies:[...o.policies],etag:o.etag}},async sync(){let a=await n(`${e.replace(/\/$/,"")}/v1/sites/${encodeURIComponent(t)}/policies`,{headers:{authorization:`Bearer ${r}`,...o.etag?{"if-none-match":o.etag}:{}}});if(a.status===304)return this.snapshot();if(!a.ok)throw new Error(`Policy sync failed with status ${a.status}.`);let s=await a.json();return o={policies:PolicyRule.array().parse(s.policies??[]),etag:a.headers.get("etag")},this.snapshot()}}};var Le=({message:e="Agent action blocked by site policy.",durationMs:t=2400,documentRef:r=typeof document>"u"?void 0:document}={})=>{if(!r?.body)return null;let n=r.createElement("div");return n.setAttribute("role","status"),n.setAttribute("data-agentronics-deny-overlay","true"),n.textContent=e,Object.assign(n.style,{position:"fixed",zIndex:"2147483647",left:"50%",bottom:"24px",transform:"translateX(-50%)",maxWidth:"min(520px, calc(100vw - 32px))",padding:"12px 16px",borderRadius:"8px",background:"#07091A",color:"#F4F4F5",border:"1px solid #6366F1",boxShadow:"0 20px 48px -16px rgba(7,9,26,0.55)",font:"13px/1.45 'Space Mono', ui-monospace, SFMono-Regular, Menlo, monospace"}),r.body.appendChild(n),window.setTimeout(()=>n.remove(),t),n};var je=({policyEngine:e,getIdentity:t,documentRef:r=typeof document>"u"?void 0:document,selector:n="[data-agentronics-tool]"})=>{if(!r)return {uninstall:()=>{}};let o=a=>{let s=a.target instanceof Element?a.target.closest(n):null;if(!(s instanceof HTMLElement))return;let l=s.dataset.agentronicsTool;l&&Promise.resolve(t()).then(i=>{let g=e.evaluate({tool:l,identity:i});g.decision==="deny"&&(a.preventDefault(),a.stopPropagation(),Le({message:g.reason,documentRef:r}));});};return r.addEventListener("click",o,true),{uninstall:()=>r.removeEventListener("click",o,true)}};var H=()=>{let e=new Map;return {read:t=>e.get(t)??null,write:(t,r)=>{e.set(t,r);},remove:t=>{e.delete(t);},keys:()=>[...e.keys()]}},Be=(e,t)=>({read:r=>{try{return e.getItem(t+r)}catch{return null}},write:(r,n)=>{try{e.setItem(t+r,n);}catch{}},remove:r=>{try{e.removeItem(t+r);}catch{}},keys:()=>{let r=[];try{for(let n=0;n<e.length;n++){let o=e.key(n);o&&o.startsWith(t)&&r.push(o.slice(t.length));}}catch{}return r}}),Ge="agtx:",We=()=>{let e=typeof window<"u",t=e&&typeof window.sessionStorage<"u"?Be(window.sessionStorage,Ge+"session:"):H(),r=e&&typeof window.localStorage<"u"?Be(window.localStorage,Ge+"user:"):H();return {session:t,user:r,org:H()}};var _e=(e,t)=>e.expiresAt!==null&&e.expiresAt<=t,Ue=e=>{if(!e)return null;try{let t=JSON.parse(e);return typeof t!="object"||t===null?null:t}catch{return null}},Jt=e=>JSON.stringify(e),Ke=(e={})=>{let t=We(),r=i=>{e.onTrace?.(i);};return {get:(i,g={})=>{let p=g.scope??"session",m=t[p],d=Ue(m.read(i));if(!d){r({type:"memory.accessed",metadata:{operation:"get",key:i,scope:p,hit:false}});return}if(_e(d,Date.now())){m.remove(i),r({type:"memory.accessed",metadata:{operation:"get",key:i,scope:p,hit:false,expired:true}});return}return r({type:"memory.accessed",metadata:{operation:"get",key:i,scope:p,hit:true}}),d.value},set:(i,g,p={})=>{let m=p.scope??"session",d=p.ttlSeconds??null,h=Date.now(),w={value:g,expiresAt:d===null?null:h+d*1e3,updatedAt:new Date(h).toISOString()};return t[m].write(i,Jt(w)),r({type:"memory.updated",metadata:{operation:"set",key:i,scope:m,ttlSeconds:d}}),MemoryEntry.parse({key:i,value:g,scope:m,ttlSeconds:d,updatedAt:w.updatedAt})},remove:(i,g={})=>{let p=g.scope??"session";t[p].remove(i),r({type:"memory.updated",metadata:{operation:"remove",key:i,scope:p}});},list:(i={})=>{let g=i.scope??"session",p=t[g],m=Date.now(),d=[];for(let h of p.keys()){let w=Ue(p.read(h));if(w){if(_e(w,m)){p.remove(h);continue}d.push(MemoryEntry.parse({key:h,value:w.value,scope:g,ttlSeconds:w.expiresAt===null?null:Math.max(0,Math.round((w.expiresAt-m)/1e3)),updatedAt:w.updatedAt}));}}return r({type:"memory.accessed",metadata:{operation:"list",scope:g,count:d.length}}),d},clear:(i={})=>{let g=i.scope??"session",p=t[g],m=p.keys().length;for(let d of p.keys())p.remove(d);r({type:"memory.updated",metadata:{operation:"clear",scope:g,count:m}});}}};var z=e=>SiteMemory.parse(JSON.parse(JSON.stringify(e))),G=e=>({...e,updatedAt:new Date().toISOString()}),He=(e={})=>{let t=SiteMemory.parse({...SITE_MEMORY_DEFAULT,...e.initial??{}}),r=null,n=new Set,o=u=>{e.onTrace?.(u);},a=()=>{r=null;},s=()=>{if(n.size===0)return;let u=z(t);r=u,n.forEach(v=>v(u));},l=u=>{let v=SiteMemory.parse({...t,...u,workflows:{...t.workflows,...u.workflows??{}},policies:{...t.policies,...u.policies??{}},uiGuidance:{...t.uiGuidance,...u.uiGuidance??{}},pageContexts:{...t.pageContexts,...u.pageContexts??{}}});return t=G(v),a(),o({type:"memory.updated",metadata:{kind:"site",operation:"provide",keys:Object.keys(u)}}),s(),p()},i=(u,v)=>{let x=u.split(".").filter(Boolean);if(x.length===0)throw new Error("siteMemory.update() requires a non-empty dot-path.");let k=JSON.parse(JSON.stringify(t)),I=k;for(let R=0;R<x.length-1;R++){let T=x[R],E=I[T];(typeof E!="object"||E===null||Array.isArray(E))&&(I[T]={}),I=I[T];}return I[x[x.length-1]]=v,t=G(SiteMemory.parse(k)),a(),o({type:"memory.updated",metadata:{kind:"site",operation:"update",path:u}}),s(),p()},g=u=>{let v=SiteMemoryPageContext.parse({path:u.path,payload:u.payload,updatedAt:new Date().toISOString()});return t=G({...t,pageContexts:{...t.pageContexts,[u.path]:v}}),a(),o({type:"memory.updated",metadata:{kind:"site",operation:"provideForPage",path:u.path}}),s(),{...v,payload:{...v.payload}}},p=()=>(r||(r=z(t)),r);return {provide:l,update:i,provideForPage:g,snapshot:p,get:u=>{if(o({type:"memory.accessed",metadata:{kind:"site",operation:u?"get":"snapshot",path:u??null}}),!u)return z(t);let v=u.split(".").filter(Boolean),x=t;for(let k of v){if(typeof x!="object"||x===null)return;x=x[k];}return x},getForPage:u=>{o({type:"memory.accessed",metadata:{kind:"site",operation:"getForPage",path:u}});let v=t.pageContexts[u];return v?{...v,payload:{...v.payload}}:null},replace:u=>(t=G(SiteMemory.parse(u)),a(),s(),p()),subscribe:u=>(n.add(u),()=>{n.delete(u);})}};var Ve=({gatewayUrl:e,siteId:t,publishableKey:r,fetcher:n=fetch})=>{let o={memory:null,etag:null};return {snapshot(){return {memory:o.memory?SiteMemory.parse(o.memory):null,etag:o.etag}},async sync(){let a=await n(`${e.replace(/\/$/,"")}/v1/sites/${encodeURIComponent(t)}/memory`,{headers:{authorization:`Bearer ${r}`,...o.etag?{"if-none-match":o.etag}:{}}});if(a.status===304)return this.snapshot();if(!a.ok)throw new Error(`Memory sync failed with status ${a.status}.`);let s=await a.json();return o={memory:SiteMemory.parse(s.memory??{}),etag:a.headers.get("etag")},this.snapshot()}}};var Yt=({toolName:e="getSiteContext",description:t="Returns Agentronics site memory: page map, workflows, policies, UI guidance.",getSnapshot:r,onAccess:n})=>({name:e,description:t,inputSchema:{type:"object",properties:{path:{type:"string",description:'Optional dot-path into the site memory (e.g. "workflows.purchase").'}},required:[]},invoke(o={}){let a=r(),s=o.path??null;if(n?.(s),!s)return {content:a};let l=s.split(".").filter(Boolean),i=a;for(let g of l){if(typeof i!="object"||i===null)return {content:void 0};i=i[g];}return {content:i}}});var A="agent-context-",V="agentronics-site-context",Qt=e=>{try{return JSON.stringify(e)}catch{return "{}"}},W=(e,t,r)=>{let n=e.querySelector(`meta[name="${t}"]`);n||(n=e.createElement("meta"),n.setAttribute("name",t),e.head.appendChild(n)),n.setAttribute("content",r);},N=(e,t)=>{e.querySelectorAll(`meta[name="${t}"]`).forEach(r=>r.remove());},F=({doc:e=typeof document>"u"?null:document,snapshot:t,schemaType:r="WebSite"})=>{if(!e)return {uninstall:()=>{}};W(e,`${A}version`,t.version),W(e,`${A}updated-at`,t.updatedAt??new Date().toISOString()),t.siteMap?.navigation?.flow&&W(e,`${A}flow`,t.siteMap.navigation.flow),W(e,`${A}workflows`,Object.keys(t.workflows).join(","));let n=e.getElementById(V);return n||(n=e.createElement("script"),n.type="application/ld+json",n.id=V,e.head.appendChild(n)),n.textContent=Qt({"@context":"https://schema.org","@type":r,name:"Agentronics Site Memory",agentronics:t}),{uninstall:()=>{N(e,`${A}version`),N(e,`${A}updated-at`),N(e,`${A}flow`),N(e,`${A}workflows`),e.getElementById(V)?.remove();}}};var Fe="agentronics-memory-overlay",Zt=e=>`
|
|
2
|
-
position: fixed;
|
|
3
|
-
bottom: 16px;
|
|
4
|
-
right: 16px;
|
|
5
|
-
max-width: 320px;
|
|
6
|
-
padding: 10px 12px;
|
|
7
|
-
background: rgba(17, 24, 39, 0.92);
|
|
8
|
-
color: #f9fafb;
|
|
9
|
-
font: 12px/1.45 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
10
|
-
border-radius: 8px;
|
|
11
|
-
z-index: 2147483647;
|
|
12
|
-
opacity: ${e?"0":"1"};
|
|
13
|
-
pointer-events: ${e?"none":"auto"};
|
|
14
|
-
box-shadow: 0 12px 32px rgba(15, 23, 42, 0.35);
|
|
15
|
-
`,Je=e=>{let t=e.siteMap?.pages?.length??0,r=Object.keys(e.workflows).length,n=Object.keys(e.uiGuidance).length;return `Agentronics site memory \xB7 pages:${t} \xB7 workflows:${r} \xB7 ui-hints:${n}`},J=({doc:e=typeof document>"u"?null:document,snapshot:t,hidden:r=false})=>{if(!e)return {uninstall:()=>{},refresh:()=>{}};let n=e.getElementById(Fe);return n||(n=e.createElement("div"),n.id=Fe,n.setAttribute("role","note"),n.setAttribute("aria-label","Agentronics site memory summary"),n.setAttribute("data-agent-context","overlay"),e.body.appendChild(n)),n.setAttribute("style",Zt(r)),n.textContent=Je(t),{uninstall:()=>{n?.remove();},refresh:o=>{n&&(n.textContent=Je(o));}}};var Xe="/.well-known/agent-context.json",q=async({origin:e,fetcher:t=fetch,signal:r}={})=>{let n=(e?e.replace(/\/$/,""):typeof window<"u"?window.location.origin:"")+Xe;if(!n.startsWith("http"))return null;let o={headers:{accept:"application/json"}};r!==void 0&&(o.signal=r);let a=await t(n,o);if(!a.ok){if(a.status===404)return null;throw new Error(`well-known agent-context fetch failed with status ${a.status}.`)}let s=await a.json();return SiteMemory.parse(s)},er=({snapshot:e})=>JSON.stringify(SiteMemory.parse(e));var Ye=({evaluate:e,setPolicies:t,listPolicies:r,onTrace:n,identityResolver:o})=>{let a=new Map,s=new Set,l=i=>{if(!i.authz||!t||!r)return;let g={id:`tool:${i.name}`,tool:i.name,...i.authz,rateLimit:i.rateLimit??i.authz.rateLimit};t([...r().filter(p=>p.id!==g.id),g]);};return {register(i){return a.set(i.name,i),s.delete(i.name),l(i),n?.({type:"tool.registered",tool:i.name,metadata:{version:i.version??null,group:i.group??null,stage:i.stage??null}}),()=>{a.delete(i.name),s.delete(i.name);}},unregister(i){a.delete(i),s.delete(i);},enable(i){!a.has(i)||!s.has(i)||(s.delete(i),n?.({type:"tool.surfaced",tool:i,metadata:{state:"enabled"}}));},disable(i){!a.has(i)||s.has(i)||(s.add(i),n?.({type:"tool.surfaced",tool:i,metadata:{state:"disabled"}}));},isEnabled:i=>a.has(i)&&!s.has(i),list({includeDisabled:i=false}={}){let g=[...a.values()];return i?g:g.filter(p=>!s.has(p.name))},get:i=>a.get(i),async execute(i,g,p){let m=p===void 0?o?.()??null:p,d=a.get(i);if(!d)throw new Error(`Tool "${i}" is not registered.`);if(s.has(i)){let u={decision:"deny",ruleId:`tool:${i}`,reason:"Tool is disabled."};throw n?.({type:"tool.executed",tool:i,agent:m,policy:u,outcome:"blocked"}),new Error(u.reason)}let h=await e(i,{identity:m});if(h.decision==="deny")throw n?.({type:"tool.executed",tool:i,agent:m,policy:h,outcome:"blocked"}),new Error(h.reason);let w=Date.now();try{let u=await d.execute(g,{identity:m});return n?.({type:"tool.executed",tool:i,agent:m,policy:h,outcome:"success",durationMs:Date.now()-w}),u}catch(u){throw n?.({type:"tool.executed",tool:i,agent:m,policy:h,outcome:"error",durationMs:Date.now()-w,error:u instanceof Error?u.message:String(u)}),u}}}};var Qe=(e,t={})=>{let r=new Map;for(let s of e.stages)r.set(s.name,s);if(!r.has(e.initial))throw new Error(`Initial stage "${e.initial}" is not declared in progression stages.`);let n=e.initial,o=()=>{let s=r.get(n);return s?.enables?[n,...s.enables]:[n]},a=(s,l)=>{let i=n;if(!r.has(s))throw new Error(`Cannot transition to unknown stage "${s}".`);return s===n?{changed:false,from:i,to:s}:(n=s,t.onTrace?.({type:"tool.progressed",metadata:{from:i,to:s,trigger:l}}),{changed:true,from:i,to:s})};return {current:()=>n,enabledStages:()=>o(),notify(s){let i=r.get(n)?.transitions?.find(g=>g.on===s);return i?a(i.to,s):{changed:false,from:n,to:n}},set(s){return a(s,"manual")},reset(){let s=n;n=e.initial,s!==n&&t.onTrace?.({type:"tool.progressed",metadata:{from:s,to:n,trigger:"reset"}});},snapshot:()=>({current:n,enabled:o()})}};var tr=(e,t)=>{let r=e.authz?.minTrust;return r?t?TRUST_RANK[t.trust]<TRUST_RANK[r]?{ok:false,reason:`trust-too-low:${t.trust}<${r}`}:{ok:true,reason:"trust-ok"}:{ok:false,reason:`requires-trust:${r}`}:{ok:true,reason:"no-trust-floor"}},rr=(e,t)=>{let r=e.authz?.allowedClasses??[];return r.length===0?{ok:true,reason:"no-class-restriction"}:t?r.includes(t.class)?{ok:true,reason:"class-ok"}:{ok:false,reason:`class-not-allowed:${t.class}`}:{ok:false,reason:`requires-class:${r.join("|")}`}},nr=(e,t)=>e.stage?t.enabledStages&&t.enabledStages.includes(e.stage)?{ok:true,reason:`stage-enabled:${e.stage}`}:t.stage===e.stage?{ok:true,reason:`stage-active:${e.stage}`}:{ok:false,reason:`stage-locked:${e.stage}`}:{ok:true,reason:"no-stage"},et=(e,t)=>{let r=tr(e,t.identity);if(!r.ok)return {tool:e,visible:false,reason:r.reason};let n=rr(e,t.identity);if(!n.ok)return {tool:e,visible:false,reason:n.reason};let o=nr(e,t);return o.ok?e.authz?.decision==="deny"?{tool:e,visible:false,reason:"authz-deny"}:{tool:e,visible:true,reason:"visible"}:{tool:e,visible:false,reason:o.reason}},tt=(e,t)=>e.filter(r=>et(r,t).visible),rt=(e,t)=>e.map(r=>et(r,t));var nt="default",ot=e=>{let t=new Map;for(let r of e){let n=r.group??nt,o=t.get(n)??[];o.push(r),t.set(n,o);}return [...t.entries()].sort(([r],[n])=>r.localeCompare(n)).map(([r,n])=>({name:r,tools:n}))},oo=e=>[...new Set(e.map(t=>t.group??nt))].sort();var X=e=>e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(X).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${X(e[r])}`).join(",")}}`,or=e=>{let t={name:e.name,version:e.version??null,group:e.group??null,description:e.description??null,inputSchema:e.inputSchema??null,authz:e.authz??null,rateLimit:e.rateLimit??null},r=X(t).length;return {name:e.name,characters:r,tokens:Math.ceil(r/4)}},it=e=>{let t=e.map(or);return {total:t.reduce((n,o)=>n+o.tokens,0),perTool:t}};var st=e=>{if(e.provider)return e.provider;let r=(e.doc?.defaultView??(typeof globalThis<"u"?globalThis:null))?.navigator?.modelContext;return !r||typeof r.provideContext!="function"?null:r},ir=(e,t)=>{let r={name:e.name,invoke:n=>t(e,n)};return e.description!==void 0&&(r.description=e.description),e.inputSchema!==void 0&&(r.inputSchema=e.inputSchema),r},at=(e={})=>{let t=e.invoke??(async(n,o)=>n.execute(o,{identity:null})),r=null;return {publish(n){let o=st(e);return o?(r?.revoke(),r=o.provideContext({tools:n.map(a=>ir(a,t))}),{revoked:true}):{revoked:false}},revoke(){r?.revoke(),r=null;},available:()=>!!st(e)}};var Y=(e=500)=>{let t=[];return {add(r){t.push(r),t.length>e&&t.splice(0,t.length-e);},list(){return [...t]},clear(){t.length=0;}}};var ct=(e,t)=>e===void 0?t:Math.max(0,Math.min(1,e)),Q=(e={})=>{let t=ct(e.traceRate,1),r=ct(e.errorRate,1),n=e.random??Math.random;return {shouldKeep(o){let a=o.outcome==="error"?r:t;return n()<a}}};var sr="[REDACTED]",ar=e=>{if(e!==void 0)return JSON.parse(JSON.stringify(e))},Z=(e,t)=>{if(t.length===0||typeof e!="object"||e===null)return;let[r,...n]=t;if(!r)return;if(Array.isArray(e)){for(let a of e)Z(a,t);return}let o=e;if(r in o){if(n.length===0){o[r]=sr;return}Z(o[r],n);}},ee=(e,t=[])=>{if(t.length===0)return e;let r=ar(e);for(let n of t)Z(r,n.split(".").filter(Boolean));return r},te=["metadata.password","metadata.token","metadata.authorization","metadata.cookie"];var lr=()=>typeof location<"u"&&typeof location.pathname=="string"?location.pathname:void 0,lt=e=>{let t=globalThis.crypto;return t&&"randomUUID"in t?`${e}_${t.randomUUID()}`:`${e}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`},re=({siteId:e,bufferSize:t,sessionId:r=lt("ses"),scrubPaths:n=te,exporters:o=[],onExporterError:a,pageProvider:s=lr,...l})=>{let i=Y(t),g=Q(l),p=()=>{try{return s()}catch{return}};return {sessionId:r,async emit(m){let d={...m.metadata};if(d.page===void 0){let w=p();w!==void 0&&(d.page=w);}let h=TraceEvent.parse(ee({id:lt("trc"),siteId:e,sessionId:r,occurredAt:new Date().toISOString(),outcome:m.outcome??"success",...m,metadata:d},n));return g.shouldKeep(h)?(i.add(h),await Promise.all(o.map(async w=>{try{await w.export([h]);}catch(u){a?.(u,w,h);}})),h):null},list:()=>i.list(),clear:()=>i.clear()}};var ne=()=>({name:"console",export(e){for(let t of e)console.info("[agentronics:trace]",t.type,t);}});var oe=({gatewayUrl:e,publishableKey:t,fetcher:r=fetch})=>({name:"gateway",async export(n){let o={publishableKey:t,events:n};await r(`${e.replace(/\/$/,"")}/v1/traces`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${t}`},body:JSON.stringify(o)});}});var ur=e=>new Promise(t=>setTimeout(t,e)),se=({url:e,fetcher:t=fetch,maxRetries:r=2,queueLimit:n=500})=>({name:"webhook",async export(o){let s=[...pr(e),...o].slice(-n),l=0;for(;;){let i=await t(e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({events:s})});if(i.ok){ut(e,[]);return}if(l>=r)throw ut(e,s),new Error(`Webhook exporter failed with status ${i.status}.`);l+=1,await ur(100*l);}}}),ie=e=>`agtx:webhook:${e}`,pr=e=>{if(typeof window>"u"||!window.localStorage)return [];try{let t=window.localStorage.getItem(ie(e));return t?JSON.parse(t):[]}catch{return []}},ut=(e,t)=>{if(!(typeof window>"u"||!window.localStorage))try{if(t.length===0){window.localStorage.removeItem(ie(e));return}window.localStorage.setItem(ie(e),JSON.stringify(t));}catch{}};var ae=e=>{let t={name:e.name,description:e.description??"",inputSchema:e.inputSchema??{},tokens:0};return e.group&&(t.group=e.group),e.stage&&(t.page=e.stage),e.outputSchema&&(t.outputSchema=e.outputSchema),t.tokens=Math.ceil(JSON.stringify({name:t.name,description:t.description,inputSchema:t.inputSchema,...t.outputSchema?{outputSchema:t.outputSchema}:{}}).length/4),t},pt=({gatewayUrl:e,siteId:t,publishableKey:r,fetcher:n=fetch})=>({async push(o){let a=o.map(ae),s=await n(`${e.replace(/\/$/,"")}/v1/sites/${encodeURIComponent(t)}/tools`,{method:"PUT",headers:{authorization:`Bearer ${r}`,"content-type":"application/json"},body:JSON.stringify({registry:{tools:a}})});if(!s.ok)throw new Error(`Tool sync failed with status ${s.status}.`);return a.length}});var dt="/v1/sdk/events",dr=({url:e,ingestKey:t,fetcher:r=fetch})=>{let n=e.replace(/\/$/,""),o=n.endsWith(dt)?n:`${n}${dt}`;return {name:"intel",async export(a){let s={events:a},l=await r(o,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${t}`},body:JSON.stringify(s)});if(!l.ok)throw new Error(`Intel exporter failed with status ${l.status}.`)}}},mr=({url:e,ingestKey:t,siteId:r,fetcher:n=fetch})=>{let o=e.replace(/\/$/,""),a=async(s,l)=>{let i=await n(`${o}${s}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${t}`},body:JSON.stringify(l)});if(!i.ok)throw new Error(`Intel sync ${s} failed with status ${i.status}.`)};return {async pushTools(s){let l=s.map(ae);return await a("/v1/sdk/tools",{siteId:r,tools:l}),l.length},async pushMemory(s,l){await a("/v1/sdk/memory",{siteId:r,snapshot:s,...typeof l=="number"?{score:l}:{}});}}};var yt="https://gateway.agentronics.dev",fr=e=>{if(e===void 0)return yt;if(e===yt)return e;let t;try{t=new URL(e);}catch{throw new Error(`Agentronics SDK: \`gatewayUrl\` is not a valid URL: ${e}`)}if(t.hostname==="localhost"||t.hostname==="127.0.0.1")return e;throw new Error(`Agentronics SDK does not support custom gateway URLs. Omit \`gatewayUrl\` to use the canonical https://gateway.agentronics.dev. The only accepted override is a localhost / 127.0.0.1 URL for local development. Got: ${e}`)},Zo=e=>{let{publishableKey:t,siteId:r="default",debug:n=false,policies:o=[],trace:a$1={}}=e,s=fr(e.gatewayUrl),l=classifyApiKey(t);if(l==="secret")throw new AgentronicsError("wrong_key_kind","A secret key was passed to Agentronics.init(). Browser code must use a publishable key (agtx_pk_*).");if(l!=="publishable")throw new AgentronicsError("invalid_api_key",`Agentronics.init() expected a key starting with "${PUBLISHABLE_KEY_PREFIX}".`);let i=a$1.enabled??true,g=[...n?[ne()]:[],...a$1.gateway?[oe({gatewayUrl:s,publishableKey:t})]:[],...a$1.webhookUrl?[se({url:a$1.webhookUrl})]:[],...a$1.exporters??[]],p={siteId:r,exporters:i?g:[],onExporterError:(c,y)=>{n&&console.warn(`[agentronics] trace exporter "${y.name}" failed`,c);}};a$1.bufferSize!==void 0&&(p.bufferSize=a$1.bufferSize),a$1.traceRate!==void 0&&(p.traceRate=a$1.traceRate),a$1.errorRate!==void 0&&(p.errorRate=a$1.errorRate),a$1.scrubPaths!==void 0&&(p.scrubPaths=a$1.scrubPaths);let m=re(p),d=c=>{i&&m.emit(c);},h=ye(),w={onTrace:d};e.auth!==void 0&&(w.context=e.auth);let u=Me(w),v=Re(),x=De(o),k=$e({gatewayUrl:s,siteId:r,publishableKey:t}),I=Ke({onTrace:d}),R={onTrace:d};e.siteMemory!==void 0&&(R.initial=e.siteMemory);let T=He(R),E=Ve({gatewayUrl:s,siteId:r,publishableKey:t}),gt=pt({gatewayUrl:s,siteId:r,publishableKey:t}),B=async c=>{let y=Date.now(),S=await me(c),b=h.preferOver(S);return i&&await m.emit({type:b?"agent.detected":"agent.missed",agent:b,durationMs:Date.now()-y,metadata:{detectedClass:S?.class??null,presented:h.snapshot()!==null}}),v.set(b,"detect"),b},ce=async(c,y={})=>{let S=Date.now(),b=y.identity!==void 0?y.identity:await B(),U=x.evaluate({tool:c,identity:b});return i&&await m.emit({type:"authz.evaluated",tool:c,agent:b,policy:U,outcome:U.decision==="deny"?"blocked":"success",durationMs:Date.now()-S}),U},M=Ye({evaluate:ce,setPolicies:c=>x.set(c),listPolicies:()=>x.list(),onTrace:d,identityResolver:()=>v.snapshot().identity});for(let c of e.tools??[])M.register(c);let P=e.progression?Qe(e.progression,{onTrace:d}):null,le=c=>{let y={identity:c};return P&&(y.stage=P.current(),y.enabledStages=P.enabledStages()),y},O=c=>tt(M.list(),le(c)),ue=c=>{if(!P)return;P.notify(c).changed&&C.publish(O(v.snapshot().identity));},ft={class:"webmcp",trust:"detected",confidence:1,vendor:null,userAgent:typeof navigator<"u"?navigator.userAgent:null,detectionVersion:a,signals:{source:"navigator.modelContext"}},C=at({invoke:async(c,y)=>{let S=v.snapshot().identity??ft,b=await M.execute(c.name,y,S);return ue(c.name),b}});v.subscribe(c=>{C.available()&&C.publish(O(c.identity));});let _=e.autoDetect??true,ht=_===false?Promise.resolve(null):(async()=>{let c=_===true?{}:_;try{return await B(c)}catch(y){return n&&console.warn("[agentronics] autoDetect failed:",y),null}})();return Object.freeze({publishableKey:t,siteId:r,gatewayUrl:s,debug:n,memory:I,siteMemory:T,memoryCache:E,tracer:m,auth:u,agentContext:v,authz:x,policyCache:k,tools:M,progression:P,webmcp:C,ready:ht,detect:B,authenticate:async c=>{let y=await u.authenticate(c);return v.set(y,"authenticate"),y},presentIdentity:c=>{let y=h.present(c);return d({type:"auth.identity_presented",agent:y.identity,metadata:{vendor:y.identity.vendor,class:y.identity.class}}),v.set(y.identity,"declare"),y},clearIdentity:()=>{h.clear(),d({type:"auth.identity_cleared"}),v.set(null,"cleared");},presentedIdentity:()=>h.snapshot(),setPolicies:c=>{x.set(c),d({type:"authz.policies_set",metadata:{count:c.length}});},listPolicies:()=>x.list(),syncPolicies:async()=>{let c=await k.sync();return x.set(c.policies),d({type:"authz.policies_set",metadata:{count:c.policies.length,synced:true}}),c.policies},syncSiteMemory:async()=>{let c=await E.sync();return c.memory&&(T.replace(c.memory),d({type:"memory.updated",metadata:{kind:"site",operation:"sync",etag:c.etag}})),c.memory},provideSiteMemory:c=>T.provide(c),provideForPage:c=>{T.provideForPage(c);},installMemoryDelivery:({metaTags:c=true,overlay:y=false}={})=>{let S=[];return c&&S.push(F({snapshot:T.snapshot()})),y&&S.push(J({snapshot:T.snapshot()})),{uninstall:()=>{S.forEach(b=>b.uninstall());}}},fetchWellKnown:async c=>{let y={};c!==void 0&&(y.origin=c);let S=await q(y);return S&&(T.replace(S),d({type:"memory.updated",metadata:{kind:"site",operation:"wellKnown",origin:c??null}})),S},installDomEnforcer:()=>je({policyEngine:x,getIdentity:()=>B({webmcp:{pollMs:0}})}),registerTool:c=>M.register(c),syncTools:async()=>{let c=M.list({includeDisabled:true}),y=await gt.push(c);return d({type:"tool.registered",metadata:{operation:"sync",count:y}}),y},surfaceTools:({identity:c=null}={})=>O(c),explainSurfacing:({identity:c=null}={})=>rt(M.list(),le(c)),groupedTools:({identity:c=null}={})=>ot(O(c)),estimateTokens:({identity:c=null}={})=>it(O(c)),publishToWebMcp:({identity:c=null}={})=>{let y=O(c),S=C.publish(y);return y.forEach(b=>{d({type:"tool.surfaced",tool:b.name,metadata:{state:"published",trust:c?.trust??null,group:b.group??null}});}),{revoked:S.revoked,surfaced:y.length}},notifyToolInvoked:c=>ue(c),evaluate:ce,traces:()=>m.list(),clearTraces:()=>m.clear(),async ping(){try{let c=await fetch(`${s.replace(/\/$/,"")}/v1/health`,{method:"GET",headers:{authorization:`Bearer ${t}`}});if(!c.ok)return {ok:!1,status:c.status,error:`gateway returned ${c.status}`};let y=await c.json().catch(()=>null)??{};return {ok:!0,status:c.status,body:y}}catch(c){return {ok:false,status:0,error:c instanceof Error?c.message:String(c)}}}})};
|
|
16
|
-
export{er as A,Ye as B,Qe as C,et as D,tt as E,rt as F,nt as G,ot as H,oo as I,or as J,it as K,at as L,Y as M,re as N,ne as O,oe as P,se as Q,dr as R,mr as S,Zo as T,pe as a,$ as b,L as c,de as d,K as e,Mt as f,Rt as g,me as h,ye as i,Hr as j,fe as k,Me as l,Re as m,Ee as n,De as o,$e as p,Le as q,je as r,Ke as s,He as t,Ve as u,Yt as v,F as w,J as x,Xe as y,q as z};//# sourceMappingURL=chunk-77VJ65X2.js.map
|
|
17
|
-
//# sourceMappingURL=chunk-77VJ65X2.js.map
|