aismemory 0.5.0 → 0.5.1
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/__tests__/auth-staleness.test.d.ts +9 -0
- package/dist/__tests__/auth-staleness.test.js +46 -0
- package/dist/__tests__/auth-staleness.test.js.map +1 -0
- package/dist/__tests__/auto-handoff.test.js +108 -2
- package/dist/__tests__/auto-handoff.test.js.map +1 -1
- package/dist/__tests__/config.test.js +6 -3
- package/dist/__tests__/config.test.js.map +1 -1
- package/dist/__tests__/env-agent.test.d.ts +1 -0
- package/dist/__tests__/env-agent.test.js +19 -0
- package/dist/__tests__/env-agent.test.js.map +1 -0
- package/dist/__tests__/existing-hashes.test.d.ts +1 -0
- package/dist/__tests__/existing-hashes.test.js +122 -0
- package/dist/__tests__/existing-hashes.test.js.map +1 -0
- package/dist/__tests__/hydration.test.js +38 -0
- package/dist/__tests__/hydration.test.js.map +1 -1
- package/dist/__tests__/local-mirror.test.js +4 -0
- package/dist/__tests__/local-mirror.test.js.map +1 -1
- package/dist/__tests__/oauth-credentials.test.d.ts +1 -0
- package/dist/__tests__/oauth-credentials.test.js +29 -0
- package/dist/__tests__/oauth-credentials.test.js.map +1 -0
- package/dist/__tests__/pipeline-ingestion.test.js +112 -1
- package/dist/__tests__/pipeline-ingestion.test.js.map +1 -1
- package/dist/__tests__/refresh.test.js +24 -0
- package/dist/__tests__/refresh.test.js.map +1 -1
- package/dist/__tests__/sync-memory-cli.test.d.ts +1 -0
- package/dist/__tests__/sync-memory-cli.test.js +200 -0
- package/dist/__tests__/sync-memory-cli.test.js.map +1 -0
- package/dist/__tests__/telemetry.test.d.ts +1 -0
- package/dist/__tests__/telemetry.test.js +67 -0
- package/dist/__tests__/telemetry.test.js.map +1 -0
- package/dist/__tests__/token-expiry-reauth.test.d.ts +1 -0
- package/dist/__tests__/token-expiry-reauth.test.js +201 -0
- package/dist/__tests__/token-expiry-reauth.test.js.map +1 -0
- package/dist/__tests__/tool-args.test.d.ts +1 -0
- package/dist/__tests__/tool-args.test.js +78 -0
- package/dist/__tests__/tool-args.test.js.map +1 -0
- package/dist/auth-staleness.d.ts +27 -0
- package/dist/auth-staleness.js +41 -0
- package/dist/auth-staleness.js.map +1 -0
- package/dist/auto-handoff.d.ts +2 -0
- package/dist/auto-handoff.js +40 -16
- package/dist/auto-handoff.js.map +1 -1
- package/dist/cli/sync-memory.js +31 -36
- package/dist/cli/sync-memory.js.map +1 -1
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/env-agent.d.ts +10 -0
- package/dist/env-agent.js +14 -0
- package/dist/env-agent.js.map +1 -0
- package/dist/hydration.js +54 -3
- package/dist/hydration.js.map +1 -1
- package/dist/index.js +229 -113
- package/dist/index.js.map +1 -1
- package/dist/local-mirror.d.ts +5 -0
- package/dist/local-mirror.js +72 -14
- package/dist/local-mirror.js.map +1 -1
- package/dist/oauth-credentials.d.ts +14 -0
- package/dist/oauth-credentials.js +35 -0
- package/dist/oauth-credentials.js.map +1 -0
- package/dist/pipeline/bulk-store.d.ts +46 -0
- package/dist/pipeline/bulk-store.js +165 -0
- package/dist/pipeline/bulk-store.js.map +1 -0
- package/dist/pipeline/existing-hashes.d.ts +20 -0
- package/dist/pipeline/existing-hashes.js +111 -0
- package/dist/pipeline/existing-hashes.js.map +1 -0
- package/dist/pipeline/ingestion.d.ts +8 -4
- package/dist/pipeline/ingestion.js +36 -8
- package/dist/pipeline/ingestion.js.map +1 -1
- package/dist/telemetry.d.ts +22 -0
- package/dist/telemetry.js +28 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/tool-args.d.ts +52 -0
- package/dist/tool-args.js +78 -0
- package/dist/tool-args.js.map +1 -0
- package/dist/trust-ledger.js +2 -2
- package/dist/trust-ledger.js.map +1 -1
- package/package.json +9 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-memory.js","sourceRoot":"","sources":["../../src/cli/sync-memory.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-memory.js","sourceRoot":"","sources":["../../src/cli/sync-memory.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -2,6 +2,9 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync } from '
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
const DEFAULT_RETENTION_DAYS = 30;
|
|
5
|
+
function stderr(msg) {
|
|
6
|
+
process.stderr.write(`[aismemory] ${msg}\n`);
|
|
7
|
+
}
|
|
5
8
|
export class SyncConfig {
|
|
6
9
|
filePath;
|
|
7
10
|
data;
|
|
@@ -21,7 +24,7 @@ export class SyncConfig {
|
|
|
21
24
|
renameSync(this.filePath, backup);
|
|
22
25
|
}
|
|
23
26
|
catch { /* ignore */ }
|
|
24
|
-
|
|
27
|
+
stderr(`corrupt config.json backed up to ${backup}, using defaults`);
|
|
25
28
|
this.data = {};
|
|
26
29
|
}
|
|
27
30
|
}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AASlC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAElC,MAAM,OAAO,UAAU;IACJ,QAAQ,CAAS;IAC1B,IAAI,CAAa;IAEzB,YAAY,OAAe,OAAO,EAAE;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAe,CAAC;YAC5E,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,YAAY,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBACxD,IAAI,CAAC;oBAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;gBACjE,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AASlC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAElC,SAAS,MAAM,CAAC,GAAW;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,OAAO,UAAU;IACJ,QAAQ,CAAS;IAC1B,IAAI,CAAa;IAEzB,YAAY,OAAe,OAAO,EAAE;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAe,CAAC;YAC5E,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,YAAY,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBACxD,IAAI,CAAC;oBAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;gBACjE,MAAM,CAAC,oCAAoC,MAAM,kBAAkB,CAAC,CAAC;gBACrE,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;YACjB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,sBAAsB,CAAC;IAC3D,CAAC;IAED,UAAU,CAAC,QAAgB;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IACnD,CAAC;IAED,eAAe,CAAC,WAAmB;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;IAC3D,CAAC;IAED,mBAAmB,CAAC,WAAmB,EAAE,KAAgB;QACvD,IAAI,CAAC,IAAI,CAAC,gBAAgB,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC;QAC7F,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAEO,OAAO;QACb,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,MAAM,CAAC;QACnC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACxE,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface TenantAgentSummary {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
status: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Ensures AIS_AGENT_ID refers to an agent in the authenticated tenant.
|
|
8
|
+
* Throws with a message suitable for stderr when the id is missing or unknown.
|
|
9
|
+
*/
|
|
10
|
+
export declare function assertEnvAgentInTenant(envAgentId: string, agents: TenantAgentSummary[]): TenantAgentSummary;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensures AIS_AGENT_ID refers to an agent in the authenticated tenant.
|
|
3
|
+
* Throws with a message suitable for stderr when the id is missing or unknown.
|
|
4
|
+
*/
|
|
5
|
+
export function assertEnvAgentInTenant(envAgentId, agents) {
|
|
6
|
+
const match = agents.find((agent) => agent.id === envAgentId);
|
|
7
|
+
if (match) {
|
|
8
|
+
return match;
|
|
9
|
+
}
|
|
10
|
+
const available = agents.map((agent) => `${agent.name} (${agent.id})`).join(', ');
|
|
11
|
+
throw new Error(`AIS_AGENT_ID="${envAgentId}" is not a valid agent in this tenant. ` +
|
|
12
|
+
`Available: ${available || '(none)'}`);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=env-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-agent.js","sourceRoot":"","sources":["../src/env-agent.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAAkB,EAClB,MAA4B;IAE5B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;IAC9D,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClF,MAAM,IAAI,KAAK,CACb,iBAAiB,UAAU,yCAAyC;QAClE,cAAc,SAAS,IAAI,QAAQ,EAAE,CACxC,CAAC;AACJ,CAAC"}
|
package/dist/hydration.js
CHANGED
|
@@ -1,13 +1,59 @@
|
|
|
1
|
+
const LOG_PREFIX = '[aismemory]';
|
|
2
|
+
function redactHydrationMessage(message) {
|
|
3
|
+
return message
|
|
4
|
+
.replace(/Bearer\s+\S+/gi, 'Bearer [REDACTED]')
|
|
5
|
+
.replace(/authorization:\s*\S+/gi, 'authorization: [REDACTED]')
|
|
6
|
+
.slice(0, 300);
|
|
7
|
+
}
|
|
8
|
+
function isRetryableHttpStatus(status) {
|
|
9
|
+
return status >= 500 || status === 429;
|
|
10
|
+
}
|
|
11
|
+
function isRetryableHydrationError(err) {
|
|
12
|
+
if (!(err instanceof Error))
|
|
13
|
+
return true;
|
|
14
|
+
const msg = err.message.toLowerCase();
|
|
15
|
+
return (msg.includes('network') ||
|
|
16
|
+
msg.includes('fetch') ||
|
|
17
|
+
msg.includes('timeout') ||
|
|
18
|
+
msg.includes('econnrefused') ||
|
|
19
|
+
msg.includes('enotfound'));
|
|
20
|
+
}
|
|
21
|
+
function logHydrationFailure(kind, details) {
|
|
22
|
+
const retryLabel = details.retryable ? 'retryable' : 'permanent';
|
|
23
|
+
const statusPart = details.status !== undefined ? ` status=${details.status}` : '';
|
|
24
|
+
const line = `${LOG_PREFIX} hydrateIdentity failed (${kind}, ${retryLabel})${statusPart}: ${redactHydrationMessage(details.message)}\n`;
|
|
25
|
+
process.stderr.write(line);
|
|
26
|
+
}
|
|
1
27
|
export async function hydrateIdentity(aisUrl, agentId, token) {
|
|
2
28
|
try {
|
|
3
29
|
const res = await fetch(`${aisUrl}/v1/agents/${agentId}/full-context`, {
|
|
4
30
|
headers: { Authorization: `Bearer ${token}` },
|
|
5
31
|
});
|
|
6
|
-
if (!res.ok)
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
let bodyHint = res.statusText;
|
|
34
|
+
try {
|
|
35
|
+
const text = await res.text();
|
|
36
|
+
if (text.length > 0)
|
|
37
|
+
bodyHint = text;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* ignore body read errors */
|
|
41
|
+
}
|
|
42
|
+
logHydrationFailure('http', {
|
|
43
|
+
status: res.status,
|
|
44
|
+
message: bodyHint,
|
|
45
|
+
retryable: isRetryableHttpStatus(res.status),
|
|
46
|
+
});
|
|
7
47
|
return null;
|
|
48
|
+
}
|
|
8
49
|
const json = (await res.json());
|
|
9
|
-
if (!json.success || !json.data)
|
|
50
|
+
if (!json.success || !json.data) {
|
|
51
|
+
logHydrationFailure('api', {
|
|
52
|
+
message: json.success === false ? 'AIS full-context success=false' : 'AIS full-context missing data',
|
|
53
|
+
retryable: false,
|
|
54
|
+
});
|
|
10
55
|
return null;
|
|
56
|
+
}
|
|
11
57
|
const d = json.data;
|
|
12
58
|
const identity = {
|
|
13
59
|
id: d.identity?.id ?? '',
|
|
@@ -55,7 +101,12 @@ export async function hydrateIdentity(aisUrl, agentId, token) {
|
|
|
55
101
|
totalTokens: d.context?.totalTokens ?? 0,
|
|
56
102
|
};
|
|
57
103
|
}
|
|
58
|
-
catch {
|
|
104
|
+
catch (err) {
|
|
105
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
106
|
+
logHydrationFailure('network', {
|
|
107
|
+
message,
|
|
108
|
+
retryable: isRetryableHydrationError(err),
|
|
109
|
+
});
|
|
59
110
|
return null;
|
|
60
111
|
}
|
|
61
112
|
}
|
package/dist/hydration.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hydration.js","sourceRoot":"","sources":["../src/hydration.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,OAAe,EACf,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,cAAc,OAAO,eAAe,EAAE;YACrE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;SAC9C,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"hydration.js","sourceRoot":"","sources":["../src/hydration.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -10,37 +10,32 @@
|
|
|
10
10
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
11
11
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
12
12
|
import { tryKeyAuth } from './key-auth.js';
|
|
13
|
+
import { isCredsStale, isAuthErrorResult } from './auth-staleness.js';
|
|
13
14
|
import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
14
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
15
|
-
import { join } from 'path';
|
|
16
15
|
import { homedir } from 'os';
|
|
16
|
+
import { loadOAuthCredentials, saveOAuthCredentials, } from './oauth-credentials.js';
|
|
17
17
|
import { hydrateIdentity } from './hydration.js';
|
|
18
18
|
import { assemblePrompt } from './prompt-resource.js';
|
|
19
19
|
import { startRefreshTimer, stopRefreshTimer } from './refresh.js';
|
|
20
20
|
import { ActivityTracker, setupAutoHandoff } from './auto-handoff.js';
|
|
21
|
+
import { assertEnvAgentInTenant } from './env-agent.js';
|
|
22
|
+
import { emitTelemetry, hashAgentId } from './telemetry.js';
|
|
23
|
+
import { parseAgentLoadArgs, parseEmptyToolArgs, parseHandoffArgs, parseRecallArgs, parseRememberArgs, } from './tool-args.js';
|
|
21
24
|
// ── Config ──────────────────────────────────────────────
|
|
22
25
|
const AIS_URL = process.env['AIS_URL'] ?? 'https://ais.agentsandswarms.ai';
|
|
23
|
-
const CREDS_DIR = join(homedir(), '.aismemory');
|
|
24
|
-
const CREDS_FILE = join(CREDS_DIR, 'credentials.json');
|
|
25
26
|
// ── Credential persistence ──────────────────────────────
|
|
26
27
|
function loadCredentials() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
stderr('Saved credentials expired. Re-authenticating...');
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
return data;
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
28
|
+
const data = loadOAuthCredentials();
|
|
29
|
+
if (!data)
|
|
30
|
+
return null;
|
|
31
|
+
if (isCredsStale(data.expiresAt, Date.now())) {
|
|
32
|
+
stderr('Saved credentials expired or expiring soon. Re-authenticating...');
|
|
38
33
|
return null;
|
|
39
34
|
}
|
|
35
|
+
return data;
|
|
40
36
|
}
|
|
41
37
|
function saveCredentials(creds) {
|
|
42
|
-
|
|
43
|
-
writeFileSync(CREDS_FILE, JSON.stringify(creds, null, 2));
|
|
38
|
+
saveOAuthCredentials(creds);
|
|
44
39
|
}
|
|
45
40
|
// ── HTTP helpers ────────────────────────────────────────
|
|
46
41
|
function stderr(msg) {
|
|
@@ -50,17 +45,55 @@ async function aisPost(path, body, token) {
|
|
|
50
45
|
const headers = { 'Content-Type': 'application/json' };
|
|
51
46
|
if (token)
|
|
52
47
|
headers['Authorization'] = `Bearer ${token}`;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
let res;
|
|
49
|
+
try {
|
|
50
|
+
res = await fetch(`${AIS_URL}${path}`, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
headers,
|
|
53
|
+
body: JSON.stringify(body),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
emitTelemetry({
|
|
58
|
+
event: 'ais.http.failure',
|
|
59
|
+
path,
|
|
60
|
+
error: err instanceof Error ? err.message : String(err),
|
|
61
|
+
});
|
|
62
|
+
throw err;
|
|
63
|
+
}
|
|
64
|
+
if (!res.ok) {
|
|
65
|
+
emitTelemetry({
|
|
66
|
+
event: 'ais.http.failure',
|
|
67
|
+
path,
|
|
68
|
+
httpStatus: res.status,
|
|
69
|
+
error: `HTTP ${res.status}`,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
58
72
|
return res.json();
|
|
59
73
|
}
|
|
60
74
|
async function aisGet(path, token) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
75
|
+
let res;
|
|
76
|
+
try {
|
|
77
|
+
res = await fetch(`${AIS_URL}${path}`, {
|
|
78
|
+
headers: { 'Authorization': `Bearer ${token}` },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
emitTelemetry({
|
|
83
|
+
event: 'ais.http.failure',
|
|
84
|
+
path,
|
|
85
|
+
error: err instanceof Error ? err.message : String(err),
|
|
86
|
+
});
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
if (!res.ok) {
|
|
90
|
+
emitTelemetry({
|
|
91
|
+
event: 'ais.http.failure',
|
|
92
|
+
path,
|
|
93
|
+
httpStatus: res.status,
|
|
94
|
+
error: `HTTP ${res.status}`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
64
97
|
return res.json();
|
|
65
98
|
}
|
|
66
99
|
async function resolveAgentForLoad(token, query) {
|
|
@@ -96,11 +129,21 @@ async function resolveAgentForLoad(token, query) {
|
|
|
96
129
|
* User can override with AIS_AGENT_ID or AIS_AGENT_NAME env vars.
|
|
97
130
|
*/
|
|
98
131
|
async function resolveAgent(token, fallbackAgentId, fallbackTenantId) {
|
|
99
|
-
// Explicit env var overrides everything
|
|
132
|
+
// Explicit env var overrides everything — must belong to this tenant.
|
|
100
133
|
const envAgentId = process.env['AIS_AGENT_ID'];
|
|
101
134
|
if (envAgentId) {
|
|
102
|
-
|
|
103
|
-
|
|
135
|
+
const listRes = (await aisGet('/v1/agents', token));
|
|
136
|
+
const agents = listRes.data?.agents ?? [];
|
|
137
|
+
try {
|
|
138
|
+
const match = assertEnvAgentInTenant(envAgentId, agents);
|
|
139
|
+
stderr(`Using agent from AIS_AGENT_ID: ${match.name} (${match.id})`);
|
|
140
|
+
return { agentId: match.id, tenantId: fallbackTenantId };
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
144
|
+
stderr(message);
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
104
147
|
}
|
|
105
148
|
try {
|
|
106
149
|
const res = await aisGet('/v1/agents', token);
|
|
@@ -155,6 +198,7 @@ class BondPendingError extends Error {
|
|
|
155
198
|
}
|
|
156
199
|
}
|
|
157
200
|
async function startDeviceFlow() {
|
|
201
|
+
emitTelemetry({ event: 'auth.device_flow.start' });
|
|
158
202
|
stderr('Starting authentication...');
|
|
159
203
|
const authRes = (await aisPost('/v1/oauth/device/authorize', {
|
|
160
204
|
name: `agent-${homedir().split('/').pop() ?? 'user'}`,
|
|
@@ -313,12 +357,15 @@ function decodeJwtClaims(token) {
|
|
|
313
357
|
}
|
|
314
358
|
}
|
|
315
359
|
async function main() {
|
|
316
|
-
// Subcommand dispatch —
|
|
317
|
-
// CLI and exits, never touching the MCP server. Other subcommands TBD.
|
|
360
|
+
// Subcommand dispatch — CLI entrypoints exit before MCP server startup.
|
|
318
361
|
if (process.argv[2] === 'enable-key-auth') {
|
|
319
362
|
await import('./cli/enable-key-auth.js');
|
|
320
363
|
return; // CLI calls process.exit() itself
|
|
321
364
|
}
|
|
365
|
+
if (process.argv[2] === 'sync') {
|
|
366
|
+
await import('./cli/sync-memory.js');
|
|
367
|
+
return; // sync-memory.ts calls process.exit() on failure
|
|
368
|
+
}
|
|
322
369
|
// Lazy-auth state. We connect the MCP transport before the user has approved
|
|
323
370
|
// the device flow so Claude Code's 30s connection timeout is not blocked on
|
|
324
371
|
// human approval. The first tool call surfaces the bond URL via its result.
|
|
@@ -338,8 +385,14 @@ async function main() {
|
|
|
338
385
|
* the next tool call without having to restart the MCP process.
|
|
339
386
|
*/
|
|
340
387
|
async function ensureCredentials(softTimeoutMs = 7000) {
|
|
341
|
-
if (creds)
|
|
342
|
-
|
|
388
|
+
if (creds) {
|
|
389
|
+
if (!isCredsStale(creds.expiresAt, Date.now()))
|
|
390
|
+
return creds;
|
|
391
|
+
// CORBOT-A5BBD580: tokens live 7 days but the process can outlive
|
|
392
|
+
// them. Drop stale creds and fall through to silent key auth.
|
|
393
|
+
stderr('Cached credentials are expired or expiring soon — re-authenticating...');
|
|
394
|
+
creds = null;
|
|
395
|
+
}
|
|
343
396
|
// ── Key auth (Phase 1 DID auth) ───────────────────────────────────────
|
|
344
397
|
// If the user has enrolled a private key for this device, sign a
|
|
345
398
|
// server-issued challenge and skip the device-flow ceremony entirely.
|
|
@@ -360,6 +413,10 @@ async function main() {
|
|
|
360
413
|
expiresAt: keyResult.expiresAt,
|
|
361
414
|
};
|
|
362
415
|
saveCredentials(creds);
|
|
416
|
+
emitTelemetry({
|
|
417
|
+
event: 'auth.key.success',
|
|
418
|
+
agentIdHash: hashAgentId(creds.agentId),
|
|
419
|
+
});
|
|
363
420
|
stderr('Authenticated via DID key auth (no browser required)');
|
|
364
421
|
if (!postAuthDone) {
|
|
365
422
|
postAuthDone = true;
|
|
@@ -369,6 +426,10 @@ async function main() {
|
|
|
369
426
|
}
|
|
370
427
|
}
|
|
371
428
|
catch (err) {
|
|
429
|
+
emitTelemetry({
|
|
430
|
+
event: 'auth.key.fallback',
|
|
431
|
+
error: err instanceof Error ? err.message : String(err),
|
|
432
|
+
});
|
|
372
433
|
stderr(`Key auth failed: ${err instanceof Error ? err.message : String(err)}. Falling back to device flow.`);
|
|
373
434
|
}
|
|
374
435
|
if (!activeFlow || activeFlow.dead) {
|
|
@@ -399,6 +460,16 @@ async function main() {
|
|
|
399
460
|
}
|
|
400
461
|
return creds;
|
|
401
462
|
}
|
|
463
|
+
/** Poll AIS for recent memories and refresh the identity prompt. */
|
|
464
|
+
function applyMemoryRefresh(agentId, token) {
|
|
465
|
+
startRefreshTimer(AIS_URL, agentId, token, (memories) => {
|
|
466
|
+
if (agentContext) {
|
|
467
|
+
agentContext.recentMemories = memories;
|
|
468
|
+
}
|
|
469
|
+
server.notification({ method: 'notifications/prompts/list_changed' });
|
|
470
|
+
stderr(`Memory refresh: ${memories.length} memories`);
|
|
471
|
+
});
|
|
472
|
+
}
|
|
402
473
|
/** Identity hydration, prompt refresh, and auto-handoff — all post-auth. */
|
|
403
474
|
async function runPostAuth(c) {
|
|
404
475
|
try {
|
|
@@ -410,13 +481,7 @@ async function main() {
|
|
|
410
481
|
else {
|
|
411
482
|
stderr('Agent identity not loaded — tools work, but no identity prompt');
|
|
412
483
|
}
|
|
413
|
-
|
|
414
|
-
if (agentContext) {
|
|
415
|
-
agentContext.recentMemories = memories;
|
|
416
|
-
}
|
|
417
|
-
server.notification({ method: 'notifications/prompts/list_changed' });
|
|
418
|
-
stderr(`Memory refresh: ${memories.length} memories`);
|
|
419
|
-
});
|
|
484
|
+
applyMemoryRefresh(c.agentId, c.token);
|
|
420
485
|
setupAutoHandoff(AIS_URL, c.agentId, c.token, activityTracker, () => {
|
|
421
486
|
stopRefreshTimer();
|
|
422
487
|
stderr('Session handoff saved');
|
|
@@ -432,94 +497,145 @@ async function main() {
|
|
|
432
497
|
? [{ name: 'agent-identity', description: 'Active AIS agent identity, personality, and context' }]
|
|
433
498
|
: [],
|
|
434
499
|
}));
|
|
435
|
-
server.setRequestHandler(GetPromptRequestSchema, async () =>
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
500
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
501
|
+
const { name } = request.params;
|
|
502
|
+
if (name !== 'agent-identity') {
|
|
503
|
+
throw new Error(`Unknown prompt: ${name}`);
|
|
504
|
+
}
|
|
505
|
+
return {
|
|
506
|
+
messages: [{
|
|
507
|
+
role: 'user',
|
|
508
|
+
content: { type: 'text', text: assemblePrompt(agentContext) },
|
|
509
|
+
}],
|
|
510
|
+
};
|
|
511
|
+
});
|
|
441
512
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
442
513
|
const { name, arguments: args } = request.params;
|
|
443
|
-
const
|
|
514
|
+
const rawArgs = args ?? {};
|
|
444
515
|
activityTracker.recordToolUse(name);
|
|
516
|
+
const toolStartedAt = Date.now();
|
|
445
517
|
try {
|
|
446
|
-
const
|
|
447
|
-
const
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
params
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
518
|
+
const UNKNOWN_TOOL = Symbol('unknown-tool');
|
|
519
|
+
const dispatchTool = async (c) => {
|
|
520
|
+
const token = c.token;
|
|
521
|
+
// agentId is mutable across `agent_load` calls within this session.
|
|
522
|
+
let agentId = c.agentId;
|
|
523
|
+
let result;
|
|
524
|
+
switch (name) {
|
|
525
|
+
case 'remember': {
|
|
526
|
+
const rememberArgs = parseRememberArgs(rawArgs);
|
|
527
|
+
result = await aisPost(`/v1/agents/${agentId}/memory`, {
|
|
528
|
+
content: rememberArgs.content,
|
|
529
|
+
type: rememberArgs.type,
|
|
530
|
+
importance: rememberArgs.importance,
|
|
531
|
+
}, token);
|
|
532
|
+
activityTracker.recordMemoryStored(rememberArgs.content);
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
case 'recall': {
|
|
536
|
+
const recallArgs = parseRecallArgs(rawArgs);
|
|
537
|
+
const params = new URLSearchParams();
|
|
538
|
+
params.set('query', recallArgs.query);
|
|
539
|
+
if (recallArgs.limit !== undefined)
|
|
540
|
+
params.set('limit', String(recallArgs.limit));
|
|
541
|
+
if (recallArgs.type !== undefined)
|
|
542
|
+
params.set('types', recallArgs.type);
|
|
543
|
+
result = await aisGet(`/v1/agents/${agentId}/memory?${params}`, token);
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
case 'whoami':
|
|
547
|
+
parseEmptyToolArgs(rawArgs);
|
|
548
|
+
result = await aisGet(`/v1/agents/${agentId}`, token);
|
|
549
|
+
break;
|
|
550
|
+
case 'full_context':
|
|
551
|
+
parseEmptyToolArgs(rawArgs);
|
|
552
|
+
result = await aisGet(`/v1/agents/${agentId}/full-context`, token);
|
|
553
|
+
break;
|
|
554
|
+
case 'dream':
|
|
555
|
+
parseEmptyToolArgs(rawArgs);
|
|
556
|
+
result = await aisPost(`/v1/agents/${agentId}/dream`, {}, token);
|
|
557
|
+
break;
|
|
558
|
+
case 'handoff': {
|
|
559
|
+
const handoffArgs = parseHandoffArgs(rawArgs);
|
|
560
|
+
result = await aisPost(`/v1/agents/${agentId}/handoff`, {
|
|
561
|
+
summary: handoffArgs.summary ?? 'Session ended',
|
|
562
|
+
keyLearnings: handoffArgs.keyLearnings ?? [],
|
|
563
|
+
}, token);
|
|
564
|
+
break;
|
|
490
565
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
566
|
+
case 'agent_load': {
|
|
567
|
+
const { query } = parseAgentLoadArgs(rawArgs);
|
|
568
|
+
const target = await resolveAgentForLoad(token, query);
|
|
569
|
+
agentId = target.id;
|
|
570
|
+
// Persist the switch so subsequent tool calls use the new agent.
|
|
571
|
+
if (creds) {
|
|
572
|
+
creds = { ...creds, agentId };
|
|
573
|
+
}
|
|
574
|
+
agentContext = await hydrateIdentity(AIS_URL, agentId, token);
|
|
575
|
+
applyMemoryRefresh(agentId, token);
|
|
576
|
+
server.notification({ method: 'notifications/prompts/list_changed' });
|
|
577
|
+
stderr(`agent_load: switched to "${target.name}" (${target.id})`);
|
|
578
|
+
result = {
|
|
579
|
+
success: true,
|
|
580
|
+
agentId: target.id,
|
|
581
|
+
name: target.name,
|
|
582
|
+
did: agentContext?.identity.did ?? null,
|
|
583
|
+
status: target.status,
|
|
584
|
+
memoriesLoaded: agentContext?.recentMemories.length ?? 0,
|
|
585
|
+
goalsLoaded: agentContext?.goals.length ?? 0,
|
|
586
|
+
};
|
|
587
|
+
break;
|
|
496
588
|
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
goalsLoaded: agentContext?.goals.length ?? 0,
|
|
508
|
-
};
|
|
509
|
-
break;
|
|
589
|
+
default:
|
|
590
|
+
emitTelemetry({
|
|
591
|
+
event: 'tool.call',
|
|
592
|
+
tool: name,
|
|
593
|
+
agentIdHash: hashAgentId(agentId),
|
|
594
|
+
latencyMs: Date.now() - toolStartedAt,
|
|
595
|
+
status: 'error',
|
|
596
|
+
error: `Unknown tool: ${name}`,
|
|
597
|
+
});
|
|
598
|
+
return UNKNOWN_TOOL;
|
|
510
599
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
600
|
+
return result;
|
|
601
|
+
};
|
|
602
|
+
let result = await dispatchTool(await ensureCredentials());
|
|
603
|
+
if (isAuthErrorResult(result)) {
|
|
604
|
+
// CORBOT-A5BBD580: the server rejected our token mid-session
|
|
605
|
+
// (expired or secret rotated). Clear the cached creds, silently
|
|
606
|
+
// re-auth (key auth when a key file exists), and retry once.
|
|
607
|
+
stderr('AIS rejected the cached token; re-authenticating and retrying once...');
|
|
608
|
+
creds = null;
|
|
609
|
+
result = await dispatchTool(await ensureCredentials());
|
|
610
|
+
}
|
|
611
|
+
if (result === UNKNOWN_TOOL) {
|
|
612
|
+
return {
|
|
613
|
+
content: [{ type: 'text', text: JSON.stringify({ error: `Unknown tool: ${name}` }) }],
|
|
614
|
+
isError: true,
|
|
615
|
+
};
|
|
516
616
|
}
|
|
617
|
+
emitTelemetry({
|
|
618
|
+
event: 'tool.call',
|
|
619
|
+
tool: name,
|
|
620
|
+
agentIdHash: creds ? hashAgentId(creds.agentId) : undefined,
|
|
621
|
+
latencyMs: Date.now() - toolStartedAt,
|
|
622
|
+
status: 'ok',
|
|
623
|
+
});
|
|
517
624
|
return {
|
|
518
625
|
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
519
626
|
};
|
|
520
627
|
}
|
|
521
628
|
catch (error) {
|
|
522
629
|
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
630
|
+
const agentHash = creds ? hashAgentId(creds.agentId) : undefined;
|
|
631
|
+
emitTelemetry({
|
|
632
|
+
event: 'tool.call',
|
|
633
|
+
tool: name,
|
|
634
|
+
agentIdHash: agentHash,
|
|
635
|
+
latencyMs: Date.now() - toolStartedAt,
|
|
636
|
+
status: 'error',
|
|
637
|
+
error: message,
|
|
638
|
+
});
|
|
523
639
|
// BondPendingError carries human-readable text that the agent should
|
|
524
640
|
// render verbatim — return as plain text rather than JSON.
|
|
525
641
|
if (error instanceof BondPendingError) {
|