@suveren/gateway 0.2.2 → 0.2.3
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/dist/control-plane/index.mjs +2 -2
- package/dist/mcp-server/http.mjs +48 -17
- package/dist/ui/assets/{index-C0DMnnek.js → index-CIhRJ6MD.js} +23 -22
- package/dist/ui/index.html +1 -1
- package/dist/ui/mockups/intent-redesign.html +1 -1
- package/node_modules/eventsource-parser/README.md +31 -0
- package/node_modules/eventsource-parser/dist/index.cjs +21 -10
- package/node_modules/eventsource-parser/dist/index.cjs.map +1 -1
- package/node_modules/eventsource-parser/dist/index.d.cts +33 -10
- package/node_modules/eventsource-parser/dist/index.d.ts +33 -10
- package/node_modules/eventsource-parser/dist/index.js +21 -10
- package/node_modules/eventsource-parser/dist/index.js.map +1 -1
- package/node_modules/eventsource-parser/dist/stream.cjs +4 -3
- package/node_modules/eventsource-parser/dist/stream.cjs.map +1 -1
- package/node_modules/eventsource-parser/dist/stream.d.cts +16 -3
- package/node_modules/eventsource-parser/dist/stream.d.ts +16 -3
- package/node_modules/eventsource-parser/dist/stream.js +4 -3
- package/node_modules/eventsource-parser/dist/stream.js.map +1 -1
- package/node_modules/eventsource-parser/package.json +8 -8
- package/node_modules/eventsource-parser/src/errors.ts +1 -1
- package/node_modules/eventsource-parser/src/index.ts +6 -1
- package/node_modules/eventsource-parser/src/parse.ts +55 -13
- package/node_modules/eventsource-parser/src/stream.ts +24 -5
- package/node_modules/eventsource-parser/src/types.ts +25 -0
- package/node_modules/hasown/CHANGELOG.md +7 -0
- package/node_modules/hasown/index.d.ts +0 -1
- package/node_modules/hasown/package.json +4 -5
- package/package.json +1 -1
|
@@ -854,7 +854,7 @@ ${contextParts.join("\n")}` : "",
|
|
|
854
854
|
}
|
|
855
855
|
}
|
|
856
856
|
var CHAT_SYSTEM_PROMPTS = {
|
|
857
|
-
context: `You help a human author "context.md" \u2014 the standing-orders brief that
|
|
857
|
+
context: `You help a human author "context.md" \u2014 the standing-orders brief that Suveren prepends to every AI agent session it gates.
|
|
858
858
|
|
|
859
859
|
This text goes straight into the system prompt of downstream agents. Keep it operational, concrete, and short. Favor examples the user would recognize from their work.
|
|
860
860
|
|
|
@@ -870,7 +870,7 @@ When you propose a complete draft (or a full-document rewrite) of the context, w
|
|
|
870
870
|
\`\`\`
|
|
871
871
|
|
|
872
872
|
Only use that fence for full-document drafts the user can click "Apply". For partial suggestions, comments, or questions, write prose without the fence.`,
|
|
873
|
-
intent: `You help a human write an "Intent" paragraph for an AI agent authorization
|
|
873
|
+
intent: `You help a human write an "Intent" paragraph for an AI agent authorization issued by Suveren.
|
|
874
874
|
|
|
875
875
|
The Intent is read by two audiences:
|
|
876
876
|
1. The agent, on demand via list-authorizations(domain), when it's about to act in this domain.
|
package/dist/mcp-server/http.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// bin/http.ts
|
|
4
|
-
import { randomUUID } from "crypto";
|
|
4
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
5
5
|
import express from "express";
|
|
6
6
|
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
7
7
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
@@ -15,12 +15,19 @@ var SPReceiptError = class extends Error {
|
|
|
15
15
|
this.name = "SPReceiptError";
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
|
+
var DEFAULT_RECEIPT_RETRY = {
|
|
19
|
+
maxAttempts: 3,
|
|
20
|
+
delaysMs: [100, 300]
|
|
21
|
+
};
|
|
22
|
+
var sleep = (ms) => ms > 0 ? new Promise((resolve3) => setTimeout(resolve3, ms)) : Promise.resolve();
|
|
18
23
|
var SPClient = class {
|
|
19
|
-
constructor(baseUrl) {
|
|
24
|
+
constructor(baseUrl, receiptRetry = {}) {
|
|
20
25
|
this.baseUrl = baseUrl;
|
|
26
|
+
this.receiptRetry = { ...DEFAULT_RECEIPT_RETRY, ...receiptRetry };
|
|
21
27
|
}
|
|
22
28
|
sessionCookie = "";
|
|
23
29
|
apiKey = "";
|
|
30
|
+
receiptRetry;
|
|
24
31
|
setApiKey(key) {
|
|
25
32
|
this.apiKey = key;
|
|
26
33
|
}
|
|
@@ -89,18 +96,39 @@ var SPClient = class {
|
|
|
89
96
|
* Errors throw SPReceiptError with the structured `errors` array in `body`.
|
|
90
97
|
*/
|
|
91
98
|
async postReceipt(data) {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
const body = JSON.stringify(data);
|
|
100
|
+
const maxAttempts = data.idempotencyKey ? this.receiptRetry.maxAttempts : 1;
|
|
101
|
+
let lastError;
|
|
102
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
103
|
+
const isLast = attempt === maxAttempts;
|
|
104
|
+
let res;
|
|
105
|
+
try {
|
|
106
|
+
res = await this.fetch("/api/as/receipt", { method: "POST", body });
|
|
107
|
+
} catch (err) {
|
|
108
|
+
lastError = err;
|
|
109
|
+
if (isLast) throw err;
|
|
110
|
+
await sleep(this.receiptRetry.delaysMs[attempt - 1] ?? 0);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const respBody = await res.json().catch(() => ({}));
|
|
114
|
+
if (res.status >= 500 && !isLast) {
|
|
115
|
+
lastError = new SPReceiptError(
|
|
116
|
+
`SP receipt request failed: ${res.status}`,
|
|
117
|
+
res.status,
|
|
118
|
+
respBody
|
|
119
|
+
);
|
|
120
|
+
await sleep(this.receiptRetry.delaysMs[attempt - 1] ?? 0);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (!res.ok || respBody.approved === false) {
|
|
124
|
+
const errors = respBody.errors;
|
|
125
|
+
const first = errors?.[0];
|
|
126
|
+
const message = first?.message ?? first?.code ?? respBody.error ?? `SP receipt request failed: ${res.status}`;
|
|
127
|
+
throw new SPReceiptError(message, res.status, respBody);
|
|
128
|
+
}
|
|
129
|
+
return { receipt: respBody.receipt };
|
|
102
130
|
}
|
|
103
|
-
|
|
131
|
+
throw lastError ?? new Error("postReceipt: retries exhausted");
|
|
104
132
|
}
|
|
105
133
|
/**
|
|
106
134
|
* Submit a proposal for deferred commitment review.
|
|
@@ -818,7 +846,8 @@ function countToolsByGating(profileId, integrationManager2) {
|
|
|
818
846
|
function buildMandateBrief(opts) {
|
|
819
847
|
const { authorizations, executionLog, integrationManager: integrationManager2, contextDir } = opts;
|
|
820
848
|
const lines = [
|
|
821
|
-
"You are
|
|
849
|
+
"You are connected to Suveren \u2014 the gateway that gates every privileged tool call you make.",
|
|
850
|
+
"Suveren implements the bounded-authority model from the open Human Agency Protocol (HAP).",
|
|
822
851
|
"You have bounded authorities granted by human decision owners.",
|
|
823
852
|
"You MUST stay within these bounds \u2014 the Gatekeeper will reject actions that exceed them."
|
|
824
853
|
];
|
|
@@ -878,6 +907,7 @@ import { getProfile as getProfile2 } from "@hap/core";
|
|
|
878
907
|
// src/lib/tool-proxy.ts
|
|
879
908
|
import { readFile } from "fs/promises";
|
|
880
909
|
import { extname } from "path";
|
|
910
|
+
import { randomUUID } from "crypto";
|
|
881
911
|
var IMAGE_MIME = {
|
|
882
912
|
".jpg": "image/jpeg",
|
|
883
913
|
".jpeg": "image/jpeg",
|
|
@@ -1048,7 +1078,8 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
|
|
|
1048
1078
|
action: tool.namespacedName,
|
|
1049
1079
|
actionType,
|
|
1050
1080
|
executionContext: { ...execution },
|
|
1051
|
-
amount: typeof execution.amount === "number" ? execution.amount : void 0
|
|
1081
|
+
amount: typeof execution.amount === "number" ? execution.amount : void 0,
|
|
1082
|
+
idempotencyKey: randomUUID()
|
|
1052
1083
|
});
|
|
1053
1084
|
} catch (err) {
|
|
1054
1085
|
if (err instanceof SPReceiptError && err.statusCode === 409) {
|
|
@@ -1427,7 +1458,7 @@ function listIntegrationsHandler(state2, integrationManager2) {
|
|
|
1427
1458
|
if (matchingAuths.length > 0) {
|
|
1428
1459
|
const soonestExpiry = Math.min(
|
|
1429
1460
|
...matchingAuths.flatMap(
|
|
1430
|
-
(a) => a.attestations.map((att) => att.
|
|
1461
|
+
(a) => a.attestations.map((att) => att.expiresAt)
|
|
1431
1462
|
)
|
|
1432
1463
|
);
|
|
1433
1464
|
const remainingMs = soonestExpiry * 1e3 - Date.now();
|
|
@@ -2497,7 +2528,7 @@ app.all("/mcp", async (req, res) => {
|
|
|
2497
2528
|
}
|
|
2498
2529
|
if (req.method === "POST" && !sessionId) {
|
|
2499
2530
|
const transport = new StreamableHTTPServerTransport({
|
|
2500
|
-
sessionIdGenerator: () =>
|
|
2531
|
+
sessionIdGenerator: () => randomUUID2()
|
|
2501
2532
|
});
|
|
2502
2533
|
transport.onclose = () => {
|
|
2503
2534
|
if (transport.sessionId) {
|