@forgeintel/sdk 0.5.0-beta.3 → 0.5.0-beta.5

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
@@ -1,6 +1,6 @@
1
1
  # @forgeintel/sdk
2
2
 
3
- > **Beta.** Install with `npm install @forgeintel/sdk@beta`. The API may change before 1.0.
3
+ > **Beta.** Install with `npm install @forgeintel/sdk`. The API may change before 1.0.
4
4
 
5
5
  The Forge SDK for x402 paid APIs. Paid responses carry a `feedback_id`, the 402 challenge asks agents to rate the call, a rating is one free GET, and every call is reported to your Forge dashboard in the background. Never on your critical path: no network calls while your API serves a request, and it fails open. Aware of x402 v1 and v2, and of OpenAPI 2.0 through 3.2. Every change is additive, and anything it doesn't understand passes through untouched.
6
6
 
@@ -93,7 +93,7 @@ OpenAPI: Swagger 2.0 and OpenAPI 3.0, 3.1 and 3.2. Additive only; shared compone
93
93
  | `challengeSentence` | built-in | Override for wording experiments. `{rate_url}` and `{summary_url}` are substituted. Wording that presents the rating as required, makes anything depend on it, or asks for user data is refused (with a warning). |
94
94
  | `challengeExtension` | `true` | Add the `forge-feedback` extension to x402 v2 challenges. |
95
95
  | `receiptExtension` | `true` | Add it, with the real `feedback_id`, to the x402 v2 payment receipt (`PAYMENT-RESPONSE`). |
96
- | `agentContext` | `true` | Ask for self-reported `agent_context` (agent name, search query), record it, and remove it before your code runs. `{ searchQuery: false }` or `false` to limit. `{ required: true }` requires context before payment processing. |
96
+ | `agentContext` | `true` | Require self-reported `agent_context` (agent name, search query) on paid requests before payment processing; record and strip it before your code runs. `{ searchQuery: false }` requires only the agent name; `false` disables collection and enforcement. |
97
97
  | `injectBody` | `true` | Add `feedback_id` / `feedback_url` to paid JSON bodies. |
98
98
  | `rateHint` | built-in | The `rate_this_call` field. A string overrides it (`{feedback_url}` is substituted); `false` removes it. |
99
99
  | `injectText` | `false` | Append a two-line trailer to paid `text/plain` bodies. |
