@springbrand/agent-runtime 0.1.3-alpha.6 → 0.1.3-alpha.7
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/package.json +1 -1
- package/src/kernel/bindings.ts +27 -0
- package/src/runtime-assembler.ts +2 -0
- package/src/runtime-definition.ts +2 -0
- package/src/runtime.ts +30 -1
package/package.json
CHANGED
package/src/kernel/bindings.ts
CHANGED
|
@@ -730,6 +730,22 @@ export interface RuntimeModelUsageEvent {
|
|
|
730
730
|
};
|
|
731
731
|
}
|
|
732
732
|
|
|
733
|
+
/**
|
|
734
|
+
* 一次 Tool 调用刚开始,还不知道它会怎么结束。
|
|
735
|
+
*
|
|
736
|
+
* @remarks
|
|
737
|
+
* 结算事件刻意不带参数,因为它只用来记账;开始事件必须带,因为它唯一的用处
|
|
738
|
+
* 就是让 Host 立刻知道「正在写的是什么」——只有工具名的话,「write 开始了」
|
|
739
|
+
* 和「一个网页正在生成」之间的差别就丢了,而后者才是盯着屏幕的人要看的。
|
|
740
|
+
* 参数本来就随 Tool 输入里程碑落库,这里没有多暴露任何东西。
|
|
741
|
+
*/
|
|
742
|
+
export interface RuntimeToolStartEvent {
|
|
743
|
+
readonly submissionId: string;
|
|
744
|
+
readonly toolCallId: string;
|
|
745
|
+
readonly toolName: string;
|
|
746
|
+
readonly args: unknown;
|
|
747
|
+
}
|
|
748
|
+
|
|
733
749
|
export interface RuntimeToolSettlementEvent {
|
|
734
750
|
readonly eventId: string;
|
|
735
751
|
readonly submissionId: string;
|
|
@@ -761,6 +777,17 @@ export interface RuntimeTurnEventsPort {
|
|
|
761
777
|
): Promise<void>;
|
|
762
778
|
/** 投递 Assistant 或 Compaction 的原始 provider usage。 */
|
|
763
779
|
onModelUsage?(event: RuntimeModelUsageEvent): Promise<void>;
|
|
780
|
+
/**
|
|
781
|
+
* 投递一次 Tool 开始执行的事件,带上它的参数。
|
|
782
|
+
*
|
|
783
|
+
* @remarks
|
|
784
|
+
* 只在这次调用第一次落下 durable intent 时投递:恢复重放不会再报一次开始,
|
|
785
|
+
* 否则一个早就结束的 Tool 会在几分钟后再宣布自己「正在跑」。
|
|
786
|
+
*
|
|
787
|
+
* 这条是活性信号而不是账,所以不进 durable outbox:迟到的开始事件本身就是
|
|
788
|
+
* 错的,投递失败就让它丢掉,最终状态由 `onToolSettled` 兜底。
|
|
789
|
+
*/
|
|
790
|
+
onToolStart?(event: RuntimeToolStartEvent): Promise<void>;
|
|
764
791
|
/** 投递不含参数与结果的 Tool 最终结算事件。 */
|
|
765
792
|
onToolSettled?(event: RuntimeToolSettlementEvent): Promise<void>;
|
|
766
793
|
onApproval?(input: {
|
package/src/runtime-assembler.ts
CHANGED
|
@@ -632,6 +632,7 @@ function hooksToTurnEventsPort<
|
|
|
632
632
|
if (
|
|
633
633
|
!hooks.onTurnEnd &&
|
|
634
634
|
!hooks.onModelUsage &&
|
|
635
|
+
!hooks.onToolStart &&
|
|
635
636
|
!hooks.onToolSettled &&
|
|
636
637
|
!hooks.onApproval &&
|
|
637
638
|
!hooks.onActivityChanged &&
|
|
@@ -644,6 +645,7 @@ function hooksToTurnEventsPort<
|
|
|
644
645
|
? (messages) => hooks.onTurnEnd!(ctx, messages)
|
|
645
646
|
: async () => undefined,
|
|
646
647
|
...(hooks.onModelUsage ? { onModelUsage: hooks.onModelUsage } : {}),
|
|
648
|
+
...(hooks.onToolStart ? { onToolStart: hooks.onToolStart } : {}),
|
|
647
649
|
...(hooks.onToolSettled ? { onToolSettled: hooks.onToolSettled } : {}),
|
|
648
650
|
...(hooks.onApproval ? { onApproval: hooks.onApproval } : {}),
|
|
649
651
|
...(hooks.onActivityChanged
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
RuntimePlatformPort,
|
|
7
7
|
RuntimeProviderPort,
|
|
8
8
|
RuntimeSkillScriptPolicy,
|
|
9
|
+
RuntimeToolStartEvent,
|
|
9
10
|
RuntimeTurnMessage,
|
|
10
11
|
} from "./kernel/bindings";
|
|
11
12
|
import type {
|
|
@@ -135,6 +136,7 @@ export interface RuntimeAgentHooks<
|
|
|
135
136
|
messages: readonly RuntimeTurnMessage[],
|
|
136
137
|
) => Promise<void>;
|
|
137
138
|
readonly onModelUsage?: (event: RuntimeModelUsageEvent) => Promise<void>;
|
|
139
|
+
readonly onToolStart?: (event: RuntimeToolStartEvent) => Promise<void>;
|
|
138
140
|
readonly onToolSettled?: (event: RuntimeToolSettlementEvent) => Promise<void>;
|
|
139
141
|
readonly onApproval?: (input: ApprovalHookInput) => Promise<void>;
|
|
140
142
|
readonly onActivityChanged?: (
|
package/src/runtime.ts
CHANGED
|
@@ -1505,12 +1505,41 @@ export abstract class AgentRuntimeKernel<
|
|
|
1505
1505
|
kind: "record-tool-input",
|
|
1506
1506
|
record: input,
|
|
1507
1507
|
});
|
|
1508
|
-
|
|
1508
|
+
const appended = this.db.transaction(() =>
|
|
1509
1509
|
this.applyPiRecoveryMutations(
|
|
1510
1510
|
submission,
|
|
1511
1511
|
decision.mutations,
|
|
1512
1512
|
),
|
|
1513
1513
|
);
|
|
1514
|
+
if (appended) this.announceToolStart(submission.submissionId, input);
|
|
1515
|
+
return appended;
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
// 作用:把「这个 Tool 开始跑了」连同参数投给 Host。
|
|
1519
|
+
// 调用:durable intent 第一次落库之后,Tool 真正执行之前。
|
|
1520
|
+
// 原因:人在等的是「正在写一个网页」,不是三十秒后的「write 完成了」。
|
|
1521
|
+
//
|
|
1522
|
+
// 只在第一次落库时发:恢复重放会再走一遍这条路径,那时 Tool 可能早就结束了,
|
|
1523
|
+
// 再宣布一次「开始」比不宣布更糟。也不进 durable outbox —— 这是活性信号,
|
|
1524
|
+
// 补投一条迟到的开始事件没有意义,投失败就算了,终态有 onToolSettled 兜底。
|
|
1525
|
+
private announceToolStart(
|
|
1526
|
+
submissionId: string,
|
|
1527
|
+
input: PiToolInputRecord,
|
|
1528
|
+
): void {
|
|
1529
|
+
const turnEvents = this.turnEventsPort();
|
|
1530
|
+
if (!turnEvents?.onToolStart) return;
|
|
1531
|
+
const delivery = turnEvents.onToolStart({
|
|
1532
|
+
submissionId,
|
|
1533
|
+
toolCallId: input.toolCallId,
|
|
1534
|
+
toolName: input.toolName,
|
|
1535
|
+
args: input.input,
|
|
1536
|
+
}).catch((error: unknown) => {
|
|
1537
|
+
console.warn(
|
|
1538
|
+
"[runtime-tool-start:degraded]",
|
|
1539
|
+
json({ toolCallId: input.toolCallId, error: errorText(error) }),
|
|
1540
|
+
);
|
|
1541
|
+
});
|
|
1542
|
+
this.ctx.waitUntil(delivery);
|
|
1514
1543
|
}
|
|
1515
1544
|
|
|
1516
1545
|
// 作用:持久化一次 Tool 结果,并推进相应的恢复里程碑。
|