@downcity/agent 1.1.228 → 1.1.236
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/bin/agent/local/Agent.d.ts +6 -1
- package/bin/agent/local/Agent.d.ts.map +1 -1
- package/bin/agent/local/Agent.js +30 -3
- package/bin/agent/local/Agent.js.map +1 -1
- package/bin/agent/local/services/AgentSessions.d.ts +23 -0
- package/bin/agent/local/services/AgentSessions.d.ts.map +1 -1
- package/bin/agent/local/services/AgentSessions.js +44 -0
- package/bin/agent/local/services/AgentSessions.js.map +1 -1
- package/bin/agent/remote/RemoteSession.d.ts +2 -0
- package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
- package/bin/agent/remote/RemoteSession.js +4 -0
- package/bin/agent/remote/RemoteSession.js.map +1 -1
- package/bin/agent/remote/RemoteTransport.d.ts +2 -0
- package/bin/agent/remote/RemoteTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +1 -0
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +11 -7
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.js.map +1 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +1 -0
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +3 -0
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.js.map +1 -1
- package/bin/executor/Executor.d.ts +43 -0
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +127 -7
- package/bin/executor/Executor.js.map +1 -1
- package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts +10 -0
- package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts +0 -10
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js +4 -34
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +1 -3
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +7 -59
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineContextCompaction.d.ts +38 -0
- package/bin/executor/core-engine/CoreEngineContextCompaction.d.ts.map +1 -0
- package/bin/executor/core-engine/CoreEngineContextCompaction.js +392 -0
- package/bin/executor/core-engine/CoreEngineContextCompaction.js.map +1 -0
- package/bin/executor/core-engine/CoreEngineMessageState.d.ts +15 -0
- package/bin/executor/core-engine/CoreEngineMessageState.d.ts.map +1 -1
- package/bin/executor/core-engine/CoreEngineMessageState.js +20 -0
- package/bin/executor/core-engine/CoreEngineMessageState.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.d.ts +15 -0
- package/bin/executor/core-engine/CoreEngineRunner.d.ts.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.js +150 -35
- package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
- package/bin/executor/store/history/SessionHistoryStore.d.ts +7 -23
- package/bin/executor/store/history/SessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +2 -4
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
- package/bin/executor/tools/plugin/PluginToolBridge.d.ts.map +1 -1
- package/bin/executor/tools/plugin/PluginToolBridge.js +4 -2
- package/bin/executor/tools/plugin/PluginToolBridge.js.map +1 -1
- package/bin/executor/types/SessionRun.d.ts +8 -0
- package/bin/executor/types/SessionRun.d.ts.map +1 -1
- package/bin/index.d.ts +3 -2
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +2 -2
- package/bin/index.js.map +1 -1
- package/bin/model/CityModelAdapter.d.ts +6 -0
- package/bin/model/CityModelAdapter.d.ts.map +1 -1
- package/bin/model/CityModelAdapter.js +13 -0
- package/bin/model/CityModelAdapter.js.map +1 -1
- package/bin/plugin/core/PluginLocalExecution.js +3 -3
- package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
- package/bin/plugin/core/PluginRegistry.d.ts +41 -2
- package/bin/plugin/core/PluginRegistry.d.ts.map +1 -1
- package/bin/plugin/core/PluginRegistry.js +145 -6
- package/bin/plugin/core/PluginRegistry.js.map +1 -1
- package/bin/rpc/Client.d.ts +4 -0
- package/bin/rpc/Client.d.ts.map +1 -1
- package/bin/rpc/Client.js +11 -0
- package/bin/rpc/Client.js.map +1 -1
- package/bin/session/Session.d.ts +15 -1
- package/bin/session/Session.d.ts.map +1 -1
- package/bin/session/Session.js +83 -11
- package/bin/session/Session.js.map +1 -1
- package/bin/session/SessionSystemBuilder.d.ts.map +1 -1
- package/bin/session/SessionSystemBuilder.js +3 -1
- package/bin/session/SessionSystemBuilder.js.map +1 -1
- package/bin/session/browse/Browse.d.ts +0 -8
- package/bin/session/browse/Browse.d.ts.map +1 -1
- package/bin/session/browse/Browse.js +72 -57
- package/bin/session/browse/Browse.js.map +1 -1
- package/bin/session/recorder/JsonlSessionMessageStore.d.ts +69 -16
- package/bin/session/recorder/JsonlSessionMessageStore.d.ts.map +1 -1
- package/bin/session/recorder/JsonlSessionMessageStore.js +283 -60
- package/bin/session/recorder/JsonlSessionMessageStore.js.map +1 -1
- package/bin/session/recorder/SessionRecorder.d.ts +20 -2
- package/bin/session/recorder/SessionRecorder.d.ts.map +1 -1
- package/bin/session/recorder/SessionRecorder.js +91 -46
- package/bin/session/recorder/SessionRecorder.js.map +1 -1
- package/bin/session/recorder/SessionRecorderCompaction.d.ts +3 -3
- package/bin/session/recorder/SessionRecorderCompaction.d.ts.map +1 -1
- package/bin/session/recorder/SessionRecorderCompaction.js +118 -88
- package/bin/session/recorder/SessionRecorderCompaction.js.map +1 -1
- package/bin/session/recorder/SessionRecorderHistoryStore.d.ts +2 -2
- package/bin/session/recorder/SessionRecorderHistoryStore.d.ts.map +1 -1
- package/bin/session/recorder/SessionRecorderHistoryStore.js +31 -36
- package/bin/session/recorder/SessionRecorderHistoryStore.js.map +1 -1
- package/bin/session/runtime/SessionPromptRuntime.d.ts +21 -1
- package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
- package/bin/session/runtime/SessionPromptRuntime.js +65 -8
- package/bin/session/runtime/SessionPromptRuntime.js.map +1 -1
- package/bin/session/services/SessionStateService.d.ts +19 -1
- package/bin/session/services/SessionStateService.d.ts.map +1 -1
- package/bin/session/services/SessionStateService.js +70 -40
- package/bin/session/services/SessionStateService.js.map +1 -1
- package/bin/session/services/SessionTurnService.d.ts +15 -0
- package/bin/session/services/SessionTurnService.d.ts.map +1 -1
- package/bin/session/services/SessionTurnService.js +104 -7
- package/bin/session/services/SessionTurnService.js.map +1 -1
- package/bin/session/services/SessionViewService.d.ts +1 -5
- package/bin/session/services/SessionViewService.d.ts.map +1 -1
- package/bin/session/services/SessionViewService.js +4 -34
- package/bin/session/services/SessionViewService.js.map +1 -1
- package/bin/session/storage/Paths.d.ts +3 -15
- package/bin/session/storage/Paths.d.ts.map +1 -1
- package/bin/session/storage/Paths.js +5 -21
- package/bin/session/storage/Paths.js.map +1 -1
- package/bin/types/agent/SessionActor.d.ts +8 -0
- package/bin/types/agent/SessionActor.d.ts.map +1 -1
- package/bin/types/agent/SessionTypes.d.ts +2 -24
- package/bin/types/agent/SessionTypes.d.ts.map +1 -1
- package/bin/types/executor/SessionRunContext.d.ts +29 -0
- package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
- package/bin/types/plugin/PluginRuntime.d.ts +59 -2
- package/bin/types/plugin/PluginRuntime.d.ts.map +1 -1
- package/bin/types/plugin/PluginState.d.ts +10 -0
- package/bin/types/plugin/PluginState.d.ts.map +1 -1
- package/bin/types/rpc/RpcProtocol.d.ts +10 -0
- package/bin/types/rpc/RpcProtocol.d.ts.map +1 -1
- package/bin/types/runtime/agent/AgentContext.d.ts +17 -5
- package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
- package/bin/types/runtime/agent/AgentContext.js +29 -6
- package/bin/types/runtime/agent/AgentContext.js.map +1 -1
- package/bin/types/session/SessionLocalState.d.ts +8 -0
- package/bin/types/session/SessionLocalState.d.ts.map +1 -1
- package/bin/types/session/SessionMessage.d.ts +16 -12
- package/bin/types/session/SessionMessage.d.ts.map +1 -1
- package/bin/types/session/SessionMutation.d.ts +1 -1
- package/bin/types/session/SessionMutation.js +1 -1
- package/bin/types/session/SessionOptions.d.ts +16 -0
- package/bin/types/session/SessionOptions.d.ts.map +1 -1
- package/bin/types/session/SessionQueueCommand.d.ts +68 -0
- package/bin/types/session/SessionQueueCommand.d.ts.map +1 -0
- package/bin/types/session/SessionQueueCommand.js +10 -0
- package/bin/types/session/SessionQueueCommand.js.map +1 -0
- package/bin/types/session/SessionSegment.d.ts +57 -0
- package/bin/types/session/SessionSegment.d.ts.map +1 -0
- package/bin/types/session/SessionSegment.js +8 -0
- package/bin/types/session/SessionSegment.js.map +1 -0
- package/bin/utils/logger/Logger.d.ts +7 -9
- package/bin/utils/logger/Logger.d.ts.map +1 -1
- package/bin/utils/logger/Logger.js +11 -9
- package/bin/utils/logger/Logger.js.map +1 -1
- package/package.json +3 -3
- package/scripts/city-model-tool-loop.test.mjs +32 -0
- package/scripts/core-engine-context-compaction.test.mjs +411 -0
- package/scripts/logger-isolation.test.mjs +55 -0
- package/scripts/multi-agent-plugin-isolation.test.mjs +289 -0
- package/scripts/plugin-tool-bridge.test.mjs +52 -0
- package/scripts/remote-session-reconnect.test.mjs +18 -0
- package/scripts/session-action-message.test.mjs +59 -13
- package/scripts/session-compaction-context-window.test.mjs +96 -0
- package/scripts/session-config-turn-boundary.test.mjs +278 -0
- package/scripts/session-list-title.test.mjs +21 -3
- package/scripts/session-prompt-runtime.test.mjs +93 -0
- package/scripts/session-recorder.test.mjs +335 -15
- package/src/agent/local/Agent.ts +34 -3
- package/src/agent/local/services/AgentSessions.ts +61 -0
- package/src/agent/remote/RemoteSession.ts +5 -0
- package/src/agent/remote/RemoteTransport.ts +2 -0
- package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +15 -5
- package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +4 -0
- package/src/executor/Executor.ts +161 -7
- package/src/executor/composer/compaction/SessionCompactionComposer.ts +12 -0
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.ts +4 -55
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +8 -66
- package/src/executor/core-engine/CoreEngineContextCompaction.ts +477 -0
- package/src/executor/core-engine/CoreEngineMessageState.ts +29 -0
- package/src/executor/core-engine/CoreEngineRunner.ts +211 -43
- package/src/executor/store/history/SessionHistoryStore.ts +7 -26
- package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +2 -4
- package/src/executor/tools/plugin/PluginToolBridge.ts +4 -2
- package/src/executor/types/SessionRun.ts +9 -0
- package/src/index.ts +9 -1
- package/src/model/CityModelAdapter.ts +15 -0
- package/src/plugin/core/PluginLocalExecution.ts +3 -3
- package/src/plugin/core/PluginRegistry.ts +187 -6
- package/src/rpc/Client.ts +12 -0
- package/src/session/Session.ts +97 -11
- package/src/session/SessionSystemBuilder.ts +4 -1
- package/src/session/browse/Browse.ts +73 -69
- package/src/session/recorder/JsonlSessionMessageStore.ts +378 -60
- package/src/session/recorder/SessionRecorder.ts +116 -49
- package/src/session/recorder/SessionRecorderCompaction.ts +131 -108
- package/src/session/recorder/SessionRecorderHistoryStore.ts +29 -49
- package/src/session/runtime/SessionPromptRuntime.ts +86 -10
- package/src/session/services/SessionStateService.ts +89 -45
- package/src/session/services/SessionTurnService.ts +112 -7
- package/src/session/services/SessionViewService.ts +4 -50
- package/src/session/storage/Paths.ts +5 -38
- package/src/types/agent/SessionActor.ts +9 -0
- package/src/types/agent/SessionTypes.ts +2 -24
- package/src/types/executor/SessionRunContext.ts +34 -0
- package/src/types/plugin/PluginRuntime.ts +63 -2
- package/src/types/plugin/PluginState.ts +10 -0
- package/src/types/rpc/RpcProtocol.ts +11 -0
- package/src/types/runtime/agent/AgentContext.ts +32 -7
- package/src/types/session/SessionLocalState.ts +9 -0
- package/src/types/session/SessionMessage.ts +16 -12
- package/src/types/session/SessionMutation.ts +1 -1
- package/src/types/session/SessionOptions.ts +21 -0
- package/src/types/session/SessionQueueCommand.ts +78 -0
- package/src/types/session/SessionSegment.ts +62 -0
- package/src/utils/logger/Logger.ts +10 -10
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -13,6 +13,8 @@ import type { Plugin } from "@/types/plugin/PluginDefinition.js";
|
|
|
13
13
|
import type { PluginActionResult } from "@/types/plugin/PluginAction.js";
|
|
14
14
|
import type {
|
|
15
15
|
AgentPlugins,
|
|
16
|
+
AgentPluginExecutionLease,
|
|
17
|
+
AgentPluginExecutionRuntime,
|
|
16
18
|
PluginAvailability,
|
|
17
19
|
PluginActionReadView,
|
|
18
20
|
PluginReadView,
|
|
@@ -45,6 +47,9 @@ function create_record(plugin: Plugin): PluginRuntimeRecord {
|
|
|
45
47
|
updated_at: current_time,
|
|
46
48
|
chain: Promise.resolve(),
|
|
47
49
|
lifecycle_started: false,
|
|
50
|
+
active_execution_leases: 0,
|
|
51
|
+
retired: false,
|
|
52
|
+
retirement_started: false,
|
|
48
53
|
};
|
|
49
54
|
}
|
|
50
55
|
|
|
@@ -101,6 +106,15 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
101
106
|
|
|
102
107
|
private readonly records = new Map<string, PluginRuntimeRecord>();
|
|
103
108
|
|
|
109
|
+
private readonly retired_records = new Set<PluginRuntimeRecord>();
|
|
110
|
+
|
|
111
|
+
private change_listener?: (input: {
|
|
112
|
+
/** 当前修改是注册还是卸载。 */
|
|
113
|
+
type: "register" | "unregister";
|
|
114
|
+
/** 当前修改的 plugin 名称。 */
|
|
115
|
+
plugin_name: string;
|
|
116
|
+
}) => void;
|
|
117
|
+
|
|
104
118
|
constructor(params: {
|
|
105
119
|
contextResolver: ContextResolver;
|
|
106
120
|
hookRegistry: HookRegistry;
|
|
@@ -111,6 +125,13 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
111
125
|
this.pluginInstances = params.pluginInstances;
|
|
112
126
|
}
|
|
113
127
|
|
|
128
|
+
/**
|
|
129
|
+
* 设置 Agent 内部配置修改监听器。
|
|
130
|
+
*/
|
|
131
|
+
set_change_listener(listener: PluginRegistry["change_listener"]): void {
|
|
132
|
+
this.change_listener = listener;
|
|
133
|
+
}
|
|
134
|
+
|
|
114
135
|
/**
|
|
115
136
|
* 注册单个 plugin。
|
|
116
137
|
*
|
|
@@ -134,6 +155,7 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
134
155
|
|
|
135
156
|
try {
|
|
136
157
|
await this.start_record(record);
|
|
158
|
+
this.change_listener?.({ type: "register", plugin_name: key });
|
|
137
159
|
return to_plugin_snapshot(record);
|
|
138
160
|
} catch (error) {
|
|
139
161
|
this.unregister_hooks(key);
|
|
@@ -167,7 +189,12 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
167
189
|
}
|
|
168
190
|
|
|
169
191
|
/**
|
|
170
|
-
* 卸载指定 plugin。
|
|
192
|
+
* 从 configured registry 卸载指定 plugin。
|
|
193
|
+
*
|
|
194
|
+
* 关键点(中文)
|
|
195
|
+
* - configured registry、hooks 与直接调用入口立即移除。
|
|
196
|
+
* - lifecycle.stop 等当前活跃 Session step 的 execution lease 全部释放后执行。
|
|
197
|
+
* - 该方法返回配置修改结果,不等待仍在运行的 step 结束。
|
|
171
198
|
*/
|
|
172
199
|
async unregister(pluginName: string): Promise<boolean> {
|
|
173
200
|
const key = normalize_plugin_name(pluginName);
|
|
@@ -175,10 +202,11 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
175
202
|
const record = this.records.get(key);
|
|
176
203
|
if (!record) return false;
|
|
177
204
|
|
|
178
|
-
await this.stop_record(record);
|
|
179
205
|
this.unregister_hooks(key);
|
|
180
206
|
this.records.delete(key);
|
|
181
207
|
this.pluginInstances.delete(key);
|
|
208
|
+
this.retire_record(record);
|
|
209
|
+
this.change_listener?.({ type: "unregister", plugin_name: key });
|
|
182
210
|
return true;
|
|
183
211
|
}
|
|
184
212
|
|
|
@@ -205,6 +233,10 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
205
233
|
for (const name of Array.from(this.records.keys())) {
|
|
206
234
|
await this.unregister(name);
|
|
207
235
|
}
|
|
236
|
+
const retirements = Array.from(this.retired_records)
|
|
237
|
+
.map((record) => record.retirement_promise)
|
|
238
|
+
.filter((promise): promise is Promise<void> => Boolean(promise));
|
|
239
|
+
await Promise.all(retirements);
|
|
208
240
|
}
|
|
209
241
|
|
|
210
242
|
/**
|
|
@@ -381,11 +413,25 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
381
413
|
plugin?: string;
|
|
382
414
|
action?: string;
|
|
383
415
|
}): PluginReadView | { plugins: PluginView[] } {
|
|
416
|
+
return this.read_from_records(this.records, params);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* 从指定记录视图读取 plugin/action metadata。
|
|
421
|
+
*/
|
|
422
|
+
private read_from_records(
|
|
423
|
+
records: ReadonlyMap<string, PluginRuntimeRecord>,
|
|
424
|
+
params: { plugin?: string; action?: string },
|
|
425
|
+
): PluginReadView | { plugins: PluginView[] } {
|
|
384
426
|
const pluginName = normalize_plugin_name(params.plugin || "");
|
|
385
427
|
if (!pluginName) {
|
|
386
|
-
return {
|
|
428
|
+
return {
|
|
429
|
+
plugins: Array.from(records.values())
|
|
430
|
+
.map((record) => toPluginView(record.plugin))
|
|
431
|
+
.sort((left, right) => left.name.localeCompare(right.name)),
|
|
432
|
+
};
|
|
387
433
|
}
|
|
388
|
-
const plugin =
|
|
434
|
+
const plugin = records.get(pluginName)?.plugin || null;
|
|
389
435
|
if (!plugin) {
|
|
390
436
|
return {
|
|
391
437
|
name: pluginName,
|
|
@@ -470,8 +516,22 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
470
516
|
action: string;
|
|
471
517
|
payload?: JsonValue;
|
|
472
518
|
}): Promise<PluginActionResult<JsonValue>> {
|
|
519
|
+
return await this.run_action_from_records(this.records, params);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* 从指定记录视图运行 plugin action。
|
|
524
|
+
*/
|
|
525
|
+
private async run_action_from_records(
|
|
526
|
+
records: ReadonlyMap<string, PluginRuntimeRecord>,
|
|
527
|
+
params: {
|
|
528
|
+
plugin: string;
|
|
529
|
+
action: string;
|
|
530
|
+
payload?: JsonValue;
|
|
531
|
+
},
|
|
532
|
+
): Promise<PluginActionResult<JsonValue>> {
|
|
473
533
|
const key = normalize_plugin_name(params.plugin);
|
|
474
|
-
const record =
|
|
534
|
+
const record = records.get(key);
|
|
475
535
|
if (!record) {
|
|
476
536
|
return {
|
|
477
537
|
success: false,
|
|
@@ -536,9 +596,18 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
536
596
|
* 读取当前生效的 plugin system blocks。
|
|
537
597
|
*/
|
|
538
598
|
async systemBlocks(): Promise<AgentSessionSystemBlock[]> {
|
|
599
|
+
return await this.system_blocks_from_records(this.records);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* 从指定记录视图解析 plugin system blocks。
|
|
604
|
+
*/
|
|
605
|
+
private async system_blocks_from_records(
|
|
606
|
+
records: ReadonlyMap<string, PluginRuntimeRecord>,
|
|
607
|
+
): Promise<AgentSessionSystemBlock[]> {
|
|
539
608
|
const context = this.contextResolver();
|
|
540
609
|
const out: AgentSessionSystemBlock[] = [];
|
|
541
|
-
for (const record of
|
|
610
|
+
for (const record of records.values()) {
|
|
542
611
|
const plugin = record.plugin;
|
|
543
612
|
if (record.state !== "ready") continue;
|
|
544
613
|
if (typeof plugin.system !== "function") continue;
|
|
@@ -560,4 +629,116 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
560
629
|
}
|
|
561
630
|
return out;
|
|
562
631
|
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* 创建当前 configured registry 的 Session step 执行视图。
|
|
635
|
+
*/
|
|
636
|
+
execution_view(): AgentPluginExecutionRuntime {
|
|
637
|
+
const records = new Map(this.records);
|
|
638
|
+
return {
|
|
639
|
+
read: (params) => this.read_from_records(records, params),
|
|
640
|
+
runAction: async (params) =>
|
|
641
|
+
await this.run_action_from_records(records, params),
|
|
642
|
+
systemBlocks: async () =>
|
|
643
|
+
await this.system_blocks_from_records(records),
|
|
644
|
+
acquire: () => this.acquire_execution_view(records),
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* 为单次 Session step 获取 Plugin execution lease。
|
|
650
|
+
*/
|
|
651
|
+
private acquire_execution_view(
|
|
652
|
+
records: ReadonlyMap<string, PluginRuntimeRecord>,
|
|
653
|
+
): AgentPluginExecutionLease {
|
|
654
|
+
const leased_records = new Map<string, PluginRuntimeRecord>();
|
|
655
|
+
for (const [name, record] of records) {
|
|
656
|
+
if (
|
|
657
|
+
record.retired ||
|
|
658
|
+
record.state !== "ready" ||
|
|
659
|
+
!record.lifecycle_started
|
|
660
|
+
) {
|
|
661
|
+
continue;
|
|
662
|
+
}
|
|
663
|
+
record.active_execution_leases += 1;
|
|
664
|
+
leased_records.set(name, record);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
let released = false;
|
|
668
|
+
return {
|
|
669
|
+
read: (params) => this.read_from_records(leased_records, params),
|
|
670
|
+
runAction: async (params) =>
|
|
671
|
+
await this.run_action_from_records(leased_records, params),
|
|
672
|
+
systemBlocks: async () =>
|
|
673
|
+
await this.system_blocks_from_records(leased_records),
|
|
674
|
+
release: async () => {
|
|
675
|
+
if (released) return;
|
|
676
|
+
released = true;
|
|
677
|
+
const retirements: Promise<void>[] = [];
|
|
678
|
+
for (const record of leased_records.values()) {
|
|
679
|
+
record.active_execution_leases = Math.max(
|
|
680
|
+
0,
|
|
681
|
+
record.active_execution_leases - 1,
|
|
682
|
+
);
|
|
683
|
+
this.try_finalize_retired_record(record);
|
|
684
|
+
if (record.retired && record.retirement_promise) {
|
|
685
|
+
retirements.push(record.retirement_promise);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
await Promise.all(retirements);
|
|
689
|
+
},
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* 把已移出 configured registry 的 Plugin 标记为等待释放。
|
|
695
|
+
*/
|
|
696
|
+
private retire_record(record: PluginRuntimeRecord): void {
|
|
697
|
+
if (record.retired) return;
|
|
698
|
+
record.retired = true;
|
|
699
|
+
let resolve_retirement!: () => void;
|
|
700
|
+
record.retirement_promise = new Promise<void>((resolve) => {
|
|
701
|
+
resolve_retirement = resolve;
|
|
702
|
+
});
|
|
703
|
+
record.resolve_retirement = resolve_retirement;
|
|
704
|
+
this.retired_records.add(record);
|
|
705
|
+
this.try_finalize_retired_record(record);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* 在最后一个 execution lease 释放后停止退休 Plugin。
|
|
710
|
+
*/
|
|
711
|
+
private try_finalize_retired_record(record: PluginRuntimeRecord): void {
|
|
712
|
+
if (
|
|
713
|
+
!record.retired ||
|
|
714
|
+
record.retirement_started ||
|
|
715
|
+
record.active_execution_leases > 0
|
|
716
|
+
) {
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
record.retirement_started = true;
|
|
720
|
+
void (async () => {
|
|
721
|
+
try {
|
|
722
|
+
await this.stop_record(record);
|
|
723
|
+
} catch (error) {
|
|
724
|
+
update_record_state(record, "error", String(error));
|
|
725
|
+
try {
|
|
726
|
+
await this.contextResolver().logger.log(
|
|
727
|
+
"error",
|
|
728
|
+
"[plugin] lifecycle.stop failed after execution release",
|
|
729
|
+
{
|
|
730
|
+
plugin: record.plugin.name,
|
|
731
|
+
error: String(error),
|
|
732
|
+
},
|
|
733
|
+
);
|
|
734
|
+
} catch {
|
|
735
|
+
// 退休清理不能因日志失败再次中断。
|
|
736
|
+
}
|
|
737
|
+
} finally {
|
|
738
|
+
this.retired_records.delete(record);
|
|
739
|
+
record.resolve_retirement?.();
|
|
740
|
+
delete record.resolve_retirement;
|
|
741
|
+
}
|
|
742
|
+
})();
|
|
743
|
+
}
|
|
563
744
|
}
|
package/src/rpc/Client.ts
CHANGED
|
@@ -217,6 +217,18 @@ export class RpcClient {
|
|
|
217
217
|
return data.result;
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
+
/**
|
|
221
|
+
* 把一次显式历史压缩加入远程 Session 的有序输入队列。
|
|
222
|
+
*/
|
|
223
|
+
async compact_session(session_id: string): Promise<void> {
|
|
224
|
+
await this.request<{ queued: true }>({
|
|
225
|
+
method: "sdk.sessions.compact",
|
|
226
|
+
params: {
|
|
227
|
+
sessionId: session_id,
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
220
232
|
/**
|
|
221
233
|
* 读取 session records。
|
|
222
234
|
*/
|
package/src/session/Session.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - 面向 `new Agent(...)` 的本地会话使用场景。
|
|
6
6
|
* - 对外保留稳定 Session facade,把状态、turn、view 逻辑下沉到独立 service。
|
|
7
|
-
* -
|
|
7
|
+
* - 内部使用 `SessionRecorder` 统一管理 Active、Segment 与流式 Assistant 草稿。
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Executor } from "@executor/Executor.js";
|
|
@@ -55,6 +55,7 @@ import { SessionStateService } from "@/session/services/SessionStateService.js";
|
|
|
55
55
|
import { SessionTurnService } from "@/session/services/SessionTurnService.js";
|
|
56
56
|
import { SessionViewService } from "@/session/services/SessionViewService.js";
|
|
57
57
|
import type { SessionLocalState } from "@/types/session/SessionLocalState.js";
|
|
58
|
+
import type { AgentSessionCommand } from "@/types/session/SessionQueueCommand.js";
|
|
58
59
|
import type {
|
|
59
60
|
SessionComposerFactoryContext,
|
|
60
61
|
SessionComposerInput,
|
|
@@ -65,6 +66,7 @@ import type { SessionContextComposer } from "@/executor/composer/context/Session
|
|
|
65
66
|
import type { SessionHistoryComposer } from "@/executor/composer/history/SessionHistoryComposer.js";
|
|
66
67
|
import type { SessionSystemComposer } from "@/executor/composer/system/SessionSystemComposer.js";
|
|
67
68
|
import type { SessionOptions } from "@/types/session/SessionOptions.js";
|
|
69
|
+
import type { AgentPluginExecutionRuntime } from "@/types/plugin/PluginRuntime.js";
|
|
68
70
|
|
|
69
71
|
/**
|
|
70
72
|
* SDK 本地 Session。
|
|
@@ -92,6 +94,11 @@ export class Session implements AgentSession {
|
|
|
92
94
|
private readonly set_approval_mode_hook: SessionOptions["set_approval_mode"];
|
|
93
95
|
private readonly resolve_approval_hook: SessionOptions["resolve_approval"];
|
|
94
96
|
private readonly localState: SessionLocalState;
|
|
97
|
+
private readonly getAgentEnv: SessionOptions["getAgentEnv"];
|
|
98
|
+
private readonly get_agent_plugins: SessionOptions["get_agent_plugins"];
|
|
99
|
+
private effective_instruction_system_blocks: AgentSessionSystemBlock[];
|
|
100
|
+
private effective_agent_env: Record<string, string>;
|
|
101
|
+
private effective_agent_plugins: AgentPluginExecutionRuntime;
|
|
95
102
|
private readonly stateService: SessionStateService;
|
|
96
103
|
private readonly turnService: SessionTurnService;
|
|
97
104
|
private readonly viewService: SessionViewService<this>;
|
|
@@ -104,6 +111,13 @@ export class Session implements AgentSession {
|
|
|
104
111
|
this.tools = options.tools;
|
|
105
112
|
this.logger = options.logger;
|
|
106
113
|
this.getInstructionSystemBlocks = options.getInstructionSystemBlocks;
|
|
114
|
+
this.getAgentEnv = options.getAgentEnv;
|
|
115
|
+
this.get_agent_plugins = options.get_agent_plugins;
|
|
116
|
+
this.effective_instruction_system_blocks = options
|
|
117
|
+
.getInstructionSystemBlocks()
|
|
118
|
+
.map((block) => ({ ...block }));
|
|
119
|
+
this.effective_agent_env = { ...options.getAgentEnv() };
|
|
120
|
+
this.effective_agent_plugins = options.get_agent_plugins();
|
|
107
121
|
this.getManagedPluginSystemBlocks = options.getManagedPluginSystemBlocks;
|
|
108
122
|
this.getPluginSystemBlocks = options.getPluginSystemBlocks;
|
|
109
123
|
this.ensureConfiguredHook = options.ensureConfigured;
|
|
@@ -187,9 +201,11 @@ export class Session implements AgentSession {
|
|
|
187
201
|
state_service: this.stateService,
|
|
188
202
|
logger: this.logger,
|
|
189
203
|
is_executing: () => this.isExecuting(),
|
|
190
|
-
get_instruction_system_blocks:
|
|
204
|
+
get_instruction_system_blocks: () =>
|
|
205
|
+
this.effective_instruction_system_blocks.map((block) => ({ ...block })),
|
|
191
206
|
get_managed_plugin_system_blocks: this.getManagedPluginSystemBlocks,
|
|
192
|
-
get_plugin_system_blocks:
|
|
207
|
+
get_plugin_system_blocks: async () =>
|
|
208
|
+
await this.effective_agent_plugins.systemBlocks(),
|
|
193
209
|
...(this.composers?.systemComposer
|
|
194
210
|
? { custom_system_composer: system_composer }
|
|
195
211
|
: {}),
|
|
@@ -226,7 +242,10 @@ export class Session implements AgentSession {
|
|
|
226
242
|
* 写入当前 session 默认配置。
|
|
227
243
|
*/
|
|
228
244
|
async set(input: AgentSessionSetInput): Promise<void> {
|
|
229
|
-
await this.stateService.set(input);
|
|
245
|
+
const configured = await this.stateService.set(input);
|
|
246
|
+
if (configured.command) {
|
|
247
|
+
this.turnService.enqueue_command(configured.command);
|
|
248
|
+
}
|
|
230
249
|
}
|
|
231
250
|
|
|
232
251
|
/**
|
|
@@ -243,6 +262,55 @@ export class Session implements AgentSession {
|
|
|
243
262
|
return await this.turnService.stop();
|
|
244
263
|
}
|
|
245
264
|
|
|
265
|
+
/**
|
|
266
|
+
* 把一次显式历史压缩加入当前 Session 的有序输入队列。
|
|
267
|
+
*/
|
|
268
|
+
async compact(): Promise<void> {
|
|
269
|
+
await this.turnService.compact();
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* 把 Agent configured state command 加入当前 Session 的统一输入队列。
|
|
274
|
+
*/
|
|
275
|
+
enqueue_agent_command(command: AgentSessionCommand): void {
|
|
276
|
+
this.turnService.enqueue_command({
|
|
277
|
+
type: "command",
|
|
278
|
+
command_id: command.command_id,
|
|
279
|
+
scope: "agent",
|
|
280
|
+
execute: async ({ turn_id }) => {
|
|
281
|
+
if (command.type === "instruction") {
|
|
282
|
+
this.effective_instruction_system_blocks = command
|
|
283
|
+
.instruction_blocks
|
|
284
|
+
.map((block) => ({ ...block }));
|
|
285
|
+
await this.stateService.emit_config_action_event({
|
|
286
|
+
id: `agent-instruction:${this.id}:${command.command_id}`,
|
|
287
|
+
title: "Agent instruction updated",
|
|
288
|
+
state: "completed",
|
|
289
|
+
turnId: turn_id,
|
|
290
|
+
});
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (command.type === "env") {
|
|
294
|
+
this.effective_agent_env = { ...command.env };
|
|
295
|
+
await this.stateService.emit_config_action_event({
|
|
296
|
+
id: `agent-env:${this.id}:${command.command_id}`,
|
|
297
|
+
title: "Agent environment updated",
|
|
298
|
+
state: "completed",
|
|
299
|
+
turnId: turn_id,
|
|
300
|
+
});
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
this.effective_agent_plugins = command.plugins;
|
|
304
|
+
await this.stateService.emit_config_action_event({
|
|
305
|
+
id: `agent-plugins:${this.id}:${command.command_id}`,
|
|
306
|
+
title: command.title,
|
|
307
|
+
state: "completed",
|
|
308
|
+
turnId: turn_id,
|
|
309
|
+
});
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
246
314
|
/**
|
|
247
315
|
* 订阅当前 Session 的未来事件。
|
|
248
316
|
*/
|
|
@@ -388,8 +456,11 @@ export class Session implements AgentSession {
|
|
|
388
456
|
tools: this.tools,
|
|
389
457
|
logger: this.logger,
|
|
390
458
|
getInstructionSystemBlocks: this.getInstructionSystemBlocks,
|
|
459
|
+
getAgentEnv: this.getAgentEnv,
|
|
460
|
+
get_agent_plugins: this.get_agent_plugins,
|
|
391
461
|
getManagedPluginSystemBlocks: this.getManagedPluginSystemBlocks,
|
|
392
|
-
getPluginSystemBlocks:
|
|
462
|
+
getPluginSystemBlocks: async () =>
|
|
463
|
+
await this.effective_agent_plugins.systemBlocks(),
|
|
393
464
|
ensureConfigured: this.ensureConfiguredHook,
|
|
394
465
|
composers: this.composers,
|
|
395
466
|
list_approvals: this.list_approvals,
|
|
@@ -422,7 +493,7 @@ export class Session implements AgentSession {
|
|
|
422
493
|
const messages_dir_path = `${session_dir_path}/messages`;
|
|
423
494
|
return new JsonlSessionMessageStore({
|
|
424
495
|
session_id: this.id,
|
|
425
|
-
file_path: `${messages_dir_path}/
|
|
496
|
+
file_path: `${messages_dir_path}/active.jsonl`,
|
|
426
497
|
assistant_message_file_path: getSdkAgentSessionAssistantMessagePath(
|
|
427
498
|
this.projectRoot,
|
|
428
499
|
this.agentId,
|
|
@@ -441,6 +512,7 @@ export class Session implements AgentSession {
|
|
|
441
512
|
private create_local_state(): SessionLocalState {
|
|
442
513
|
return {
|
|
443
514
|
sessionConfig: {},
|
|
515
|
+
effective_session_config: {},
|
|
444
516
|
createdAt: Date.now(),
|
|
445
517
|
timezone: resolveSystemTimezone(),
|
|
446
518
|
initializePromise: null,
|
|
@@ -455,9 +527,11 @@ export class Session implements AgentSession {
|
|
|
455
527
|
sessionId: this.id,
|
|
456
528
|
historyStore: this.historyStore,
|
|
457
529
|
getTools: () => this.tools,
|
|
458
|
-
getInstructionSystemBlocks:
|
|
530
|
+
getInstructionSystemBlocks: () =>
|
|
531
|
+
this.effective_instruction_system_blocks.map((block) => ({ ...block })),
|
|
459
532
|
getManagedPluginSystemBlocks: this.getManagedPluginSystemBlocks,
|
|
460
|
-
getPluginSystemBlocks:
|
|
533
|
+
getPluginSystemBlocks: async () =>
|
|
534
|
+
await this.effective_agent_plugins.systemBlocks(),
|
|
461
535
|
getSessionCreatedAt: () => this.localState.createdAt,
|
|
462
536
|
getSessionTimezone: () => this.localState.timezone,
|
|
463
537
|
};
|
|
@@ -482,9 +556,11 @@ export class Session implements AgentSession {
|
|
|
482
556
|
projectRoot: this.projectRoot,
|
|
483
557
|
getSessionCreatedAt: () => this.localState.createdAt,
|
|
484
558
|
getSessionTimezone: () => this.localState.timezone,
|
|
485
|
-
getInstructionSystemBlocks:
|
|
559
|
+
getInstructionSystemBlocks: () =>
|
|
560
|
+
this.effective_instruction_system_blocks.map((block) => ({ ...block })),
|
|
486
561
|
getManagedPluginSystemBlocks: this.getManagedPluginSystemBlocks,
|
|
487
|
-
getPluginSystemBlocks:
|
|
562
|
+
getPluginSystemBlocks: async () =>
|
|
563
|
+
await this.effective_agent_plugins.systemBlocks(),
|
|
488
564
|
}),
|
|
489
565
|
);
|
|
490
566
|
}
|
|
@@ -516,10 +592,20 @@ export class Session implements AgentSession {
|
|
|
516
592
|
sessionId: this.id,
|
|
517
593
|
historyStore: this.historyStore,
|
|
518
594
|
historyComposer: this.historyComposer,
|
|
519
|
-
getModel: () =>
|
|
595
|
+
getModel: () =>
|
|
596
|
+
this.localState.effective_session_config.model ||
|
|
597
|
+
this.localState.sessionConfig.model,
|
|
598
|
+
get_model_context_window: () =>
|
|
599
|
+
this.localState.effective_session_config.model
|
|
600
|
+
? this.localState.effective_session_config.model_context_window
|
|
601
|
+
: this.localState.sessionConfig.model_context_window,
|
|
520
602
|
logger: this.logger,
|
|
521
603
|
systemComposer: system_composer,
|
|
522
604
|
getTools: () => this.tools,
|
|
605
|
+
getEnv: () => ({ ...this.effective_agent_env }),
|
|
606
|
+
get_systems: () =>
|
|
607
|
+
this.effective_instruction_system_blocks.map((block) => block.content),
|
|
608
|
+
get_plugins: () => this.effective_agent_plugins,
|
|
523
609
|
...(context_composer ? { contextComposer: context_composer } : {}),
|
|
524
610
|
...(compaction_composer
|
|
525
611
|
? { compactionComposer: compaction_composer }
|
|
@@ -253,7 +253,10 @@ export class SessionSystemBuilder implements SessionSystemComposer {
|
|
|
253
253
|
timezone: this.getSessionTimezone(),
|
|
254
254
|
getInstructionSystemBlocks: this.getInstructionSystemBlocks,
|
|
255
255
|
getManagedPluginSystemBlocks: this.getManagedPluginSystemBlocks,
|
|
256
|
-
getPluginSystemBlocks:
|
|
256
|
+
getPluginSystemBlocks: async () =>
|
|
257
|
+
run_context.agentPlugins
|
|
258
|
+
? await run_context.agentPlugins.systemBlocks()
|
|
259
|
+
: await this.getPluginSystemBlocks(),
|
|
257
260
|
});
|
|
258
261
|
}
|
|
259
262
|
}
|