@amodalai/runtime 0.3.68 → 0.3.70

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.
@@ -10,16 +10,16 @@
10
10
  * resolution, session lookup/resume/create into a single function so
11
11
  * chat-stream, ai-stream, and chat routes share the same flow.
12
12
  */
13
- import type { AgentBundle, CustomToolExecutor, StoreBackend } from '@amodalai/types';
14
- import type { McpManager, FieldScrubber } from '@amodalai/core';
15
- import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
16
- import type { StandaloneSessionManager } from '../session/manager.js';
17
- import type { Session } from '../session/types.js';
18
- import type { ToolContext } from '../tools/types.js';
19
- import type { SessionComponents, SessionType } from '../session/session-builder.js';
20
- import type { AuthContext } from '../middleware/auth.js';
21
- import type { Logger } from '../logger.js';
22
- import type { CredentialResolver } from '../credentials.js';
13
+ import type { AgentBundle, CustomToolExecutor, StoreBackend } from "@amodalai/types";
14
+ import type { McpManager, FieldScrubber } from "@amodalai/core";
15
+ import type { NodePgDatabase } from "drizzle-orm/node-postgres";
16
+ import type { StandaloneSessionManager } from "../session/manager.js";
17
+ import type { Session } from "../session/types.js";
18
+ import type { ToolContext } from "../tools/types.js";
19
+ import type { SessionComponents, SessionType } from "../session/session-builder.js";
20
+ import type { AuthContext } from "../middleware/auth.js";
21
+ import type { Logger } from "../logger.js";
22
+ import type { CredentialResolver } from "../credentials.js";
23
23
  /** How the route resolves an AgentBundle for a given request. */
