@forgeintel/sdk 0.5.0-beta.14 → 0.5.0-beta.15

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 CHANGED
@@ -11,6 +11,8 @@ import { createForge } from "@forgeintel/sdk";
11
11
 
12
12
  const forge = createForge({
13
13
  apiKey: process.env.FORGE_API_KEY,
14
+ feedback: true, // the rating ask; off by default
15
+ agentContext: true, // ask agents who they are, optional; off by default
14
16
  });
15
17
 
16
18
  app.use(forge.middleware()); // 1. first: before payments and your /openapi.json route
@@ -24,7 +26,7 @@ Works with `@x402/express` (v2) and `x402-express` (v1), on Express 4.21+ or 5.
24
26
  ```ts
25
27
  import { createForge } from "@forgeintel/sdk/hono";
26
28
 
27
- const forge = createForge({ apiKey });
29
+ const forge = createForge({ apiKey, feedback: true, agentContext: true });
28
30
  app.use(forge.middleware()); // before paymentMiddleware from @x402/hono
29
31
  app.use(paymentMiddleware(routes, resourceServer));
30
32
  ```
@@ -34,7 +36,7 @@ app.use(paymentMiddleware(routes, resourceServer));
34
36
  ```ts
35
37
  import { createForge } from "@forgeintel/sdk/next";
36
38
 
37
- export const forge = createForge({ apiKey });
39
+ export const forge = createForge({ apiKey, feedback: true, agentContext: true });
38
40
  // app/api/…/route.ts: Forge outermost, around @x402/next's withX402
39
41
  export const POST = forge.withForge(withX402(handler, route, resourceServer));
40
42
  // app/feedback/[[...path]]/route.ts: Forge's own routes
@@ -53,6 +55,8 @@ Zero runtime dependencies. Node ≥ 20.19. Works from both `import` and `require
53
55
 
54
56
  ## What it does
55
57
 
58
+ Both switches are off by default: with only an API key, Forge reports every 402 and paid call in the background and changes nothing agents see. `feedback: true` turns on the rows about rating below; `agentContext: true` turns on the agent context row.
59
+
56
60
  | When | What happens |
57
61
  | --- | --- |
58
62
  | 402 challenge | Appends one line to the description: *After your call, please rate this service for other agents: GET https://…/feedback/rate?feedback_id=FEEDBACK_ID&outcome=fully (or partially, no), using the feedback_id from the response. Free, one request.* On x402 v2 it also adds an `extensions["forge-feedback"]` block with the `ask`, the rating link and the outcome values, and previews the `forge_feedback` object (with a sample ID) in your Bazaar output example. The description never exceeds 500 characters (the CDP facilitator rejects longer ones): a shorter line is used when the full one doesn't fit, and none when neither does. Payment terms are never touched. |
@@ -110,16 +114,16 @@ Client headers are captured automatically at discovery, challenge, payment, and
110
114
  ### Agent context on paid requests
111
115
 
112
116
  ```ts
113
- createForge({ apiKey }); // default: asked for, optional
114
- createForge({ apiKey, agentContext: true }); // required before payment
115
- createForge({ apiKey, agentContext: { searchQuery: false } }); // required, agent name only
116
- createForge({ apiKey, agentContext: { required: false, searchQuery: false } }); // optional, agent name only
117
- createForge({ apiKey, agentContext: false }); // off
117
+ createForge({ apiKey }); // default: off
118
+ createForge({ apiKey, agentContext: true }); // asked for, optional
119
+ createForge({ apiKey, agentContext: { searchQuery: false } }); // optional, agent name only
120
+ createForge({ apiKey, agentContext: { required: true } }); // required before payment
121
+ createForge({ apiKey, agentContext: { required: true, searchQuery: false } }); // required, agent name only
118
122
  ```
119
123
 
120
- By default Forge asks for context and records it whenever an agent sends it, but a paid request without it is never rejected, so existing paying clients keep working. Forge documents `agent_context` and its `agent_type` and `search_query` fields as optional. Any agent name is accepted; known spellings are normalized (`Claude` and `claude-code` become `Claude Code`). Send the search query, or `"direct"`. When the merchant declares a `bazaar` extension, Forge adds the same field there (schema and example), so agents that discover the service through Bazaar see it too. Context is self-reported, not authenticated identity.
124
+ When on, Forge asks for context and records it whenever an agent sends it, but a paid request without it is never rejected unless you require it, so existing paying clients keep working. Forge documents `agent_context` and its `agent_type` and `search_query` fields as optional. Any agent name is accepted; known spellings are normalized (`Claude` and `claude-code` become `Claude Code`). Send the search query, or `"direct"`. When the merchant declares a `bazaar` extension, Forge adds the same field there (schema and example), so agents that discover the service through Bazaar see it too. Context is self-reported, not authenticated identity.
121
125
 
