@downcity/agent 1.1.135 → 1.1.149
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 +2 -2
- package/bin/agent/local/Agent.d.ts +3 -21
- package/bin/agent/local/Agent.d.ts.map +1 -1
- package/bin/agent/local/Agent.js +3 -30
- package/bin/agent/local/Agent.js.map +1 -1
- package/bin/agent/local/ProjectSetup.js +2 -2
- package/bin/agent/local/ProjectSetup.js.map +1 -1
- package/bin/agent/local/services/AgentAssemblyService.d.ts +1 -6
- package/bin/agent/local/services/AgentAssemblyService.d.ts.map +1 -1
- package/bin/agent/local/services/AgentAssemblyService.js +13 -20
- package/bin/agent/local/services/AgentAssemblyService.js.map +1 -1
- package/bin/agent/local/services/AgentSessionManager.d.ts +16 -7
- package/bin/agent/local/services/AgentSessionManager.d.ts.map +1 -1
- package/bin/agent/local/services/AgentSessionManager.js +83 -8
- package/bin/agent/local/services/AgentSessionManager.js.map +1 -1
- package/bin/agent/remote/RemoteAgent.d.ts +9 -13
- package/bin/agent/remote/RemoteAgent.d.ts.map +1 -1
- package/bin/agent/remote/RemoteAgent.js +23 -24
- package/bin/agent/remote/RemoteAgent.js.map +1 -1
- package/bin/agent/remote/RemoteSession.d.ts +11 -4
- package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
- package/bin/agent/remote/RemoteSession.js +15 -3
- package/bin/agent/remote/RemoteSession.js.map +1 -1
- package/bin/agent/remote/RemoteTransport.d.ts +9 -1
- package/bin/agent/remote/RemoteTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +7 -3
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +65 -2
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.js.map +1 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +5 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +12 -0
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.js.map +1 -1
- package/bin/config/AgentInitializer.d.ts +2 -2
- package/bin/config/AgentInitializer.js +2 -2
- package/bin/executor/Executor.d.ts +5 -0
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +34 -0
- package/bin/executor/Executor.js.map +1 -1
- package/bin/executor/composer/system/default/InitPrompts.d.ts +1 -1
- package/bin/executor/composer/system/default/InitPrompts.js +1 -1
- package/bin/executor/composer/system/default/SystemDomain.js +2 -2
- package/bin/executor/composer/system/default/SystemDomain.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.d.ts.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.js +16 -0
- package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
- package/bin/executor/messages/ChatMessageMarkupTypes.d.ts +1 -1
- package/bin/executor/messages/ChatMessageMarkupTypes.js +1 -1
- package/bin/executor/types/SessionExecutor.d.ts +8 -0
- package/bin/executor/types/SessionExecutor.d.ts.map +1 -1
- package/bin/index.d.ts +2 -2
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js.map +1 -1
- package/bin/plugin/core/Activation.d.ts +0 -2
- package/bin/plugin/core/Activation.d.ts.map +1 -1
- package/bin/plugin/core/Activation.js +1 -1
- package/bin/plugin/core/Activation.js.map +1 -1
- package/bin/plugin/core/PluginCommandRequest.d.ts +1 -1
- package/bin/plugin/core/PluginCommandRequest.js +1 -1
- package/bin/plugin/core/PluginStateController.d.ts +0 -5
- package/bin/plugin/core/PluginStateController.d.ts.map +1 -1
- package/bin/plugin/core/PluginStateController.js +1 -5
- package/bin/plugin/core/PluginStateController.js.map +1 -1
- package/bin/plugin/types/PluginApi.d.ts +1 -1
- package/bin/plugin/types/PluginApi.js +1 -1
- package/bin/rpc/Client.d.ts +17 -1
- package/bin/rpc/Client.d.ts.map +1 -1
- package/bin/rpc/Client.js +47 -0
- package/bin/rpc/Client.js.map +1 -1
- package/bin/session/Session.d.ts +5 -0
- package/bin/session/Session.d.ts.map +1 -1
- package/bin/session/Session.js +7 -0
- package/bin/session/Session.js.map +1 -1
- package/bin/session/browse/Browse.d.ts +9 -1
- package/bin/session/browse/Browse.d.ts.map +1 -1
- package/bin/session/browse/Browse.js +81 -3
- package/bin/session/browse/Browse.js.map +1 -1
- package/bin/session/index.d.ts +3 -3
- package/bin/session/index.d.ts.map +1 -1
- package/bin/session/index.js +3 -3
- package/bin/session/index.js.map +1 -1
- package/bin/session/runtime/SessionPromptRuntime.d.ts +13 -0
- package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
- package/bin/session/runtime/SessionPromptRuntime.js +82 -5
- package/bin/session/runtime/SessionPromptRuntime.js.map +1 -1
- package/bin/session/services/SessionTurnService.d.ts +5 -0
- package/bin/session/services/SessionTurnService.d.ts.map +1 -1
- package/bin/session/services/SessionTurnService.js +10 -1
- package/bin/session/services/SessionTurnService.js.map +1 -1
- package/bin/session/storage/Metadata.d.ts +15 -0
- package/bin/session/storage/Metadata.d.ts.map +1 -1
- package/bin/session/storage/Metadata.js +15 -1
- package/bin/session/storage/Metadata.js.map +1 -1
- package/bin/session/storage/Paths.d.ts +24 -0
- package/bin/session/storage/Paths.d.ts.map +1 -1
- package/bin/session/storage/Paths.js +34 -0
- package/bin/session/storage/Paths.js.map +1 -1
- package/bin/session/storage/RuntimeSessionPort.d.ts +5 -0
- package/bin/session/storage/RuntimeSessionPort.d.ts.map +1 -1
- package/bin/session/storage/RuntimeSessionPort.js +4 -0
- package/bin/session/storage/RuntimeSessionPort.js.map +1 -1
- package/bin/types/agent/AgentTypes.d.ts +2 -1
- package/bin/types/agent/AgentTypes.d.ts.map +1 -1
- package/bin/types/agent/SessionActor.d.ts +13 -4
- package/bin/types/agent/SessionActor.d.ts.map +1 -1
- package/bin/types/agent/SessionTypes.d.ts +62 -0
- package/bin/types/agent/SessionTypes.d.ts.map +1 -1
- package/bin/types/config/DowncityConfig.d.ts +1 -1
- package/bin/types/executor/SessionRunContext.d.ts +8 -0
- package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
- package/bin/types/platform/Store.d.ts +2 -2
- package/bin/types/platform/Store.js +2 -2
- package/bin/types/rpc/RpcProtocol.d.ts +37 -5
- package/bin/types/rpc/RpcProtocol.d.ts.map +1 -1
- package/bin/types/rpc/RpcProtocol.js +1 -1
- package/bin/types/runtime/agent/AgentContext.d.ts +36 -11
- package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
- package/bin/types/runtime/agent/AgentContext.js +26 -8
- package/bin/types/runtime/agent/AgentContext.js.map +1 -1
- package/bin/types/runtime/platform/Platform.d.ts +8 -8
- package/bin/types/runtime/platform/PlatformGateway.d.ts +2 -2
- package/bin/types/sdk/AgentSessionStop.d.ts +36 -0
- package/bin/types/sdk/AgentSessionStop.d.ts.map +1 -0
- package/bin/types/sdk/AgentSessionStop.js +9 -0
- package/bin/types/sdk/AgentSessionStop.js.map +1 -0
- package/package.json +3 -3
- package/scripts/city-model-tool-loop.test.mjs +2 -2
- package/scripts/session-prompt-runtime.test.mjs +59 -0
- package/src/agent/local/Agent.ts +3 -41
- package/src/agent/local/ProjectSetup.ts +2 -2
- package/src/agent/local/services/AgentAssemblyService.ts +17 -28
- package/src/agent/local/services/AgentSessionManager.ts +127 -13
- package/src/agent/remote/RemoteAgent.ts +25 -34
- package/src/agent/remote/RemoteSession.ts +21 -6
- package/src/agent/remote/RemoteTransport.ts +14 -0
- package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +100 -2
- package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +26 -0
- package/src/config/AgentInitializer.ts +2 -2
- package/src/executor/Executor.ts +33 -0
- package/src/executor/composer/system/default/InitPrompts.ts +1 -1
- package/src/executor/composer/system/default/SystemDomain.ts +2 -2
- package/src/executor/core-engine/CoreEngineRunner.ts +21 -0
- package/src/executor/messages/ChatMessageMarkupTypes.ts +1 -1
- package/src/executor/types/SessionExecutor.ts +2 -1
- package/src/index.ts +6 -1
- package/src/plugin/core/Activation.ts +1 -3
- package/src/plugin/core/PluginCommandRequest.ts +1 -1
- package/src/plugin/core/PluginStateController.ts +1 -10
- package/src/plugin/types/PluginApi.ts +1 -1
- package/src/rpc/Client.ts +61 -0
- package/src/session/Session.ts +9 -0
- package/src/session/browse/Browse.ts +103 -3
- package/src/session/index.ts +7 -0
- package/src/session/runtime/SessionPromptRuntime.ts +100 -5
- package/src/session/services/SessionTurnService.ts +13 -1
- package/src/session/storage/Metadata.ts +23 -1
- package/src/session/storage/Paths.ts +70 -0
- package/src/session/storage/RuntimeSessionPort.ts +9 -0
- package/src/types/agent/AgentTypes.ts +6 -0
- package/src/types/agent/SessionActor.ts +21 -3
- package/src/types/agent/SessionTypes.ts +68 -0
- package/src/types/config/DowncityConfig.ts +1 -1
- package/src/types/executor/SessionRunContext.ts +9 -0
- package/src/types/platform/Store.ts +2 -2
- package/src/types/rpc/RpcProtocol.ts +46 -4
- package/src/types/runtime/agent/AgentContext.ts +41 -14
- package/src/types/runtime/platform/Platform.ts +8 -8
- package/src/types/runtime/platform/PlatformGateway.ts +2 -2
- package/src/types/sdk/AgentSessionStop.ts +39 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/bin/agent/local/AgentRuntimeFactory.d.ts +0 -47
- package/bin/agent/local/AgentRuntimeFactory.d.ts.map +0 -1
- package/bin/agent/local/AgentRuntimeFactory.js +0 -34
- package/bin/agent/local/AgentRuntimeFactory.js.map +0 -1
- package/bin/types/runtime/agent/AgentRuntime.d.ts +0 -79
- package/bin/types/runtime/agent/AgentRuntime.d.ts.map +0 -1
- package/bin/types/runtime/agent/AgentRuntime.js +0 -13
- package/bin/types/runtime/agent/AgentRuntime.js.map +0 -1
- package/src/agent/local/AgentRuntimeFactory.ts +0 -78
- package/src/types/runtime/agent/AgentRuntime.ts +0 -84
|
@@ -9,12 +9,18 @@
|
|
|
9
9
|
import type {
|
|
10
10
|
AgentCreateSessionInput,
|
|
11
11
|
AgentListSessionsInput,
|
|
12
|
+
AgentArchiveSessionInput,
|
|
13
|
+
AgentArchiveSessionsInput,
|
|
14
|
+
AgentArchiveSessionResult,
|
|
15
|
+
AgentArchiveSessionsResult,
|
|
16
|
+
AgentCleanArchiveResult,
|
|
12
17
|
AgentSessionForkInput,
|
|
13
18
|
AgentSessionHistoryInput,
|
|
14
19
|
AgentSessionHistoryPage,
|
|
15
20
|
AgentSessionInfo,
|
|
16
21
|
AgentSessionSummaryPage,
|
|
17
22
|
AgentSessionSystemSnapshot,
|
|
23
|
+
AgentSessionStopResult,
|
|
18
24
|
RemoteAgentPluginActionInput,
|
|
19
25
|
RemoteAgentPluginActionResult,
|
|
20
26
|
} from "@/types/agent/AgentTypes.js";
|
|
@@ -48,6 +54,8 @@ export type RemoteSessionTransport = {
|
|
|
48
54
|
session_id: string,
|
|
49
55
|
input: AgentSessionPromptInput,
|
|
50
56
|
): Promise<{ id: string }>;
|
|
57
|
+
/** 停止当前 session turn,并取消未吸收队列。 */
|
|
58
|
+
stop(session_id: string): Promise<AgentSessionStopResult>;
|
|
51
59
|
/** 订阅 session 事件。 */
|
|
52
60
|
subscribe(params: {
|
|
53
61
|
session_id: string;
|
|
@@ -76,6 +84,12 @@ export type RemoteAgentTransport = RemoteSessionTransport & {
|
|
|
76
84
|
create_session(input?: AgentCreateSessionInput): Promise<AgentSessionInfo>;
|
|
77
85
|
/** 列出 sessions。 */
|
|
78
86
|
list_sessions(input?: AgentListSessionsInput): Promise<AgentSessionSummaryPage>;
|
|
87
|
+
/** 归档 session。 */
|
|
88
|
+
archive_session(input: AgentArchiveSessionInput): Promise<AgentArchiveSessionResult>;
|
|
89
|
+
/** 列出已归档 sessions。 */
|
|
90
|
+
archive_sessions(input?: AgentArchiveSessionsInput): Promise<AgentArchiveSessionsResult>;
|
|
91
|
+
/** 清空归档 sessions。 */
|
|
92
|
+
clean_archive(): Promise<AgentCleanArchiveResult>;
|
|
79
93
|
/** 执行远程 Agent runtime 内的 plugin action。 */
|
|
80
94
|
run_plugin_action(
|
|
81
95
|
input: RemoteAgentPluginActionInput,
|
|
@@ -2,19 +2,25 @@
|
|
|
2
2
|
* RemoteAgent HTTP transport。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* - 只适配
|
|
5
|
+
* - 只适配 downcity Agent HTTP gateway 的 SDK routes。
|
|
6
6
|
* - 不处理 RemoteSession 的 turn lifecycle,避免 transport 与 actor 逻辑混在一起。
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type {
|
|
10
10
|
AgentCreateSessionInput,
|
|
11
11
|
AgentListSessionsInput,
|
|
12
|
+
AgentArchiveSessionInput,
|
|
13
|
+
AgentArchiveSessionsInput,
|
|
14
|
+
AgentArchiveSessionResult,
|
|
15
|
+
AgentArchiveSessionsResult,
|
|
16
|
+
AgentCleanArchiveResult,
|
|
12
17
|
AgentSessionForkInput,
|
|
13
18
|
AgentSessionHistoryInput,
|
|
14
19
|
AgentSessionHistoryPage,
|
|
15
20
|
AgentSessionInfo,
|
|
16
21
|
AgentSessionSummaryPage,
|
|
17
22
|
AgentSessionSystemSnapshot,
|
|
23
|
+
AgentSessionStopResult,
|
|
18
24
|
RemoteAgentPluginActionInput,
|
|
19
25
|
RemoteAgentPluginActionResult,
|
|
20
26
|
} from "@/types/agent/AgentTypes.js";
|
|
@@ -39,7 +45,7 @@ type SdkEventsReadyFrame = {
|
|
|
39
45
|
};
|
|
40
46
|
|
|
41
47
|
/**
|
|
42
|
-
*
|
|
48
|
+
* downcity HTTP gateway transport。
|
|
43
49
|
*/
|
|
44
50
|
export class HttpRemoteAgentTransport implements RemoteAgentTransport {
|
|
45
51
|
private readonly base_url: string;
|
|
@@ -118,6 +124,23 @@ export class HttpRemoteAgentTransport implements RemoteAgentTransport {
|
|
|
118
124
|
return { id };
|
|
119
125
|
}
|
|
120
126
|
|
|
127
|
+
async stop(session_id: string): Promise<AgentSessionStopResult> {
|
|
128
|
+
const payload = await read_http_json<{
|
|
129
|
+
success?: boolean;
|
|
130
|
+
error?: string;
|
|
131
|
+
result?: AgentSessionStopResult;
|
|
132
|
+
}>(`${this.base_url}/api/sdk/sessions/${encodeURIComponent(session_id)}/stop`, {
|
|
133
|
+
method: "POST",
|
|
134
|
+
headers: this.headers({
|
|
135
|
+
"Content-Type": "application/json",
|
|
136
|
+
}),
|
|
137
|
+
});
|
|
138
|
+
if (!payload.success || !payload.result) {
|
|
139
|
+
throw new Error(String(payload.error || "Remote session stop failed"));
|
|
140
|
+
}
|
|
141
|
+
return payload.result;
|
|
142
|
+
}
|
|
143
|
+
|
|
121
144
|
async subscribe(params: {
|
|
122
145
|
session_id: string;
|
|
123
146
|
on_ready: () => void;
|
|
@@ -250,6 +273,81 @@ export class HttpRemoteAgentTransport implements RemoteAgentTransport {
|
|
|
250
273
|
return payload.page;
|
|
251
274
|
}
|
|
252
275
|
|
|
276
|
+
async archive_session(
|
|
277
|
+
input: AgentArchiveSessionInput,
|
|
278
|
+
): Promise<AgentArchiveSessionResult> {
|
|
279
|
+
const session_id = String(input?.id || "").trim();
|
|
280
|
+
if (!session_id) {
|
|
281
|
+
throw new Error("archive_session requires a non-empty id");
|
|
282
|
+
}
|
|
283
|
+
const payload = await read_http_json<{
|
|
284
|
+
success?: boolean;
|
|
285
|
+
error?: string;
|
|
286
|
+
sessionId?: string;
|
|
287
|
+
archivedAt?: number;
|
|
288
|
+
}>(
|
|
289
|
+
`${this.base_url}/api/sdk/sessions/${encodeURIComponent(session_id)}/archive`,
|
|
290
|
+
{
|
|
291
|
+
method: "POST",
|
|
292
|
+
headers: this.headers({
|
|
293
|
+
"Content-Type": "application/json",
|
|
294
|
+
}),
|
|
295
|
+
},
|
|
296
|
+
);
|
|
297
|
+
if (!payload.success || !payload.sessionId) {
|
|
298
|
+
throw new Error(String(payload.error || "Remote session archive failed"));
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
sessionId: payload.sessionId,
|
|
302
|
+
archivedAt:
|
|
303
|
+
typeof payload.archivedAt === "number" && Number.isFinite(payload.archivedAt)
|
|
304
|
+
? payload.archivedAt
|
|
305
|
+
: Date.now(),
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async archive_sessions(
|
|
310
|
+
input?: AgentArchiveSessionsInput,
|
|
311
|
+
): Promise<AgentArchiveSessionsResult> {
|
|
312
|
+
const query = new URLSearchParams();
|
|
313
|
+
if (input?.limit !== undefined) query.set("limit", String(input.limit));
|
|
314
|
+
if (input?.cursor) query.set("cursor", input.cursor);
|
|
315
|
+
if (input?.query) query.set("query", input.query);
|
|
316
|
+
const payload = await read_http_json<{
|
|
317
|
+
success?: boolean;
|
|
318
|
+
error?: string;
|
|
319
|
+
page?: AgentArchiveSessionsResult;
|
|
320
|
+
}>(
|
|
321
|
+
`${this.base_url}/api/sdk/archived-sessions${query.size > 0 ? `?${query.toString()}` : ""}`,
|
|
322
|
+
{
|
|
323
|
+
headers: this.headers(),
|
|
324
|
+
},
|
|
325
|
+
);
|
|
326
|
+
if (!payload.success || !payload.page) {
|
|
327
|
+
throw new Error(String(payload.error || "Remote archived sessions list failed"));
|
|
328
|
+
}
|
|
329
|
+
return payload.page;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
async clean_archive(): Promise<AgentCleanArchiveResult> {
|
|
333
|
+
const payload = await read_http_json<{
|
|
334
|
+
success?: boolean;
|
|
335
|
+
error?: string;
|
|
336
|
+
removedSessionIds?: string[];
|
|
337
|
+
}>(`${this.base_url}/api/sdk/archived-sessions`, {
|
|
338
|
+
method: "DELETE",
|
|
339
|
+
headers: this.headers(),
|
|
340
|
+
});
|
|
341
|
+
if (!payload.success) {
|
|
342
|
+
throw new Error(String(payload.error || "Remote clean archive failed"));
|
|
343
|
+
}
|
|
344
|
+
return {
|
|
345
|
+
removedSessionIds: Array.isArray(payload.removedSessionIds)
|
|
346
|
+
? payload.removedSessionIds
|
|
347
|
+
: [],
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
253
351
|
async run_plugin_action(
|
|
254
352
|
input: RemoteAgentPluginActionInput,
|
|
255
353
|
): Promise<RemoteAgentPluginActionResult> {
|
|
@@ -9,12 +9,18 @@
|
|
|
9
9
|
import type {
|
|
10
10
|
AgentCreateSessionInput,
|
|
11
11
|
AgentListSessionsInput,
|
|
12
|
+
AgentArchiveSessionInput,
|
|
13
|
+
AgentArchiveSessionsInput,
|
|
14
|
+
AgentArchiveSessionResult,
|
|
15
|
+
AgentArchiveSessionsResult,
|
|
16
|
+
AgentCleanArchiveResult,
|
|
12
17
|
AgentSessionForkInput,
|
|
13
18
|
AgentSessionHistoryInput,
|
|
14
19
|
AgentSessionHistoryPage,
|
|
15
20
|
AgentSessionInfo,
|
|
16
21
|
AgentSessionSummaryPage,
|
|
17
22
|
AgentSessionSystemSnapshot,
|
|
23
|
+
AgentSessionStopResult,
|
|
18
24
|
RemoteAgentPluginActionInput,
|
|
19
25
|
RemoteAgentPluginActionResult,
|
|
20
26
|
} from "@/types/agent/AgentTypes.js";
|
|
@@ -62,6 +68,10 @@ export class RpcRemoteAgentTransport implements RemoteAgentTransport {
|
|
|
62
68
|
});
|
|
63
69
|
}
|
|
64
70
|
|
|
71
|
+
async stop(session_id: string): Promise<AgentSessionStopResult> {
|
|
72
|
+
return await this.client.stop_session(session_id);
|
|
73
|
+
}
|
|
74
|
+
|
|
65
75
|
async subscribe(params: {
|
|
66
76
|
session_id: string;
|
|
67
77
|
on_ready: () => void;
|
|
@@ -111,6 +121,22 @@ export class RpcRemoteAgentTransport implements RemoteAgentTransport {
|
|
|
111
121
|
return await this.client.list_sessions(input);
|
|
112
122
|
}
|
|
113
123
|
|
|
124
|
+
async archive_session(
|
|
125
|
+
input: AgentArchiveSessionInput,
|
|
126
|
+
): Promise<AgentArchiveSessionResult> {
|
|
127
|
+
return await this.client.archive_session(input);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async archive_sessions(
|
|
131
|
+
input?: AgentArchiveSessionsInput,
|
|
132
|
+
): Promise<AgentArchiveSessionsResult> {
|
|
133
|
+
return await this.client.archive_sessions(input);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async clean_archive(): Promise<AgentCleanArchiveResult> {
|
|
137
|
+
return await this.client.clean_archive();
|
|
138
|
+
}
|
|
139
|
+
|
|
114
140
|
async run_plugin_action(
|
|
115
141
|
input: RemoteAgentPluginActionInput,
|
|
116
142
|
): Promise<RemoteAgentPluginActionResult> {
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* Agent 项目初始化模块。
|
|
3
3
|
*
|
|
4
4
|
* 职责说明(中文)
|
|
5
|
-
* - CLI `
|
|
5
|
+
* - CLI `downcity agent create` 与 Console 共用同一套初始化逻辑,避免模板与目录结构分叉。
|
|
6
6
|
* - 负责创建项目骨架、静态 prompt、默认 `downcity.json`、基础目录与 schema 文件。
|
|
7
7
|
* - 负责把用户在创建阶段提供的最小执行配置与渠道配置写入项目。
|
|
8
8
|
*
|
|
9
9
|
* 边界说明(中文)
|
|
10
|
-
* - 这里只处理“初始化一个新项目”所需的静态文件与目录,不处理
|
|
10
|
+
* - 这里只处理“初始化一个新项目”所需的静态文件与目录,不处理 downcity 托管进程启停。
|
|
11
11
|
* - 这里只校验项目创建阶段依赖的最小平台条件,不承担后续运行时配置合并职责。
|
|
12
12
|
*/
|
|
13
13
|
|
package/src/executor/Executor.ts
CHANGED
|
@@ -109,6 +109,7 @@ export class Executor implements SessionExecutor {
|
|
|
109
109
|
private readonly core_engine_runner: CoreEngineRunner;
|
|
110
110
|
|
|
111
111
|
private executing = false;
|
|
112
|
+
private abort_controller: AbortController | null = null;
|
|
112
113
|
|
|
113
114
|
constructor(options: ExecutorOptions) {
|
|
114
115
|
const sessionId = String(options.sessionId || "").trim();
|
|
@@ -162,6 +163,17 @@ export class Executor implements SessionExecutor {
|
|
|
162
163
|
return this.executing;
|
|
163
164
|
}
|
|
164
165
|
|
|
166
|
+
/**
|
|
167
|
+
* 请求停止当前执行。
|
|
168
|
+
*/
|
|
169
|
+
stop(): boolean {
|
|
170
|
+
if (!this.executing || !this.abort_controller) return false;
|
|
171
|
+
if (!this.abort_controller.signal.aborted) {
|
|
172
|
+
this.abort_controller.abort(new Error("Turn stopped"));
|
|
173
|
+
}
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
|
|
165
177
|
/**
|
|
166
178
|
* 获取当前 session 的 history 事实源。
|
|
167
179
|
*/
|
|
@@ -260,6 +272,22 @@ export class Executor implements SessionExecutor {
|
|
|
260
272
|
};
|
|
261
273
|
run_context.onAssistantStepCallback = wrappedOnAssistantStepCallback;
|
|
262
274
|
|
|
275
|
+
const upstream_abort_signal = run_context.abortSignal;
|
|
276
|
+
const abort_controller = new AbortController();
|
|
277
|
+
const abort_from_upstream = () => {
|
|
278
|
+
if (!abort_controller.signal.aborted) {
|
|
279
|
+
abort_controller.abort(upstream_abort_signal?.reason);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
if (upstream_abort_signal?.aborted) {
|
|
283
|
+
abort_from_upstream();
|
|
284
|
+
} else {
|
|
285
|
+
upstream_abort_signal?.addEventListener("abort", abort_from_upstream, {
|
|
286
|
+
once: true,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
this.abort_controller = abort_controller;
|
|
290
|
+
run_context.abortSignal = abort_controller.signal;
|
|
263
291
|
this.executing = true;
|
|
264
292
|
this.recovery_policy.reset_run_state();
|
|
265
293
|
try {
|
|
@@ -308,6 +336,10 @@ export class Executor implements SessionExecutor {
|
|
|
308
336
|
return result;
|
|
309
337
|
} finally {
|
|
310
338
|
this.recovery_policy.reset_run_state();
|
|
339
|
+
if (this.abort_controller === abort_controller) {
|
|
340
|
+
this.abort_controller = null;
|
|
341
|
+
}
|
|
342
|
+
upstream_abort_signal?.removeEventListener("abort", abort_from_upstream);
|
|
311
343
|
this.executing = false;
|
|
312
344
|
}
|
|
313
345
|
}
|
|
@@ -397,6 +429,7 @@ export class Executor implements SessionExecutor {
|
|
|
397
429
|
...(typeof input?.onUiMessageChunkCallback === "function"
|
|
398
430
|
? { onUiMessageChunkCallback: input.onUiMessageChunkCallback }
|
|
399
431
|
: {}),
|
|
432
|
+
...(input?.abortSignal ? { abortSignal: input.abortSignal } : {}),
|
|
400
433
|
injectedUserMessages: Array.isArray(input?.injectedUserMessages)
|
|
401
434
|
? [...input.injectedUserMessages]
|
|
402
435
|
: [],
|
|
@@ -74,7 +74,7 @@ export function buildContextSystemPrompt(input: {
|
|
|
74
74
|
const outputRules = [
|
|
75
75
|
"Task-run output rules:",
|
|
76
76
|
"- This is a task execution context, not an interactive chat turn.",
|
|
77
|
-
"- Do NOT send external channel messages via `
|
|
77
|
+
"- Do NOT send external channel messages via `downcity chat send` unless explicitly required by the task itself.",
|
|
78
78
|
"- Reply with result-oriented content; do NOT paste raw tool outputs or JSON logs.",
|
|
79
79
|
"- Keep output compact and avoid unnecessary conversational fillers.",
|
|
80
80
|
].join("\n");
|
|
@@ -173,7 +173,7 @@ export async function loadManagedPluginSystemPrompts(input: {
|
|
|
173
173
|
.filter(Boolean),
|
|
174
174
|
);
|
|
175
175
|
|
|
176
|
-
for (const plugin of input.context.
|
|
176
|
+
for (const plugin of input.context.pluginInstances.values()) {
|
|
177
177
|
if (disabledPluginNames.has(plugin.name)) continue;
|
|
178
178
|
if (typeof plugin.system !== "function") continue;
|
|
179
179
|
try {
|
|
@@ -43,6 +43,8 @@ import type {
|
|
|
43
43
|
} from "@/executor/types/SessionRun.js";
|
|
44
44
|
import type { SessionMessageV1 } from "@/executor/types/SessionMessages.js";
|
|
45
45
|
|
|
46
|
+
const TURN_STOPPED_MESSAGE = "Turn stopped";
|
|
47
|
+
|
|
46
48
|
/**
|
|
47
49
|
* 生成 file part 去重 key。
|
|
48
50
|
*/
|
|
@@ -200,6 +202,7 @@ export class CoreEngineRunner {
|
|
|
200
202
|
prepareStep: prepare_step,
|
|
201
203
|
messages: message_state.modelMessages,
|
|
202
204
|
tools,
|
|
205
|
+
abortSignal: input.run_context.abortSignal,
|
|
203
206
|
providerOptions: buildOpenAIResponsesProviderOptions(),
|
|
204
207
|
onError: async ({ error }) => {
|
|
205
208
|
last_observed_stream_error = error;
|
|
@@ -405,6 +408,24 @@ export class CoreEngineRunner {
|
|
|
405
408
|
],
|
|
406
409
|
};
|
|
407
410
|
} catch (error) {
|
|
411
|
+
if (input.run_context.abortSignal?.aborted) {
|
|
412
|
+
const error_text = TURN_STOPPED_MESSAGE;
|
|
413
|
+
await this.logger.log("info", "[agent] stopped", {
|
|
414
|
+
sessionId: session_id,
|
|
415
|
+
});
|
|
416
|
+
return {
|
|
417
|
+
success: false,
|
|
418
|
+
error: error_text,
|
|
419
|
+
assistantMessage: this.context_composer.buildFallbackAssistantMessage(
|
|
420
|
+
error_text,
|
|
421
|
+
input.run_context,
|
|
422
|
+
),
|
|
423
|
+
deferredPersistedUserMessages: [
|
|
424
|
+
...input.run_context.deferredPersistedUserMessages,
|
|
425
|
+
],
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
|
|
408
429
|
if (this.should_compact_on_error(error)) {
|
|
409
430
|
throw error;
|
|
410
431
|
}
|
|
@@ -21,9 +21,10 @@ export interface SessionExecutor {
|
|
|
21
21
|
* 请求取消当前正在执行的 turn。
|
|
22
22
|
*
|
|
23
23
|
* 关键点(中文)
|
|
24
|
-
* -
|
|
24
|
+
* - `session.stop()` 会调用这里终止当前模型流与 tool-loop。
|
|
25
25
|
* - 返回 `true` 表示本次请求已发出;`false` 表示当前没有可取消的 turn。
|
|
26
26
|
*/
|
|
27
|
+
stop(): boolean;
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* 释放执行器持有的资源。
|
package/src/index.ts
CHANGED
|
@@ -17,6 +17,11 @@ export {
|
|
|
17
17
|
normalizeAgentModel,
|
|
18
18
|
} from "./model/CityModelAdapter.js";
|
|
19
19
|
export type {
|
|
20
|
+
AgentArchiveSessionInput,
|
|
21
|
+
AgentArchiveSessionsInput,
|
|
22
|
+
AgentArchiveSessionResult,
|
|
23
|
+
AgentArchiveSessionsResult,
|
|
24
|
+
AgentCleanArchiveResult,
|
|
20
25
|
AgentSessionCollection,
|
|
21
26
|
AgentModel,
|
|
22
27
|
AgentManagedSession,
|
|
@@ -51,11 +56,11 @@ export type {
|
|
|
51
56
|
AgentSessionUnsubscribe,
|
|
52
57
|
} from "./types/sdk/AgentSessionEvent.js";
|
|
53
58
|
export type { AgentSessionPromptInput } from "./types/sdk/AgentSessionPrompt.js";
|
|
59
|
+
export type { AgentSessionStopResult } from "./types/sdk/AgentSessionStop.js";
|
|
54
60
|
export type {
|
|
55
61
|
AgentSessionTurnHandle,
|
|
56
62
|
AgentSessionTurnResult,
|
|
57
63
|
} from "./types/sdk/AgentSessionTurn.js";
|
|
58
|
-
export type { AgentRuntime, AgentRuntimeBase } from "./types/runtime/agent/AgentRuntime.js";
|
|
59
64
|
export { AgentContext } from "./types/runtime/agent/AgentContext.js";
|
|
60
65
|
export type {
|
|
61
66
|
AgentContextOptions,
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
import { readProjectPluginEnabled } from "@/plugin/core/ProjectConfigStore.js";
|
|
10
10
|
import type { Plugin } from "@/plugin/types/Plugin.js";
|
|
11
11
|
import type { AgentContext } from "@/types/runtime/agent/AgentContext.js";
|
|
12
|
-
import type { AgentRuntimeBase } from "@/types/runtime/agent/AgentRuntime.js";
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
14
|
* 读取当前项目配置下的 plugin 启用态。
|
|
@@ -17,12 +16,11 @@ import type { AgentRuntimeBase } from "@/types/runtime/agent/AgentRuntime.js";
|
|
|
17
16
|
export function isPluginEnabled(params: {
|
|
18
17
|
plugin: Plugin;
|
|
19
18
|
context?: Pick<AgentContext, "config">;
|
|
20
|
-
runtime?: Pick<AgentRuntimeBase, "config">;
|
|
21
19
|
}): boolean {
|
|
22
20
|
const pluginName = String(params.plugin.name || "").trim();
|
|
23
21
|
if (!pluginName) return false;
|
|
24
22
|
return readProjectPluginEnabled({
|
|
25
23
|
pluginName,
|
|
26
|
-
config: params.context?.config
|
|
24
|
+
config: params.context?.config,
|
|
27
25
|
});
|
|
28
26
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* PluginCommandRequest:统一 plugin runtime command 请求解析模块。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* - 统一收口
|
|
5
|
+
* - 统一收口 downcity gateway command 入口的请求体解析。
|
|
6
6
|
* - plugin runtime 远程调用统一走 runtime command 协议,不再让 action 自带 HTTP route。
|
|
7
7
|
* - ActionSchedule 参数(`schedule` / `delay` / `time`)也在这里一次性归一化。
|
|
8
8
|
*/
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { AgentContext } from "@/types/runtime/agent/AgentContext.js";
|
|
6
|
-
import type { AgentRuntime } from "@/types/runtime/agent/AgentRuntime.js";
|
|
7
6
|
import type {
|
|
8
7
|
PluginLifecycle,
|
|
9
8
|
PluginState,
|
|
@@ -27,16 +26,11 @@ function resolveLifecycle(plugin: BasePlugin): PluginLifecycle | undefined {
|
|
|
27
26
|
*/
|
|
28
27
|
export function listPluginInstances(input?: {
|
|
29
28
|
context?: AgentContext;
|
|
30
|
-
runtime?: AgentRuntime;
|
|
31
29
|
}): BasePlugin[] {
|
|
32
|
-
const contextPlugins = input?.context?.
|
|
30
|
+
const contextPlugins = input?.context?.pluginInstances;
|
|
33
31
|
if (contextPlugins instanceof Map && contextPlugins.size > 0) {
|
|
34
32
|
return [...contextPlugins.values()];
|
|
35
33
|
}
|
|
36
|
-
const runtimePlugins = input?.runtime?.pluginInstances;
|
|
37
|
-
if (runtimePlugins instanceof Map && runtimePlugins.size > 0) {
|
|
38
|
-
return [...runtimePlugins.values()];
|
|
39
|
-
}
|
|
40
34
|
return [];
|
|
41
35
|
}
|
|
42
36
|
|
|
@@ -47,7 +41,6 @@ export function resolvePluginByName(
|
|
|
47
41
|
name: string,
|
|
48
42
|
input?: {
|
|
49
43
|
context?: AgentContext;
|
|
50
|
-
runtime?: AgentRuntime;
|
|
51
44
|
},
|
|
52
45
|
): BasePlugin | null {
|
|
53
46
|
const key = String(name || "").trim();
|
|
@@ -136,7 +129,6 @@ export function markPluginCommand(
|
|
|
136
129
|
*/
|
|
137
130
|
export function listPluginStates(input?: {
|
|
138
131
|
context?: AgentContext;
|
|
139
|
-
runtime?: AgentRuntime;
|
|
140
132
|
}): PluginStateSnapshot[] {
|
|
141
133
|
return listPluginInstances(input)
|
|
142
134
|
.map((plugin) =>
|
|
@@ -152,7 +144,6 @@ export function isPluginRunning(
|
|
|
152
144
|
pluginName: string,
|
|
153
145
|
input?: {
|
|
154
146
|
context?: AgentContext;
|
|
155
|
-
runtime?: AgentRuntime;
|
|
156
147
|
},
|
|
157
148
|
): boolean {
|
|
158
149
|
const plugin = resolvePluginByName(pluginName, input);
|
package/src/rpc/Client.ts
CHANGED
|
@@ -11,9 +11,15 @@ import net from "node:net";
|
|
|
11
11
|
import type {
|
|
12
12
|
AgentCreateSessionInput,
|
|
13
13
|
AgentListSessionsInput,
|
|
14
|
+
AgentArchiveSessionInput,
|
|
15
|
+
AgentArchiveSessionsInput,
|
|
16
|
+
AgentArchiveSessionResult,
|
|
17
|
+
AgentArchiveSessionsResult,
|
|
18
|
+
AgentCleanArchiveResult,
|
|
14
19
|
AgentSessionHistoryInput,
|
|
15
20
|
AgentSessionHistoryPage,
|
|
16
21
|
AgentSessionInfo,
|
|
22
|
+
AgentSessionStopResult,
|
|
17
23
|
AgentSessionSummaryPage,
|
|
18
24
|
AgentSessionSystemSnapshot,
|
|
19
25
|
} from "@/types/agent/AgentTypes.js";
|
|
@@ -104,6 +110,48 @@ export class RpcClient {
|
|
|
104
110
|
return data.session;
|
|
105
111
|
}
|
|
106
112
|
|
|
113
|
+
/**
|
|
114
|
+
* 归档远程 session。
|
|
115
|
+
*/
|
|
116
|
+
async archive_session(
|
|
117
|
+
input: AgentArchiveSessionInput,
|
|
118
|
+
): Promise<AgentArchiveSessionResult> {
|
|
119
|
+
const data = await this.request<{ result: AgentArchiveSessionResult }>({
|
|
120
|
+
method: "sdk.sessions.archive",
|
|
121
|
+
params: {
|
|
122
|
+
sessionId: input.id,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
return data.result;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* 列出远程已归档 session。
|
|
130
|
+
*/
|
|
131
|
+
async archive_sessions(
|
|
132
|
+
input?: AgentArchiveSessionsInput,
|
|
133
|
+
): Promise<AgentArchiveSessionsResult> {
|
|
134
|
+
const data = await this.request<{ page: AgentArchiveSessionsResult }>({
|
|
135
|
+
method: "sdk.sessions.archived.list",
|
|
136
|
+
params: input,
|
|
137
|
+
});
|
|
138
|
+
return data.page;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* 清空远程已归档 session。
|
|
143
|
+
*/
|
|
144
|
+
async clean_archive(): Promise<AgentCleanArchiveResult> {
|
|
145
|
+
const data = await this.request<{ removedSessionIds: string[] }>({
|
|
146
|
+
method: "sdk.sessions.archived.clean",
|
|
147
|
+
});
|
|
148
|
+
return {
|
|
149
|
+
removedSessionIds: Array.isArray(data.removedSessionIds)
|
|
150
|
+
? data.removedSessionIds
|
|
151
|
+
: [],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
107
155
|
/**
|
|
108
156
|
* 获取远程 session 信息。
|
|
109
157
|
*/
|
|
@@ -134,6 +182,19 @@ export class RpcClient {
|
|
|
134
182
|
return data.turn;
|
|
135
183
|
}
|
|
136
184
|
|
|
185
|
+
/**
|
|
186
|
+
* 停止远程 session 当前 turn。
|
|
187
|
+
*/
|
|
188
|
+
async stop_session(session_id: string): Promise<AgentSessionStopResult> {
|
|
189
|
+
const data = await this.request<{ result: AgentSessionStopResult }>({
|
|
190
|
+
method: "sdk.sessions.stop",
|
|
191
|
+
params: {
|
|
192
|
+
sessionId: session_id,
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
return data.result;
|
|
196
|
+
}
|
|
197
|
+
|
|
137
198
|
/**
|
|
138
199
|
* 读取 history。
|
|
139
200
|
*/
|
package/src/session/Session.ts
CHANGED
|
@@ -36,6 +36,7 @@ import type {
|
|
|
36
36
|
AgentSessionUnsubscribe,
|
|
37
37
|
} from "@/types/sdk/AgentSessionEvent.js";
|
|
38
38
|
import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
|
|
39
|
+
import type { AgentSessionStopResult } from "@/types/sdk/AgentSessionStop.js";
|
|
39
40
|
import type { AgentSessionTurnHandle } from "@/types/sdk/AgentSessionTurn.js";
|
|
40
41
|
import { SessionEventHub } from "@/session/runtime/SessionEventHub.js";
|
|
41
42
|
import { SessionStateService } from "@/session/services/SessionStateService.js";
|
|
@@ -189,6 +190,13 @@ export class Session implements AgentSession {
|
|
|
189
190
|
return await this.turnService.prompt(input);
|
|
190
191
|
}
|
|
191
192
|
|
|
193
|
+
/**
|
|
194
|
+
* 停止当前 turn,并取消尚未被吸收的排队 prompt。
|
|
195
|
+
*/
|
|
196
|
+
async stop(): Promise<AgentSessionStopResult> {
|
|
197
|
+
return await this.turnService.stop();
|
|
198
|
+
}
|
|
199
|
+
|
|
192
200
|
/**
|
|
193
201
|
* 订阅当前 Session 的未来事件。
|
|
194
202
|
*/
|
|
@@ -269,6 +277,7 @@ export class Session implements AgentSession {
|
|
|
269
277
|
sessionId: this.id,
|
|
270
278
|
getExecutor: () => this.executor.getExecutor(),
|
|
271
279
|
prompt: async (input) => await this.prompt(input),
|
|
280
|
+
stop: async () => await this.stop(),
|
|
272
281
|
subscribe: (subscriber) => this.subscribe(subscriber),
|
|
273
282
|
publishEvent: (event) => {
|
|
274
283
|
this.eventHub.publish(event);
|