@forgeintel/sdk 0.5.0-beta.3 → 0.5.0-beta.4
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 +5 -5
- package/dist/context.js +3 -3
- package/dist/core.d.ts +3 -2
- package/dist/core.js +3 -1
- package/dist/express.js +1 -1
- package/dist/fetch.js +2 -2
- package/dist/openapi.d.ts +2 -2
- package/dist/openapi.js +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -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` |
|
|
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
|
-
###
|
|
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:
|
|
119
|
+
agentContext: true,
|
|
120
120
|
});
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
|
|
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.
|
|
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
|
-
//
|
|
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 =
|
|
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 =
|
|
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:
|
|
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
|
-
*
|
|
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
|
|
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
|
-
//
|
|
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;
|
|
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 ||
|
|
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
|
|
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
|
|
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.
|
|
4
|
-
"description": "The Forge SDK for x402 paid APIs: agent feedback
|
|
3
|
+
"version": "0.5.0-beta.4",
|
|
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": {
|