24
24
  export interface BundleResolver {
25
25
  /** Static bundle for local dev (used when no deploy_id is provided). */
@@ -3,10 +3,10 @@
3
3
  * Copyright 2026 Amodal Labs, Inc.
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
- import { buildSessionComponents } from '../session/session-builder.js';
7
- import { loadIntents } from '../intent/index.js';
8
- import { loadMemoryContent } from '../tools/memory-tool.js';
9
- import { SessionError } from '../errors.js';
6
+ import { buildSessionComponents } from "../session/session-builder.js";
7
+ import { loadIntents } from "../intent/index.js";
8
+ import { loadMemoryContent } from "../tools/memory-tool.js";
9
+ import { SessionError } from "../errors.js";
10
10
  // ---------------------------------------------------------------------------
11
11
  // Bundle resolution
12
12
  // ---------------------------------------------------------------------------
@@ -30,17 +30,20 @@ async function buildComponents(bundle, shared, opts) {
30
30
  let memoryContent;
31
31
  const memoryDb = shared.memoryDb;
32
32
  if (bundle.config.memory?.enabled && memoryDb) {
33
- memoryContent = await loadMemoryContent(memoryDb, shared.appId ?? 'local', opts.scopeId ?? '');
34
- shared.logger.info('memory_loaded', { contentLength: memoryContent.length, scopeId: opts.scopeId ?? '' });
33
+ memoryContent = await loadMemoryContent(memoryDb, shared.appId ?? "local", opts.scopeId ?? "");
34
+ shared.logger.info("memory_loaded", {
35
+ contentLength: memoryContent.length,
36
+ scopeId: opts.scopeId ?? "",
37
+ });
35
38
  }
36
39
  const credentialResolver = shared.buildCredentialResolver?.(opts.scopeId);
37
40
  // Load deterministic intents from <repoPath>/intents/. Empty array
38
41
  // when the repo doesn't have one (most agents). Loaded async here
39
42
  // because esbuild compile + dynamic import are async; the rest of
40
43
  // session building stays sync.
41
- const intents = bundle.source === 'local' && bundle.origin
44
+ const intents = bundle.source === "local" && bundle.origin
42
45
  ? await loadIntents(bundle.origin).catch((err) => {
43
- shared.logger.warn('intent_load_failed', {
46
+ shared.logger.warn("intent_load_failed", {
44
47
  repoPath: bundle.origin,
45
48
  error: err instanceof Error ? err.message : String(err),
46
49
  });
@@ -85,12 +88,15 @@ async function buildComponents(bundle, shared, opts) {
85
88
  */
86
89
  export async function resolveSession(sessionId, opts) {
87
90
  const { sessionManager, bundleResolver, shared, auth } = opts;
88
- const scopeId = opts.scopeId ?? '';
91
+ const scopeId = opts.scopeId ?? "";
89
92
  // 1. In-memory lookup (existing live session)
90
93
  if (sessionId) {
91
94
  const existing = sessionManager.get(sessionId);
92
95
  if (existing && existing.toolContextFactory) {
93
- return { session: existing, toolContextFactory: existing.toolContextFactory };
96
+ return {
97
+ session: existing,
98
+ toolContextFactory: existing.toolContextFactory,
99
+ };
94
100
  }
95
101
  }
96
102
  // Resolve bundle once — shared between resume and create paths
@@ -106,7 +112,10 @@ export async function resolveSession(sessionId, opts) {
106
112
  // regardless of sessionId. Cache the first result and apply it to
107
113
  // subsequent components by copying the enhanced systemPrompt.
108
114
  if (!hookResult) {
109
- hookResult = await opts.onSessionBuild(components, { auth, bundle: bundle });
115
+ hookResult = await opts.onSessionBuild(components, {
116
+ auth,
117
+ bundle: bundle,
118
+ });
110
119
  return hookResult;
111
120
  }
112
121
  // Reuse the enhanced prompt from the first call
@@ -118,10 +127,13 @@ export async function resolveSession(sessionId, opts) {
118
127
  if (!resolvedSessionId && scopeId && bundle) {
119
128
  const sessionStore = sessionManager.getStore();
120
129
  if (sessionStore?.findByScopeId) {
121
- const found = await sessionStore.findByScopeId(scopeId);
130
+ const found = await sessionStore.findByScopeId(scopeId, shared.appId);
122
131
  if (found) {
123
132
  resolvedSessionId = found;
124
- shared.logger.info('session_resolved_by_scope', { scopeId, sessionId: found });
133
+ shared.logger.info("session_resolved_by_scope", {
134
+ scopeId,
135
+ sessionId: found,
136
+ });
125
137
  }
126
138
  }
127
139
  }
@@ -142,18 +154,22 @@ export async function resolveSession(sessionId, opts) {
142
154
  permissionChecker: components.permissionChecker,
143
155
  systemPrompt: components.systemPrompt,
144
156
  toolContextFactory: components.toolContextFactory,
157
+ appId: shared.appId,
145
158
  scopeId,
146
159
  ...(metadata ? { metadata } : {}),
147
160
  });
148
161
  if (resumed) {
149
- return { session: resumed, toolContextFactory: components.toolContextFactory };
162
+ return {
163
+ session: resumed,
164
+ toolContextFactory: components.toolContextFactory,
165
+ };
150
166
  }
151
167
  }
152
168
  // 3. Create new session
153
169
  if (!bundle) {
154
- throw new SessionError('No bundle available — provide a deploy_id or configure a static bundle', {
155
- sessionId: resolvedSessionId ?? 'new',
156
- context: { operation: 'resolveSession', deployId: opts.deployId },
170
+ throw new SessionError("No bundle available — provide a deploy_id or configure a static bundle", {
171
+ sessionId: resolvedSessionId ?? "new",
172
+ context: { operation: "resolveSession", deployId: opts.deployId },
157
173
  });
158
174
  }
159
175
  const rawComponents = await buildComponents(bundle, shared, {
@@ -1 +1 @@
1
- {"version":3,"file":"session-resolver.js","sourceRoot":"","sources":["../../../src/routes/session-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-resolver.js","sourceRoot":"","sources":["../../../src/routes/session-resolver.ts"],"names":[],"mappings":"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"}
@@ -3,22 +3,25 @@
3
3
  * Copyright 2026 Amodal Labs, Inc.
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
- import { describe, it, expect, vi, beforeEach } from 'vitest';
7
- import { resolveBundle, resolveSession } from './session-resolver.js';
8
- import { SessionError } from '../errors.js';
6
+ import { describe, it, expect, vi, beforeEach } from "vitest";
7
+ import { resolveBundle, resolveSession } from "./session-resolver.js";
8
+ import { SessionError } from "../errors.js";
9
9
  // ---------------------------------------------------------------------------
10
10
  // Mock buildSessionComponents — we test the resolver, not the builder
11
11
  // ---------------------------------------------------------------------------
12
12
  const mockBuildSessionComponents = vi.fn();
13
- vi.mock('../session/session-builder.js', () => ({
13
+ vi.mock("../session/session-builder.js", () => ({
14
14
  buildSessionComponents: (...args) => mockBuildSessionComponents(...args),
15
15
  }));
16
16
  // ---------------------------------------------------------------------------
17
17
  // Fixtures
18
18
  // ---------------------------------------------------------------------------
19
- function stubBundle(name = 'test-agent') {
19
+ function stubBundle(name = "test-agent") {
20
20
  return {
21
- config: { name, models: { main: { provider: 'test', model: 'test-model' } } },
21
+ config: {
22
+ name,
23
+ models: { main: { provider: "test", model: "test-model" } },
24
+ },
22
25
  connections: new Map(),
23
26
  resolvedCredentials: {},
24
27
  stores: [],
@@ -31,18 +34,18 @@ function stubBundle(name = 'test-agent') {
31
34
  function stubComponents() {
32
35
  const factory = vi.fn();
33
36
  return {
34
- provider: { model: 'test-model', provider: 'test' },
37
+ provider: { model: "test-model", provider: "test" },
35
38
  toolRegistry: { size: 0 },
36
39
  permissionChecker: { check: () => ({ allowed: true }) },
37
- systemPrompt: 'test prompt',
40
+ systemPrompt: "test prompt",
38
41
  toolContextFactory: factory,
39
42
  };
40
43
  }
41
44
  function stubSession(id, hasFactory = true) {
42
45
  return {
43
46
  id,
44
- model: 'test-model',
45
- providerName: 'test',
47
+ model: "test-model",
48
+ providerName: "test",
46
49
  toolContextFactory: hasFactory ? vi.fn() : undefined,
47
50
  };
48
51
  }
@@ -51,6 +54,7 @@ function stubSessionManager(overrides = {}) {
51
54
  get: vi.fn(),
52
55
  resume: vi.fn(),
53
56
  create: vi.fn(),
57
+ getStore: vi.fn(),
54
58
  ...overrides,
55
59
  };
56
60
  }
@@ -58,33 +62,44 @@ function stubShared() {
58
62
  return {
59
63
  storeBackend: null,
60
64
  mcpManager: null,
61
- logger: { info: vi.fn(), warn: vi.fn(), debug: vi.fn(), error: vi.fn(), fatal: vi.fn(), child: vi.fn() },
65
+ logger: {
66
+ info: vi.fn(),
67
+ warn: vi.fn(),
68
+ debug: vi.fn(),
69
+ error: vi.fn(),
70
+ fatal: vi.fn(),
71
+ child: vi.fn(),
72
+ },
73
+ appId: "test-agent",
62
74
  };
63
75
  }
64
76
  // ---------------------------------------------------------------------------
65
77
  // resolveBundle
66
78
  // ---------------------------------------------------------------------------
67
- describe('resolveBundle', () => {
68
- it('returns static bundle when no deployId', async () => {
79
+ describe("resolveBundle", () => {
80
+ it("returns static bundle when no deployId", async () => {
69
81
  const bundle = stubBundle();
70
82
  const result = await resolveBundle({ staticBundle: bundle });
71
83
  expect(result).toBe(bundle);
72
84
  });
73
- it('returns null when no bundle available', async () => {
85
+ it("returns null when no bundle available", async () => {
74
86
  const result = await resolveBundle({});
75
87
  expect(result).toBeNull();
76
88
  });
77
- it('calls bundleProvider when deployId is provided', async () => {
89
+ it("calls bundleProvider when deployId is provided", async () => {
78
90
  const bundle = stubBundle();
79
91
  const provider = vi.fn().mockResolvedValue(bundle);
80
- const result = await resolveBundle({ bundleProvider: provider }, 'deploy-1', 'token-abc');
81
- expect(provider).toHaveBeenCalledWith('deploy-1', 'token-abc');
92
+ const result = await resolveBundle({ bundleProvider: provider }, "deploy-1", "token-abc");
93
+ expect(provider).toHaveBeenCalledWith("deploy-1", "token-abc");
82
94
  expect(result).toBe(bundle);
83
95
  });
84
- it('falls back to static bundle when no deployId even if bundleProvider exists', async () => {
85
- const staticBundle = stubBundle('static');
96
+ it("falls back to static bundle when no deployId even if bundleProvider exists", async () => {
97
+ const staticBundle = stubBundle("static");
86
98
  const provider = vi.fn();
87
- const result = await resolveBundle({ staticBundle, bundleProvider: provider });
99
+ const result = await resolveBundle({
100
+ staticBundle,
101
+ bundleProvider: provider,
102
+ });
88
103
  expect(provider).not.toHaveBeenCalled();
89
104
  expect(result).toBe(staticBundle);
90
105
  });
@@ -92,15 +107,15 @@ describe('resolveBundle', () => {
92
107
  // ---------------------------------------------------------------------------
93
108
  // resolveSession
94
109
  // ---------------------------------------------------------------------------
95
- describe('resolveSession', () => {
110
+ describe("resolveSession", () => {
96
111
  beforeEach(() => {
97
112
  vi.clearAllMocks();
98
113
  mockBuildSessionComponents.mockReturnValue(stubComponents());
99
114
  });
100
- it('returns in-memory session with cached factory (no rebuild)', async () => {
101
- const session = stubSession('sess-1');
115
+ it("returns in-memory session with cached factory (no rebuild)", async () => {
116
+ const session = stubSession("sess-1");
102
117
  const mgr = stubSessionManager({ get: vi.fn().mockReturnValue(session) });
103
- const result = await resolveSession('sess-1', {
118
+ const result = await resolveSession("sess-1", {
104
119
  sessionManager: mgr,
105
120
  bundleResolver: { staticBundle: stubBundle() },
106
121
  shared: stubShared(),
@@ -109,29 +124,29 @@ describe('resolveSession', () => {
109
124
  expect(result.toolContextFactory).toBe(session.toolContextFactory);
110
125
  expect(mockBuildSessionComponents).not.toHaveBeenCalled();
111
126
  });
112
- it('resumes from store when not in memory', async () => {
113
- const resumed = stubSession('sess-2');
127
+ it("resumes from store when not in memory", async () => {
128
+ const resumed = stubSession("sess-2");
114
129
  const mgr = stubSessionManager({
115
130
  get: vi.fn().mockReturnValue(undefined),
116
131
  resume: vi.fn().mockResolvedValue(resumed),
117
132
  });
118
- const result = await resolveSession('sess-2', {
133
+ const result = await resolveSession("sess-2", {
119
134
  sessionManager: mgr,
120
135
  bundleResolver: { staticBundle: stubBundle() },
121
136
  shared: stubShared(),
122
137
  });
123
138
  expect(result.session).toBe(resumed);
124
139
  expect(mockBuildSessionComponents).toHaveBeenCalledOnce();
125
- expect(mgr.resume).toHaveBeenCalledWith('sess-2', expect.any(Object));
140
+ expect(mgr.resume).toHaveBeenCalledWith("sess-2", expect.any(Object));
126
141
  });
127
- it('creates new session when session_id not found', async () => {
128
- const created = stubSession('sess-3');
142
+ it("creates new session when session_id not found", async () => {
143
+ const created = stubSession("sess-3");
129
144
  const mgr = stubSessionManager({
130
145
  get: vi.fn().mockReturnValue(undefined),
131
146
  resume: vi.fn().mockResolvedValue(null),
132
147
  create: vi.fn().mockReturnValue(created),
133
148
  });
134
- const result = await resolveSession('sess-not-found', {
149
+ const result = await resolveSession("sess-not-found", {
135
150
  sessionManager: mgr,
136
151
  bundleResolver: { staticBundle: stubBundle() },
137
152
  shared: stubShared(),
@@ -139,8 +154,8 @@ describe('resolveSession', () => {
139
154
  expect(result.session).toBe(created);
140
155
  expect(mgr.create).toHaveBeenCalledOnce();
141
156
  });
142
- it('creates new session when no session_id provided', async () => {
143
- const created = stubSession('sess-new');
157
+ it("creates new session when no session_id provided", async () => {
158
+ const created = stubSession("sess-new");
144
159
  const mgr = stubSessionManager({
145
160
  create: vi.fn().mockReturnValue(created),
146
161
  });
@@ -152,38 +167,54 @@ describe('resolveSession', () => {
152
167
  expect(result.session).toBe(created);
153
168
  expect(mgr.get).not.toHaveBeenCalled();
154
169
  });
155
- it('passes deploy metadata when creating a hosted session', async () => {
156
- const created = stubSession('sess-deploy');
170
+ it("passes deploy metadata when creating a hosted session", async () => {
171
+ const created = stubSession("sess-deploy");
157
172
  const mockCreate = vi.fn().mockReturnValue(created);
158
173
  const mgr = stubSessionManager({ create: mockCreate });
159
174
  await resolveSession(undefined, {
160
175
  sessionManager: mgr,
161
176
  bundleResolver: { staticBundle: stubBundle() },
162
177
  shared: stubShared(),
163
- deployId: 'deploy-123',
178
+ deployId: "deploy-123",
164
179
  });
165
180
  expect(mockCreate.mock.calls[0][0]).toEqual(expect.objectContaining({
166
- metadata: { deployId: 'deploy-123' },
181
+ metadata: { deployId: "deploy-123" },
167
182
  }));
168
183
  });
169
- it('passes deploy metadata when resuming a hosted session', async () => {
170
- const resumed = stubSession('sess-resume-deploy');
184
+ it("passes deploy metadata when resuming a hosted session", async () => {
185
+ const resumed = stubSession("sess-resume-deploy");
171
186
  const mockResume = vi.fn().mockResolvedValue(resumed);
172
187
  const mgr = stubSessionManager({
173
188
  get: vi.fn().mockReturnValue(undefined),
174
189
  resume: mockResume,
175
190
  });
176
- await resolveSession('sess-resume-deploy', {
191
+ await resolveSession("sess-resume-deploy", {
177
192
  sessionManager: mgr,
178
193
  bundleResolver: { staticBundle: stubBundle() },
179
194
  shared: stubShared(),
180
- deployId: 'deploy-456',
195
+ deployId: "deploy-456",
181
196
  });
182
197
  expect(mockResume.mock.calls[0][1]).toEqual(expect.objectContaining({
183
- metadata: { deployId: 'deploy-456' },
198
+ appId: "test-agent",
199
+ metadata: { deployId: "deploy-456" },
184
200
  }));
185
201
  });
186
- it('throws SessionError when no bundle available', async () => {
202
+ it("scopes latest-session lookup by agent id", async () => {
203
+ const found = stubSession("scope-session");
204
+ const findByScopeId = vi.fn().mockResolvedValue("scope-session");
205
+ const mgr = stubSessionManager({
206
+ getStore: vi.fn().mockReturnValue({ findByScopeId }),
207
+ resume: vi.fn().mockResolvedValue(found),
208
+ });
209
+ await resolveSession(undefined, {
210
+ sessionManager: mgr,
211
+ bundleResolver: { staticBundle: stubBundle() },
212
+ shared: stubShared(),
213
+ scopeId: "scope-a",
214
+ });
215
+ expect(findByScopeId).toHaveBeenCalledWith("scope-a", "test-agent");
216
+ });
217
+ it("throws SessionError when no bundle available", async () => {
187
218
  const mgr = stubSessionManager();
188
219
  await expect(resolveSession(undefined, {
189
220
  sessionManager: mgr,
@@ -191,11 +222,11 @@ describe('resolveSession', () => {
191
222
  shared: stubShared(),
192
223
  })).rejects.toThrow(SessionError);
193
224
  });
194
- it('passes auth context through to the session manager', async () => {
225
+ it("passes auth context through to the session manager", async () => {
195
226
  // Session identity (tenant / user mapping) is no longer threaded
196
227
  // through the session manager — callers that need it live at the
197
228
  // API boundary. This test is reduced to verify create() is called.
198
- const created = stubSession('sess-auth');
229
+ const created = stubSession("sess-auth");
199
230
  const mgr = stubSessionManager({
200
231
  create: vi.fn().mockReturnValue(created),
201
232
  });
@@ -203,12 +234,12 @@ describe('resolveSession', () => {
203
234
  sessionManager: mgr,
204
235
  bundleResolver: { staticBundle: stubBundle() },
205
236
  shared: stubShared(),
206
- auth: { applicationId: 'app-1', authMethod: 'api_key' },
237
+ auth: { applicationId: "app-1", authMethod: "api_key" },
207
238
  });
208
239
  expect(mgr.create).toHaveBeenCalled();
209
240
  });
210
- it('stores toolContextFactory on created session via CreateSessionOptions', async () => {
211
- const created = stubSession('sess-factory');
241
+ it("stores toolContextFactory on created session via CreateSessionOptions", async () => {
242
+ const created = stubSession("sess-factory");
212
243
  const mockCreate = vi.fn().mockReturnValue(created);
213
244
  const mgr = stubSessionManager({ create: mockCreate });
214
245
  await resolveSession(undefined, {
@@ -217,21 +248,21 @@ describe('resolveSession', () => {
217
248
  shared: stubShared(),
218
249
  });
219
250
  const createArg = mockCreate.mock.calls[0][0];
220
- expect(createArg['toolContextFactory']).toBeDefined();
221
- expect(typeof createArg['toolContextFactory']).toBe('function');
251
+ expect(createArg["toolContextFactory"]).toBeDefined();
252
+ expect(typeof createArg["toolContextFactory"]).toBe("function");
222
253
  });
223
254
  // -------------------------------------------------------------------------
224
255
  // onSessionBuild hook
225
256
  // -------------------------------------------------------------------------
226
- describe('onSessionBuild hook', () => {
227
- it('enhances components on new session creation', async () => {
228
- const created = stubSession('sess-hook');
257
+ describe("onSessionBuild hook", () => {
258
+ it("enhances components on new session creation", async () => {
259
+ const created = stubSession("sess-hook");
229
260
  const mockCreate = vi.fn().mockReturnValue(created);
230
261
  const mgr = stubSessionManager({ create: mockCreate });
231
262
  const bundle = stubBundle();
232
263
  const hook = vi.fn().mockImplementation((components) => ({
233
264
  ...components,
234
- systemPrompt: components.systemPrompt + '\n## Extra guidance',
265
+ systemPrompt: components.systemPrompt + "\n## Extra guidance",
235
266
  }));
236
267
  await resolveSession(undefined, {
237
268
  sessionManager: mgr,
@@ -239,12 +270,12 @@ describe('resolveSession', () => {
239
270
  shared: stubShared(),
240
271
  onSessionBuild: hook,
241
272
  });
242
- expect(hook).toHaveBeenCalledExactlyOnceWith(expect.objectContaining({ systemPrompt: 'test prompt' }), expect.objectContaining({ bundle }));
273
+ expect(hook).toHaveBeenCalledExactlyOnceWith(expect.objectContaining({ systemPrompt: "test prompt" }), expect.objectContaining({ bundle }));
243
274
  const createArg = mockCreate.mock.calls[0][0];
244
- expect(createArg['systemPrompt']).toBe('test prompt\n## Extra guidance');
275
+ expect(createArg["systemPrompt"]).toBe("test prompt\n## Extra guidance");
245
276
  });
246
- it('enhances components on session resume', async () => {
247
- const resumed = stubSession('sess-resume-hook');
277
+ it("enhances components on session resume", async () => {
278
+ const resumed = stubSession("sess-resume-hook");
248
279
  const mockResume = vi.fn().mockResolvedValue(resumed);
249
280
  const mgr = stubSessionManager({
250
281
  get: vi.fn().mockReturnValue(undefined),
@@ -253,9 +284,9 @@ describe('resolveSession', () => {
253
284
  const bundle = stubBundle();
254
285
  const hook = vi.fn().mockImplementation((components) => ({
255
286
  ...components,
256
- systemPrompt: components.systemPrompt + '\n## Roles injected',
287
+ systemPrompt: components.systemPrompt + "\n## Roles injected",
257
288
  }));
258
- await resolveSession('sess-resume-hook', {
289
+ await resolveSession("sess-resume-hook", {
259
290
  sessionManager: mgr,
260
291
  bundleResolver: { staticBundle: bundle },
261
292
  shared: stubShared(),
@@ -263,13 +294,13 @@ describe('resolveSession', () => {
263
294
  });
264
295
  expect(hook).toHaveBeenCalledOnce();
265
296
  const resumeArg = mockResume.mock.calls[0][1];
266
- expect(resumeArg['systemPrompt']).toBe('test prompt\n## Roles injected');
297
+ expect(resumeArg["systemPrompt"]).toBe("test prompt\n## Roles injected");
267
298
  });
268
- it('is not called for in-memory session hits', async () => {
269
- const session = stubSession('sess-mem');
299
+ it("is not called for in-memory session hits", async () => {
300
+ const session = stubSession("sess-mem");
270
301
  const mgr = stubSessionManager({ get: vi.fn().mockReturnValue(session) });
271
302
  const hook = vi.fn();
272
- await resolveSession('sess-mem', {
303
+ await resolveSession("sess-mem", {
273
304
  sessionManager: mgr,
274
305
  bundleResolver: { staticBundle: stubBundle() },
275
306
  shared: stubShared(),
@@ -277,8 +308,8 @@ describe('resolveSession', () => {
277
308
  });
278
309
  expect(hook).not.toHaveBeenCalled();
279
310
  });
280
- it('calls hook only once when resume misses and falls through to create', async () => {
281
- const created = stubSession('sess-fallthrough');
311
+ it("calls hook only once when resume misses and falls through to create", async () => {
312
+ const created = stubSession("sess-fallthrough");
282
313
  const mgr = stubSessionManager({
283
314
  get: vi.fn().mockReturnValue(undefined),
284
315
  resume: vi.fn().mockResolvedValue(null),
@@ -286,9 +317,9 @@ describe('resolveSession', () => {
286
317
  });
287
318
  const hook = vi.fn().mockImplementation((components) => ({
288
319
  ...components,
289
- systemPrompt: 'enhanced prompt',
320
+ systemPrompt: "enhanced prompt",
290
321
  }));
291
- await resolveSession('sess-not-in-store', {
322
+ await resolveSession("sess-not-in-store", {
292
323
  sessionManager: mgr,
293
324
  bundleResolver: { staticBundle: stubBundle() },
294
325
  shared: stubShared(),
@@ -296,15 +327,18 @@ describe('resolveSession', () => {
296
327
  });
297
328
  // Hook called once (resume path), cached result reused (create path)
298
329
  expect(hook).toHaveBeenCalledOnce();
299
- const createArg = mgr.create.mock.calls[0][0];
300
- expect(createArg['systemPrompt']).toBe('enhanced prompt');
330
+ const createArg = mgr.create.mock
331
+ .calls[0][0];
332
+ expect(createArg["systemPrompt"]).toBe("enhanced prompt");
301
333
  });
302
- it('works with async hooks', async () => {
303
- const created = stubSession('sess-async');
304
- const mgr = stubSessionManager({ create: vi.fn().mockReturnValue(created) });
334
+ it("works with async hooks", async () => {
335
+ const created = stubSession("sess-async");
336
+ const mgr = stubSessionManager({
337
+ create: vi.fn().mockReturnValue(created),
338
+ });
305
339
  const hook = vi.fn().mockImplementation(async (components) => ({
306
340
  ...components,
307
- systemPrompt: 'async enhanced',
341
+ systemPrompt: "async enhanced",
308
342
  }));
309
343
  await resolveSession(undefined, {
310
344
  sessionManager: mgr,
@@ -312,14 +346,21 @@ describe('resolveSession', () => {
312
346
  shared: stubShared(),
313
347
  onSessionBuild: hook,
314
348
  });
315
- const createArg = mgr.create.mock.calls[0][0];
316
- expect(createArg['systemPrompt']).toBe('async enhanced');
349
+ const createArg = mgr.create.mock
350
+ .calls[0][0];
351
+ expect(createArg["systemPrompt"]).toBe("async enhanced");
317
352
  });
318
- it('passes auth context to hook', async () => {
319
- const created = stubSession('sess-auth-hook');
320
- const mgr = stubSessionManager({ create: vi.fn().mockReturnValue(created) });
353
+ it("passes auth context to hook", async () => {
354
+ const created = stubSession("sess-auth-hook");
355
+ const mgr = stubSessionManager({
356
+ create: vi.fn().mockReturnValue(created),
357
+ });
321
358
  const hook = vi.fn().mockImplementation((c) => c);
322
- const auth = { applicationId: 'app-1', authMethod: 'api_key', token: 'tok-123' };
359
+ const auth = {
360
+ applicationId: "app-1",
361
+ authMethod: "api_key",
362
+ token: "tok-123",
363
+ };
323
364
  await resolveSession(undefined, {
324
365
  sessionManager: mgr,
325
366
  bundleResolver: { staticBundle: stubBundle() },