@downcity/agent 1.1.81 → 1.1.83

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.
@@ -75,7 +75,7 @@ export class Session implements AgentSession {
75
75
  private readonly localState: SessionLocalState;
76
76
  private readonly stateService: SessionStateService;
77
77
  private readonly turnService: SessionTurnService;
78
- private readonly viewService: SessionViewService<Session>;
78
+ private readonly viewService: SessionViewService<this>;
79
79
  private runtimePort: SessionPort | null = null;
80
80
 
81
81
  constructor(options: SessionOptions) {
@@ -99,82 +99,19 @@ export class Session implements AgentSession {
99
99
  throw new Error("Session requires a non-empty projectRoot");
100
100
  }
101
101
 
102
- const session_dir_path = getSdkAgentSessionDirPath(
103
- this.projectRoot,
104
- this.agentId,
105
- this.id,
106
- );
107
- const messages_dir_path = `${session_dir_path}/messages`;
108
- this.historyStore = new JsonlSessionHistoryStore({
109
- rootPath: this.projectRoot,
110
- agentId: this.agentId,
111
- sessionId: this.id,
112
- paths: {
113
- sessionDirPath: session_dir_path,
114
- messagesDirPath: messages_dir_path,
115
- messagesFilePath: `${messages_dir_path}/messages.jsonl`,
116
- metaFilePath: `${messages_dir_path}/meta.json`,
117
- archiveDirPath: getSdkAgentSessionArchiveDirPath(
118
- this.projectRoot,
119
- this.agentId,
120
- this.id,
121
- ),
122
- inflightFilePath: getSdkAgentSessionInflightPath(
123
- this.projectRoot,
124
- this.agentId,
125
- this.id,
126
- ),
127
- },
128
- });
129
- this.localState = {
130
- sessionConfig: {},
131
- createdAt: Date.now(),
132
- timezone: resolveSystemTimezone(),
133
- initializePromise: null,
134
- ensureConfiguredPromise: null,
135
- };
102
+ this.historyStore = this.create_history_store();
103
+ this.localState = this.create_local_state();
136
104
  const composer_context = this.create_composer_context();
137
- this.historyComposer = this.resolve_composer(
138
- this.composers?.historyComposer,
139
- composer_context,
140
- () =>
141
- new JsonlSessionHistoryComposer({
142
- store: this.historyStore,
143
- }),
144
- );
145
- const system_composer = this.resolve_composer(
146
- this.composers?.systemComposer,
147
- composer_context,
148
- () =>
149
- new SessionSystemBuilder({
150
- agentId: this.agentId,
151
- projectRoot: this.projectRoot,
152
- getSessionCreatedAt: () => this.localState.createdAt,
153
- getSessionTimezone: () => this.localState.timezone,
154
- getInstructionSystemBlocks: this.getInstructionSystemBlocks,
155
- getManagedPluginSystemBlocks: this.getManagedPluginSystemBlocks,
156
- getPluginSystemBlocks: this.getPluginSystemBlocks,
157
- }),
105
+ this.historyComposer = this.create_history_composer(composer_context);
106
+ const system_composer = this.create_system_composer(composer_context);
107
+ const context_composer = this.create_context_composer(composer_context);
108
+ const compaction_composer =
109
+ this.create_compaction_composer(composer_context);
110
+ this.executor = this.create_executor(
111
+ system_composer,
112
+ context_composer,
113
+ compaction_composer,
158
114
  );
159
- const context_composer = this.resolve_optional_composer<
160
- SessionContextComposer
161
- >(this.composers?.contextComposer, composer_context);
162
- const compaction_composer = this.resolve_optional_composer<
163
- SessionCompactionComposer
164
- >(this.composers?.compactionComposer, composer_context);
165
- this.executor = new Executor({
166
- sessionId: this.id,
167
- historyStore: this.historyStore,
168
- historyComposer: this.historyComposer,
169
- getModel: () => this.localState.sessionConfig.model,
170
- logger: this.logger as never,
171
- systemComposer: system_composer,
172
- getTools: () => this.tools,
173
- ...(context_composer ? { contextComposer: context_composer } : {}),
174
- ...(compaction_composer
175
- ? { compactionComposer: compaction_composer }
176
- : {}),
177
- });
178
115
  this.stateService = new SessionStateService({
179
116
  agent_id: this.agentId,
180
117
  project_root: this.projectRoot,
@@ -197,7 +134,7 @@ export class Session implements AgentSession {
197
134
  state_service: this.stateService,
198
135
  event_hub: this.eventHub,
199
136
  });
200
- this.viewService = new SessionViewService<Session>({
137
+ this.viewService = new SessionViewService<this>({
201
138
  agent_id: this.agentId,
202
139
  project_root: this.projectRoot,
203
140
  session_id: this.id,
@@ -211,7 +148,7 @@ export class Session implements AgentSession {
211
148
  ? { custom_system_composer: system_composer }
212
149
  : {}),
213
150
  create_fork_session: async (session_id) => {
214
- const session = this.createChildSession(session_id);
151
+ const session = this.create_fork_session(session_id);
215
152
  await session.initialize();
216
153
  return {
217
154
  session,
@@ -318,7 +255,7 @@ export class Session implements AgentSession {
318
255
  /**
319
256
  * 从当前 session 创建一个分叉会话。
320
257
  */
321
- async fork(input?: AgentSessionForkInput | string): Promise<Session> {
258
+ async fork(input?: AgentSessionForkInput | string): Promise<this> {
322
259
  return await this.viewService.fork(input);
323
260
  }
324
261
 
@@ -363,8 +300,8 @@ export class Session implements AgentSession {
363
300
  await this.stateService.ensure_ready_for_execution();
364
301
  }
365
302
 
366
- private createChildSession(session_id: string): Session {
367
- return new Session({
303
+ private create_fork_session(session_id: string): this {
304
+ return this.create_child_session({
368
305
  agentId: this.agentId,
369
306
  projectRoot: this.projectRoot,
370
307
  sessionId: session_id,
@@ -373,10 +310,65 @@ export class Session implements AgentSession {
373
310
  getInstructionSystemBlocks: this.getInstructionSystemBlocks,
374
311
  getManagedPluginSystemBlocks: this.getManagedPluginSystemBlocks,
375
312
  getPluginSystemBlocks: this.getPluginSystemBlocks,
313
+ ensureConfigured: this.ensureConfiguredHook,
376
314
  composers: this.composers,
377
315
  });
378
316
  }
379
317
 
318
+ /**
319
+ * 创建当前 Session 的同类子会话。
320
+ *
321
+ * 关键点(中文)
322
+ * - 默认沿用当前实例的 class,避免自定义 Session 在 fork 后退回默认实现。
323
+ * - 子类仍可覆盖该方法,接管更特殊的子会话创建逻辑。
324
+ */
325
+ protected create_child_session(options: SessionOptions): this {
326
+ const SessionClass = this.constructor as new (
327
+ options: SessionOptions,
328
+ ) => Session;
329
+ return new SessionClass(options) as this;
330
+ }
331
+
332
+ private create_history_store(): JsonlSessionHistoryStore {
333
+ const session_dir_path = getSdkAgentSessionDirPath(
334
+ this.projectRoot,
335
+ this.agentId,
336
+ this.id,
337
+ );
338
+ const messages_dir_path = `${session_dir_path}/messages`;
339
+ return new JsonlSessionHistoryStore({
340
+ rootPath: this.projectRoot,
341
+ agentId: this.agentId,
342
+ sessionId: this.id,
343
+ paths: {
344
+ sessionDirPath: session_dir_path,
345
+ messagesDirPath: messages_dir_path,
346
+ messagesFilePath: `${messages_dir_path}/messages.jsonl`,
347
+ metaFilePath: `${messages_dir_path}/meta.json`,
348
+ archiveDirPath: getSdkAgentSessionArchiveDirPath(
349
+ this.projectRoot,
350
+ this.agentId,
351
+ this.id,
352
+ ),
353
+ inflightFilePath: getSdkAgentSessionInflightPath(
354
+ this.projectRoot,
355
+ this.agentId,
356
+ this.id,
357
+ ),
358
+ },
359
+ });
360
+ }
361
+
362
+ private create_local_state(): SessionLocalState {
363
+ return {
364
+ sessionConfig: {},
365
+ createdAt: Date.now(),
366
+ timezone: resolveSystemTimezone(),
367
+ initializePromise: null,
368
+ ensureConfiguredPromise: null,
369
+ };
370
+ }
371
+
380
372
  private create_composer_context(): SessionComposerFactoryContext {
381
373
  return {
382
374
  agentId: this.agentId,
@@ -392,6 +384,70 @@ export class Session implements AgentSession {
392
384
  };
393
385
  }
394
386
 
387
+ private create_history_composer(
388
+ context: SessionComposerFactoryContext,
389
+ ): SessionHistoryComposer {
390
+ return this.resolve_composer(this.composers?.historyComposer, context, () =>
391
+ new JsonlSessionHistoryComposer({
392
+ store: this.historyStore,
393
+ }),
394
+ );
395
+ }
396
+
397
+ private create_system_composer(
398
+ context: SessionComposerFactoryContext,
399
+ ): SessionSystemComposer {
400
+ return this.resolve_composer(this.composers?.systemComposer, context, () =>
401
+ new SessionSystemBuilder({
402
+ agentId: this.agentId,
403
+ projectRoot: this.projectRoot,
404
+ getSessionCreatedAt: () => this.localState.createdAt,
405
+ getSessionTimezone: () => this.localState.timezone,
406
+ getInstructionSystemBlocks: this.getInstructionSystemBlocks,
407
+ getManagedPluginSystemBlocks: this.getManagedPluginSystemBlocks,
408
+ getPluginSystemBlocks: this.getPluginSystemBlocks,
409
+ }),
410
+ );
411
+ }
412
+
413
+ private create_context_composer(
414
+ context: SessionComposerFactoryContext,
415
+ ): SessionContextComposer | undefined {
416
+ return this.resolve_optional_composer<SessionContextComposer>(
417
+ this.composers?.contextComposer,
418
+ context,
419
+ );
420
+ }
421
+
422
+ private create_compaction_composer(
423
+ context: SessionComposerFactoryContext,
424
+ ): SessionCompactionComposer | undefined {
425
+ return this.resolve_optional_composer<SessionCompactionComposer>(
426
+ this.composers?.compactionComposer,
427
+ context,
428
+ );
429
+ }
430
+
431
+ private create_executor(
432
+ system_composer: SessionSystemComposer,
433
+ context_composer?: SessionContextComposer,
434
+ compaction_composer?: SessionCompactionComposer,
435
+ ): Executor {
436
+ return new Executor({
437
+ sessionId: this.id,
438
+ historyStore: this.historyStore,
439
+ historyComposer: this.historyComposer,
440
+ getModel: () => this.localState.sessionConfig.model,
441
+ logger: this.logger,
442
+ systemComposer: system_composer,
443
+ getTools: () => this.tools,
444
+ ...(context_composer ? { contextComposer: context_composer } : {}),
445
+ ...(compaction_composer
446
+ ? { compactionComposer: compaction_composer }
447
+ : {}),
448
+ });
449
+ }
450
+
395
451
  private resolve_composer<TComposer>(
396
452
  input: SessionComposerInput<TComposer> | undefined,
397
453
  context: SessionComposerFactoryContext,
@@ -22,6 +22,7 @@ import type {
22
22
  AgentSessionHistoryInput,
23
23
  AgentSessionHistoryPage,
24
24
  AgentSessionInfo,
25
+ AgentSession,
25
26
  AgentSessionSystemBlock,
26
27
  AgentSessionSystemSnapshot,
27
28
  } from "@/types/agent/AgentTypes.js";
@@ -29,7 +30,7 @@ import type { SessionMessageV1 } from "@/executor/types/SessionMessages.js";
29
30
  import { SessionStateService } from "@/session/services/SessionStateService.js";
30
31
  import type { SessionRunContext } from "@/types/executor/SessionRunContext.js";
31
32
 
32
- type SessionViewServiceOptions<TSession> = {
33
+ type SessionViewServiceOptions<TSession extends Pick<AgentSession, "set">> = {
33
34
  /**
34
35
  * 当前 agent 稳定标识。
35
36
  */
@@ -97,7 +98,7 @@ type SessionViewServiceOptions<TSession> = {
97
98
  /**
98
99
  * 本地 Session 查询与派生视图服务。
99
100
  */
100
- export class SessionViewService<TSession> {
101
+ export class SessionViewService<TSession extends Pick<AgentSession, "set">> {
101
102
  private readonly agent_id: string;
102
103
  private readonly project_root: string;
103
104
  private readonly session_id: string;
@@ -137,20 +138,37 @@ export class SessionViewService<TSession> {
137
138
  }),
138
139
  this.history_store.list(),
139
140
  ]);
140
- const metadata_with_title = metadata.title
141
- ? metadata
141
+ return await this.build_info({
142
+ metadata,
143
+ messages,
144
+ });
145
+ }
146
+
147
+ private async build_info(input: {
148
+ /**
149
+ * 当前 session metadata。
150
+ */
151
+ metadata: Awaited<ReturnType<typeof readSessionMetadata>>;
152
+
153
+ /**
154
+ * 当前 session 消息列表。
155
+ */
156
+ messages: SessionMessageV1[];
157
+ }): Promise<AgentSessionInfo> {
158
+ const metadata_with_title = input.metadata.title
159
+ ? input.metadata
142
160
  : await ensureSessionTitle({
143
161
  projectRoot: this.project_root,
144
162
  agentId: this.agent_id,
145
163
  sessionId: this.session_id,
146
- messages,
164
+ messages: input.messages,
147
165
  });
148
166
  return buildSessionInfo({
149
167
  projectRoot: this.project_root,
150
168
  agentId: this.agent_id,
151
169
  sessionId: this.session_id,
152
170
  metadata: metadata_with_title,
153
- messages,
171
+ messages: input.messages,
154
172
  executing: this.is_executing(),
155
173
  });
156
174
  }
@@ -161,10 +179,18 @@ export class SessionViewService<TSession> {
161
179
  async history(
162
180
  input?: AgentSessionHistoryInput,
163
181
  ): Promise<AgentSessionHistoryPage> {
164
- const [session, messages] = await Promise.all([
165
- this.get_info(),
182
+ const [metadata, messages] = await Promise.all([
183
+ readSessionMetadata({
184
+ projectRoot: this.project_root,
185
+ agentId: this.agent_id,
186
+ sessionId: this.session_id,
187
+ }),
166
188
  this.history_store.list(),
167
189
  ]);
190
+ const session = await this.build_info({
191
+ metadata,
192
+ messages,
193
+ });
168
194
  return buildSessionHistoryPage({
169
195
  session,
170
196
  messages,
@@ -246,11 +272,7 @@ export class SessionViewService<TSession> {
246
272
  const forked = forked_bundle.session;
247
273
  const session_config = this.state_service.get_config();
248
274
  if (session_config.model) {
249
- await (
250
- forked as unknown as {
251
- set(input: { model: unknown }): Promise<void>;
252
- }
253
- ).set({
275
+ await forked.set({
254
276
  model: session_config.model,
255
277
  });
256
278
  }
@@ -12,6 +12,7 @@ import type { AgentSession } from "@/types/agent/SessionActor.js";
12
12
  import type { SessionPort } from "@/types/runtime/agent/AgentContext.js";
13
13
  import type { AgentSessionSystemBlock } from "@/types/agent/SessionTypes.js";
14
14
  import type { SessionComposerOptions } from "@/types/session/SessionComposerOptions.js";
15
+ import type { Logger } from "@/utils/logger/Logger.js";
15
16
 
16
17
  /**
17
18
  * Agent 可管理的本地 Session 实例。
@@ -60,17 +61,7 @@ export interface SessionOptions {
60
61
  /**
61
62
  * 统一日志器。
62
63
  */
63
- logger: {
64
- /**
65
- * 记录普通信息。
66
- */
67
- info(message: string, details?: Record<string, unknown>): void;
68
-
69
- /**
70
- * 记录警告信息。
71
- */
72
- warn(message: string, details?: Record<string, unknown>): void;
73
- };
64
+ logger: Logger;
74
65
 
75
66
  /**
76
67
  * 读取当前 SDK 调用方传入的 instruction system blocks。