@knownagents/sdk 1.10.0 → 2.0.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/src/index.ts CHANGED
@@ -1,263 +1,10 @@
1
- import { IncomingMessage, ServerResponse } from "http"
2
-
3
- /**
4
- * A framework-agnostic HTTP request interface.
5
- * Used as a convenience type for single-request methods.
6
- */
7
- export interface Request {
8
- /** The URL path and query string (e.g. "/about?foo=bar") */
9
- path: string
10
- /** The HTTP method (e.g. "GET", "POST") */
11
- method: string
12
- /** The HTTP request headers */
13
- headers: Record<string, string | string[] | undefined>
14
- }
15
-
16
- /**
17
- * A minimal HTTP response interface.
18
- * Used as a convenience type for single-request methods.
19
- */
20
- export interface Response {
21
- /** The HTTP response status code (e.g. 200, 404) */
22
- statusCode: number
23
- }
24
-
25
- /**
26
- * A visit tracking request for the Known Agents API.
27
- * Used for batch visit tracking with `trackVisits()`.
28
- */
29
- export interface VisitRequest {
30
- /** The URL path of the request (e.g. "/about?foo=bar") */
31
- request_path: string
32
- /** The HTTP method (e.g. "GET", "POST") */
33
- request_method: string
34
- /** The HTTP request headers */
35
- request_headers: Record<string, string | string[] | undefined>
36
- /** The HTTP response status code (e.g. 200, 404) */
37
- response_status_code?: number
38
- /** The HTTP response headers */
39
- response_headers?: Record<string, string | string[] | undefined>
40
- /** The response duration in milliseconds */
41
- response_duration_in_milliseconds?: number
42
- /** The timestamp when the visit occurred (ISO 8601 format) */
43
- created?: string
44
- }
45
-
46
- /**
47
- * An agent identification request for the Known Agents API.
48
- * Used for batch agent identification with `identifyAgents()`.
49
- */
50
- export interface IdentificationRequest {
51
- /** An identifier that will be echoed back in the response to match requests with results */
52
- id?: string
53
- /** The HTTP request headers */
54
- request_headers: Record<string, string | string[] | undefined>
55
- }
56
-
57
- /**
58
- * The result of an agent identification request.
59
- */
60
- export interface IdentificationResult {
61
- /** The identifier from the request (if provided) */
62
- id?: string
63
- /**
64
- * The identification result:
65
- * - "verified": The agent was identified and verified
66
- * - "verification_failed": The agent was identified but failed verification (spoofed)
67
- * - "unknown_agent": The request is from an unrecognized agent or human
68
- * - "not_verifiable": The agent was identified but cannot be verified
69
- */
70
- result: "verified" | "verification_failed" | "unknown_agent" | "not_verifiable"
71
- /** The unique ID of the identified agent */
72
- agent_id?: string
73
- /** The name of the identified agent (e.g. "Googlebot") */
74
- agent_token?: string
75
- /** The documentation URL for the identified agent */
76
- agent_url?: string
77
- /** The type of the identified agent (e.g. "AI Agent", "Search Engine Crawler") */
78
- agent_type_name?: string
79
- /** The company behind the identified agent (e.g. "Google") */
80
- operator_name?: string
81
- }
82
-
83
- /**
84
- * Agent types that can be controlled with robots.txt rules.
85
- */
86
- export enum AgentType {
87
- AIAgent = "AI Agent",
88
- AIAssistant = "AI Assistant",
89
- AICodingAgent = "AI Coding Agent",
90
- AIDataProvider = "AI Data Provider",
91
- AIDataScraper = "AI Data Scraper",
92
- AISearchCrawler = "AI Search Crawler",
93
- Archiver = "Archiver",
94
- DeveloperHelper = "Developer Helper",
95
- Fetcher = "Fetcher",
96
- HeadlessAgent = "Headless Agent",
97
- IntelligenceGatherer = "Intelligence Gatherer",
98
- Scraper = "Scraper",
99
- SEOCrawler = "SEO Crawler",
100
- SearchEngineCrawler = "Search Engine Crawler",
101
- SecurityScanner = "Security Scanner",
102
- UndocumentedAIAgent = "Undocumented AI Agent"
103
- }
104
-
105
- export class KnownAgents {
106
- private readonly accessToken: string
107
-
108
- /**
109
- * Creates a new instance of the Known Agents client.
110
- *
111
- * @param accessToken - Your project's access token.
112
- */
113
- constructor(accessToken: string) {
114
- this.accessToken = accessToken
115
- }
116
-
117
- /**
118
- * Tracks a single agent visit for analytics.
119
- * This method is non-blocking and handles errors internally.
120
- *
121
- * @param request - The incoming HTTP request (Request or Node.js IncomingMessage).
122
- * @param response - The outgoing HTTP response (optional).
123
- * @param responseDurationInMilliseconds - The time taken to process the request in milliseconds (optional).
124
- */
125
- trackVisit(request: Request | IncomingMessage, response?: Response | ServerResponse, responseDurationInMilliseconds?: number): void {
126
- fetch("https://api.knownagents.com/visits", {
127
- method: "POST",
128
- headers: {
129
- "Authorization": `Bearer ${this.accessToken}`,
130
- "Content-Type": "application/json"
131
- },
132
- body: JSON.stringify({
133
- request_path: "path" in request ? request.path : request.url,
134
- request_method: request.method,
135
- request_headers: this.filterHeaders(request.headers),
136
- response_status_code: response?.statusCode,
137
- response_duration_in_milliseconds: responseDurationInMilliseconds,
138
- created: new Date().toISOString()
139
- })
140
- }).catch(error => {
141
- console.error(`Known Agents failed to track visit: ${error.message}`)
142
- })
143
- }
144
-
145
- /**
146
- * Tracks multiple agent visits in a batch for analytics.
147
- * This method is non-blocking and handles errors internally.
148
- * Recommended for high-traffic websites - batch visits and send periodically (e.g. every 30 seconds).
149
- *
150
- * @param visits - An array of visit tracking requests.
151
- */
152
- trackVisits(visits: VisitRequest[]): void {
153
- fetch("https://api.knownagents.com/visits", {
154
- method: "POST",
155
- headers: {
156
- "Authorization": `Bearer ${this.accessToken}`,
157
- "Content-Type": "application/json"
158
- },
159
- body: JSON.stringify(visits)
160
- }).catch(error => {
161
- console.error(`Known Agents failed to track visits: ${error.message}`)
162
- })
163
- }
164
-
165
- /**
166
- * Generates a robots.txt file that disallows the specified agent types.
167
- * The generated file stays up-to-date with all current and future agents in the specified categories.
168
- * Cache and serve the result at your website's `/robots.txt` endpoint.
169
- *
170
- * @param agentTypes - An array of agent types to disallow.
171
- * @param disallow - The path to disallow (default: "/" for all paths).
172
- * @returns A promise that resolves to the generated robots.txt content as a string.
173
- * @throws {Error} If the API call fails or returns a non-200 status.
174
- */
175
- async generateRobotsTXT(agentTypes: AgentType[], disallow: string = "/"): Promise<string> {
176
- const response = await fetch("https://api.knownagents.com/robots-txts", {
177
- method: "POST",
178
- headers: {
179
- "Authorization": `Bearer ${this.accessToken}`,
180
- "Content-Type": "application/json"
181
- },
182
- body: JSON.stringify({
183
- agent_types: agentTypes,
184
- disallow: disallow
185
- })
186
- })
187
-
188
- if (response.ok) {
189
- return await response.text()
190
- } else {
191
- throw new Error(`Known Agents failed to generate robots.txt: ${response.status} ${response.statusText}`)
192
- }
193
- }
194
-
195
- /**
196
- * Identifies and verifies a single agent from an HTTP request.
197
- * Uses Web Bot Auth (HTTP message signatures), IP matching, or other available methods.
198
- *
199
- * @param request - The incoming HTTP request (Request or Node.js IncomingMessage).
200
- * @returns A promise that resolves to the identification result.
201
- * @throws {Error} If the API call fails or returns a non-200 status.
202
- */
203
- async identifyAgent(request: Request | IncomingMessage): Promise<IdentificationResult> {
204
- const response = await fetch("https://api.knownagents.com/agent-identifications", {
205
- method: "POST",
206
- headers: {
207
- "Authorization": `Bearer ${this.accessToken}`,
208
- "Content-Type": "application/json"
209
- },
210
- body: JSON.stringify({
211
- request_headers: this.filterHeaders(request.headers)
212
- })
213
- })
214
-
215
- if (response.ok) {
216
- return await response.json()
217
- } else {
218
- throw new Error(`Known Agents failed to identify agent: ${response.status} ${response.statusText}`)
219
- }
220
- }
221
-
222
- /**
223
- * Identifies and verifies multiple agents from HTTP requests in a batch.
224
- * Uses Web Bot Auth (HTTP message signatures), IP matching, or other available methods.
225
- *
226
- * @param requests - An array of identification requests.
227
- * @returns A promise that resolves to an array of identification results.
228
- * @throws {Error} If the API call fails or returns a non-200 status.
229
- */
230
- async identifyAgents(requests: IdentificationRequest[]): Promise<IdentificationResult[]> {
231
- const response = await fetch("https://api.knownagents.com/agent-identifications", {
232
- method: "POST",
233
- headers: {
234
- "Authorization": `Bearer ${this.accessToken}`,
235
- "Content-Type": "application/json"
236
- },
237
- body: JSON.stringify(requests)
238
- })
239
-
240
- if (response.ok) {
241
- return await response.json()
242
- } else {
243
- throw new Error(`Known Agents failed to identify agents: ${response.status} ${response.statusText}`)
244
- }
245
- }
246
-
247
- // Helpers
248
-
249
- private filterHeaders(headers: Record<string, string | string[] | undefined>): Record<string, string | string[] | undefined> {
250
- const excludedHeaders = new Set([
251
- "authorization",
252
- "proxy-authorization",
253
- "cookie",
254
- "set-cookie"
255
- ])
256
-
257
- return Object.fromEntries(
258
- Object.entries(headers).filter(([key]) => {
259
- return !excludedHeaders.has(key.toLowerCase())
260
- })
261
- )
262
- }
263
- }
1
+ export { KnownAgents } from "./KnownAgents"
2
+ export {
3
+ AgentType,
4
+ type IdentificationRequest,
5
+ type IdentificationResult,
6
+ type RESTACPResponseBody,
7
+ type RESTUCPResponseBody,
8
+ type TrackPageviewOrRESTCallOptions,
9
+ type VisitRequest
10
+ } from "./types"
package/src/paths.ts ADDED
@@ -0,0 +1,72 @@
1
+ export function getIsPathExcluded(path: string): boolean {
2
+ const pathWithoutQueryString = path.split(/[?#]/)[0]
3
+ const lowercasedPath = pathWithoutQueryString.toLowerCase()
4
+
5
+ const excludedPrefixes = [
6
+ "/_next/",
7
+ "/_nuxt/",
8
+ "/_astro/",
9
+ "/_app/",
10
+ "/__nextjs",
11
+ "/__vite_ping",
12
+ "/__webpack_hmr",
13
+ "/@vite/",
14
+ "/@fs/",
15
+ "/@id/",
16
+ "/@react-refresh",
17
+ "/node_modules/",
18
+ "/_vercel/",
19
+ "/sockjs-node/",
20
+ "/webpack-dev-server/",
21
+ ]
22
+
23
+ const excludedSuffixes = [
24
+ ".ico",
25
+ ".png",
26
+ ".jpg",
27
+ ".jpeg",
28
+ ".gif",
29
+ ".webp",
30
+ ".svg",
31
+ ".bmp",
32
+ ".tiff",
33
+ ".avif",
34
+ ".heic",
35
+ ".heif",
36
+ ".css",
37
+ ".js",
38
+ ".mjs",
39
+ ".ts",
40
+ ".jsx",
41
+ ".tsx",
42
+ ".map",
43
+ ".wasm",
44
+ ".woff",
45
+ ".woff2",
46
+ ".ttf",
47
+ ".otf",
48
+ ".eot",
49
+ ".mp3",
50
+ ".mp4",
51
+ ".webm",
52
+ ".wav",
53
+ ".ogg",
54
+ ".aac",
55
+ ".m4a",
56
+ ".flac",
57
+ ".mov",
58
+ ".avi",
59
+ ".flv",
60
+ ".m4v",
61
+ ".webmanifest",
62
+ ".pdf",
63
+ ".zip",
64
+ ".gz",
65
+ ]
66
+
67
+ return excludedPrefixes.some((excludedPrefix) => {
68
+ return lowercasedPath.startsWith(excludedPrefix.toLowerCase())
69
+ }) || excludedSuffixes.some((excludedSuffix) => {
70
+ return lowercasedPath.endsWith(excludedSuffix.toLowerCase())
71
+ })
72
+ }
package/src/types.ts ADDED
@@ -0,0 +1,139 @@
1
+ import type { IncomingHttpHeaders, OutgoingHttpHeaders } from "http"
2
+
3
+ /**
4
+ * ACP response details from a REST API call.
5
+ */
6
+ export interface RESTACPResponseBody {
7
+ /** The response currency, usually an ISO 4217 code. */
8
+ currency?: string
9
+ /** ACP totals returned by the REST endpoint. The "total" item is sent to Known Agents. */
10
+ totals?: {
11
+ type?: string
12
+ amount?: number
13
+ }[]
14
+ }
15
+
16
+ /**
17
+ * UCP response details from a REST API call.
18
+ */
19
+ export interface RESTUCPResponseBody {
20
+ /** The response currency, usually an ISO 4217 code. */
21
+ currency?: string
22
+ /** UCP totals returned by the REST endpoint. The "total" item is sent to Known Agents. */
23
+ totals?: {
24
+ type?: string
25
+ amount?: number
26
+ }[]
27
+ }
28
+
29
+ /**
30
+ * Additional metadata to include when tracking a pageview or REST API call.
31
+ */
32
+ export interface TrackPageviewOrRESTCallOptions {
33
+ /** ACP response body from the REST endpoint. */
34
+ restACPResponseBody?: RESTACPResponseBody
35
+ /** UCP response body from the REST endpoint. */
36
+ restUCPResponseBody?: RESTUCPResponseBody
37
+ }
38
+
39
+ /**
40
+ * A normalized visit payload for the Known Agents API.
41
+ * Use this with `trackVisits()` when batching requests yourself.
42
+ */
43
+ export interface VisitRequest {
44
+ /** The URL path and query string of the request (e.g. "/about?foo=bar") */
45
+ request_path: string
46
+ /** The HTTP method (e.g. "GET", "POST") */
47
+ request_method: string
48
+ /** The HTTP request headers. Sensitive headers are removed before sending. */
49
+ request_headers: IncomingHttpHeaders
50
+ /** The HTTP response status code (e.g. 200, 404) */
51
+ response_status_code?: number
52
+ /** The HTTP response headers. Sensitive headers are removed before sending. */
53
+ response_headers?: OutgoingHttpHeaders
54
+ /** The response duration in milliseconds */
55
+ response_duration_in_milliseconds?: number
56
+ /** The MCP JSON-RPC request method */
57
+ mcp_request_method?: string
58
+ /** The MCP request tool name */
59
+ mcp_request_tool_name?: string
60
+ /** The MCP request client name */
61
+ mcp_request_client_info_name?: string
62
+ /** The MCP request client version */
63
+ mcp_request_client_info_version?: string
64
+ /** Whether the MCP response result is an error */
65
+ mcp_response_result_is_error?: boolean
66
+ /** The MCP response error code */
67
+ mcp_response_error_code?: number
68
+ /** The MCP response error message */
69
+ mcp_response_error_message?: string
70
+ /** The ACP response currency */
71
+ acp_response_currency?: string
72
+ /** The ACP response "total" amount */
73
+ acp_response_total_amount?: number
74
+ /** The UCP response currency */
75
+ ucp_response_currency?: string
76
+ /** The UCP response "total" amount */
77
+ ucp_response_total_amount?: number
78
+ /** The timestamp when the visit occurred (ISO 8601 format) */
79
+ created?: string
80
+ }
81
+
82
+ /**
83
+ * An agent identification request for the Known Agents API.
84
+ * Used for batch agent identification with `identifyAgents()`.
85
+ */
86
+ export interface IdentificationRequest {
87
+ /** An identifier that will be echoed back in the response to match requests with results */
88
+ id?: string
89
+ /** The HTTP request headers. Sensitive headers are removed before sending. */
90
+ request_headers: IncomingHttpHeaders
91
+ }
92
+
93
+ /**
94
+ * The result of an agent identification request.
95
+ */
96
+ export interface IdentificationResult {
97
+ /** The identifier from the request (if provided) */
98
+ id?: string
99
+ /**
100
+ * The identification result:
101
+ * - "verified": The agent was identified and verified
102
+ * - "verification_failed": The agent was identified but failed verification (spoofed)
103
+ * - "unknown_agent": The request is from an unrecognized agent or human
104
+ * - "not_verifiable": The agent was identified but cannot be verified
105
+ */
106
+ result: "verified" | "verification_failed" | "unknown_agent" | "not_verifiable"
107
+ /** The unique ID of the identified agent */
108
+ agent_id?: string
109
+ /** The name of the identified agent (e.g. "Googlebot") */
110
+ agent_token?: string
111
+ /** The documentation URL for the identified agent */
112
+ agent_url?: string
113
+ /** The type of the identified agent (e.g. "AI Agent", "Search Engine Crawler") */
114
+ agent_type_name?: string
115
+ /** The company behind the identified agent (e.g. "Google") */
116
+ operator_name?: string
117
+ }
118
+
119
+ /**
120
+ * Agent types that can be controlled with robots.txt rules.
121
+ */
122
+ export enum AgentType {
123
+ AIAgent = "AI Agent",
124
+ AIAssistant = "AI Assistant",
125
+ AICodingAgent = "AI Coding Agent",
126
+ AIDataProvider = "AI Data Provider",
127
+ AIDataScraper = "AI Data Scraper",
128
+ AISearchCrawler = "AI Search Crawler",
129
+ Archiver = "Archiver",
130
+ AutomatedAgent = "Automated Agent",
131
+ DeveloperHelper = "Developer Helper",
132
+ Fetcher = "Fetcher",
133
+ IntelligenceGatherer = "Intelligence Gatherer",
134
+ Scraper = "Scraper",
135
+ SEOCrawler = "SEO Crawler",
136
+ SearchEngineCrawler = "Search Engine Crawler",
137
+ SecurityScanner = "Security Scanner",
138
+ UndocumentedAIAgent = "Undocumented AI Agent"
139
+ }
package/tsconfig.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "include": ["src"],
3
- "compilerOptions": {
4
- "target": "ES2020",
5
- "module": "CommonJS",
6
- "outDir": "dist",
7
- "rootDir": "src",
8
- "declaration": true,
9
- "declarationMap": true,
10
- "esModuleInterop": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "strict": true,
13
- "skipLibCheck": true,
14
- "types": ["node"]
15
- }
16
- }