@downcity/agent 1.1.43 → 1.1.51
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 +6 -8
- package/bin/agent/Agent.d.ts +31 -16
- package/bin/agent/Agent.d.ts.map +1 -1
- package/bin/agent/Agent.js +47 -63
- package/bin/agent/Agent.js.map +1 -1
- package/bin/agent/RemoteAgent.d.ts +6 -6
- package/bin/agent/RemoteAgent.d.ts.map +1 -1
- package/bin/agent/RemoteAgent.js +377 -267
- package/bin/agent/RemoteAgent.js.map +1 -1
- package/bin/config/AgentInitializer.d.ts +4 -4
- package/bin/config/AgentInitializer.d.ts.map +1 -1
- package/bin/config/AgentInitializer.js +14 -12
- package/bin/config/AgentInitializer.js.map +1 -1
- package/bin/config/Config.d.ts +9 -30
- package/bin/config/Config.d.ts.map +1 -1
- package/bin/config/Config.js +23 -70
- package/bin/config/Config.js.map +1 -1
- package/bin/config/Defaults.d.ts.map +1 -1
- package/bin/config/Defaults.js +1 -9
- package/bin/config/Defaults.js.map +1 -1
- package/bin/config/DowncitySchema.d.ts.map +1 -1
- package/bin/config/DowncitySchema.js +3 -111
- package/bin/config/DowncitySchema.js.map +1 -1
- package/bin/config/ExecutionBinding.d.ts +0 -15
- package/bin/config/ExecutionBinding.d.ts.map +1 -1
- package/bin/config/ExecutionBinding.js +1 -21
- package/bin/config/ExecutionBinding.js.map +1 -1
- package/bin/config/Paths.d.ts +4 -43
- package/bin/config/Paths.d.ts.map +1 -1
- package/bin/config/Paths.js +10 -30
- package/bin/config/Paths.js.map +1 -1
- package/bin/config/PlatformPaths.d.ts +0 -4
- package/bin/config/PlatformPaths.d.ts.map +1 -1
- package/bin/config/PlatformPaths.js +5 -1
- package/bin/config/PlatformPaths.js.map +1 -1
- package/bin/executor/composer/system/default/assets/init/PROFILE.md.d.ts +1 -1
- package/bin/executor/composer/system/default/assets/init/PROFILE.md.d.ts.map +1 -1
- package/bin/executor/composer/system/default/assets/init/PROFILE.md.js +1 -1
- package/bin/executor/composer/system/default/assets/init/PROFILE.md.js.map +1 -1
- package/bin/executor/tools/shell/ShellToolFormatting.js +2 -2
- package/bin/executor/tools/shell/ShellToolFormatting.js.map +1 -1
- package/bin/executor/types/SessionRun.d.ts +1 -1
- package/bin/index.d.ts +4 -6
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +5 -5
- package/bin/index.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/PluginLocalExecution.d.ts.map +1 -1
- package/bin/plugin/core/PluginLocalExecution.js +4 -8
- package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
- package/bin/plugin/types/PluginApi.d.ts +1 -1
- package/bin/rpc/Client.d.ts +104 -0
- package/bin/rpc/Client.d.ts.map +1 -0
- package/bin/rpc/Client.js +300 -0
- package/bin/rpc/Client.js.map +1 -0
- package/bin/rpc/Server.d.ts +41 -0
- package/bin/rpc/Server.d.ts.map +1 -0
- package/bin/rpc/Server.js +164 -0
- package/bin/rpc/Server.js.map +1 -0
- package/bin/runtime/host/daemon/Api.d.ts +1 -1
- package/bin/runtime/host/daemon/Client.d.ts +1 -1
- package/bin/runtime/host/daemon/Client.d.ts.map +1 -1
- package/bin/runtime/host/daemon/Client.js +30 -20
- package/bin/runtime/host/daemon/Client.js.map +1 -1
- package/bin/runtime/server/http/control/OverviewRoutes.js +1 -1
- package/bin/runtime/server/http/control/OverviewRoutes.js.map +1 -1
- package/bin/session/index.d.ts +1 -1
- package/bin/session/index.d.ts.map +1 -1
- package/bin/session/index.js +1 -1
- package/bin/session/index.js.map +1 -1
- package/bin/session/storage/Paths.d.ts +0 -4
- package/bin/session/storage/Paths.d.ts.map +1 -1
- package/bin/session/storage/Paths.js +0 -6
- package/bin/session/storage/Paths.js.map +1 -1
- package/bin/types/agent/AgentTypes.d.ts +23 -52
- package/bin/types/agent/AgentTypes.d.ts.map +1 -1
- package/bin/types/config/AgentProject.d.ts +6 -5
- package/bin/types/config/AgentProject.d.ts.map +1 -1
- package/bin/types/config/DowncityConfig.d.ts +8 -66
- package/bin/types/config/DowncityConfig.d.ts.map +1 -1
- package/bin/types/config/LlmConfig.d.ts +1 -1
- package/bin/types/config/Start.d.ts +3 -0
- package/bin/types/config/Start.d.ts.map +1 -1
- package/bin/types/config/Start.js +2 -0
- package/bin/types/config/Start.js.map +1 -1
- package/bin/types/runtime/host/Store.d.ts +7 -50
- package/bin/types/runtime/host/Store.d.ts.map +1 -1
- package/bin/types/runtime/platform/Platform.d.ts +6 -6
- package/bin/types/runtime/platform/Platform.d.ts.map +1 -1
- package/bin/types/runtime/platform/PlatformGateway.d.ts +2 -2
- package/bin/types/runtime/platform/PlatformGateway.d.ts.map +1 -1
- package/bin/utils/Time.d.ts +0 -1
- package/bin/utils/Time.d.ts.map +1 -1
- package/bin/utils/Time.js +0 -7
- package/bin/utils/Time.js.map +1 -1
- package/bin/utils/storage/index.d.ts +0 -1
- package/bin/utils/storage/index.d.ts.map +1 -1
- package/bin/utils/storage/index.js +0 -6
- package/bin/utils/storage/index.js.map +1 -1
- package/package.json +4 -6
- package/src/agent/Agent.ts +54 -71
- package/src/agent/RemoteAgent.ts +515 -345
- package/src/config/AgentInitializer.ts +14 -12
- package/src/config/Config.ts +28 -85
- package/src/config/Defaults.ts +1 -9
- package/src/config/DowncitySchema.ts +3 -113
- package/src/config/ExecutionBinding.ts +1 -23
- package/src/config/Paths.ts +10 -43
- package/src/config/PlatformPaths.ts +5 -1
- package/src/executor/composer/system/default/assets/init/PROFILE.md.ts +1 -1
- package/src/executor/composer/system/default/assets/init/PROFILE.md.ts.txt +1 -2
- package/src/executor/tools/shell/ShellToolFormatting.ts +2 -2
- package/src/executor/types/SessionRun.ts +1 -1
- package/src/index.ts +7 -14
- package/src/plugin/core/PluginCommandRequest.ts +1 -1
- package/src/plugin/core/PluginLocalExecution.ts +4 -8
- package/src/plugin/types/PluginApi.ts +1 -1
- package/src/rpc/Client.ts +467 -0
- package/src/rpc/Server.ts +302 -0
- package/src/runtime/host/daemon/Api.ts +1 -1
- package/src/runtime/host/daemon/Client.ts +44 -22
- package/src/runtime/server/http/control/OverviewRoutes.ts +1 -1
- package/src/session/index.ts +0 -1
- package/src/session/storage/Paths.ts +0 -10
- package/src/types/agent/AgentTypes.ts +23 -57
- package/src/types/config/AgentProject.ts +6 -5
- package/src/types/config/DowncityConfig.ts +8 -67
- package/src/types/config/LlmConfig.ts +1 -1
- package/src/types/config/Start.ts +3 -0
- package/src/types/runtime/host/Store.ts +7 -53
- package/src/types/runtime/platform/Platform.ts +6 -6
- package/src/types/runtime/platform/PlatformGateway.ts +2 -2
- package/src/utils/Time.ts +0 -6
- package/src/utils/storage/index.ts +0 -7
- package/tsconfig.tsbuildinfo +1 -1
- package/bin/config/ConfigEnvResolver.d.ts +0 -22
- package/bin/config/ConfigEnvResolver.d.ts.map +0 -1
- package/bin/config/ConfigEnvResolver.js +0 -41
- package/bin/config/ConfigEnvResolver.js.map +0 -1
- package/bin/runtime/server/rpc/Server.d.ts +0 -18
- package/bin/runtime/server/rpc/Server.d.ts.map +0 -1
- package/bin/runtime/server/rpc/Server.js +0 -315
- package/bin/runtime/server/rpc/Server.js.map +0 -1
- package/bin/runtime/transport/rpc/Client.d.ts +0 -13
- package/bin/runtime/transport/rpc/Client.d.ts.map +0 -1
- package/bin/runtime/transport/rpc/Client.js +0 -98
- package/bin/runtime/transport/rpc/Client.js.map +0 -1
- package/bin/runtime/transport/rpc/Paths.d.ts +0 -14
- package/bin/runtime/transport/rpc/Paths.d.ts.map +0 -1
- package/bin/runtime/transport/rpc/Paths.js +0 -42
- package/bin/runtime/transport/rpc/Paths.js.map +0 -1
- package/bin/runtime/transport/rpc/Transport.d.ts +0 -21
- package/bin/runtime/transport/rpc/Transport.d.ts.map +0 -1
- package/bin/runtime/transport/rpc/Transport.js +0 -30
- package/bin/runtime/transport/rpc/Transport.js.map +0 -1
- package/bin/types/common/ResolvedConfigValue.d.ts +0 -12
- package/bin/types/common/ResolvedConfigValue.d.ts.map +0 -1
- package/bin/types/common/ResolvedConfigValue.js +0 -2
- package/bin/types/common/ResolvedConfigValue.js.map +0 -1
- package/bin/types/runtime/rpc/LocalRpc.d.ts +0 -69
- package/bin/types/runtime/rpc/LocalRpc.d.ts.map +0 -1
- package/bin/types/runtime/rpc/LocalRpc.js +0 -9
- package/bin/types/runtime/rpc/LocalRpc.js.map +0 -1
- package/src/config/ConfigEnvResolver.ts +0 -52
- package/src/runtime/server/rpc/Server.ts +0 -408
- package/src/runtime/transport/rpc/Client.ts +0 -113
- package/src/runtime/transport/rpc/Paths.ts +0 -50
- package/src/runtime/transport/rpc/Transport.ts +0 -43
- package/src/types/common/ResolvedConfigValue.ts +0 -16
- package/src/types/runtime/rpc/LocalRpc.ts +0 -72
package/src/index.ts
CHANGED
|
@@ -17,9 +17,8 @@ export type {
|
|
|
17
17
|
AgentCreateSessionInput,
|
|
18
18
|
AgentListSessionsInput,
|
|
19
19
|
AgentOptions,
|
|
20
|
-
AgentHttpBinding,
|
|
21
|
-
AgentHttpStartOptions,
|
|
22
20
|
AgentRpcBinding,
|
|
21
|
+
AgentRpcStartOptions,
|
|
23
22
|
AgentStartOptions,
|
|
24
23
|
AgentStartResult,
|
|
25
24
|
AgentStopResult,
|
|
@@ -103,10 +102,11 @@ export {
|
|
|
103
102
|
registerPluginActionCommandsForCli,
|
|
104
103
|
} from "./plugin/core/PluginCommand.js";
|
|
105
104
|
|
|
106
|
-
// Agent
|
|
105
|
+
// Agent RPC 集成
|
|
106
|
+
export { startRpcServer } from "./rpc/Server.js";
|
|
107
|
+
|
|
108
|
+
// 宿主 HTTP gateway 集成
|
|
107
109
|
export { startServer } from "./runtime/server/http/Server.js";
|
|
108
|
-
export { startLocalRpcServer } from "./runtime/server/rpc/Server.js";
|
|
109
|
-
export { callAgentTransport } from "./runtime/transport/rpc/Transport.js";
|
|
110
110
|
|
|
111
111
|
// Runtime plugin 运行集成
|
|
112
112
|
export {
|
|
@@ -127,7 +127,7 @@ export { persistProjectPluginConfig } from "./plugin/core/ProjectConfigStore.js"
|
|
|
127
127
|
export {
|
|
128
128
|
initializeAgentProject,
|
|
129
129
|
isAgentProjectInitialized,
|
|
130
|
-
|
|
130
|
+
normalizeDefaultAgentId,
|
|
131
131
|
} from "./config/AgentInitializer.js";
|
|
132
132
|
export { loadDowncityConfig } from "./config/Config.js";
|
|
133
133
|
export {
|
|
@@ -193,7 +193,7 @@ export type {
|
|
|
193
193
|
PlatformAgentShipStartConfig,
|
|
194
194
|
} from "./types/runtime/platform/PlatformGateway.js";
|
|
195
195
|
|
|
196
|
-
// Daemon
|
|
196
|
+
// Daemon 协议类型
|
|
197
197
|
export {
|
|
198
198
|
DAEMON_LOG_FILENAME,
|
|
199
199
|
DAEMON_META_FILENAME,
|
|
@@ -203,10 +203,6 @@ export type {
|
|
|
203
203
|
DaemonMeta,
|
|
204
204
|
DaemonStaleReason,
|
|
205
205
|
} from "./types/runtime/daemon/Daemon.js";
|
|
206
|
-
export type {
|
|
207
|
-
LocalRpcRequest,
|
|
208
|
-
LocalRpcResponse,
|
|
209
|
-
} from "./types/runtime/rpc/LocalRpc.js";
|
|
210
206
|
|
|
211
207
|
// Inline instant 协议类型
|
|
212
208
|
export type {
|
|
@@ -281,16 +277,13 @@ export type {
|
|
|
281
277
|
|
|
282
278
|
// Platform store 类型
|
|
283
279
|
export type {
|
|
284
|
-
StoredAgentEnvEntry,
|
|
285
280
|
StoredChannelAccount,
|
|
286
281
|
StoredChannelAccountChannel,
|
|
287
282
|
StoredEnvEntry,
|
|
288
|
-
StoredEnvScope,
|
|
289
283
|
StoredGlobalEnvEntry,
|
|
290
284
|
StoredModel,
|
|
291
285
|
StoredModelProvider,
|
|
292
286
|
StoredProviderMeta,
|
|
293
|
-
UpsertAgentEnvEntryInput,
|
|
294
287
|
UpsertChannelAccountInput,
|
|
295
288
|
UpsertEnvEntryInput,
|
|
296
289
|
UpsertGlobalEnvEntryInput,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* PluginCommandRequest:统一 plugin runtime command 请求解析模块。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* -
|
|
5
|
+
* - 统一收口当前 HTTP 入口的请求体解析。
|
|
6
6
|
* - plugin runtime 远程调用统一走 runtime command 协议,不再让 action 自带 HTTP route。
|
|
7
7
|
* - ActionSchedule 参数(`schedule` / `delay` / `time`)也在这里一次性归一化。
|
|
8
8
|
*/
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { logger as defaultLogger } from "@/utils/logger/Logger.js";
|
|
12
|
-
import {
|
|
12
|
+
import { loadDowncityConfig, resolveAgentEnv } from "@/config/Config.js";
|
|
13
13
|
import { isPluginEnabled } from "@/plugin/core/Activation.js";
|
|
14
14
|
import { findPluginByName } from "@/plugin/core/PluginCatalog.js";
|
|
15
15
|
import {
|
|
@@ -30,12 +30,8 @@ import type { AgentContext } from "@/types/runtime/agent/AgentContext.js";
|
|
|
30
30
|
*/
|
|
31
31
|
export function createLocalPluginCommandContext(projectRoot: string): PluginCommandContext {
|
|
32
32
|
const rootPath = path.resolve(String(projectRoot || "").trim() || ".");
|
|
33
|
-
const env =
|
|
34
|
-
const config = loadDowncityConfig(rootPath
|
|
35
|
-
projectEnv: env,
|
|
36
|
-
agentEnv: env,
|
|
37
|
-
globalEnv: {},
|
|
38
|
-
});
|
|
33
|
+
const env = resolveAgentEnv(rootPath);
|
|
34
|
+
const config = loadDowncityConfig(rootPath);
|
|
39
35
|
|
|
40
36
|
defaultLogger.bindProjectRoot(rootPath);
|
|
41
37
|
|
|
@@ -47,7 +43,7 @@ export function createLocalPluginCommandContext(projectRoot: string): PluginComm
|
|
|
47
43
|
env,
|
|
48
44
|
paths: createAgentPathRuntime(
|
|
49
45
|
rootPath,
|
|
50
|
-
String(config.
|
|
46
|
+
String(config.id || "").trim() || path.basename(rootPath) || "agent",
|
|
51
47
|
),
|
|
52
48
|
pluginConfig: createAgentPluginConfigRuntime(rootPath),
|
|
53
49
|
};
|
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent 本机 RPC Client。
|
|
3
|
+
*
|
|
4
|
+
* 职责说明(中文)
|
|
5
|
+
* - 为 `RemoteAgent(rpc://...)` 提供最小客户端实现。
|
|
6
|
+
* - 复用逐行 JSON(NDJSON)协议,与本机 RPC Server 对接。
|
|
7
|
+
* - 当前只承载 Session actor 所需方法。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import net from "node:net";
|
|
11
|
+
import type {
|
|
12
|
+
AgentCreateSessionInput,
|
|
13
|
+
AgentListSessionsInput,
|
|
14
|
+
AgentSessionHistoryInput,
|
|
15
|
+
AgentSessionHistoryPage,
|
|
16
|
+
AgentSessionInfo,
|
|
17
|
+
AgentSessionSummaryPage,
|
|
18
|
+
AgentSessionSystemSnapshot,
|
|
19
|
+
} from "@/types/agent/AgentTypes.js";
|
|
20
|
+
import type { AgentSessionEvent } from "@/types/sdk/AgentSessionEvent.js";
|
|
21
|
+
import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
|
|
22
|
+
|
|
23
|
+
type RpcClientRequest =
|
|
24
|
+
| {
|
|
25
|
+
id: string;
|
|
26
|
+
method: "sdk.sessions.list";
|
|
27
|
+
params?: AgentListSessionsInput;
|
|
28
|
+
}
|
|
29
|
+
| {
|
|
30
|
+
id: string;
|
|
31
|
+
method: "sdk.sessions.create";
|
|
32
|
+
params?: AgentCreateSessionInput;
|
|
33
|
+
}
|
|
34
|
+
| {
|
|
35
|
+
id: string;
|
|
36
|
+
method: "sdk.sessions.get";
|
|
37
|
+
params: {
|
|
38
|
+
sessionId: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
| {
|
|
42
|
+
id: string;
|
|
43
|
+
method: "sdk.sessions.prompt";
|
|
44
|
+
params: {
|
|
45
|
+
sessionId: string;
|
|
46
|
+
input: AgentSessionPromptInput;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
| {
|
|
50
|
+
id: string;
|
|
51
|
+
method: "sdk.sessions.history";
|
|
52
|
+
params: {
|
|
53
|
+
sessionId: string;
|
|
54
|
+
input?: AgentSessionHistoryInput;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
| {
|
|
58
|
+
id: string;
|
|
59
|
+
method: "sdk.sessions.system";
|
|
60
|
+
params: {
|
|
61
|
+
sessionId: string;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
| {
|
|
65
|
+
id: string;
|
|
66
|
+
method: "sdk.sessions.fork";
|
|
67
|
+
params: {
|
|
68
|
+
sessionId: string;
|
|
69
|
+
messageId?: string;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
| {
|
|
73
|
+
id: string;
|
|
74
|
+
method: "sdk.sessions.subscribe";
|
|
75
|
+
params: {
|
|
76
|
+
sessionId: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
| {
|
|
80
|
+
id: string;
|
|
81
|
+
method: "sdk.sessions.unsubscribe";
|
|
82
|
+
params: {
|
|
83
|
+
subscriptionId: string;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
type RpcResponseFrame = {
|
|
88
|
+
id: string;
|
|
89
|
+
success: boolean;
|
|
90
|
+
data?: unknown;
|
|
91
|
+
error?: string;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
type RpcReadyFrame = {
|
|
95
|
+
type: "ready";
|
|
96
|
+
subscriptionId: string;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
type RpcEventFrame = {
|
|
100
|
+
type: "event";
|
|
101
|
+
subscriptionId: string;
|
|
102
|
+
event: AgentSessionEvent;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
type PendingRequest = {
|
|
106
|
+
resolve: (value: any) => void;
|
|
107
|
+
reject: (error: unknown) => void;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
type RpcSubscription = {
|
|
111
|
+
on_ready: () => void;
|
|
112
|
+
on_event: (event: AgentSessionEvent) => void;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* RPC endpoint。
|
|
117
|
+
*/
|
|
118
|
+
export interface RpcClientEndpoint {
|
|
119
|
+
/** RPC host。 */
|
|
120
|
+
host: string;
|
|
121
|
+
/** RPC port。 */
|
|
122
|
+
port: number;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* RPC Session 订阅句柄。
|
|
127
|
+
*/
|
|
128
|
+
export interface RpcSessionSubscription {
|
|
129
|
+
/** 当前订阅 id。 */
|
|
130
|
+
subscription_id: string;
|
|
131
|
+
/** 取消订阅。 */
|
|
132
|
+
unsubscribe(): Promise<void>;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* RPC Client。
|
|
137
|
+
*/
|
|
138
|
+
export class RpcClient {
|
|
139
|
+
private readonly endpoint: RpcClientEndpoint;
|
|
140
|
+
private socket: net.Socket | null = null;
|
|
141
|
+
private connect_promise: Promise<void> | null = null;
|
|
142
|
+
private buffered = "";
|
|
143
|
+
private readonly pending_requests = new Map<string, PendingRequest>();
|
|
144
|
+
private readonly subscriptions = new Map<string, RpcSubscription>();
|
|
145
|
+
private request_sequence = 0;
|
|
146
|
+
|
|
147
|
+
constructor(endpoint: RpcClientEndpoint) {
|
|
148
|
+
this.endpoint = endpoint;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* 列出远程 session。
|
|
153
|
+
*/
|
|
154
|
+
async list_sessions(
|
|
155
|
+
input?: AgentListSessionsInput,
|
|
156
|
+
): Promise<AgentSessionSummaryPage> {
|
|
157
|
+
const data = await this.request<{ page: AgentSessionSummaryPage }>({
|
|
158
|
+
method: "sdk.sessions.list",
|
|
159
|
+
params: input,
|
|
160
|
+
});
|
|
161
|
+
return data.page;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* 创建远程 session。
|
|
166
|
+
*/
|
|
167
|
+
async create_session(
|
|
168
|
+
input?: AgentCreateSessionInput,
|
|
169
|
+
): Promise<AgentSessionInfo> {
|
|
170
|
+
const data = await this.request<{ session: AgentSessionInfo }>({
|
|
171
|
+
method: "sdk.sessions.create",
|
|
172
|
+
params: input,
|
|
173
|
+
});
|
|
174
|
+
return data.session;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* 获取远程 session 信息。
|
|
179
|
+
*/
|
|
180
|
+
async get_session(session_id: string): Promise<AgentSessionInfo> {
|
|
181
|
+
const data = await this.request<{ session: AgentSessionInfo }>({
|
|
182
|
+
method: "sdk.sessions.get",
|
|
183
|
+
params: {
|
|
184
|
+
sessionId: session_id,
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
return data.session;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* 发送 prompt。
|
|
192
|
+
*/
|
|
193
|
+
async prompt_session(params: {
|
|
194
|
+
session_id: string;
|
|
195
|
+
input: AgentSessionPromptInput;
|
|
196
|
+
}): Promise<{ id: string }> {
|
|
197
|
+
const data = await this.request<{ turn: { id: string } }>({
|
|
198
|
+
method: "sdk.sessions.prompt",
|
|
199
|
+
params: {
|
|
200
|
+
sessionId: params.session_id,
|
|
201
|
+
input: params.input,
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
return data.turn;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* 读取 history。
|
|
209
|
+
*/
|
|
210
|
+
async get_session_history(params: {
|
|
211
|
+
session_id: string;
|
|
212
|
+
input?: AgentSessionHistoryInput;
|
|
213
|
+
}): Promise<AgentSessionHistoryPage> {
|
|
214
|
+
const data = await this.request<{ history: AgentSessionHistoryPage }>({
|
|
215
|
+
method: "sdk.sessions.history",
|
|
216
|
+
params: {
|
|
217
|
+
sessionId: params.session_id,
|
|
218
|
+
input: params.input,
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
return data.history;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* 读取 system snapshot。
|
|
226
|
+
*/
|
|
227
|
+
async get_session_system(session_id: string): Promise<AgentSessionSystemSnapshot> {
|
|
228
|
+
const data = await this.request<{ system: AgentSessionSystemSnapshot }>({
|
|
229
|
+
method: "sdk.sessions.system",
|
|
230
|
+
params: {
|
|
231
|
+
sessionId: session_id,
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
return data.system;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* 分叉 session。
|
|
239
|
+
*/
|
|
240
|
+
async fork_session(params: {
|
|
241
|
+
session_id: string;
|
|
242
|
+
message_id?: string;
|
|
243
|
+
}): Promise<AgentSessionInfo> {
|
|
244
|
+
const data = await this.request<{ session: AgentSessionInfo }>({
|
|
245
|
+
method: "sdk.sessions.fork",
|
|
246
|
+
params: {
|
|
247
|
+
sessionId: params.session_id,
|
|
248
|
+
...(params.message_id ? { messageId: params.message_id } : {}),
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
return data.session;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* 订阅 session 事件。
|
|
256
|
+
*/
|
|
257
|
+
async subscribe_session(params: {
|
|
258
|
+
session_id: string;
|
|
259
|
+
on_ready: () => void;
|
|
260
|
+
on_event: (event: AgentSessionEvent) => void;
|
|
261
|
+
}): Promise<RpcSessionSubscription> {
|
|
262
|
+
const data = await this.request<{ subscriptionId: string }>({
|
|
263
|
+
method: "sdk.sessions.subscribe",
|
|
264
|
+
params: {
|
|
265
|
+
sessionId: params.session_id,
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
const subscription_id = String(data.subscriptionId || "").trim();
|
|
269
|
+
if (!subscription_id) {
|
|
270
|
+
throw new Error("RPC subscription did not return subscriptionId");
|
|
271
|
+
}
|
|
272
|
+
this.subscriptions.set(subscription_id, {
|
|
273
|
+
on_ready: params.on_ready,
|
|
274
|
+
on_event: params.on_event,
|
|
275
|
+
});
|
|
276
|
+
params.on_ready();
|
|
277
|
+
return {
|
|
278
|
+
subscription_id,
|
|
279
|
+
unsubscribe: async () => {
|
|
280
|
+
this.subscriptions.delete(subscription_id);
|
|
281
|
+
await this.request({
|
|
282
|
+
method: "sdk.sessions.unsubscribe",
|
|
283
|
+
params: {
|
|
284
|
+
subscriptionId: subscription_id,
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* 关闭底层连接。
|
|
293
|
+
*/
|
|
294
|
+
async close(): Promise<void> {
|
|
295
|
+
const socket = this.socket;
|
|
296
|
+
this.socket = null;
|
|
297
|
+
this.connect_promise = null;
|
|
298
|
+
this.buffered = "";
|
|
299
|
+
for (const pending of this.pending_requests.values()) {
|
|
300
|
+
pending.reject(new Error("RPC client closed"));
|
|
301
|
+
}
|
|
302
|
+
this.pending_requests.clear();
|
|
303
|
+
this.fail_all_subscriptions("RPC client closed");
|
|
304
|
+
if (!socket) return;
|
|
305
|
+
await new Promise<void>((resolve) => {
|
|
306
|
+
socket.end(() => resolve());
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
private async request<TData = unknown>(input: {
|
|
311
|
+
method: RpcClientRequest["method"];
|
|
312
|
+
params?: unknown;
|
|
313
|
+
}): Promise<TData> {
|
|
314
|
+
await this.ensure_connected();
|
|
315
|
+
const socket = this.socket;
|
|
316
|
+
if (!socket) {
|
|
317
|
+
throw new Error("RPC socket is not connected");
|
|
318
|
+
}
|
|
319
|
+
const id = `rpc_${Date.now()}_${this.request_sequence += 1}`;
|
|
320
|
+
const request = (
|
|
321
|
+
input.params === undefined
|
|
322
|
+
? {
|
|
323
|
+
id,
|
|
324
|
+
method: input.method,
|
|
325
|
+
}
|
|
326
|
+
: {
|
|
327
|
+
id,
|
|
328
|
+
method: input.method,
|
|
329
|
+
params: input.params as never,
|
|
330
|
+
}
|
|
331
|
+
) as RpcClientRequest;
|
|
332
|
+
const result = await new Promise<TData>((resolve, reject) => {
|
|
333
|
+
this.pending_requests.set(id, { resolve, reject });
|
|
334
|
+
socket.write(`${JSON.stringify(request)}\n`, (error) => {
|
|
335
|
+
if (!error) return;
|
|
336
|
+
this.pending_requests.delete(id);
|
|
337
|
+
reject(error);
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
return result;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
private async ensure_connected(): Promise<void> {
|
|
344
|
+
if (this.socket && !this.socket.destroyed) return;
|
|
345
|
+
if (this.connect_promise) {
|
|
346
|
+
await this.connect_promise;
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
this.connect_promise = new Promise<void>((resolve, reject) => {
|
|
351
|
+
const socket = net.createConnection({
|
|
352
|
+
host: this.endpoint.host,
|
|
353
|
+
port: this.endpoint.port,
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
socket.setEncoding("utf8");
|
|
357
|
+
|
|
358
|
+
socket.on("connect", () => {
|
|
359
|
+
this.socket = socket;
|
|
360
|
+
resolve();
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
socket.on("data", (chunk: string) => {
|
|
364
|
+
this.consume_data(chunk);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
socket.on("error", (error) => {
|
|
368
|
+
if (!this.socket) {
|
|
369
|
+
reject(error);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
this.fail_all_pending(error);
|
|
373
|
+
this.fail_all_subscriptions(
|
|
374
|
+
error instanceof Error ? error.message : String(error),
|
|
375
|
+
);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
socket.on("close", () => {
|
|
379
|
+
this.socket = null;
|
|
380
|
+
this.connect_promise = null;
|
|
381
|
+
this.fail_all_pending(new Error("RPC socket closed"));
|
|
382
|
+
this.fail_all_subscriptions("RPC socket closed");
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
try {
|
|
387
|
+
await this.connect_promise;
|
|
388
|
+
} catch (error) {
|
|
389
|
+
this.connect_promise = null;
|
|
390
|
+
throw error;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
private consume_data(chunk: string): void {
|
|
395
|
+
this.buffered += chunk;
|
|
396
|
+
let newline_index = this.buffered.indexOf("\n");
|
|
397
|
+
while (newline_index >= 0) {
|
|
398
|
+
const line = this.buffered.slice(0, newline_index).trim();
|
|
399
|
+
this.buffered = this.buffered.slice(newline_index + 1);
|
|
400
|
+
if (line) {
|
|
401
|
+
this.consume_line(line);
|
|
402
|
+
}
|
|
403
|
+
newline_index = this.buffered.indexOf("\n");
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
private consume_line(line: string): void {
|
|
408
|
+
const payload = JSON.parse(line) as RpcResponseFrame | RpcReadyFrame | RpcEventFrame;
|
|
409
|
+
if ("type" in payload && payload.type === "ready") {
|
|
410
|
+
const subscription = this.subscriptions.get(payload.subscriptionId);
|
|
411
|
+
subscription?.on_ready();
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if ("type" in payload && payload.type === "event") {
|
|
415
|
+
const subscription = this.subscriptions.get(payload.subscriptionId);
|
|
416
|
+
subscription?.on_event(payload.event);
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const pending = this.pending_requests.get(payload.id);
|
|
420
|
+
if (!pending) return;
|
|
421
|
+
this.pending_requests.delete(payload.id);
|
|
422
|
+
if (payload.success) {
|
|
423
|
+
pending.resolve(payload.data);
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
pending.reject(new Error(String(payload.error || "RPC request failed")));
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
private fail_all_pending(error: unknown): void {
|
|
430
|
+
for (const pending of this.pending_requests.values()) {
|
|
431
|
+
pending.reject(error);
|
|
432
|
+
}
|
|
433
|
+
this.pending_requests.clear();
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
private fail_all_subscriptions(message: string): void {
|
|
437
|
+
for (const subscription of this.subscriptions.values()) {
|
|
438
|
+
subscription.on_event({
|
|
439
|
+
type: "error",
|
|
440
|
+
message,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
this.subscriptions.clear();
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* 解析 rpc url。
|
|
449
|
+
*/
|
|
450
|
+
export function parse_rpc_url(url_input: string): RpcClientEndpoint {
|
|
451
|
+
const url = new URL(url_input);
|
|
452
|
+
if (url.protocol !== "rpc:") {
|
|
453
|
+
throw new Error(`Unsupported RPC protocol: ${url.protocol}`);
|
|
454
|
+
}
|
|
455
|
+
const host = String(url.hostname || "").trim();
|
|
456
|
+
const port = Number.parseInt(String(url.port || ""), 10);
|
|
457
|
+
if (!host) {
|
|
458
|
+
throw new Error("RPC url requires a host");
|
|
459
|
+
}
|
|
460
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
|
|
461
|
+
throw new Error("RPC url requires a valid port");
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
host,
|
|
465
|
+
port,
|
|
466
|
+
};
|
|
467
|
+
}
|