@mnemom/mnemom 0.17.24 → 0.17.26
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/commands/agent-config.js +9 -0
- package/dist/commands/agent-doctor.d.ts +3 -2
- package/dist/commands/agent-doctor.js +22 -7
- package/dist/commands/agent-goal.js +7 -2
- package/dist/commands/agent-sessions.js +2 -1
- package/dist/commands/agent-setup.d.ts +104 -4
- package/dist/commands/agent-setup.js +414 -18
- package/dist/commands/agent-slack.d.ts +14 -1
- package/dist/commands/agent-slack.js +108 -23
- package/dist/commands/agent.d.ts +29 -1
- package/dist/commands/agent.js +89 -12
- package/dist/commands/wrap.d.ts +2 -0
- package/dist/commands/wrap.js +13 -1
- package/dist/index.js +19 -5
- package/dist/lib/agent-identity-route.d.ts +21 -3
- package/dist/lib/agent-identity-route.js +42 -15
- package/dist/lib/agent-ledger.d.ts +5 -0
- package/dist/lib/agent.d.ts +62 -1
- package/dist/lib/agent.js +55 -0
- package/dist/lib/api.d.ts +33 -1
- package/dist/lib/api.js +10 -0
- package/dist/lib/experimental.js +14 -2
- package/dist/lib/goal-api.d.ts +3 -3
- package/dist/lib/goal-api.js +5 -2
- package/dist/lib/launcher-config.d.ts +18 -0
- package/dist/lib/launcher-config.js +47 -1
- package/dist/lib/oauth.d.ts +7 -0
- package/dist/lib/oauth.js +92 -17
- package/dist/lib/served-agent-cache.d.ts +8 -1
- package/dist/lib/served-agent-cache.js +11 -2
- package/dist/lib/slack-channel.d.ts +1 -0
- package/dist/lib/slack-channel.js +30 -12
- package/dist/lib/slack-route.d.ts +72 -9
- package/dist/lib/slack-route.js +113 -24
- package/dist/lib/slack-router.d.ts +37 -2
- package/dist/lib/slack-router.js +98 -13
- package/dist/lib/slack-state.d.ts +105 -4
- package/dist/lib/slack-state.js +230 -11
- package/dist/lib/subscription-login.d.ts +12 -3
- package/dist/lib/subscription-login.js +19 -7
- package/dist/mcp/handoff-server.mjs +31 -3
- package/dist/rc-proxy.mjs +14 -0
- package/package.json +1 -1
|
@@ -175,6 +175,9 @@ function deleteKey(cfg, key) {
|
|
|
175
175
|
case "agent":
|
|
176
176
|
delete cfg.agent;
|
|
177
177
|
break;
|
|
178
|
+
case "agent_id":
|
|
179
|
+
delete cfg.agentId;
|
|
180
|
+
break;
|
|
178
181
|
case "effort":
|
|
179
182
|
delete cfg.effort;
|
|
180
183
|
break;
|
|
@@ -217,6 +220,12 @@ function deleteKey(cfg, key) {
|
|
|
217
220
|
case "slack_allow":
|
|
218
221
|
delete cfg.slackAllow;
|
|
219
222
|
break;
|
|
223
|
+
case "slack_aliases":
|
|
224
|
+
delete cfg.slackAliases;
|
|
225
|
+
break;
|
|
226
|
+
case "slack_sticky_threads":
|
|
227
|
+
delete cfg.slackStickyThreads;
|
|
228
|
+
break;
|
|
220
229
|
default:
|
|
221
230
|
requireSpec(key); // throws the known-keys message for anything unknown
|
|
222
231
|
}
|
|
@@ -43,8 +43,9 @@ export interface GovernanceProbe {
|
|
|
43
43
|
* The governance line: the composed (every layer, strictest wins) integrity and
|
|
44
44
|
* Safe House modes of the agent a launch would use. Signed out, no such agent,
|
|
45
45
|
* or an unreadable card → info with the off-by-default note, never a MISS
|
|
46
|
-
* (governance never blocks a launch). On → info naming the per-turn cost;
|
|
47
|
-
* agent's own card
|
|
46
|
+
* (governance never blocks a launch). On → info naming the per-turn cost; a
|
|
47
|
+
* stricter layer outranks the agent's own card (any rung up the ladder off <
|
|
48
|
+
* observe < nudge < enforce, MNE-8612) → warn naming the layer.
|
|
48
49
|
*/
|
|
49
50
|
export declare function probeGovernance(agent: string | undefined): Promise<GovernanceProbe>;
|
|
50
51
|
export {};
|
|
@@ -24,7 +24,7 @@ import { isLoggedIn } from "../lib/auth.js";
|
|
|
24
24
|
import { getActiveOrg } from "../lib/cli-config.js";
|
|
25
25
|
import { isCodeNotEnabled, REQUEST_ACCESS_URL, sanitizeTerminalText, sourceLabel, withRequestAccess, } from "./agent-invite.js";
|
|
26
26
|
import { probeUpdateStatus } from "../lib/update/doctor.js";
|
|
27
|
-
import { describeModes, GOVERNANCE_OPT_IN_HINT, resolveDefaultSlug } from "./agent-setup.js";
|
|
27
|
+
import { describeModes, GOVERNANCE_OPT_IN_HINT, layersSettingMode, outranksAgentCard, resolveDefaultSlug, } from "./agent-setup.js";
|
|
28
28
|
const MARK = { ok: "[ ok ]", warn: "[warn]", miss: "[MISS]", info: "[info]" };
|
|
29
29
|
const out = (line = "") => console.log(line);
|
|
30
30
|
/** Run the preflight and print the checklist. Sets process.exitCode on failure. */
|
|
@@ -232,8 +232,9 @@ const OPT_IN_HINT = GOVERNANCE_OPT_IN_HINT.trim();
|
|
|
232
232
|
* The governance line: the composed (every layer, strictest wins) integrity and
|
|
233
233
|
* Safe House modes of the agent a launch would use. Signed out, no such agent,
|
|
234
234
|
* or an unreadable card → info with the off-by-default note, never a MISS
|
|
235
|
-
* (governance never blocks a launch). On → info naming the per-turn cost;
|
|
236
|
-
* agent's own card
|
|
235
|
+
* (governance never blocks a launch). On → info naming the per-turn cost; a
|
|
236
|
+
* stricter layer outranks the agent's own card (any rung up the ladder off <
|
|
237
|
+
* observe < nudge < enforce, MNE-8612) → warn naming the layer.
|
|
237
238
|
*/
|
|
238
239
|
export async function probeGovernance(agent) {
|
|
239
240
|
const offByDefault = {
|
|
@@ -268,13 +269,27 @@ export async function probeGovernance(agent) {
|
|
|
268
269
|
protection: read(prot, "agent", "mode"),
|
|
269
270
|
};
|
|
270
271
|
const text = `governance: ${slug} — ${describeModes(composed)}`;
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
272
|
+
// A stricter layer outranks the agent's own card on the ladder off < observe <
|
|
273
|
+
// nudge < enforce: name the feature, the mode that runs, and the layer that set it,
|
|
274
|
+
// and point only at the show command for a feature that was outranked.
|
|
275
|
+
const raised = [];
|
|
276
|
+
const shows = [];
|
|
277
|
+
const raise = (feature, mine, eff, sources, field, platformIsFloor, show) => {
|
|
278
|
+
if (!outranksAgentCard(mine, eff))
|
|
279
|
+
return;
|
|
280
|
+
const layers = layersSettingMode(sources, field, eff, { platform: platformIsFloor });
|
|
281
|
+
const from = layers.length > 0 ? ` from ${layers.join(" and ")}` : "";
|
|
282
|
+
raised.push(`${feature} ${eff}${from} (agent card: ${mine})`);
|
|
283
|
+
shows.push(show);
|
|
284
|
+
};
|
|
285
|
+
raise("integrity", own.integrity, composed.integrity, align, "integrity_mode", false, "`mnemom card show` prints the composed alignment card (integrity_mode).");
|
|
286
|
+
raise("Safe House", own.protection, composed.protection, prot, "mode", true, "`mnemom protection show` prints the composed Safe House card.");
|
|
287
|
+
if (raised.length > 0) {
|
|
274
288
|
return {
|
|
275
289
|
mark: "warn",
|
|
276
290
|
text,
|
|
277
|
-
hint:
|
|
291
|
+
hint: `a stricter org, team or platform policy outranks the agent's own card: ${raised.join(", ")}. ` +
|
|
292
|
+
`The stricter mode is the one that runs and is billed. Change it at that layer. ${shows.join(" ")}`,
|
|
278
293
|
};
|
|
279
294
|
}
|
|
280
295
|
if (composed.integrity === "off" && composed.protection === "off") {
|
|
@@ -27,9 +27,14 @@ import { localGoalFlag, resolveSessionRef } from "./agent-sessions.js";
|
|
|
27
27
|
* for. Lazy import: commands/agent.ts is the launcher and carries a heavy import graph.
|
|
28
28
|
*/
|
|
29
29
|
export async function resolveLaunchCreds() {
|
|
30
|
-
const { resolveAnthropicKey } = await import("./agent.js");
|
|
30
|
+
const { defaultMnemomKeyDeps, resolveAnthropicKey } = await import("./agent.js");
|
|
31
|
+
const { readMnemomKey } = await import("../lib/subscription-login.js");
|
|
31
32
|
try {
|
|
32
|
-
|
|
33
|
+
const anthropicKey = await resolveAnthropicKey(process.env, { allowPrompt: false });
|
|
34
|
+
// The Mnemom key the launch sent beside it (env, else the store; never minted here) — a
|
|
35
|
+
// pinned session's control calls need it, and every call is then asked as the launch was.
|
|
36
|
+
const mnemomKey = readMnemomKey(defaultMnemomKeyDeps());
|
|
37
|
+
return mnemomKey ? { anthropicKey, mnemomKey } : { anthropicKey };
|
|
33
38
|
}
|
|
34
39
|
catch {
|
|
35
40
|
throw new Error("no Anthropic key in env (MNEMOM_AGENT_ANTHROPIC_KEY / ANTHROPIC_API_KEY) or ~/.mnemom/launcher.json — " +
|
|
@@ -329,7 +329,8 @@ export function buildShowView(local, remote, reason) {
|
|
|
329
329
|
if (local.cc_session_id && local.launch_shape !== "server") {
|
|
330
330
|
L.push(fmt.label("resume: ", resumeCommand({
|
|
331
331
|
scenario: local.session,
|
|
332
|
-
|
|
332
|
+
// A pinned launch resumes pinned (its served id), never by a name that could birth.
|
|
333
|
+
agent: local.agent_pinned && local.agent_id ? local.agent_id : local.agent_slug,
|
|
333
334
|
ccSessionId: local.cc_session_id,
|
|
334
335
|
})));
|
|
335
336
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* on drift). Specifically:
|
|
14
14
|
* - alignment card: autonomy_mode = observe, integrity_mode = off,
|
|
15
15
|
* principal.relationship = delegated_authority, coding bounded/forbidden
|
|
16
|
-
* actions,
|
|
16
|
+
* actions, no default escalation triggers (the customer adds their own);
|
|
17
17
|
* - protection card: mode = off, thresholds 0.60/0.80/0.95 and all four
|
|
18
18
|
* screen_surfaces declared, ready for when it is turned on.
|
|
19
19
|
* - goal-alignment: nudge — sealed per-conversation via the goal contract
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* (agents.ts), claimAgent + putAlignmentCard/putProtectionCard (lib/api.ts) — rather than
|
|
32
32
|
* reinventing it.
|
|
33
33
|
*/
|
|
34
|
-
import { type CodeEntitlement } from "../lib/api.js";
|
|
34
|
+
import { type CardSources, type CodeEntitlement } from "../lib/api.js";
|
|
35
35
|
/** A card's governance mode as the CLI writes it: off, or observe-only. */
|
|
36
36
|
export type GovernanceMode = "off" | "observe";
|
|
37
37
|
/**
|
|
@@ -80,6 +80,53 @@ export interface CardModes {
|
|
|
80
80
|
}
|
|
81
81
|
/** One phrase for the posture line: "integrity off, Safe House off". */
|
|
82
82
|
export declare function describeModes(m: Pick<CardModes, "integrity" | "protection">): string;
|
|
83
|
+
/**
|
|
84
|
+
* The governance mode ladder, weakest first. The same order mnemom-api composes
|
|
85
|
+
* on (compose.ts ALIGNMENT_MODE_ORDER and PROTECTION_MODE_ORDER): strictest wins.
|
|
86
|
+
*/
|
|
87
|
+
export declare const MODE_LADDER: readonly ["off", "observe", "nudge", "enforce"];
|
|
88
|
+
/** A mode's rung on MODE_LADDER, or -1 when it is not on the ladder (absent, "unknown"). */
|
|
89
|
+
export declare function modeRank(mode: string | undefined): number;
|
|
90
|
+
/**
|
|
91
|
+
* True when the composed mode sits on a higher rung than the agent's own card, so a
|
|
92
|
+
* stricter layer decides the mode that runs. An agent card that sets no mode, or a
|
|
93
|
+
* composed mode that is not on the ladder, is never an outrank.
|
|
94
|
+
*/
|
|
95
|
+
export declare function outranksAgentCard(own: string | undefined, effective: string): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* The upstream layers of a sources envelope whose own card sets `field` to `mode`,
|
|
98
|
+
* named for a person (`team "Lane Leads"`, `org "Acme"`, `platform`), in cascade
|
|
99
|
+
* order. Those are the layers that put the composed mode where it is. `platform`
|
|
100
|
+
* is asked for only where the platform card is a floor (protection mode); for
|
|
101
|
+
* integrity_mode it is only a default, so it never outranks an agent card that
|
|
102
|
+
* sets one. Empty when no layer row matches (an older api without the rows, or a
|
|
103
|
+
* composed card older than a template edit).
|
|
104
|
+
*/
|
|
105
|
+
export declare function layersSettingMode(sources: CardSources | null, field: string, mode: string, opts: {
|
|
106
|
+
platform: boolean;
|
|
107
|
+
}): string[];
|
|
108
|
+
/**
|
|
109
|
+
* The composed Safe House (protection) mode for the launch summary, naming the
|
|
110
|
+
* layer that set it when the agent's own card says something else:
|
|
111
|
+
* `enforce (from team "Lane Leads"; agent card: observe)`. Same mode as the
|
|
112
|
+
* agent card prints the mode alone. No composed card reads `unknown`.
|
|
113
|
+
*/
|
|
114
|
+
export declare function describeComposedProtection(sources: CardSources | null): string;
|
|
115
|
+
/**
|
|
116
|
+
* How long the launch waits for the protection card sources before printing the
|
|
117
|
+
* line without them. An object so tests can shorten it, like TWIN_LISTING.
|
|
118
|
+
*/
|
|
119
|
+
export declare const PROTECTION_READ: {
|
|
120
|
+
timeoutMs: number;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* The launch summary's protection phrase for `agentId`: one `getCardSources`
|
|
124
|
+
* read (`GET /v1/protection/agent/:id?include=sources`, the same read the doctor
|
|
125
|
+
* makes), which carries both the composed card and every layer's own card. Best
|
|
126
|
+
* effort: it never throws, so the caller can start it early and await it later,
|
|
127
|
+
* and a failed or slow read prints `unknown` rather than holding up the launch.
|
|
128
|
+
*/
|
|
129
|
+
export declare function readComposedProtection(agentId: string): Promise<string>;
|
|
83
130
|
/**
|
|
84
131
|
* The modes for a NEW agent: autonomy observe (rules only, no model call) unless
|
|
85
132
|
* --no-governance; integrity and Safe House off unless --governance asks for them.
|
|
@@ -122,8 +169,18 @@ export interface ClaimedAgentOptions {
|
|
|
122
169
|
slug: string;
|
|
123
170
|
/** Anthropic-key launch: the key that anchors the gateway identity. Never logged. */
|
|
124
171
|
anthropicKey?: string;
|
|
125
|
-
/**
|
|
172
|
+
/**
|
|
173
|
+
* The Mnemom API key: on a subscription launch it anchors the gateway identity; on an api-key
|
|
174
|
+
* launch (beside `anthropicKey`) it rides along as the key principal, and the identity stays
|
|
175
|
+
* hash(Anthropic key, name). Required with `pin`. Never logged.
|
|
176
|
+
*/
|
|
126
177
|
mnemomKey?: string;
|
|
178
|
+
/**
|
|
179
|
+
* The agent id this launch pins (`--agent mnm-<uuid>` / launcher.toml `agent_id`). The gateway
|
|
180
|
+
* must serve exactly this agent (identity route `resolved_by: "pin"`) or the launch refuses;
|
|
181
|
+
* a pinned launch never claims and never births.
|
|
182
|
+
*/
|
|
183
|
+
pin?: string;
|
|
127
184
|
/** Gateway host the launch targets (the probe goes to the same cell). */
|
|
128
185
|
gatewayHost: string;
|
|
129
186
|
/**
|
|
@@ -156,6 +213,11 @@ export interface ClaimedAgentResult {
|
|
|
156
213
|
agentId: string;
|
|
157
214
|
/** true only when this call claimed it. */
|
|
158
215
|
claimedNow: boolean;
|
|
216
|
+
/**
|
|
217
|
+
* The gateway rejected the Mnemom key an api-key launch offered alongside its Anthropic key;
|
|
218
|
+
* the agent was confirmed without it, and the launch must not send it either.
|
|
219
|
+
*/
|
|
220
|
+
mnemomKeyRejected?: boolean;
|
|
159
221
|
}
|
|
160
222
|
/**
|
|
161
223
|
* A failure worth retrying, and that an outage fallback may cover: no answer at all (network,
|
|
@@ -183,17 +245,55 @@ export declare function isTransient(err: unknown): boolean;
|
|
|
183
245
|
* Interactive and non-interactive runs behave the same: there is no prompt to decline.
|
|
184
246
|
* MNE-7650: the name is client-controlled, so a same-named org agent proves nothing — only the
|
|
185
247
|
* served id counts.
|
|
248
|
+
*
|
|
249
|
+
* A PINNED launch (`opts.pin`, from `--agent mnm-<uuid>` / launcher.toml `agent_id`) takes a
|
|
250
|
+
* separate path (ensurePinnedAgent): the gateway must serve exactly the pin, and it never claims.
|
|
251
|
+
*
|
|
252
|
+
* An api-key launch that also carries a Mnemom key (`opts.mnemomKey` beside `opts.anthropicKey`)
|
|
253
|
+
* asks the probe with it too, so the answer is the one its requests will get. If the gateway
|
|
254
|
+
* rejects that key, the launch continues without it (result.mnemomKeyRejected) rather than fail.
|
|
186
255
|
*/
|
|
187
256
|
export declare function ensureClaimedServedAgent(opts: ClaimedAgentOptions): Promise<ClaimedAgentResult>;
|
|
257
|
+
/**
|
|
258
|
+
* How long the anti-twin listing may take before it is treated as failed (best effort). An
|
|
259
|
+
* object so tests can shorten it, like CONFIRM_RETRY_DELAYS_MS.
|
|
260
|
+
*/
|
|
261
|
+
export declare const TWIN_LISTING: {
|
|
262
|
+
timeoutMs: number;
|
|
263
|
+
};
|
|
264
|
+
/**
|
|
265
|
+
* The ids of the caller's OTHER live, claimed agents named `slug` in `orgId` — the same set the
|
|
266
|
+
* gateway's principal resolution picks from (claimed_by = the caller). Reads the caller's own
|
|
267
|
+
* agents (`GET /v1/agents?scope=all`), then each same-named one's full record for its claim and
|
|
268
|
+
* org; a tombstoned one (404) is skipped. Throws when the listing can't be completed in
|
|
269
|
+
* TWIN_LISTING.timeoutMs — every caller treats that as "unknown", never as "none".
|
|
270
|
+
*/
|
|
271
|
+
export declare function claimedSameNamedAgents(slug: string, excludeId: string, orgId: string): Promise<string[]>;
|
|
272
|
+
/** The refusal when an unclaimed served agent would become a same-named twin. */
|
|
273
|
+
export declare function twinRefusal(slug: string, servedId: string, twins: readonly string[], orgLabel: string): string;
|
|
274
|
+
/**
|
|
275
|
+
* Resolve a pin before launch: the agent must be visible to the caller (the org-member view) and
|
|
276
|
+
* claimed; its name becomes the launch's slug (`x-mnemom-agent`, which the gateway checks against
|
|
277
|
+
* the pin). Any failure refuses — a pinned launch never falls back to a name.
|
|
278
|
+
*/
|
|
279
|
+
export declare function resolvePinnedAgent(id: string): Promise<{
|
|
280
|
+
id: string;
|
|
281
|
+
slug: string;
|
|
282
|
+
}>;
|
|
188
283
|
/**
|
|
189
284
|
* One line for an api failure that keeps the parts an operator can act on: the
|
|
190
285
|
* message, the error code, and the scope the endpoint said it needed
|
|
191
286
|
* (`details.required_scope`). Never the token, never the body.
|
|
192
287
|
*/
|
|
193
288
|
export declare function describeApiError(err: unknown): string;
|
|
194
|
-
/**
|
|
289
|
+
/**
|
|
290
|
+
* `mnemom agent setup [--agent <slug|mnm-id>] [--governance …]` — the explicit provisioning entry
|
|
291
|
+
* point. An id (`--agent mnm-<uuid>`, or launcher.toml `agent_id`) refreshes that pinned agent's
|
|
292
|
+
* cards and never claims or births; a malformed `mnm-…` refuses.
|
|
293
|
+
*/
|
|
195
294
|
export declare function agentSetupCommand(opts?: {
|
|
196
295
|
agent?: string;
|
|
296
|
+
agentId?: string;
|
|
197
297
|
governance?: GovernanceOptIn;
|
|
198
298
|
}): Promise<void>;
|
|
199
299
|
/** Thrown when the agent's org has no spendable MU balance. The user-facing
|