@mnemom/mnemom 0.17.32-next.1 → 0.17.32-next.2
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.d.ts +9 -0
- package/dist/commands/agent.js +20 -2
- package/dist/lib/record-org.d.ts +27 -0
- package/dist/lib/record-org.js +44 -0
- package/package.json +1 -1
package/dist/commands/agent.d.ts
CHANGED
|
@@ -367,6 +367,15 @@ export declare function prepareStatuslineFeed(o: {
|
|
|
367
367
|
}): {
|
|
368
368
|
feedFile: string;
|
|
369
369
|
} | null;
|
|
370
|
+
/**
|
|
371
|
+
* Whether the launch reads or writes Record, and so needs the served agent's org: the conduct
|
|
372
|
+
* receipt, commit reporting and the fed status line each key on it (lib/record-org).
|
|
373
|
+
*/
|
|
374
|
+
export declare function recordOrgWanted(o: {
|
|
375
|
+
receipt: boolean;
|
|
376
|
+
commitReport: boolean;
|
|
377
|
+
fedStatusline: boolean;
|
|
378
|
+
}): boolean;
|
|
370
379
|
/**
|
|
371
380
|
* Whether this launch feeds the status line measured model cost and μ (W1.4): prerelease
|
|
372
381
|
* builds only (stable stays "mnemom", decision 14), and only when the turn proxy runs, since
|
package/dist/commands/agent.js
CHANGED
|
@@ -38,6 +38,7 @@ import { attributionSettings, COMMIT_REPORT_ENV, commitReportEnabled, realGit, s
|
|
|
38
38
|
import { ALLOW_AUTOCOMPACT_OFF_ENV, dropAutocompactOffEnv, hasOwnSettingsFlag, mergedSettingsArgs, planAutocompactGuard, } from "../lib/autocompact-guard.js";
|
|
39
39
|
import { getApiUrl, getGatewayUrl, MNEMOM_DIR } from "../lib/config.js";
|
|
40
40
|
import { createApiKey } from "../lib/api.js";
|
|
41
|
+
import { recordOrgFor } from "../lib/record-org.js";
|
|
41
42
|
import { MNEMOM_KEY_STORE_FIELD, resolveAgentAuth, sayRetiredConsoleNotice, readMnemomKey, resolveSubscriptionMnemomKey, subscriptionChildEnv, subscriptionShape, } from "../lib/subscription-login.js";
|
|
42
43
|
import { LEDGER_FILE, appendSessionRecord, findResumeCandidate, readSessionRecords, resolveRetentionDays, resumedContextProfile, toLedgerContract, } from "../lib/agent-ledger.js";
|
|
43
44
|
import { isLoggedIn } from "../lib/auth.js";
|
|
@@ -706,6 +707,16 @@ export async function agentCommand(scenarioArg, options = {}) {
|
|
|
706
707
|
}
|
|
707
708
|
}
|
|
708
709
|
if (shape === "terminal") {
|
|
710
|
+
// Record keys the lineage under the served agent's org, not the account org (lib/record-org).
|
|
711
|
+
const recordOrgId = recordOrgWanted({
|
|
712
|
+
receipt: experimental.includes("record"),
|
|
713
|
+
commitReport: cli.name === "claude" && commitReportEnabled(process.env[COMMIT_REPORT_ENV], CLI_VERSION),
|
|
714
|
+
fedStatusline: cli.name === "claude" && fedStatuslineWanted(CLI_VERSION, Boolean(goalMode), process.env),
|
|
715
|
+
}) && account.orgId
|
|
716
|
+
? await recordOrgFor(servedAgentId, account.orgId, {
|
|
717
|
+
onFallback: (reason) => say(fmt.warn(`mnemom agent: record: could not read ${servedAgentId}'s org (${reason}); using ${account.orgId}, which may hold none of this session's record.`)),
|
|
718
|
+
})
|
|
719
|
+
: account.orgId;
|
|
709
720
|
launchTerminal({
|
|
710
721
|
cli,
|
|
711
722
|
door,
|
|
@@ -735,9 +746,9 @@ export async function agentCommand(scenarioArg, options = {}) {
|
|
|
735
746
|
knownCcSessionId: cc.id ?? continuedCcSessionId,
|
|
736
747
|
plugin,
|
|
737
748
|
receipt: experimental.includes("record")
|
|
738
|
-
? { orgId:
|
|
749
|
+
? { orgId: recordOrgId, agentId: servedAgentId }
|
|
739
750
|
: undefined,
|
|
740
|
-
orgId:
|
|
751
|
+
orgId: recordOrgId,
|
|
741
752
|
commitReport: cli.name === "claude" &&
|
|
742
753
|
Boolean(account.orgId) &&
|
|
743
754
|
commitReportEnabled(process.env[COMMIT_REPORT_ENV], CLI_VERSION),
|
|
@@ -1428,6 +1439,13 @@ export function prepareStatuslineFeed(o) {
|
|
|
1428
1439
|
o.childEnv[FEED_ENV] = feed.feedFile;
|
|
1429
1440
|
return feed;
|
|
1430
1441
|
}
|
|
1442
|
+
/**
|
|
1443
|
+
* Whether the launch reads or writes Record, and so needs the served agent's org: the conduct
|
|
1444
|
+
* receipt, commit reporting and the fed status line each key on it (lib/record-org).
|
|
1445
|
+
*/
|
|
1446
|
+
export function recordOrgWanted(o) {
|
|
1447
|
+
return o.receipt || o.commitReport || o.fedStatusline;
|
|
1448
|
+
}
|
|
1431
1449
|
/**
|
|
1432
1450
|
* Whether this launch feeds the status line measured model cost and μ (W1.4): prerelease
|
|
1433
1451
|
* builds only (stable stays "mnemom", decision 14), and only when the turn proxy runs, since
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The org Record keys a launch's lineage under (Doors W1.2, W1.4, W1.8).
|
|
3
|
+
*
|
|
4
|
+
* The gateway writes a request's record deltas under the org it bills, which is the served
|
|
5
|
+
* agent's org. The launcher's account org can differ: with an org API key, the account
|
|
6
|
+
* preflight resolves the key owner's personal org (`/v1/auth/me/personal-org`, a `pers-*`
|
|
7
|
+
* id), so a totals read or commit report keyed on it lands on an org that holds no row for
|
|
8
|
+
* the lineage, and Record answers 404. Every Record read and write of a launch (conduct
|
|
9
|
+
* receipt, status-line feed, commit reporting) therefore uses the served agent's org.
|
|
10
|
+
*
|
|
11
|
+
* FAIL-OPEN, BOUNDED. One agent read, raced against RECORD_ORG_TIMEOUT_MS; a failed, slow or
|
|
12
|
+
* off-shape answer falls back to the account org (the behaviour before this read existed), and
|
|
13
|
+
* `onFallback` says why: Record answers a wrong-org read or commit report with 404, which its
|
|
14
|
+
* callers treat as "dark", so a silent fallback would look like Record being off. Never throws.
|
|
15
|
+
*/
|
|
16
|
+
/** The most the read adds to launch. */
|
|
17
|
+
export declare const RECORD_ORG_TIMEOUT_MS = 1500;
|
|
18
|
+
export interface RecordOrgDeps {
|
|
19
|
+
/** The served agent's record; only `org_id` is read. */
|
|
20
|
+
readAgent?: (agentId: string) => Promise<{
|
|
21
|
+
org_id?: string | null;
|
|
22
|
+
}>;
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
/** Told why the account org was used instead (one line, no secret). */
|
|
25
|
+
onFallback?: (reason: string) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare function recordOrgFor(agentId: string, accountOrgId: string, deps?: RecordOrgDeps): Promise<string>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The org Record keys a launch's lineage under (Doors W1.2, W1.4, W1.8).
|
|
3
|
+
*
|
|
4
|
+
* The gateway writes a request's record deltas under the org it bills, which is the served
|
|
5
|
+
* agent's org. The launcher's account org can differ: with an org API key, the account
|
|
6
|
+
* preflight resolves the key owner's personal org (`/v1/auth/me/personal-org`, a `pers-*`
|
|
7
|
+
* id), so a totals read or commit report keyed on it lands on an org that holds no row for
|
|
8
|
+
* the lineage, and Record answers 404. Every Record read and write of a launch (conduct
|
|
9
|
+
* receipt, status-line feed, commit reporting) therefore uses the served agent's org.
|
|
10
|
+
*
|
|
11
|
+
* FAIL-OPEN, BOUNDED. One agent read, raced against RECORD_ORG_TIMEOUT_MS; a failed, slow or
|
|
12
|
+
* off-shape answer falls back to the account org (the behaviour before this read existed), and
|
|
13
|
+
* `onFallback` says why: Record answers a wrong-org read or commit report with 404, which its
|
|
14
|
+
* callers treat as "dark", so a silent fallback would look like Record being off. Never throws.
|
|
15
|
+
*/
|
|
16
|
+
import { getAgent } from "./api.js";
|
|
17
|
+
/** The most the read adds to launch. */
|
|
18
|
+
export const RECORD_ORG_TIMEOUT_MS = 1500;
|
|
19
|
+
const ORG_ID_RE = /^[A-Za-z0-9_-]{1,128}$/;
|
|
20
|
+
export async function recordOrgFor(agentId, accountOrgId, deps = {}) {
|
|
21
|
+
const readAgent = deps.readAgent ?? getAgent;
|
|
22
|
+
let timer;
|
|
23
|
+
const timeout = new Promise((resolve) => {
|
|
24
|
+
timer = setTimeout(() => resolve(null), deps.timeoutMs ?? RECORD_ORG_TIMEOUT_MS);
|
|
25
|
+
});
|
|
26
|
+
try {
|
|
27
|
+
let failed = false;
|
|
28
|
+
const agent = await Promise.race([
|
|
29
|
+
readAgent(agentId).catch(() => {
|
|
30
|
+
failed = true;
|
|
31
|
+
return null;
|
|
32
|
+
}),
|
|
33
|
+
timeout,
|
|
34
|
+
]);
|
|
35
|
+
const org = agent?.org_id;
|
|
36
|
+
if (typeof org === "string" && ORG_ID_RE.test(org))
|
|
37
|
+
return org;
|
|
38
|
+
deps.onFallback?.(failed ? "agent read failed" : agent ? "agent has no org" : "agent read timed out");
|
|
39
|
+
return accountOrgId;
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
clearTimeout(timer);
|
|
43
|
+
}
|
|
44
|
+
}
|