@downcity/agent 1.1.162 → 1.1.163
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/remote/RemoteSession.d.ts.map +1 -1
- package/bin/agent/remote/RemoteSession.js +2 -2
- package/bin/agent/remote/RemoteSession.js.map +1 -1
- package/bin/executor/messages/UIMessageTransformer.d.ts +8 -3
- package/bin/executor/messages/UIMessageTransformer.d.ts.map +1 -1
- package/bin/executor/messages/UIMessageTransformer.js +12 -0
- package/bin/executor/messages/UIMessageTransformer.js.map +1 -1
- package/bin/index.d.ts +1 -1
- package/bin/index.d.ts.map +1 -1
- package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
- package/bin/session/runtime/SessionPromptRuntime.js +1 -3
- package/bin/session/runtime/SessionPromptRuntime.js.map +1 -1
- package/bin/session/services/SessionStateService.d.ts.map +1 -1
- package/bin/session/services/SessionStateService.js +27 -3
- package/bin/session/services/SessionStateService.js.map +1 -1
- package/bin/session/services/SessionTurnService.d.ts.map +1 -1
- package/bin/session/services/SessionTurnService.js +7 -7
- package/bin/session/services/SessionTurnService.js.map +1 -1
- package/bin/types/sdk/AgentSessionPrompt.d.ts +23 -3
- package/bin/types/sdk/AgentSessionPrompt.d.ts.map +1 -1
- package/bin/types/sdk/AgentSessionPrompt.js +26 -1
- package/bin/types/sdk/AgentSessionPrompt.js.map +1 -1
- package/package.json +1 -1
- package/src/agent/remote/RemoteSession.ts +2 -2
- package/src/executor/messages/UIMessageTransformer.ts +20 -9
- package/src/index.ts +1 -1
- package/src/session/runtime/SessionPromptRuntime.ts +1 -3
- package/src/session/services/SessionStateService.ts +28 -3
- package/src/session/services/SessionTurnService.ts +7 -7
- package/src/types/sdk/AgentSessionPrompt.ts +44 -3
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -35,6 +35,7 @@ import type {
|
|
|
35
35
|
SessionUserMessageV1,
|
|
36
36
|
} from "@/executor/types/SessionMessages.js";
|
|
37
37
|
import type { SessionLocalState } from "@/types/session/SessionLocalState.js";
|
|
38
|
+
import { generateId } from "@/utils/Id.js";
|
|
38
39
|
|
|
39
40
|
type SessionStateServiceOptions = {
|
|
40
41
|
/**
|
|
@@ -307,12 +308,36 @@ export class SessionStateService {
|
|
|
307
308
|
async create_and_persist_user_prompt_message(
|
|
308
309
|
input: AgentSessionPromptInput,
|
|
309
310
|
): Promise<SessionUserMessageV1> {
|
|
310
|
-
const
|
|
311
|
-
|
|
311
|
+
const query = input.query;
|
|
312
|
+
if (typeof query === "string") {
|
|
313
|
+
const message = this.history_store.userText({
|
|
314
|
+
text: query.trim(),
|
|
315
|
+
metadata: {
|
|
316
|
+
sessionId: this.session_id,
|
|
317
|
+
},
|
|
318
|
+
}) as SessionUserMessageV1;
|
|
319
|
+
await this.executor.appendUserMessage({
|
|
320
|
+
message,
|
|
321
|
+
});
|
|
322
|
+
await this.ensure_title_from_history({ generate: true });
|
|
323
|
+
await this.touch_metadata();
|
|
324
|
+
return message;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// query 是 parts 数组,直接用其构造 user 消息
|
|
328
|
+
const parts = Array.isArray(query) ? query : [];
|
|
329
|
+
const message: SessionUserMessageV1 = {
|
|
330
|
+
id: `u:${this.session_id}:${generateId()}`,
|
|
331
|
+
role: "user",
|
|
332
|
+
parts,
|
|
312
333
|
metadata: {
|
|
334
|
+
v: 1,
|
|
335
|
+
ts: Date.now(),
|
|
313
336
|
sessionId: this.session_id,
|
|
337
|
+
source: "ingress",
|
|
338
|
+
kind: "normal",
|
|
314
339
|
},
|
|
315
|
-
}
|
|
340
|
+
};
|
|
316
341
|
await this.executor.appendUserMessage({
|
|
317
342
|
message,
|
|
318
343
|
});
|
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
* - metadata、title、assistant 结果持久化等状态副作用交由 SessionStateService 处理。
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { extractTextFromUiMessage } from "@/executor/messages/UIMessageTransformer.js";
|
|
10
|
+
import { extractTextFromParts, extractTextFromUiMessage } from "@/executor/messages/UIMessageTransformer.js";
|
|
11
11
|
import type { Executor } from "@executor/Executor.js";
|
|
12
12
|
import type { AgentSessionEvent } from "@/types/sdk/AgentSessionEvent.js";
|
|
13
13
|
import type {
|
|
14
14
|
AgentSessionSubscriber,
|
|
15
15
|
AgentSessionUnsubscribe,
|
|
16
16
|
} from "@/types/sdk/AgentSessionEvent.js";
|
|
17
|
+
import { isAgentSessionPromptInputEmpty } from "@/types/sdk/AgentSessionPrompt.js";
|
|
17
18
|
import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
|
|
18
19
|
import type { AgentSessionStopResult } from "@/types/sdk/AgentSessionStop.js";
|
|
19
20
|
import type { AgentSessionTurnHandle } from "@/types/sdk/AgentSessionTurn.js";
|
|
@@ -118,14 +119,11 @@ export class SessionTurnService {
|
|
|
118
119
|
* 追加一条新的 Session prompt。
|
|
119
120
|
*/
|
|
120
121
|
async prompt(input: AgentSessionPromptInput): Promise<AgentSessionTurnHandle> {
|
|
121
|
-
|
|
122
|
-
if (!query) {
|
|
122
|
+
if (isAgentSessionPromptInputEmpty(input)) {
|
|
123
123
|
throw new Error("session.prompt requires a non-empty query");
|
|
124
124
|
}
|
|
125
125
|
await this.state_service.ensure_runnable();
|
|
126
|
-
return await this.prompt_runtime.prompt(
|
|
127
|
-
query,
|
|
128
|
-
});
|
|
126
|
+
return await this.prompt_runtime.prompt(input);
|
|
129
127
|
}
|
|
130
128
|
|
|
131
129
|
/**
|
|
@@ -205,8 +203,10 @@ export class SessionTurnService {
|
|
|
205
203
|
pendingAssistantFileParts: [],
|
|
206
204
|
...(input.abortSignal ? { abortSignal: input.abortSignal } : {}),
|
|
207
205
|
};
|
|
206
|
+
const query = input.promptInput.query;
|
|
207
|
+
const executor_query = typeof query === "string" ? query : extractTextFromParts(query);
|
|
208
208
|
const result = await this.executor.run({
|
|
209
|
-
query:
|
|
209
|
+
query: executor_query,
|
|
210
210
|
runContext: run_context,
|
|
211
211
|
});
|
|
212
212
|
await this.state_service.persist_assistant_result(result.assistantMessage);
|
|
@@ -6,16 +6,57 @@
|
|
|
6
6
|
* - 首条输入、运行中补充输入、排队到下一轮的输入,调用侧都使用同一结构。
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import type { UIDataTypes, UITools, UIMessagePart } from "ai";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Session user message part 类型。
|
|
13
|
+
*
|
|
14
|
+
* 说明(中文)
|
|
15
|
+
* - 与 AI SDK 标准 `UIMessagePart` 等价,但已固定泛型参数,避免调用侧引入 `ai` 包。
|
|
16
|
+
* - 可直接用于 `session.prompt({ query: [...parts] })` 传入 text parts、file parts 等。
|
|
17
|
+
*/
|
|
18
|
+
export type SessionUserMessagePart = UIMessagePart<UIDataTypes, UITools>;
|
|
19
|
+
|
|
9
20
|
/**
|
|
10
21
|
* Session prompt 输入。
|
|
11
22
|
*/
|
|
12
23
|
export interface AgentSessionPromptInput {
|
|
13
24
|
/**
|
|
14
|
-
* 当前这次要追加到 Session
|
|
25
|
+
* 当前这次要追加到 Session 的用户文本或 parts 数组。
|
|
15
26
|
*
|
|
16
27
|
* 说明(中文)
|
|
17
|
-
* -
|
|
28
|
+
* - 支持两种格式:
|
|
29
|
+
* 1. `string`:纯文本用户输入,Session 会将其包装为 `role="user"` 的 UIMessage。
|
|
30
|
+
* 2. `SessionUserMessagePart[]`:AI SDK 标准 user message parts 数组,可直接携带 text parts、file parts 等。
|
|
31
|
+
* - 调用侧永远只传"新的用户输入"。
|
|
18
32
|
* - 它是否并入当前 turn,还是排到下一 turn,由 Session 内部决定。
|
|
19
33
|
*/
|
|
20
|
-
query: string;
|
|
34
|
+
query: string | SessionUserMessagePart[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 判断 prompt 输入是否为空。
|
|
39
|
+
*
|
|
40
|
+
* 说明(中文)
|
|
41
|
+
* - `string`:trim 后为空即视为空。
|
|
42
|
+
* - `SessionUserMessagePart[]`:数组为空或仅包含空文本时视为空。
|
|
43
|
+
*/
|
|
44
|
+
export function isAgentSessionPromptInputEmpty(input: AgentSessionPromptInput): boolean {
|
|
45
|
+
const query = input.query;
|
|
46
|
+
if (typeof query === "string") {
|
|
47
|
+
return query.trim() === "";
|
|
48
|
+
}
|
|
49
|
+
if (Array.isArray(query)) {
|
|
50
|
+
if (query.length === 0) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
// 如果所有 parts 都是空文本,也视为空
|
|
54
|
+
return query.every((part) => {
|
|
55
|
+
if (part && typeof part === "object" && "type" in part && part.type === "text") {
|
|
56
|
+
return String(part.text ?? "").trim() === "";
|
|
57
|
+
}
|
|
58
|
+
return false; // 非文本 part(如 file)不算空
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
21
62
|
}
|