@suveren/gateway 0.19.4 → 0.19.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/content/guides/1-interview.md +6 -0
- package/content/guides/2-package.md +4 -1
- package/content/guides/3-mandates.md +3 -0
- package/content/guides/6-risks.md +2 -0
- package/dist/mcp-server/http.mjs +77 -3
- package/dist/ui/assets/{index-BseWI4iJ.js → index-Du68zJhH.js} +24 -24
- package/dist/ui/assets/{index-RCFQUjaF.css → index-blnpvM2g.css} +1 -1
- package/dist/ui/index.html +2 -2
- package/package.json +1 -1
|
@@ -4,6 +4,12 @@ Learn the company, the team and the work, and collect real cases. Nothing is loa
|
|
|
4
4
|
|
|
5
5
|
You ask; the person answers and checks. Ask one topic at a time and write down what you learn.
|
|
6
6
|
|
|
7
|
+
## Before you start: the systems
|
|
8
|
+
|
|
9
|
+
Look at the systems in the header above. If a system the work needs is listed under **Available but not activated**, ask the person to activate it first (Integrations → its card → Activate) and read this guide again. Do not plan around a system you cannot see.
|
|
10
|
+
|
|
11
|
+
Plan the test only with the actions the connected systems offer — the header lists each system's changes and reads. If the work needs an action no system offers (for example a refund when the ERP has only quotes and orders), say so and agree with the person on what to test instead. Never pretend a system can do more than it does.
|
|
12
|
+
|
|
7
13
|
## What to ask, in this order
|
|
8
14
|
|
|
9
15
|
1. **Company:** what it sells, to whom, in which currency, and which systems it uses. The systems connected to this gateway are listed in the header above; ask about the ones that matter for the work.
|
|
@@ -4,7 +4,7 @@ Turn the confirmed cases into test data and load it into the simulated systems.
|
|
|
4
4
|
|
|
5
5
|
## Build the package
|
|
6
6
|
|
|
7
|
-
One package feeds every simulated system. Its format
|
|
7
|
+
One package feeds every simulated system. Its exact format is at the end of this guide (read from the simulated systems themselves), and how to build a good one is described there too. In short: the company's `name` and `currency`, the `customers`, `products` and `contacts` the cases need, and the `cases` themselves (each request as it arrived and the reply that was actually sent).
|
|
8
8
|
|
|
9
9
|
- Include every customer, product and contact a case mentions, with stock, prices and credit limits that make each case answerable the way it really was.
|
|
10
10
|
- Use only the renamed cases.
|
|
@@ -27,4 +27,7 @@ Clear and load each count against the setup mandate's daily limit, so one re-run
|
|
|
27
27
|
|
|
28
28
|
The real replies stay inside the simulated email system. They are never shown to the working AI; they exist for comparing afterwards.
|
|
29
29
|
|
|
30
|
+
|
|
31
|
+
<!-- generated: package -->
|
|
32
|
+
|
|
30
33
|
Next: **mandates**.
|
|
@@ -10,5 +10,7 @@ What can make a test say more than it should, and what to do about each. Read th
|
|
|
10
10
|
| Mandates too loose | A wrong result can look like success | Start in review mode or with low caps; loosen by replacing the mandate |
|
|
11
11
|
| Proposals are stored readable on the Authority Server | The content of every proposal, including intents, can be read there | Test data and renamed cases only — never real customer data in a setup |
|
|
12
12
|
| Setup limit too low | A clear without the following load leaves empty systems | Use a setup limit of 4–6 per day; clear and load in one go |
|
|
13
|
+
| An AI that can control a browser or the screen | It could open the gateway's page, read the API key there and approve its own proposals — the person would no longer decide | Never open or operate the gateway's page, never handle the API key, never approve. Tell the person to approve themselves, and to keep the gateway page out of any browser an AI controls |
|
|
14
|
+
| Calls around the Suveren tools | A terminal, HTTP or browser call to the gateway's ports is not governed by a mandate | Use only the Suveren tools. If something is missing, tell the person what — do not probe the gateway |
|
|
13
15
|
|
|
14
16
|
Next: start a run — the person asks the working AI to work the new requests.
|
package/dist/mcp-server/http.mjs
CHANGED
|
@@ -4079,6 +4079,12 @@ function agentVisibleAuthorizations(authorizations, integrationManager2) {
|
|
|
4079
4079
|
);
|
|
4080
4080
|
}
|
|
4081
4081
|
|
|
4082
|
+
// src/lib/agent-rules.ts
|
|
4083
|
+
var AGENT_RULES = [
|
|
4084
|
+
"Never open or operate the Suveren Gateway's web page \u2014 not in a browser you control, not with computer use. Never ask for, read or type the person's API key. Never approve a proposal: approvals are the person's alone.",
|
|
4085
|
+
"Use only the Suveren tools. No terminal, HTTP or browser calls to the gateway's ports (for example `curl localhost:3500/mcp`)."
|
|
4086
|
+
];
|
|
4087
|
+
|
|
4082
4088
|
// src/lib/mandate-brief.ts
|
|
4083
4089
|
function shortProfileName(profileId) {
|
|
4084
4090
|
const withoutVersion = profileId.replace(/@.*$/, "");
|
|
@@ -4165,6 +4171,10 @@ function buildMandateBrief(opts) {
|
|
|
4165
4171
|
lines.push(canSetUp ? "If the person asks how to start with Suveren or how to set up their work with it: call setup__get_guide first and follow its steps in order." : `If the person asks how to start with Suveren: they first create a "Delegation" mandate in the Suveren Gateway at ${uiUrl()}. With it you can read the setup guide and lead them through the setup.`);
|
|
4166
4172
|
lines.push("");
|
|
4167
4173
|
}
|
|
4174
|
+
lines.push("=== RULES ===");
|
|
4175
|
+
lines.push("");
|
|
4176
|
+
for (const r of AGENT_RULES) lines.push(`- ${r}`);
|
|
4177
|
+
lines.push("");
|
|
4168
4178
|
lines.push("When you receive a task, call list-authorizations(domain) to load full details for the relevant domain.");
|
|
4169
4179
|
return lines.join("\n");
|
|
4170
4180
|
}
|
|
@@ -6862,7 +6872,7 @@ function loadGuides(builtinDir = builtinGuidesDir(), overrideDir = process.env.S
|
|
|
6862
6872
|
}
|
|
6863
6873
|
return [...byTopic.values()].sort((a, b) => a.order - b.order || a.topic.localeCompare(b.topic));
|
|
6864
6874
|
}
|
|
6865
|
-
function guideHeader(systems) {
|
|
6875
|
+
function guideHeader(systems, inactive = []) {
|
|
6866
6876
|
const lines = [
|
|
6867
6877
|
"> This guide is in English. Talk to the person in their language, and write the brief and mandate intents in the language the team uses.",
|
|
6868
6878
|
"",
|
|
@@ -6880,12 +6890,67 @@ function guideHeader(systems) {
|
|
|
6880
6890
|
lines.push(`- **${s.id}** \u2014 ${parts.join("; ")}`);
|
|
6881
6891
|
}
|
|
6882
6892
|
}
|
|
6893
|
+
if (inactive.length) {
|
|
6894
|
+
lines.push("");
|
|
6895
|
+
lines.push("**Available but not activated:** " + inactive.map((n) => `**${n}**`).join(", ") + ". Before anything else, ask the person to activate the ones the work needs: in the Suveren Gateway, Integrations \u2192 the system's card \u2192 Activate. Then read this guide again \u2014 a system you cannot see here does not exist for the test.");
|
|
6896
|
+
}
|
|
6883
6897
|
lines.push("");
|
|
6884
6898
|
lines.push(`**Approvals:** every mandate and brief you propose waits until the person approves it in the Suveren Gateway at ${uiUrl()}/approvals. Tell them each time you propose one.`);
|
|
6899
|
+
lines.push("");
|
|
6900
|
+
lines.push("**Rules:**");
|
|
6901
|
+
for (const r of AGENT_RULES) lines.push(`- ${r}`);
|
|
6885
6902
|
return lines.join("\n");
|
|
6886
6903
|
}
|
|
6904
|
+
function scopeFieldsOf(profile) {
|
|
6905
|
+
return profile.scopeSchema ?? profile.contextSchema;
|
|
6906
|
+
}
|
|
6907
|
+
function fieldLine(name, f) {
|
|
6908
|
+
const kind = [];
|
|
6909
|
+
const values = f.boundType?.values ?? f.enum;
|
|
6910
|
+
if (Array.isArray(values)) kind.push(`one of ${values.map((v) => `\`${String(v)}\``).join(", ")}`);
|
|
6911
|
+
else if (f.type) kind.push(f.type);
|
|
6912
|
+
if (f.unit) kind.push(f.unit);
|
|
6913
|
+
if (f.boundType?.window) kind.push(`per ${f.boundType.window === "daily" ? "day" : f.boundType.window}`);
|
|
6914
|
+
if (typeof f.maximum === "number") kind.push(`at most ${f.maximum}`);
|
|
6915
|
+
if (f.default !== void 0) kind.push(`default \`${String(f.default)}\``);
|
|
6916
|
+
const label = f.displayName ? ` (${f.displayName})` : "";
|
|
6917
|
+
return `- \`${name}\`${label} \u2014 ${kind.join(", ") || "value"}${f.description ? `. ${f.description}` : ""}`;
|
|
6918
|
+
}
|
|
6919
|
+
function fieldLines(schema) {
|
|
6920
|
+
const fields = schema?.fields ?? {};
|
|
6921
|
+
const order = (schema?.keyOrder ?? Object.keys(fields)).filter((k) => k !== "profile" && k !== "path" && fields[k]);
|
|
6922
|
+
return order.map((k) => fieldLine(k, fields[k]));
|
|
6923
|
+
}
|
|
6924
|
+
function limitsSection(systems) {
|
|
6925
|
+
const out = ["## Limits and scope per system", "", "From the profiles \u2014 use exactly these names in `create_mandate` (`limits` and `scope`). Every limit must be set.", ""];
|
|
6926
|
+
for (const s of systems) {
|
|
6927
|
+
if (!s.profile) continue;
|
|
6928
|
+
out.push(`### ${s.id} \u2014 profile \`${s.profile.id}\``, "", "**Limits:**", ...fieldLines(s.profile.boundsSchema));
|
|
6929
|
+
const scope2 = fieldLines(scopeFieldsOf(s.profile));
|
|
6930
|
+
out.push("", "**Scope:**", ...scope2.length ? scope2 : ["- none"], "");
|
|
6931
|
+
}
|
|
6932
|
+
return out.join("\n");
|
|
6933
|
+
}
|
|
6934
|
+
function packageSection(tool) {
|
|
6935
|
+
if (!tool?.inputSchema) return "## The package format\n\nNo simulated system with `load_simulation` is active \u2014 ask the person to activate one first.";
|
|
6936
|
+
const pkg = tool.inputSchema.properties?.package ?? tool.inputSchema;
|
|
6937
|
+
return [
|
|
6938
|
+
"## The package format",
|
|
6939
|
+
"",
|
|
6940
|
+
...tool.description ? ["What the simulated systems say about it:", "", `> ${tool.description}`, ""] : [],
|
|
6941
|
+
"The `package` argument of `load_simulation` \u2014 the same package for every simulated system:",
|
|
6942
|
+
"",
|
|
6943
|
+
"```json",
|
|
6944
|
+
JSON.stringify(pkg, null, 2),
|
|
6945
|
+
"```"
|
|
6946
|
+
].join("\n");
|
|
6947
|
+
}
|
|
6948
|
+
function fillGenerated(body, sections) {
|
|
6949
|
+
return body.replace(/<!--\s*generated:\s*([a-z-]+)\s*-->/g, (m, key) => sections[key] ? sections[key]() : m);
|
|
6950
|
+
}
|
|
6887
6951
|
|
|
6888
6952
|
// src/lib/builtins/setup.ts
|
|
6953
|
+
import { getProfile as getProfile7 } from "@hap/core";
|
|
6889
6954
|
var DELEGATION_PROFILE = "delegation";
|
|
6890
6955
|
var DELEGATION_INTENT_HINT = [
|
|
6891
6956
|
"Why \u2014 With test data only, I want to find out which routine parts of my work an AI could take over, so people gain time \u2014 before anything touches real systems.",
|
|
@@ -6974,7 +7039,10 @@ function setupBuiltin(deps) {
|
|
|
6974
7039
|
handler: async (args) => {
|
|
6975
7040
|
if (!isSimulationMode()) return { ...builtinText("Refused: not available outside simulation mode."), isError: true };
|
|
6976
7041
|
const guides = loadGuides();
|
|
6977
|
-
const
|
|
7042
|
+
const systems = connectedSystems(deps.integrationManager);
|
|
7043
|
+
const running = new Set(systems.map((s) => s.id));
|
|
7044
|
+
const inactive = getAllManifests().filter((m) => manifestIsSimulated(m) && !running.has(m.id)).map((m) => m.name);
|
|
7045
|
+
const header = guideHeader(systems, inactive);
|
|
6978
7046
|
const topic = typeof args.topic === "string" ? args.topic.trim().toLowerCase() : "";
|
|
6979
7047
|
if (!topic) {
|
|
6980
7048
|
const list = guides.map((g, i) => `${i + 1}. **${g.topic}** \u2014 ${g.summary}`).join("\n");
|
|
@@ -6990,9 +7058,15 @@ Read each topic with get_guide(topic) before doing that step.`);
|
|
|
6990
7058
|
if (!guide) {
|
|
6991
7059
|
return { ...builtinText(`Unknown topic "${topic}". Topics: ${guides.map((g) => g.topic).join(", ") || "none installed"}.`), isError: true };
|
|
6992
7060
|
}
|
|
7061
|
+
const body = fillGenerated(guide.body.trim(), {
|
|
7062
|
+
limits: () => limitsSection(systems.map((s) => ({ id: s.id, profile: getProfile7(s.profile) }))),
|
|
7063
|
+
package: () => packageSection(
|
|
7064
|
+
deps.integrationManager.getAllTools().find((t) => !deps.integrationManager.isBuiltin(t.integrationId) && t.originalName === "load_simulation")
|
|
7065
|
+
)
|
|
7066
|
+
});
|
|
6993
7067
|
return builtinText(`${header}
|
|
6994
7068
|
|
|
6995
|
-
${
|
|
7069
|
+
${body}`);
|
|
6996
7070
|
}
|
|
6997
7071
|
},
|
|
6998
7072
|
{
|