@scitrera/memorylayer-mcp-server 0.0.3 → 0.0.4
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/README.md +115 -10
- package/dist/bin/memorylayer-mcp.js +19 -0
- package/dist/bin/memorylayer-mcp.js.map +1 -1
- package/dist/src/client.d.ts +153 -0
- package/dist/src/client.d.ts.map +1 -0
- package/dist/src/client.js +330 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/handlers.d.ts +33 -0
- package/dist/src/handlers.d.ts.map +1 -0
- package/dist/src/handlers.js +466 -0
- package/dist/src/handlers.js.map +1 -0
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +13 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/server.d.ts +42 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +249 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/session.d.ts +68 -0
- package/dist/src/session.d.ts.map +1 -0
- package/dist/src/session.js +103 -0
- package/dist/src/session.js.map +1 -0
- package/dist/src/tools.d.ts +1977 -0
- package/dist/src/tools.d.ts.map +1 -0
- package/dist/src/tools.js +696 -0
- package/dist/src/tools.js.map +1 -0
- package/dist/src/types.d.ts +136 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +7 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/workspace.d.ts +6 -0
- package/dist/src/workspace.d.ts.map +1 -0
- package/dist/src/workspace.js +35 -0
- package/dist/src/workspace.js.map +1 -0
- package/package.json +8 -9
- package/dist/bin/memorylayer-hook.d.ts +0 -19
- package/dist/bin/memorylayer-hook.d.ts.map +0 -1
- package/dist/bin/memorylayer-hook.js +0 -223
- package/dist/bin/memorylayer-hook.js.map +0 -1
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server implementation for MemoryLayer.ai
|
|
3
|
+
*/
|
|
4
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
7
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, renameSync } from "fs";
|
|
8
|
+
import { join, dirname } from "path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
import { tmpdir } from "os";
|
|
11
|
+
// ESM-compatible version reading (require() is not available in ESM)
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const PACKAGE_VERSION = JSON.parse(readFileSync(join(__dirname, "..", "..", "package.json"), "utf-8")).version;
|
|
14
|
+
import { MCPToolHandlers } from "./handlers.js";
|
|
15
|
+
import { DEFAULT_PROFILE, getToolsForProfile, isToolEnabled, } from "./tools.js";
|
|
16
|
+
import { SessionManager } from "./session.js";
|
|
17
|
+
/**
|
|
18
|
+
* Format an error for display, handling various error types.
|
|
19
|
+
* Prevents "[object Object]" from appearing in error messages.
|
|
20
|
+
*/
|
|
21
|
+
function formatError(error) {
|
|
22
|
+
// Standard Error object - check for details (e.g., MemoryLayerError from SDK)
|
|
23
|
+
if (error instanceof Error) {
|
|
24
|
+
const errWithDetails = error;
|
|
25
|
+
if (errWithDetails.details) {
|
|
26
|
+
const details = typeof errWithDetails.details === 'string'
|
|
27
|
+
? errWithDetails.details
|
|
28
|
+
: JSON.stringify(errWithDetails.details);
|
|
29
|
+
return `${error.message}: ${details}`;
|
|
30
|
+
}
|
|
31
|
+
return error.message;
|
|
32
|
+
}
|
|
33
|
+
// String error
|
|
34
|
+
if (typeof error === 'string') {
|
|
35
|
+
return error;
|
|
36
|
+
}
|
|
37
|
+
// Object with common error properties
|
|
38
|
+
if (error && typeof error === 'object') {
|
|
39
|
+
const errorObj = error;
|
|
40
|
+
// Check for common error message properties
|
|
41
|
+
if (typeof errorObj.message === 'string') {
|
|
42
|
+
return errorObj.message;
|
|
43
|
+
}
|
|
44
|
+
if (typeof errorObj.error === 'string') {
|
|
45
|
+
return errorObj.error;
|
|
46
|
+
}
|
|
47
|
+
if (typeof errorObj.detail === 'string') {
|
|
48
|
+
return errorObj.detail;
|
|
49
|
+
}
|
|
50
|
+
// API error response with nested error object
|
|
51
|
+
if (errorObj.error && typeof errorObj.error === 'object') {
|
|
52
|
+
const nestedError = errorObj.error;
|
|
53
|
+
if (typeof nestedError.message === 'string') {
|
|
54
|
+
return nestedError.message;
|
|
55
|
+
}
|
|
56
|
+
if (typeof nestedError.detail === 'string') {
|
|
57
|
+
return nestedError.detail;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Fallback: stringify the object
|
|
61
|
+
try {
|
|
62
|
+
return JSON.stringify(error);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return 'Unknown error (could not serialize)';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Fallback for other types
|
|
69
|
+
return String(error);
|
|
70
|
+
}
|
|
71
|
+
export class MCPServer {
|
|
72
|
+
server;
|
|
73
|
+
handlers;
|
|
74
|
+
sessionManager;
|
|
75
|
+
toolProfile;
|
|
76
|
+
autoStartSession;
|
|
77
|
+
constructor(client, options = {}) {
|
|
78
|
+
// Determine tool profile (env var > option > legacy options > default)
|
|
79
|
+
const envProfile = process.env.MEMORYLAYER_TOOL_PROFILE;
|
|
80
|
+
if (envProfile && !["cc", "full", "minimal"].includes(envProfile)) {
|
|
81
|
+
console.error(`Invalid MEMORYLAYER_TOOL_PROFILE: "${envProfile}", using default "${DEFAULT_PROFILE}"`);
|
|
82
|
+
}
|
|
83
|
+
const validEnvProfile = envProfile && ["cc", "full", "minimal"].includes(envProfile) ? envProfile : undefined;
|
|
84
|
+
// Handle legacy options for backwards compatibility
|
|
85
|
+
let legacyProfile;
|
|
86
|
+
if (options.extendedTools === true) {
|
|
87
|
+
console.error("Warning: extendedTools option is deprecated, use toolProfile: 'full' instead");
|
|
88
|
+
legacyProfile = "full";
|
|
89
|
+
}
|
|
90
|
+
this.toolProfile = validEnvProfile ?? options.toolProfile ?? legacyProfile ?? DEFAULT_PROFILE;
|
|
91
|
+
// Session mode is always enabled (session tools controlled by profile)
|
|
92
|
+
const sessionModeEnabled = true;
|
|
93
|
+
// Auto-start session: enabled by default
|
|
94
|
+
// Can be disabled via env var MEMORYLAYER_AUTO_START_SESSION=false
|
|
95
|
+
const envAutoStart = process.env.MEMORYLAYER_AUTO_START_SESSION;
|
|
96
|
+
const envAutoStartDisabled = envAutoStart?.toLowerCase() === 'false' || envAutoStart === '0';
|
|
97
|
+
this.autoStartSession = options.autoStartSession ?? !envAutoStartDisabled;
|
|
98
|
+
this.sessionManager = new SessionManager({ enabled: sessionModeEnabled });
|
|
99
|
+
this.server = new Server({
|
|
100
|
+
name: "memorylayer",
|
|
101
|
+
version: PACKAGE_VERSION,
|
|
102
|
+
}, {
|
|
103
|
+
capabilities: {
|
|
104
|
+
tools: {}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
this.handlers = new MCPToolHandlers(client, this.sessionManager);
|
|
108
|
+
this.setupHandlers();
|
|
109
|
+
console.error(`MemoryLayer MCP server initialized with profile: "${this.toolProfile}"`);
|
|
110
|
+
}
|
|
111
|
+
setupHandlers() {
|
|
112
|
+
// List tools based on the configured profile
|
|
113
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
114
|
+
const profileTools = getToolsForProfile(this.toolProfile);
|
|
115
|
+
const tools = profileTools.map(toolDef => ({
|
|
116
|
+
name: toolDef.name,
|
|
117
|
+
description: toolDef.description,
|
|
118
|
+
inputSchema: toolDef.inputSchema
|
|
119
|
+
}));
|
|
120
|
+
return { tools };
|
|
121
|
+
});
|
|
122
|
+
// Handle tool invocations
|
|
123
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
124
|
+
const { name, arguments: args } = request.params;
|
|
125
|
+
try {
|
|
126
|
+
// Check if tool is enabled for current profile
|
|
127
|
+
if (!isToolEnabled(name, this.toolProfile)) {
|
|
128
|
+
const errorMsg = `Tool "${name}" is not available in profile "${this.toolProfile}". Use MEMORYLAYER_TOOL_PROFILE=full to enable all tools.`;
|
|
129
|
+
console.error(errorMsg);
|
|
130
|
+
return {
|
|
131
|
+
content: [
|
|
132
|
+
{
|
|
133
|
+
type: "text",
|
|
134
|
+
text: JSON.stringify({ error: errorMsg, profile: this.toolProfile })
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
isError: true
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// Route to appropriate handler
|
|
141
|
+
const handlerMethodName = name.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
142
|
+
const handlerMethod = `handle${handlerMethodName.charAt(0).toUpperCase()}${handlerMethodName.slice(1)}`;
|
|
143
|
+
if (!(handlerMethod in this.handlers)) {
|
|
144
|
+
const errorMsg = `Unknown tool: ${name}`;
|
|
145
|
+
console.error(errorMsg);
|
|
146
|
+
return {
|
|
147
|
+
content: [
|
|
148
|
+
{
|
|
149
|
+
type: "text",
|
|
150
|
+
text: JSON.stringify({ error: errorMsg })
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
// Call the handler
|
|
156
|
+
const handler = this.handlers[handlerMethod];
|
|
157
|
+
const result = await handler.call(this.handlers, args || {});
|
|
158
|
+
return {
|
|
159
|
+
content: [
|
|
160
|
+
{
|
|
161
|
+
type: "text",
|
|
162
|
+
text: result
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
const errorMsg = formatError(error);
|
|
169
|
+
console.error(`Tool execution failed for ${name}:`, errorMsg);
|
|
170
|
+
return {
|
|
171
|
+
content: [
|
|
172
|
+
{
|
|
173
|
+
type: "text",
|
|
174
|
+
text: JSON.stringify({
|
|
175
|
+
success: false,
|
|
176
|
+
error: errorMsg
|
|
177
|
+
}, null, 2)
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
isError: true
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
async run() {
|
|
186
|
+
console.error("Starting MemoryLayer MCP server on stdio transport");
|
|
187
|
+
const transport = new StdioServerTransport();
|
|
188
|
+
await this.server.connect(transport);
|
|
189
|
+
console.error("MCP server running");
|
|
190
|
+
// Auto-start session if enabled
|
|
191
|
+
if (this.autoStartSession) {
|
|
192
|
+
try {
|
|
193
|
+
const result = await this.handlers.handleMemorySessionStart({});
|
|
194
|
+
console.error("Session auto-started:", result);
|
|
195
|
+
// Write session handoff file for hook to adopt
|
|
196
|
+
const session = this.sessionManager.currentSession;
|
|
197
|
+
if (session?.serverSessionId) {
|
|
198
|
+
this.writeSessionHandoff(session.serverSessionId, session.workspaceId);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
console.error("Failed to auto-start session:", error instanceof Error ? error.message : error);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Write session handoff file for hook to adopt the MCP-created session
|
|
208
|
+
*/
|
|
209
|
+
writeSessionHandoff(sessionId, workspaceId) {
|
|
210
|
+
try {
|
|
211
|
+
const handoffDir = join(tmpdir(), "memorylayer");
|
|
212
|
+
const handoffFile = join(handoffDir, `session-${process.ppid}.json`);
|
|
213
|
+
if (!existsSync(handoffDir)) {
|
|
214
|
+
mkdirSync(handoffDir, { recursive: true });
|
|
215
|
+
}
|
|
216
|
+
const handoff = {
|
|
217
|
+
sessionId,
|
|
218
|
+
workspaceId,
|
|
219
|
+
pid: process.pid,
|
|
220
|
+
createdAt: new Date().toISOString()
|
|
221
|
+
};
|
|
222
|
+
// Write atomically: tmp file then rename
|
|
223
|
+
const tmpFile = handoffFile + ".tmp";
|
|
224
|
+
writeFileSync(tmpFile, JSON.stringify(handoff));
|
|
225
|
+
renameSync(tmpFile, handoffFile);
|
|
226
|
+
console.error(`Session handoff written: ${handoffFile}`);
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
console.error("Failed to write session handoff:", error instanceof Error ? error.message : error);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
getManifest() {
|
|
233
|
+
const profileTools = getToolsForProfile(this.toolProfile);
|
|
234
|
+
return {
|
|
235
|
+
name: "memorylayer",
|
|
236
|
+
version: PACKAGE_VERSION,
|
|
237
|
+
description: "MemoryLayer.ai - Memory infrastructure for LLM-powered agents",
|
|
238
|
+
homepage: "https://memorylayer.ai",
|
|
239
|
+
toolProfile: this.toolProfile,
|
|
240
|
+
capabilities: {
|
|
241
|
+
tools: profileTools.map(t => t.name)
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
export async function createServer(client, options = {}) {
|
|
247
|
+
return new MCPServer(client, options);
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session state management for MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Each MCP server instance (spawned per Claude Code window) maintains
|
|
5
|
+
* a single session. This provides working memory that persists across
|
|
6
|
+
* tool calls within a Claude Code session.
|
|
7
|
+
*/
|
|
8
|
+
export interface WorkingMemoryEntry {
|
|
9
|
+
key: string;
|
|
10
|
+
value: unknown;
|
|
11
|
+
createdAt: Date;
|
|
12
|
+
updatedAt: Date;
|
|
13
|
+
}
|
|
14
|
+
export interface SessionState {
|
|
15
|
+
id: string;
|
|
16
|
+
workspaceId: string;
|
|
17
|
+
createdAt: Date;
|
|
18
|
+
workingMemory: Map<string, WorkingMemoryEntry>;
|
|
19
|
+
/** Whether this session has been committed to long-term storage */
|
|
20
|
+
committed: boolean;
|
|
21
|
+
/** Server-side session ID (from MemoryLayer API) */
|
|
22
|
+
serverSessionId?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SessionConfig {
|
|
25
|
+
/** Enable session tracking (default: true) */
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
/** Auto-create session on first tool call (default: true) */
|
|
28
|
+
autoCreate: boolean;
|
|
29
|
+
/** Session TTL in seconds for server-side session (default: 3600) */
|
|
30
|
+
ttlSeconds: number;
|
|
31
|
+
}
|
|
32
|
+
export declare class SessionManager {
|
|
33
|
+
private session;
|
|
34
|
+
private config;
|
|
35
|
+
constructor(config?: Partial<SessionConfig>);
|
|
36
|
+
get isEnabled(): boolean;
|
|
37
|
+
get hasActiveSession(): boolean;
|
|
38
|
+
get currentSession(): SessionState | null;
|
|
39
|
+
/**
|
|
40
|
+
* Start a new session. Replaces any existing session.
|
|
41
|
+
*/
|
|
42
|
+
startSession(workspaceId: string, serverSessionId?: string): SessionState;
|
|
43
|
+
/**
|
|
44
|
+
* End the current session.
|
|
45
|
+
*/
|
|
46
|
+
endSession(): SessionState | null;
|
|
47
|
+
/**
|
|
48
|
+
* Mark session as committed.
|
|
49
|
+
*/
|
|
50
|
+
markCommitted(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Get all working memory entries.
|
|
53
|
+
*/
|
|
54
|
+
getAllWorkingMemory(): WorkingMemoryEntry[];
|
|
55
|
+
/**
|
|
56
|
+
* Clear all working memory.
|
|
57
|
+
*/
|
|
58
|
+
clearWorkingMemory(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Get session summary for briefing.
|
|
61
|
+
*/
|
|
62
|
+
getSessionSummary(): Record<string, unknown>;
|
|
63
|
+
/**
|
|
64
|
+
* Get TTL config for server-side session creation.
|
|
65
|
+
*/
|
|
66
|
+
getTtlSeconds(): number;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC/C,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;IACnB,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,6DAA6D;IAC7D,UAAU,EAAE,OAAO,CAAC;IACpB,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM;IAQ/C,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED,IAAI,cAAc,IAAI,YAAY,GAAG,IAAI,CAExC;IAED;;OAEG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,YAAY;IAgBzE;;OAEG;IACH,UAAU,IAAI,YAAY,GAAG,IAAI;IASjC;;OAEG;IACH,aAAa,IAAI,IAAI;IAMrB;;OAEG;IACH,mBAAmB,IAAI,kBAAkB,EAAE;IAO3C;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAkB5C;;OAEG;IACH,aAAa,IAAI,MAAM;CAGxB"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session state management for MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Each MCP server instance (spawned per Claude Code window) maintains
|
|
5
|
+
* a single session. This provides working memory that persists across
|
|
6
|
+
* tool calls within a Claude Code session.
|
|
7
|
+
*/
|
|
8
|
+
export class SessionManager {
|
|
9
|
+
session = null;
|
|
10
|
+
config;
|
|
11
|
+
constructor(config = {}) {
|
|
12
|
+
this.config = {
|
|
13
|
+
enabled: config.enabled ?? true,
|
|
14
|
+
autoCreate: config.autoCreate ?? true,
|
|
15
|
+
ttlSeconds: config.ttlSeconds ?? 3600,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
get isEnabled() {
|
|
19
|
+
return this.config.enabled;
|
|
20
|
+
}
|
|
21
|
+
get hasActiveSession() {
|
|
22
|
+
return this.session !== null;
|
|
23
|
+
}
|
|
24
|
+
get currentSession() {
|
|
25
|
+
return this.session;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start a new session. Replaces any existing session.
|
|
29
|
+
*/
|
|
30
|
+
startSession(workspaceId, serverSessionId) {
|
|
31
|
+
const sessionId = `local_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
32
|
+
this.session = {
|
|
33
|
+
id: sessionId,
|
|
34
|
+
workspaceId,
|
|
35
|
+
createdAt: new Date(),
|
|
36
|
+
workingMemory: new Map(),
|
|
37
|
+
committed: false,
|
|
38
|
+
serverSessionId,
|
|
39
|
+
};
|
|
40
|
+
console.error(`Session started: ${sessionId} (workspace: ${workspaceId})`);
|
|
41
|
+
return this.session;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* End the current session.
|
|
45
|
+
*/
|
|
46
|
+
endSession() {
|
|
47
|
+
const session = this.session;
|
|
48
|
+
if (session) {
|
|
49
|
+
console.error(`Session ended: ${session.id}`);
|
|
50
|
+
}
|
|
51
|
+
this.session = null;
|
|
52
|
+
return session;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Mark session as committed.
|
|
56
|
+
*/
|
|
57
|
+
markCommitted() {
|
|
58
|
+
if (this.session) {
|
|
59
|
+
this.session.committed = true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get all working memory entries.
|
|
64
|
+
*/
|
|
65
|
+
getAllWorkingMemory() {
|
|
66
|
+
if (!this.session) {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
return Array.from(this.session.workingMemory.values());
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Clear all working memory.
|
|
73
|
+
*/
|
|
74
|
+
clearWorkingMemory() {
|
|
75
|
+
this.session?.workingMemory.clear();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get session summary for briefing.
|
|
79
|
+
*/
|
|
80
|
+
getSessionSummary() {
|
|
81
|
+
if (!this.session) {
|
|
82
|
+
return {
|
|
83
|
+
active: false,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
active: true,
|
|
88
|
+
id: this.session.id,
|
|
89
|
+
workspaceId: this.session.workspaceId,
|
|
90
|
+
createdAt: this.session.createdAt.toISOString(),
|
|
91
|
+
workingMemoryCount: this.session.workingMemory.size,
|
|
92
|
+
committed: this.session.committed,
|
|
93
|
+
serverSessionId: this.session.serverSessionId,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get TTL config for server-side session creation.
|
|
98
|
+
*/
|
|
99
|
+
getTtlSeconds() {
|
|
100
|
+
return this.config.ttlSeconds;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session.ts"],"names":[],"mappings":"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"}
|