@downcity/agent 1.1.188 → 1.1.195
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/executor/Executor.d.ts +4 -0
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +40 -1
- package/bin/executor/Executor.js.map +1 -1
- package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts +9 -0
- package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js +1 -0
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +2 -0
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +49 -5
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts +1 -1
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts.map +1 -1
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js +2 -0
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js.map +1 -1
- package/bin/executor/messages/SessionMessageCodec.d.ts +1 -1
- package/bin/executor/messages/SessionMessageCodec.d.ts.map +1 -1
- package/bin/executor/messages/SessionMessageCodec.js +6 -1
- package/bin/executor/messages/SessionMessageCodec.js.map +1 -1
- package/bin/executor/store/history/SessionHistoryStore.d.ts +22 -0
- package/bin/executor/store/history/SessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +7 -0
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +53 -0
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
- package/bin/executor/types/SessionMessages.d.ts +15 -2
- package/bin/executor/types/SessionMessages.d.ts.map +1 -1
- package/bin/executor/types/SessionMessages.js +9 -1
- package/bin/executor/types/SessionMessages.js.map +1 -1
- package/bin/index.d.ts +1 -0
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js.map +1 -1
- package/bin/session/browse/Browse.d.ts.map +1 -1
- package/bin/session/browse/Browse.js +22 -0
- package/bin/session/browse/Browse.js.map +1 -1
- package/bin/session/services/SessionStateService.d.ts +21 -1
- package/bin/session/services/SessionStateService.d.ts.map +1 -1
- package/bin/session/services/SessionStateService.js +101 -11
- 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 +9 -0
- package/bin/session/services/SessionTurnService.js.map +1 -1
- package/bin/session/services/SessionViewService.d.ts.map +1 -1
- package/bin/session/services/SessionViewService.js +42 -8
- package/bin/session/services/SessionViewService.js.map +1 -1
- package/bin/types/agent/SessionTypes.d.ts +22 -1
- package/bin/types/agent/SessionTypes.d.ts.map +1 -1
- package/bin/types/executor/SessionRunContext.d.ts +10 -0
- package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
- package/bin/types/sdk/AgentSessionEvent.d.ts +2 -1
- package/bin/types/sdk/AgentSessionEvent.d.ts.map +1 -1
- package/bin/types/sdk/AgentSessionOperation.d.ts +99 -0
- package/bin/types/sdk/AgentSessionOperation.d.ts.map +1 -0
- package/bin/types/sdk/AgentSessionOperation.js +10 -0
- package/bin/types/sdk/AgentSessionOperation.js.map +1 -0
- package/package.json +3 -3
- package/scripts/session-operation-message.test.mjs +182 -0
- package/src/executor/Executor.ts +49 -1
- package/src/executor/composer/compaction/SessionCompactionComposer.ts +10 -0
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.ts +1 -0
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +64 -5
- package/src/executor/composer/history/jsonl/JsonlSessionHistoryComposer.ts +5 -1
- package/src/executor/messages/SessionMessageCodec.ts +11 -2
- package/src/executor/store/history/SessionHistoryStore.ts +27 -0
- package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +66 -0
- package/src/executor/types/SessionMessages.ts +26 -2
- package/src/index.ts +7 -0
- package/src/session/browse/Browse.ts +24 -0
- package/src/session/services/SessionStateService.ts +125 -11
- package/src/session/services/SessionTurnService.ts +8 -0
- package/src/session/services/SessionViewService.ts +47 -10
- package/src/types/agent/SessionTypes.ts +22 -1
- package/src/types/executor/SessionRunContext.ts +20 -0
- package/src/types/sdk/AgentSessionEvent.ts +2 -0
- package/src/types/sdk/AgentSessionOperation.ts +125 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/index.ts
CHANGED
|
@@ -55,6 +55,13 @@ export type {
|
|
|
55
55
|
AgentSessionSubscriber,
|
|
56
56
|
AgentSessionUnsubscribe,
|
|
57
57
|
} from "./types/sdk/AgentSessionEvent.js";
|
|
58
|
+
export type {
|
|
59
|
+
AgentSessionOperationCallback,
|
|
60
|
+
AgentSessionOperationEvent,
|
|
61
|
+
AgentSessionOperationName,
|
|
62
|
+
AgentSessionOperationRecord,
|
|
63
|
+
AgentSessionOperationStatus,
|
|
64
|
+
} from "./types/sdk/AgentSessionOperation.js";
|
|
58
65
|
export type { AgentSessionPromptInput, SessionUserMessagePart } from "./types/sdk/AgentSessionPrompt.js";
|
|
59
66
|
export type { AgentSessionStopResult } from "./types/sdk/AgentSessionStop.js";
|
|
60
67
|
export type {
|
|
@@ -29,6 +29,7 @@ import type {
|
|
|
29
29
|
SessionMessageV1,
|
|
30
30
|
SessionMetadataV1,
|
|
31
31
|
} from "@/executor/types/SessionMessages.js";
|
|
32
|
+
import { isSessionOperationMessage } from "@/executor/types/SessionMessages.js";
|
|
32
33
|
import type { SessionHistoryMetaV1 } from "@/executor/types/SessionHistoryMeta.js";
|
|
33
34
|
import { pickLastSuccessfulChatSendText } from "@/executor/messages/UserVisibleText.js";
|
|
34
35
|
import { getSdkAgentSessionMessagesPath } from "@/session/storage/Paths.js";
|
|
@@ -240,6 +241,15 @@ function toTimelineEvent(params: {
|
|
|
240
241
|
...(typeof metadata?.source === "string" ? { source: metadata.source } : {}),
|
|
241
242
|
text: params.text,
|
|
242
243
|
...(params.toolName ? { toolName: params.toolName } : {}),
|
|
244
|
+
...(params.role === "operation" && metadata?.operation?.operationId
|
|
245
|
+
? { operationId: metadata.operation.operationId }
|
|
246
|
+
: {}),
|
|
247
|
+
...(params.role === "operation" && metadata?.operation?.name
|
|
248
|
+
? { operationName: metadata.operation.name }
|
|
249
|
+
: {}),
|
|
250
|
+
...(params.role === "operation" && metadata?.operation?.status
|
|
251
|
+
? { operationStatus: metadata.operation.status }
|
|
252
|
+
: {}),
|
|
243
253
|
};
|
|
244
254
|
}
|
|
245
255
|
|
|
@@ -249,6 +259,20 @@ function toTimelineEvent(params: {
|
|
|
249
259
|
export function toSessionTimelineEvents(
|
|
250
260
|
message: SessionMessageV1,
|
|
251
261
|
): AgentSessionTimelineEvent[] {
|
|
262
|
+
if (isSessionOperationMessage(message)) {
|
|
263
|
+
const metadata = (message.metadata || null) as SessionMetadataV1 | null;
|
|
264
|
+
return [
|
|
265
|
+
toTimelineEvent({
|
|
266
|
+
message,
|
|
267
|
+
role: "operation",
|
|
268
|
+
text:
|
|
269
|
+
String(metadata?.operation?.label || "").trim() ||
|
|
270
|
+
resolveSessionMessagePreview(message),
|
|
271
|
+
sequence: 0,
|
|
272
|
+
}),
|
|
273
|
+
];
|
|
274
|
+
}
|
|
275
|
+
|
|
252
276
|
if (message.role !== "assistant") {
|
|
253
277
|
return [
|
|
254
278
|
toTimelineEvent({
|
|
@@ -30,6 +30,10 @@ import type {
|
|
|
30
30
|
import type {
|
|
31
31
|
AgentSessionEvent,
|
|
32
32
|
} from "@/types/sdk/AgentSessionEvent.js";
|
|
33
|
+
import type {
|
|
34
|
+
AgentSessionOperationEvent,
|
|
35
|
+
AgentSessionOperationRecord,
|
|
36
|
+
} from "@/types/sdk/AgentSessionOperation.js";
|
|
33
37
|
import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
|
|
34
38
|
import type {
|
|
35
39
|
SessionMessageV1,
|
|
@@ -80,6 +84,20 @@ type SessionStateServiceOptions = {
|
|
|
80
84
|
publish_event: (event: AgentSessionEvent) => void;
|
|
81
85
|
};
|
|
82
86
|
|
|
87
|
+
type SessionSetOptions = {
|
|
88
|
+
/**
|
|
89
|
+
* 是否写入并发布 model-switching operation。
|
|
90
|
+
*
|
|
91
|
+
* 说明(中文)
|
|
92
|
+
* - 公开 `session.set()` 应保持默认开启。
|
|
93
|
+
* - fork 内部复制模型配置时关闭,避免污染 forked session 历史。
|
|
94
|
+
*/
|
|
95
|
+
emit_operation?: boolean;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
type EmitOperationInput = Omit<AgentSessionOperationRecord, "operationId"> &
|
|
99
|
+
Partial<Pick<AgentSessionOperationRecord, "operationId">>;
|
|
100
|
+
|
|
83
101
|
/**
|
|
84
102
|
* 本地 Session 状态与持久化服务。
|
|
85
103
|
*/
|
|
@@ -203,18 +221,66 @@ export class SessionStateService {
|
|
|
203
221
|
/**
|
|
204
222
|
* 写入当前 session 配置。
|
|
205
223
|
*/
|
|
206
|
-
async set(input: AgentSessionSetInput): Promise<void> {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
224
|
+
async set(input: AgentSessionSetInput, options?: SessionSetOptions): Promise<void> {
|
|
225
|
+
const should_emit_operation = options?.emit_operation !== false;
|
|
226
|
+
const previous_model_label = this.state.sessionConfig.modelLabel;
|
|
227
|
+
const next_model_label = input.model
|
|
228
|
+
? inferAgentModelLabel(input.model)
|
|
229
|
+
: undefined;
|
|
230
|
+
const operation_id = `model-switching:${this.session_id}:${Date.now()}:${generateId()}`;
|
|
231
|
+
|
|
232
|
+
if (input.model && should_emit_operation) {
|
|
233
|
+
await this.emit_operation_event({
|
|
234
|
+
operationId: operation_id,
|
|
235
|
+
name: "model-switching",
|
|
236
|
+
status: "started",
|
|
237
|
+
label: "Switching session model",
|
|
238
|
+
result: {
|
|
239
|
+
...(previous_model_label ? { previousModelLabel: previous_model_label } : {}),
|
|
240
|
+
...(next_model_label ? { modelLabel: next_model_label } : {}),
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
if (input.model) {
|
|
247
|
+
this.state.sessionConfig.model = normalizeAgentModel(input.model);
|
|
248
|
+
this.state.sessionConfig.modelLabel = next_model_label;
|
|
249
|
+
this.executor.clearExecutor();
|
|
250
|
+
}
|
|
251
|
+
await patchSessionModelLabel({
|
|
252
|
+
projectRoot: this.project_root,
|
|
253
|
+
agentId: this.agent_id,
|
|
254
|
+
sessionId: this.session_id,
|
|
255
|
+
model: this.state.sessionConfig.model,
|
|
256
|
+
});
|
|
257
|
+
} catch (error) {
|
|
258
|
+
if (input.model && should_emit_operation) {
|
|
259
|
+
await this.emit_operation_event({
|
|
260
|
+
operationId: operation_id,
|
|
261
|
+
name: "model-switching",
|
|
262
|
+
status: "failed",
|
|
263
|
+
label: "Session model switch failed",
|
|
264
|
+
error: error instanceof Error ? error.message : String(error),
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (input.model && should_emit_operation) {
|
|
271
|
+
await this.emit_operation_event({
|
|
272
|
+
operationId: operation_id,
|
|
273
|
+
name: "model-switching",
|
|
274
|
+
status: "finished",
|
|
275
|
+
label: "Session model switched",
|
|
276
|
+
result: {
|
|
277
|
+
...(previous_model_label ? { previousModelLabel: previous_model_label } : {}),
|
|
278
|
+
...(this.state.sessionConfig.modelLabel
|
|
279
|
+
? { modelLabel: this.state.sessionConfig.modelLabel }
|
|
280
|
+
: {}),
|
|
281
|
+
},
|
|
282
|
+
});
|
|
211
283
|
}
|
|
212
|
-
await patchSessionModelLabel({
|
|
213
|
-
projectRoot: this.project_root,
|
|
214
|
-
agentId: this.agent_id,
|
|
215
|
-
sessionId: this.session_id,
|
|
216
|
-
model: this.state.sessionConfig.model,
|
|
217
|
-
});
|
|
218
284
|
}
|
|
219
285
|
|
|
220
286
|
/**
|
|
@@ -301,6 +367,54 @@ export class SessionStateService {
|
|
|
301
367
|
});
|
|
302
368
|
}
|
|
303
369
|
|
|
370
|
+
/**
|
|
371
|
+
* 持久化一条 operation message。
|
|
372
|
+
*/
|
|
373
|
+
async persist_operation_event(
|
|
374
|
+
event: AgentSessionOperationEvent,
|
|
375
|
+
): Promise<void> {
|
|
376
|
+
const message = this.history_store.operation({
|
|
377
|
+
operation: {
|
|
378
|
+
operationId: event.operationId,
|
|
379
|
+
name: event.name,
|
|
380
|
+
status: event.status,
|
|
381
|
+
...(event.turnId ? { turnId: event.turnId } : {}),
|
|
382
|
+
...(event.label ? { label: event.label } : {}),
|
|
383
|
+
...(event.reason ? { reason: event.reason } : {}),
|
|
384
|
+
...(typeof event.progress === "number" ? { progress: event.progress } : {}),
|
|
385
|
+
...(event.result !== undefined ? { result: event.result } : {}),
|
|
386
|
+
...(event.error ? { error: event.error } : {}),
|
|
387
|
+
...(event.visible === false ? { visible: false } : {}),
|
|
388
|
+
},
|
|
389
|
+
metadata: {
|
|
390
|
+
sessionId: this.session_id,
|
|
391
|
+
},
|
|
392
|
+
});
|
|
393
|
+
await this.history_store.append(message);
|
|
394
|
+
await this.touch_metadata();
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* 写入并发布一条 operation。
|
|
399
|
+
*/
|
|
400
|
+
async emit_operation_event(input: EmitOperationInput): Promise<void> {
|
|
401
|
+
const operation_id =
|
|
402
|
+
String(input.operationId || "").trim() ||
|
|
403
|
+
`${input.name}:${this.session_id}:${Date.now()}:${generateId()}`;
|
|
404
|
+
const event: AgentSessionOperationEvent = {
|
|
405
|
+
type: "operation",
|
|
406
|
+
sessionId: this.session_id,
|
|
407
|
+
...input,
|
|
408
|
+
operationId: operation_id,
|
|
409
|
+
};
|
|
410
|
+
try {
|
|
411
|
+
await this.persist_operation_event(event);
|
|
412
|
+
} catch {
|
|
413
|
+
// operation 持久化失败不应阻断宿主操作。
|
|
414
|
+
}
|
|
415
|
+
this.publish_event(event);
|
|
416
|
+
}
|
|
417
|
+
|
|
304
418
|
/**
|
|
305
419
|
* 构造并持久化一条 prompt user 消息。
|
|
306
420
|
*/
|
|
@@ -198,6 +198,14 @@ export class SessionTurnService {
|
|
|
198
198
|
this.publish_event(session_event);
|
|
199
199
|
}
|
|
200
200
|
},
|
|
201
|
+
onOperationCallback: async (event) => {
|
|
202
|
+
try {
|
|
203
|
+
await this.state_service.persist_operation_event(event);
|
|
204
|
+
} catch {
|
|
205
|
+
// operation 持久化失败不应阻断当前 turn。
|
|
206
|
+
}
|
|
207
|
+
this.publish_event(event);
|
|
208
|
+
},
|
|
201
209
|
injectedUserMessages: [],
|
|
202
210
|
deferredPersistedUserMessages: [],
|
|
203
211
|
pendingAssistantFileParts: [],
|
|
@@ -278,19 +278,56 @@ export class SessionViewService<TSession extends Pick<AgentSession, "set">> {
|
|
|
278
278
|
!message_id
|
|
279
279
|
? messages
|
|
280
280
|
: this.resolve_fork_messages(messages, message_id);
|
|
281
|
+
const operation_id = `history-forking:${this.session_id}:${Date.now()}:${nanoid(8)}`;
|
|
281
282
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
283
|
+
await this.state_service.emit_operation_event({
|
|
284
|
+
operationId: operation_id,
|
|
285
|
+
name: "history-forking",
|
|
286
|
+
status: "started",
|
|
287
|
+
label: "Forking session history",
|
|
288
|
+
result: {
|
|
289
|
+
messageCount: fork_messages.length,
|
|
290
|
+
...(message_id ? { messageId: message_id } : {}),
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
try {
|
|
295
|
+
const forked_bundle = await this.create_fork_session(
|
|
296
|
+
`fork-${Date.now()}-${nanoid(8)}`,
|
|
297
|
+
);
|
|
298
|
+
const forked = forked_bundle.session;
|
|
299
|
+
const session_config = this.state_service.get_config();
|
|
300
|
+
if (session_config.model) {
|
|
301
|
+
await forked_bundle.state_service.set(
|
|
302
|
+
{
|
|
303
|
+
model: session_config.model,
|
|
304
|
+
},
|
|
305
|
+
{ emit_operation: false },
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
await this.append_fork_messages(forked_bundle, fork_messages);
|
|
309
|
+
await this.state_service.emit_operation_event({
|
|
310
|
+
operationId: operation_id,
|
|
311
|
+
name: "history-forking",
|
|
312
|
+
status: "finished",
|
|
313
|
+
label: "Session history forked",
|
|
314
|
+
result: {
|
|
315
|
+
forkedSessionId: String((forked as { id?: unknown }).id || ""),
|
|
316
|
+
messageCount: fork_messages.length,
|
|
317
|
+
...(message_id ? { messageId: message_id } : {}),
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
return forked;
|
|
321
|
+
} catch (error) {
|
|
322
|
+
await this.state_service.emit_operation_event({
|
|
323
|
+
operationId: operation_id,
|
|
324
|
+
name: "history-forking",
|
|
325
|
+
status: "failed",
|
|
326
|
+
label: "Session history fork failed",
|
|
327
|
+
error: error instanceof Error ? error.message : String(error),
|
|
290
328
|
});
|
|
329
|
+
throw error;
|
|
291
330
|
}
|
|
292
|
-
await this.append_fork_messages(forked_bundle, fork_messages);
|
|
293
|
-
return forked;
|
|
294
331
|
}
|
|
295
332
|
|
|
296
333
|
private resolve_fork_messages(
|
|
@@ -99,7 +99,7 @@ export interface AgentSessionTimelineEvent {
|
|
|
99
99
|
* 说明(中文)
|
|
100
100
|
* - `tool-call` / `tool-result` 用于把 assistant 内部工具过程平铺给 UI。
|
|
101
101
|
*/
|
|
102
|
-
role: "user" | "assistant" | "tool-call" | "tool-result";
|
|
102
|
+
role: "user" | "assistant" | "tool-call" | "tool-result" | "operation";
|
|
103
103
|
/** 事件时间戳(毫秒)。 */
|
|
104
104
|
ts?: number;
|
|
105
105
|
/** 事件所属消息种类。 */
|
|
@@ -115,6 +115,27 @@ export interface AgentSessionTimelineEvent {
|
|
|
115
115
|
* - 仅 `tool-call` / `tool-result` 这类事件通常会携带该字段。
|
|
116
116
|
*/
|
|
117
117
|
toolName?: string;
|
|
118
|
+
/**
|
|
119
|
+
* 当前 operation ID。
|
|
120
|
+
*
|
|
121
|
+
* 说明(中文)
|
|
122
|
+
* - 仅 `role=operation` 的事件通常会携带该字段。
|
|
123
|
+
*/
|
|
124
|
+
operationId?: string;
|
|
125
|
+
/**
|
|
126
|
+
* 当前 operation 名称。
|
|
127
|
+
*
|
|
128
|
+
* 说明(中文)
|
|
129
|
+
* - 仅 `role=operation` 的事件通常会携带该字段。
|
|
130
|
+
*/
|
|
131
|
+
operationName?: string;
|
|
132
|
+
/**
|
|
133
|
+
* 当前 operation 状态。
|
|
134
|
+
*
|
|
135
|
+
* 说明(中文)
|
|
136
|
+
* - 仅 `role=operation` 的事件通常会携带该字段。
|
|
137
|
+
*/
|
|
138
|
+
operationStatus?: string;
|
|
118
139
|
}
|
|
119
140
|
|
|
120
141
|
/**
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
* - tool 深层回调等无法直接传参的场景,才通过 run scope 间接读取这个对象。
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import type {
|
|
11
|
+
AgentSessionOperationCallback,
|
|
12
|
+
AgentSessionOperationEvent,
|
|
13
|
+
AgentSessionOperationRecord,
|
|
14
|
+
} from "@/types/sdk/AgentSessionOperation.js";
|
|
10
15
|
import type {
|
|
11
16
|
SessionAssistantStepCallback,
|
|
12
17
|
SessionUiMessageChunkCallback,
|
|
@@ -66,6 +71,15 @@ export interface SessionRunContext {
|
|
|
66
71
|
*/
|
|
67
72
|
onUiMessageChunkCallback?: SessionUiMessageChunkCallback;
|
|
68
73
|
|
|
74
|
+
/**
|
|
75
|
+
* operation 发布回调。
|
|
76
|
+
*
|
|
77
|
+
* 关键点(中文)
|
|
78
|
+
* - 用于把 compaction 等辅助操作转成 session event 与 operation message。
|
|
79
|
+
* - operation 不代表 assistant 正文,也不会进入 LLM 输入。
|
|
80
|
+
*/
|
|
81
|
+
onOperationCallback?: AgentSessionOperationCallback;
|
|
82
|
+
|
|
69
83
|
/**
|
|
70
84
|
* 当前 turn 的取消信号。
|
|
71
85
|
*
|
|
@@ -101,3 +115,9 @@ export interface SessionRunContext {
|
|
|
101
115
|
*/
|
|
102
116
|
pendingAssistantFileParts: FileUIPart[];
|
|
103
117
|
}
|
|
118
|
+
|
|
119
|
+
export type {
|
|
120
|
+
AgentSessionOperationCallback,
|
|
121
|
+
AgentSessionOperationEvent,
|
|
122
|
+
AgentSessionOperationRecord,
|
|
123
|
+
};
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import type { JsonValue } from "@/types/common/Json.js";
|
|
10
10
|
import type { SessionAssistantStepVisibility } from "@/executor/types/SessionRun.js";
|
|
11
|
+
import type { AgentSessionOperationEvent } from "@/types/sdk/AgentSessionOperation.js";
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* 单个 turn 开始事件。
|
|
@@ -354,6 +355,7 @@ export type AgentSessionEvent =
|
|
|
354
355
|
| AgentSessionToolApprovalResultEvent
|
|
355
356
|
| AgentSessionAssistantStepEvent
|
|
356
357
|
| AgentSessionTitleEvent
|
|
358
|
+
| AgentSessionOperationEvent
|
|
357
359
|
| AgentSessionTurnFinishEvent
|
|
358
360
|
| AgentSessionErrorEvent;
|
|
359
361
|
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Session operation 类型定义。
|
|
3
|
+
*
|
|
4
|
+
* 关键点(中文)
|
|
5
|
+
* - operation 描述 session 内部正在发生的辅助操作,不代表 assistant 正文。
|
|
6
|
+
* - operation 可以同时作为订阅事件发布,也可以作为 UIMessage 持久化到 JSONL。
|
|
7
|
+
* - operation message 只用于前端时间线与调试,不应进入 LLM 输入。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { JsonValue } from "@/types/common/Json.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Session operation 当前状态。
|
|
14
|
+
*/
|
|
15
|
+
export type AgentSessionOperationStatus =
|
|
16
|
+
| "started"
|
|
17
|
+
| "progress"
|
|
18
|
+
| "finished"
|
|
19
|
+
| "skipped"
|
|
20
|
+
| "failed";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Session operation 名称。
|
|
24
|
+
*
|
|
25
|
+
* 说明(中文)
|
|
26
|
+
* - 内置名称用于 SDK 与前端约定常见辅助操作。
|
|
27
|
+
* - 字符串扩展允许 plugin 或宿主运行时声明自己的 operation。
|
|
28
|
+
*/
|
|
29
|
+
export type AgentSessionOperationName =
|
|
30
|
+
| "compacting"
|
|
31
|
+
| "model-switching"
|
|
32
|
+
| "history-forking"
|
|
33
|
+
| (string & {});
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Session operation 记录。
|
|
37
|
+
*/
|
|
38
|
+
export interface AgentSessionOperationRecord {
|
|
39
|
+
/**
|
|
40
|
+
* 同一个 operation 生命周期内稳定复用的 ID。
|
|
41
|
+
*/
|
|
42
|
+
operationId: string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 当前 operation 名称。
|
|
46
|
+
*/
|
|
47
|
+
name: AgentSessionOperationName;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 当前 operation 状态。
|
|
51
|
+
*/
|
|
52
|
+
status: AgentSessionOperationStatus;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 当前 operation 关联的 turn 标识。
|
|
56
|
+
*
|
|
57
|
+
* 说明(中文)
|
|
58
|
+
* - turn 内触发的 operation 应写入该字段。
|
|
59
|
+
* - session 级 operation 可以省略。
|
|
60
|
+
*/
|
|
61
|
+
turnId?: string;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 面向用户展示的短文本。
|
|
65
|
+
*/
|
|
66
|
+
label?: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 机器可读原因。
|
|
70
|
+
*
|
|
71
|
+
* 示例(中文)
|
|
72
|
+
* - `under_budget`:未达到压缩阈值。
|
|
73
|
+
* - `summary_fallback`:摘要生成失败后使用降级摘要。
|
|
74
|
+
*/
|
|
75
|
+
reason?: string;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 当前 operation 进度,范围 0 到 1。
|
|
79
|
+
*
|
|
80
|
+
* 说明(中文)
|
|
81
|
+
* - 无法估算进度时省略。
|
|
82
|
+
*/
|
|
83
|
+
progress?: number;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* operation 完成后产生的轻量结果。
|
|
87
|
+
*/
|
|
88
|
+
result?: JsonValue;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* operation 失败时的错误文本。
|
|
92
|
+
*/
|
|
93
|
+
error?: string;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* 是否建议前端展示。
|
|
97
|
+
*
|
|
98
|
+
* 说明(中文)
|
|
99
|
+
* - 默认视为 `true`。
|
|
100
|
+
* - 调试或审计类辅助事件可显式写入 `false`。
|
|
101
|
+
*/
|
|
102
|
+
visible?: boolean;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Session operation 订阅事件。
|
|
107
|
+
*/
|
|
108
|
+
export interface AgentSessionOperationEvent extends AgentSessionOperationRecord {
|
|
109
|
+
/**
|
|
110
|
+
* 当前事件类型。
|
|
111
|
+
*/
|
|
112
|
+
type: "operation";
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 当前 session 唯一标识。
|
|
116
|
+
*/
|
|
117
|
+
sessionId: string;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Session operation 发布回调。
|
|
122
|
+
*/
|
|
123
|
+
export type AgentSessionOperationCallback = (
|
|
124
|
+
operation: AgentSessionOperationEvent,
|
|
125
|
+
) => Promise<void>;
|