@springbrand/agent-runtime 0.3.0-alpha.1 → 0.3.0-alpha.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@springbrand/agent-runtime",
3
- "version": "0.3.0-alpha.1",
3
+ "version": "0.3.0-alpha.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src",
@@ -668,11 +668,13 @@ export abstract class AgentRuntimeKernel<
668
668
  return submission;
669
669
  }
670
670
  if (submission.abortReason && submission.status === "pending") {
671
- return this.submissions.finish(
671
+ const terminal = await this.submissions.finish(
672
672
  submission,
673
673
  "aborted",
674
674
  submission.abortReason,
675
675
  );
676
+ await this.projectTerminal(terminal);
677
+ return terminal;
676
678
  }
677
679
  if (mode === "recovery") {
678
680
  this.telemetry.capture("turnRecovering", {
@@ -683,7 +685,11 @@ export abstract class AgentRuntimeKernel<
683
685
  await this.broadcastApprovals();
684
686
  }
685
687
  try {
686
- return await this.executeHarnessSubmission(submission, mode);
688
+ const outcome = await this.executeHarnessSubmission(submission, mode);
689
+ if (isTerminalSubmissionStatus(outcome.status)) {
690
+ await this.projectTerminal(outcome);
691
+ }
692
+ return outcome;
687
693
  } catch (error) {
688
694
  const failed = await this.submissions.finish(
689
695
  submission,
@@ -697,10 +703,57 @@ export abstract class AgentRuntimeKernel<
697
703
  : undefined,
698
704
  mode !== "fresh",
699
705
  );
706
+ await this.projectTerminal(failed);
700
707
  return failed;
701
708
  }
702
709
  }
703
710
 
711
+ /** Project one authoritative Submission terminal after Harness and client settlement. */
712
+ private async projectTerminal(submission: StoredSubmission): Promise<void> {
713
+ if (!isTerminalSubmissionStatus(submission.status)) {
714
+ throw new Error(`Cannot project unfinished Submission: ${submission.submissionId}`);
715
+ }
716
+ const events = this.activeRuntime?.snapshot.bindings.turnEvents;
717
+ if (!events) return;
718
+ const messages = await this.getMessages();
719
+ try {
720
+ await events.onResponse(
721
+ messages.flatMap((message) =>
722
+ message.role === "user" || message.role === "assistant"
723
+ ? [{
724
+ role: message.role,
725
+ text: message.parts
726
+ .filter(
727
+ (
728
+ part,
729
+ ): part is Extract<UIMessage["parts"][number], { type: "text" }> =>
730
+ part.type === "text",
731
+ )
732
+ .map((part) => part.text)
733
+ .join(""),
734
+ }]
735
+ : []
736
+ ),
737
+ );
738
+ } catch (error) {
739
+ console.warn("[runtime-turn-projection:degraded]", json({
740
+ error: errorText(error),
741
+ }));
742
+ }
743
+ try {
744
+ await events.onSubmissionTerminal?.({
745
+ submissionId: submission.submissionId,
746
+ status: submission.status,
747
+ ...(submission.error ? { error: submission.error } : {}),
748
+ resultMessageId: submission.assistantMessageId,
749
+ });
750
+ } catch (error) {
751
+ console.warn("[runtime-terminal-projection:degraded]", json({
752
+ error: errorText(error),
753
+ }));
754
+ }
755
+ }
756
+
704
757
  /** Run or recover the Submission through Pi's single durable AgentHarness. */
705
758
  private async executeHarnessSubmission(
706
759
  submission: StoredSubmission,
@@ -23,7 +23,7 @@ const TERMINAL_SUBMISSION_STATUSES: ReadonlySet<SubmissionStatus> = new Set([
23
23
  // 终态集合收口在一处防止各生命周期的判断漂移;增加状态时必须先确认它是否真的不可再继续。
24
24
  export function isTerminalSubmissionStatus(
25
25
  status: SubmissionStatus,
26
- ): boolean {
26
+ ): status is Exclude<SubmissionStatus, "pending" | "running"> {
27
27
  return TERMINAL_SUBMISSION_STATUSES.has(status);
28
28
  }
29
29