122
- `agentContext: true`, or an object without `required: false`, makes context required: Forge documents the fields as required, and a request carrying `PAYMENT-SIGNATURE` or `X-PAYMENT` gets HTTP 400 with field errors when context is missing or invalid, before the downstream payment handler runs. Mount Forge **before payment middleware**. Initial unpaid requests can still receive a 402, and inspection and feedback routes stay accessible. Feedback has its own `feedback` switch.
126
+ `{ required: true }` makes context required: Forge documents the fields as required, and a request carrying `PAYMENT-SIGNATURE` or `X-PAYMENT` gets HTTP 400 with field errors when context is missing or invalid, before the downstream payment handler runs. Mount Forge **before payment middleware**. Initial unpaid requests can still receive a 402, and inspection and feedback routes stay accessible. Feedback has its own `feedback` switch.
123
127
 
124
128
  Required mode reads JSON bodies up to 1 MiB, including chunked bodies, before payment processing. It rejects malformed or oversized JSON. Express parses these bodies even if your JSON parser is mounted later; mount a custom parser before Forge if you need one. For non-JSON bodies and bodyless requests, supply `agent_type` and `agent_search_query` query parameters. Forge strips context before forwarding to merchant validators. Next.js integrations that use a payment proxy should wrap both the proxy with `forge.proxy(...)` and the route with `forge.withForge(...)`.
125
129
 
package/dist/core.d.ts CHANGED
@@ -22,7 +22,7 @@ export interface ForgeOptions {
22
22
  backendUrl?: string;
23
23
  /** Optional public origin for absolute feedback links. By default links use same-origin paths. Never derived from the Host header. */
24
24
  publicUrl?: string;
25
- /** Enable rating prompts, feedback IDs and feedback routes. Default true. Telemetry and agent context are independent. */
25
+ /** Enable rating prompts, feedback IDs and feedback routes. Off by default: with only an API key, Forge reports telemetry and changes nothing agents see. Agent context is independent. */
26
26
  feedback?: boolean;
27
27
  /** Path for the feedback routes. Default "/feedback" (quick rating at "/feedback/rate"). */
28
28
  basePath?: string;
@@ -53,11 +53,10 @@ export interface ForgeOptions {
53
53
  * Agent context: self-reported `agent_context` {agent_type, search_query} on the paid request
54
54
  * (JSON body, or agent_type / agent_search_query query parameters). Forge documents it in the
55
55
  * extension and OpenAPI, reads it, reports it with the call, and removes it before your validators and handlers
56
- * run. By default it is asked for but optional: a paid request without it is never rejected.
57
- * `true` or `{ required: true }` requires it: payment-bearing requests with missing/invalid context get a 400
58
- * before payment middleware (an object is required unless it sets `required: false`).
59
- * `{ searchQuery: false }` stops asking for (and recording) the search query; `false` stops
60
- * asking and recording altogether (the fields are still removed if an agent sends them).
56
+ * run. Off by default. `true` (or an object) asks for it but keeps it optional: a paid request without it is
57
+ * never rejected. `{ required: true }` requires it: payment-bearing requests with missing/invalid context get a
58
+ * 400 before payment middleware. `{ searchQuery: false }` stops asking for (and recording) the search query.
59
+ * When off, the fields are still removed if an agent sends them.
61
60
  */
62
61
  agentContext?: boolean | {
63
62
  searchQuery?: boolean;
package/dist/core.js CHANGED
@@ -182,16 +182,16 @@ function enabledCore(options, configWarnings) {
182
182
  };
183
183
  const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
184
184
  const fetchImpl = options.fetch ?? fetch;
185
- const feedback = options.feedback !== false;
185
+ const feedback = options.feedback === true;
186
186
  const describe = feedback && (options.describeChallenges ?? true);
187
187
  const injectBody = options.injectBody ?? true;
188
188
  const injectText = options.injectText ?? false;
189
189
  const tone = options.tone ?? "soft";
190
190
  const contextOption = options.agentContext;
191
- const collectContext = contextOption !== false;
191
+ // Off unless configured. true or an object turns it on, optional; only { required: true } rejects (400).
192
+ const collectContext = contextOption === true || (!!contextOption && typeof contextOption === "object");
192
193
  const searchQuery = collectContext && (typeof contextOption !== "object" || contextOption.searchQuery !== false);
193
- // Optional unless configured: true, or an object without required: false, keeps the strict (400) behavior.
194
- const requiredContext = contextOption === true || (typeof contextOption === "object" && contextOption.required !== false);
194
+ const requiredContext = typeof contextOption === "object" && contextOption.required === true;
195
195
  const receipts = options.receiptExtension ?? true;
196
196
  const rateHint = options.rateHint === false
197
197
  ? null
package/dist/fetch.js CHANGED
@@ -70,7 +70,7 @@ export function createForge(options) {
70
70
  return own ? toResponse(own) : null;
71
71
  }
72
72
  async function validate(request) {
73
- if (!core.enabled || options.agentContext === false)
73
+ if (!core.enabled || !options.agentContext)
74
74
  return null;
75
75
  const url = new URL(request.url);
76
76
  const call = core.call(forgeRequest(request, url));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeintel/sdk",
3
- "version": "0.5.0-beta.14",
3
+ "version": "0.5.0-beta.15",
4
4
  "description": "The Forge SDK for x402 paid APIs: agent feedback, agent context, OpenAPI and challenge enrichment, and passive call signals. Express, Hono, Next.js and fetch handlers. No Forge network request on the merchant response path.",
5
5
  "license": "MIT",
6
6
  "type": "module",