@downcity/agent 1.1.161 → 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.
Files changed (31) hide show
  1. package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
  2. package/bin/agent/remote/RemoteSession.js +2 -2
  3. package/bin/agent/remote/RemoteSession.js.map +1 -1
  4. package/bin/executor/messages/UIMessageTransformer.d.ts +8 -3
  5. package/bin/executor/messages/UIMessageTransformer.d.ts.map +1 -1
  6. package/bin/executor/messages/UIMessageTransformer.js +12 -0
  7. package/bin/executor/messages/UIMessageTransformer.js.map +1 -1
  8. package/bin/index.d.ts +1 -1
  9. package/bin/index.d.ts.map +1 -1
  10. package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
  11. package/bin/session/runtime/SessionPromptRuntime.js +1 -3
  12. package/bin/session/runtime/SessionPromptRuntime.js.map +1 -1
  13. package/bin/session/services/SessionStateService.d.ts.map +1 -1
  14. package/bin/session/services/SessionStateService.js +27 -3
  15. package/bin/session/services/SessionStateService.js.map +1 -1
  16. package/bin/session/services/SessionTurnService.d.ts.map +1 -1
  17. package/bin/session/services/SessionTurnService.js +7 -7
  18. package/bin/session/services/SessionTurnService.js.map +1 -1
  19. package/bin/types/sdk/AgentSessionPrompt.d.ts +23 -3
  20. package/bin/types/sdk/AgentSessionPrompt.d.ts.map +1 -1
  21. package/bin/types/sdk/AgentSessionPrompt.js +26 -1
  22. package/bin/types/sdk/AgentSessionPrompt.js.map +1 -1
  23. package/package.json +3 -4
  24. package/src/agent/remote/RemoteSession.ts +2 -2
  25. package/src/executor/messages/UIMessageTransformer.ts +20 -9
  26. package/src/index.ts +1 -1
  27. package/src/session/runtime/SessionPromptRuntime.ts +1 -3
  28. package/src/session/services/SessionStateService.ts +28 -3
  29. package/src/session/services/SessionTurnService.ts +7 -7
  30. package/src/types/sdk/AgentSessionPrompt.ts +44 -3
  31. package/tsconfig.tsbuildinfo +1 -1
@@ -146,9 +146,7 @@ export class SessionPromptRuntime {
146
146
  prompt(input: AgentSessionPromptInput): Promise<AgentSessionTurnHandle> {
147
147
  const deferredHandle = createDeferred<AgentSessionTurnHandle>();
148
148
  this.queue.push({
149
- input: {
150
- query: String(input.query || "").trim(),
151
- },
149
+ input,
152
150
  deferredHandle,
153
151
  });
154
152
  this.ensureProcessing();
@@ -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 message = this.history_store.userText({
311
- text: String(input.query || "").trim(),
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
- }) as SessionUserMessageV1;
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
- const query = String(input.query || "").trim();
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: input.promptInput.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
  }