@@ -109,21 +109,21 @@ Source, examples and design notes: [github.com/ClawCash/forge-feedback](https://
109
109
 
110
110
  Client headers are captured automatically at discovery, challenge, payment, and rating stages, including unknown clients. Forge identifies awal, AgentCash, pay.sh and x402scan-mcp from known headers; other clients remain unknown. There is no client-signals switch. Legacy `agent_context.client` inputs remain accepted but are no longer requested.
111
111
 
112
- ### Requiring agent context
112
+ ### Agent context on paid requests
113
113
 
114
114
  ```ts
115
115
  const forge = createForge({
116
116
  apiKey: process.env.FORGE_API_KEY!,
117
117
  backendUrl: "https://your-forge-backend.example/api/sdk/v2",
118
118
  publicUrl: "https://api.example.com",
119
- agentContext: { required: true },
119
+ agentContext: true,
120
120
  });
121
121
  ```
122
122
 
123
- `agentContext: true` remains optional; `false` disables asking and recording. Required mode documents `agent_context` and its `agent_type` and `search_query` fields as required. Use a listed agent name (or `Others` with `agent_type_other`), and the search query or `"direct"`. `{ required: true, searchQuery: false }` requires only the agent type. Context is self-reported, not authenticated identity.
123
+ When enabled, context is always required on payment-bearing requests. `false` disables asking and recording. Forge documents `agent_context` and its `agent_type` and `search_query` fields as required. Use a listed agent name (or `Others` with `agent_type_other`), and the search query or `"direct"`. `{ searchQuery: false }` requires only the agent type. The legacy `required: false` option is ignored; disable `agentContext` to opt out. Context is self-reported, not authenticated identity.
124
124
 
125
125
  Mount Forge **before payment middleware**. 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. Initial unpaid requests can still receive a 402, and inspection and feedback routes stay accessible. Feedback remains optional and has its own `feedback` switch.
126
126
 
127
127
  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(...)`.
128
128
 
129
- If using the framework-free core directly, call `requestUrl` and `requestBody`, then check `call.contextError()` **before** invoking your payment logic; send its response when non-null. Existing SDK integrations remain optional until explicitly configured and upgraded.
129
+ If using the framework-free core directly, call `requestUrl` and `requestBody`, then check `call.contextError()` **before** invoking your payment logic; send its response when non-null. Upgrading an existing integration to this version makes enabled context mandatory for paid requests.
package/dist/context.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Self-reported facts about the calling agent, removed before merchant validation.
2
- // Optional by default; merchants can require context on payment-bearing requests.
2
+ // Enabled context is required on payment-bearing requests.
3
3
  /** Suggested agent names; anything else is kept as given. */
4
4
  export const AGENT_TYPES = ["Claude Code", "Codex", "Cursor", "Grok Bot", "Muse", "Hermes", "Instinct", "OpenClaw", "Others"];
5
5
  /** Suggested x402 clients; anything else is kept as given. */
@@ -91,7 +91,7 @@ const DESCRIPTIONS = {
91
91
  search_query: "The search query you used to find this service, or \"direct\" if you did not search.",
92
92
  };
93
93
  /** JSON Schema for the `agent_context` body property. */
94
- export function agentContextSchema({ searchQuery = true, required = false } = {}) {
94
+ export function agentContextSchema({ searchQuery = true, required = true } = {}) {
95
95
  return {
96
96
  type: "object",
97
97
  description: DESCRIPTIONS.object,
@@ -114,7 +114,7 @@ export function agentContextParameters({ searchQuery = true } = {}) {
114
114
  return params;
115
115
  }
116
116
  /** One line for the forge-feedback extension, so clients that only inspect the 402 learn about it too. */
117
- export function agentContextAsk({ searchQuery = true, required = false } = {}) {
117
+ export function agentContextAsk({ searchQuery = true, required = true } = {}) {
118
118
  const fields = searchQuery ? "agent_type, search_query" : "agent_type";
119
119
  const query = searchQuery ? "agent_type, agent_search_query query parameters" : "agent_type query parameter";
120
120
  return `${required ? "Required before payment" : "Please add"}: agent_context {${fields}} in your paid request's JSON body (without a body: ${query}).${searchQuery ? ' search_query: share the query you used to find this service, or "direct" if you did not search.' : ""}`;
package/dist/core.d.ts CHANGED
@@ -50,12 +50,13 @@ export interface ForgeOptions {
50
50
  */
51
51
  receiptExtension?: boolean;
52
52
  /**
53
- * Agent context: optional, self-reported `agent_context` {agent_type, search_query} on the paid request
53
+ * Agent context: required, 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
56
  * run. Default true. `{ searchQuery: false }` stops asking for (and recording) the search query; `false` stops
57
57
  * asking and recording altogether (the fields are still removed if an agent sends them).
58
- * `{ required: true }` rejects payment-bearing requests with missing/invalid context before payment middleware.
58
+ * Enabled context rejects payment-bearing requests with missing/invalid context before payment middleware.
59
+ * `required` is retained for compatibility; `false` is ignored. Use `false` for agentContext to disable it.
59
60
  */
60
61
  agentContext?: boolean | {
61
62
  searchQuery?: boolean;
package/dist/core.js CHANGED
@@ -64,6 +64,8 @@ export function checkOptions(input) {
64
64
  fallback("agentContext", boolean(raw.agentContext) || (!!raw.agentContext && typeof raw.agentContext === "object" && !Array.isArray(raw.agentContext)), "must be true, false or { searchQuery, required }");
65
65
  if (raw.agentContext && typeof raw.agentContext === "object" && !Array.isArray(raw.agentContext)) {
66
66
  const context = raw.agentContext;
67
+ if (context.required === false)
68
+ warnings.push("agentContext.required: false is no longer supported; enabled context is required on paid requests. Set agentContext: false to disable context");
67
69
  for (const key of ["required", "searchQuery"]) {
68
70
  if (context[key] !== undefined && typeof context[key] !== "boolean") {
69
71
  errors.push(`agentContext.${key} must be a boolean`);
@@ -175,7 +177,7 @@ function enabledCore(options, configWarnings) {
175
177
  const contextOption = options.agentContext ?? true;
176
178
  const collectContext = contextOption !== false;
177
179
  const searchQuery = collectContext && (typeof contextOption !== "object" || contextOption.searchQuery !== false);
178
- const requiredContext = collectContext && typeof contextOption === "object" && contextOption.required === true;
180
+ const requiredContext = collectContext;
179
181
  const receipts = options.receiptExtension ?? true;
180
182
  const rateHint = options.rateHint === false
181
183
  ? null
package/dist/express.js CHANGED
@@ -135,7 +135,7 @@ export function createForge(options) {
135
135
  core.onError(error);
136
136
  }
137
137
  if (call.contextRequired) {
138
- // Opt-in only: parse before payment middleware even when the merchant mounts express.json later.
138
+ // Enabled context: parse before payment middleware even when the merchant mounts express.json later.
139
139
  // The body setter above captures context and leaves only merchant fields in req.body.
140
140
  const parseError = await new Promise((resolve) => {
141
141
  express.json({ limit: "1mb", type: ["application/json", "application/*+json"] })(req, res, resolve);
package/dist/fetch.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // Web-standard adapter: Request in, Response out. Works wherever handlers are (request) => Response:
2
2
  // Hono, Next.js route handlers, Cloudflare Workers, Bun, Deno. The Hono and Next adapters build on this.
3
3
  import { BODY_LIMIT, SPEC_LIMIT, createForgeCore } from "./core.js";
4
- /** Buffer limit; optional mode passes larger bodies through, required mode rejects oversized JSON. */
4
+ /** Buffer limit; enabled context rejects oversized paid JSON before payment processing. */
5
5
  const JSON_LIMIT = 1024 * 1024;
6
6
  const isJson = (type) => /^application\/(?:[\w.+-]+\+)?json\b/i.test(type ?? "");
7
7
  export function toResponse(response) {
@@ -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 || typeof options.agentContext !== "object" || !options.agentContext.required)
73
+ if (!core.enabled || options.agentContext === false)
74
74
  return null;
75
75
  const url = new URL(request.url);
76
76
  const call = core.call(forgeRequest(request, url));
package/dist/openapi.d.ts CHANGED
@@ -2,7 +2,7 @@ type Json = Record<string, any>;
2
2
  export type SpecVersion = "2.0" | "3.0" | "3.1" | "3.2";
3
3
  export type ResponseSupport = "extended" | "incompatible" | "undocumented";
4
4
  export interface EnrichOptions {
5
- /** Disable all feedback additions while retaining optional agent context. */
5
+ /** Disable all feedback additions while retaining enabled agent context. */
6
6
  feedback?: boolean;
7
7
  /** Merchant public origin, e.g. https://api.example.com */
8
8
  publicUrl: string;
@@ -30,7 +30,7 @@ export interface OperationReport {
30
30
  path: string;
31
31
  /** Per 2xx status code: whether feedback_id was added to its JSON schema. */
32
32
  responses: Record<string, ResponseSupport>;
33
- /** Where optional agent context was documented, if asked to. */
33
+ /** Where enabled agent context was documented, if asked to. */
34
34
  agentContext?: "body" | "query" | "not_added";
35
35
  reasons: string[];
36
36
  }
package/dist/openapi.js CHANGED
@@ -102,6 +102,7 @@ function extendSchema(doc, schema, props) {
102
102
  const BODYLESS = new Set(["get", "head", "delete", "options", "trace"]);
103
103
  /** Document agent context on a paid operation; skip schemas that cannot be extended safely. */
104
104
  function addAgentContext(doc, version, item, method, op, opts, report) {
105
+ opts = { ...opts, required: true }; // Enabled context cannot be made optional by a legacy option.
105
106
  const resolve = (v) => (isObj(v) && typeof v.$ref === "string" ? resolveRef(doc, v.$ref) : v);
106
107
  const listed = [...(Array.isArray(item.parameters) ? item.parameters : []), ...(Array.isArray(op.parameters) ? op.parameters : [])].map(resolve).filter(isObj);
107
108
  const props = { [CONTEXT_FIELD]: agentContextSchema(opts) };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@forgeintel/sdk",
3
- "version": "0.5.0-beta.3",
4
- "description": "The Forge SDK for x402 paid APIs: agent feedback (feedback IDs, one-request GET ratings), agent context, OpenAPI and challenge enrichment, and passive call signals. Express, Hono, Next.js and any fetch handler. Never on your critical path.",
3
+ "version": "0.5.0-beta.5",
4
+ "description": "The Forge SDK for x402 paid APIs: agent feedback, required 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",
7
7
  "engines": {
@@ -73,7 +73,7 @@
73
73
  },
74
74
  "publishConfig": {
75
75
  "access": "public",
76
- "tag": "beta"
76
+ "tag": "latest"
77
77
  },
78
78
  "peerDependencies": {
79
79
  "express": ">=4.21 <6",