mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
docs: document embedded subscribe lifecycle
This commit is contained in:
+3
@@ -1,3 +1,5 @@
|
||||
// Soft chunking tests cover paragraph-preferred block reply splits and fenced
|
||||
// code preservation during streamed assistant output.
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
createParagraphChunkedBlockReplyHarness,
|
||||
@@ -5,6 +7,7 @@ import {
|
||||
} from "./embedded-agent-subscribe.e2e-harness.js";
|
||||
|
||||
function blockReplyTexts(onBlockReply: ReturnType<typeof vi.fn>): string[] {
|
||||
// Helper extracts just user-visible text from emitted block reply payloads.
|
||||
return onBlockReply.mock.calls.map(([payload]) => (payload as { text?: string }).text ?? "");
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -1,3 +1,5 @@
|
||||
// End-to-end subscription tests cover usage, lifecycle, tool logging,
|
||||
// messaging/media side effects, and replay-state behavior for embedded runs.
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
@@ -22,6 +24,8 @@ import { makeZeroUsageSnapshot } from "./usage.js";
|
||||
|
||||
describe("subscribeEmbeddedAgentSession", () => {
|
||||
async function flushBlockReplyCallbacks(): Promise<void> {
|
||||
// Block replies can schedule nested microtasks; drain twice before checking
|
||||
// delivery state in broad subscription tests.
|
||||
await Promise.resolve();
|
||||
await Promise.resolve();
|
||||
}
|
||||
@@ -54,6 +58,8 @@ describe("subscribeEmbeddedAgentSession", () => {
|
||||
function createSubscribedHarness(
|
||||
options: Omit<Parameters<typeof subscribeEmbeddedAgentSession>[0], "session">,
|
||||
) {
|
||||
// Default trusted media tools to built-ins so tests that opt into custom
|
||||
// builtin sets get matching local media trust behavior.
|
||||
const { session, emit } = createStubSessionHarness();
|
||||
subscribeEmbeddedAgentSession({
|
||||
session,
|
||||
@@ -135,6 +141,8 @@ describe("subscribeEmbeddedAgentSession", () => {
|
||||
}
|
||||
|
||||
async function captureToolLifecycleLogSubsystems(messageChannel?: string): Promise<string[]> {
|
||||
// Use a temporary file-backed logger so subsystem attribution is verified
|
||||
// against real serialized log lines.
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-tool-log-attribution-"));
|
||||
const logFile = path.join(tempDir, "openclaw.log");
|
||||
try {
|
||||
|
||||
+4
@@ -1,8 +1,12 @@
|
||||
// Commentary suppression tests ensure commentary-phase assistant messages do
|
||||
// not become replies or assistantTexts before tool use.
|
||||
import type { AssistantMessage } from "openclaw/plugin-sdk/llm";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { createSubscribedSessionHarness } from "./embedded-agent-subscribe.e2e-harness.js";
|
||||
|
||||
type AssistantMessageWithPhase = AssistantMessage & {
|
||||
// Some providers expose phase on the assistant message, while others only
|
||||
// include it in textSignature metadata.
|
||||
phase?: "commentary" | "final_answer";
|
||||
};
|
||||
|
||||
|
||||
+8
@@ -1,3 +1,5 @@
|
||||
// Message-tool suppression tests cover delivery tracking, source-reply mirrors,
|
||||
// and duplicate reply prevention after message tool sends.
|
||||
import type { AssistantMessage } from "openclaw/plugin-sdk/llm";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
@@ -9,6 +11,8 @@ import {
|
||||
import { subscribeEmbeddedAgentSession } from "./embedded-agent-subscribe.js";
|
||||
|
||||
function createBlockReplyHarness(blockReplyBreak: "message_end" | "text_end") {
|
||||
// Harness exposes both emitted block replies and subscription state so tests
|
||||
// can distinguish suppression from missing delivery tracking.
|
||||
const { session, emit } = createStubSessionHarness();
|
||||
const onBlockReply = vi.fn();
|
||||
const subscription = subscribeEmbeddedAgentSession({
|
||||
@@ -27,6 +31,8 @@ async function emitMessageToolLifecycle(params: {
|
||||
media?: string;
|
||||
result: unknown;
|
||||
}) {
|
||||
// Message tool sends are modeled as normal tool start/end events because the
|
||||
// subscription records pending send text at start and delivery at end.
|
||||
params.emit({
|
||||
type: "tool_execution_start",
|
||||
toolName: "message",
|
||||
@@ -97,6 +103,8 @@ describe("subscribeEmbeddedAgentSession", () => {
|
||||
});
|
||||
|
||||
it("tracks internal-ui source replies for message-tool-only final payloads", async () => {
|
||||
// internal-ui source replies are not ordinary channel sends; they are stored
|
||||
// for terminal payload mirroring in message_tool_only mode.
|
||||
const { emit, subscription } = createBlockReplyHarness("message_end");
|
||||
|
||||
await emitMessageToolLifecycle({
|
||||
|
||||
+5
@@ -1,3 +1,5 @@
|
||||
// Compaction retry subscription tests cover retry wait accounting, compaction
|
||||
// event emission, abort-on-unsubscribe, and verbose tool summary behavior.
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { onAgentEvent } from "../infra/agent-events.js";
|
||||
import { createSubscribedSessionHarness } from "./embedded-agent-subscribe.e2e-harness.js";
|
||||
@@ -8,6 +10,7 @@ function toolResultPayloadAt(
|
||||
): {
|
||||
text?: string;
|
||||
} {
|
||||
// Tool summary assertions only need text payloads from onToolResult calls.
|
||||
const [payload] = onToolResult.mock.calls[index] ?? [];
|
||||
if (!payload || typeof payload !== "object") {
|
||||
throw new Error(`expected tool result payload for call ${index + 1}`);
|
||||
@@ -17,6 +20,8 @@ function toolResultPayloadAt(
|
||||
|
||||
describe("subscribeEmbeddedAgentSession", () => {
|
||||
it("waits for multiple compaction retries before resolving", async () => {
|
||||
// Each retrying compaction requires a matching agent_end before waiters are
|
||||
// released, preventing early continuation during repeated overflow repairs.
|
||||
const { emit, subscription } = createSubscribedSessionHarness({
|
||||
runId: "run-3",
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user