



















1-export type LiveTransportStandardScenarioId =
2-| "canary"
3-| "mention-gating"
4-| "allowlist-block"
5-| "top-level-reply-shape"
6-| "restart-resume"
7-| "thread-follow-up"
8-| "thread-isolation"
9-| "reaction-observation"
10-| "help-command";
1+import {
2+LIVE_TRANSPORT_BASELINE_STANDARD_SCENARIO_IDS,
3+collectLiveTransportStandardScenarioCoverage,
4+findMissingLiveTransportStandardScenarios,
5+type LiveTransportStandardScenarioId,
6+} from "openclaw/plugin-sdk/qa-runtime";
11712-export type LiveTransportScenarioDefinition<TId extends string = string> = {
13-id: TId;
14-standardId?: LiveTransportStandardScenarioId;
15-timeoutMs: number;
16-title: string;
17-};
18-19-type LiveTransportStandardScenarioDefinition = {
20-description: string;
21-id: LiveTransportStandardScenarioId;
22-title: string;
23-};
8+export {
9+LIVE_TRANSPORT_BASELINE_STANDARD_SCENARIO_IDS,
10+collectLiveTransportStandardScenarioCoverage,
11+findMissingLiveTransportStandardScenarios,
12+selectLiveTransportScenarios,
13+type LiveTransportScenarioDefinition,
14+type LiveTransportStandardScenarioId,
15+} from "openclaw/plugin-sdk/qa-runtime";
24162517export type LiveTransportCoverageMember = {
2618scenarioId?: string;
@@ -42,63 +34,6 @@ export type LiveTransportCoverageLaneSummary = {
4234transportId: string;
4335};
443645-const LIVE_TRANSPORT_STANDARD_SCENARIOS: readonly LiveTransportStandardScenarioDefinition[] = [
46-{
47-id: "canary",
48-title: "Transport canary",
49-description: "The lane can trigger one known-good reply on the real transport.",
50-},
51-{
52-id: "mention-gating",
53-title: "Mention gating",
54-description: "Messages without the required mention do not trigger a reply.",
55-},
56-{
57-id: "allowlist-block",
58-title: "Sender allowlist block",
59-description: "Non-allowlisted senders do not trigger a reply.",
60-},
61-{
62-id: "top-level-reply-shape",
63-title: "Top-level reply shape",
64-description: "Top-level replies stay top-level when the lane is configured that way.",
65-},
66-{
67-id: "restart-resume",
68-title: "Restart resume",
69-description: "The lane still responds after a gateway restart.",
70-},
71-{
72-id: "thread-follow-up",
73-title: "Thread follow-up",
74-description: "Threaded prompts receive threaded replies with the expected relation metadata.",
75-},
76-{
77-id: "thread-isolation",
78-title: "Thread isolation",
79-description: "Fresh top-level prompts stay out of prior threads.",
80-},
81-{
82-id: "reaction-observation",
83-title: "Reaction observation",
84-description: "Reaction events are observed and normalized correctly.",
85-},
86-{
87-id: "help-command",
88-title: "Help command",
89-description: "The transport-specific help command path replies successfully.",
90-},
91-] as const;
92-93-export const LIVE_TRANSPORT_BASELINE_STANDARD_SCENARIO_IDS: readonly LiveTransportStandardScenarioId[] =
94-[
95-"canary",
96-"mention-gating",
97-"allowlist-block",
98-"top-level-reply-shape",
99-"restart-resume",
100-] as const;
101-10237export const LIVE_TRANSPORT_COVERAGE_LANES: readonly LiveTransportCoverageLane[] = [
10338{
10439transportId: "discord",
@@ -141,74 +76,6 @@ export const LIVE_TRANSPORT_COVERAGE_LANES: readonly LiveTransportCoverageLane[]
14176},
14277] as const;
14378144-const LIVE_TRANSPORT_STANDARD_SCENARIO_ID_SET = new Set(
145-LIVE_TRANSPORT_STANDARD_SCENARIOS.map((scenario) => scenario.id),
146-);
147-148-function assertKnownStandardScenarioIds(ids: readonly LiveTransportStandardScenarioId[]) {
149-for (const id of ids) {
150-if (!LIVE_TRANSPORT_STANDARD_SCENARIO_ID_SET.has(id)) {
151-throw new Error(`unknown live transport standard scenario id: ${id}`);
152-}
153-}
154-}
155-156-export function selectLiveTransportScenarios<TDefinition extends { id: string }>(params: {
157-ids?: string[];
158-laneLabel: string;
159-scenarios: readonly TDefinition[];
160-}) {
161-if (!params.ids || params.ids.length === 0) {
162-return [...params.scenarios];
163-}
164-const requested = new Set(params.ids);
165-const selected = params.scenarios.filter((scenario) => params.ids?.includes(scenario.id));
166-const missingIds = [...requested].filter(
167-(id) => !selected.some((scenario) => scenario.id === id),
168-);
169-if (missingIds.length > 0) {
170-throw new Error(`unknown ${params.laneLabel} QA scenario id(s): ${missingIds.join(", ")}`);
171-}
172-return selected;
173-}
174-175-export function collectLiveTransportStandardScenarioCoverage<TId extends string>(params: {
176-alwaysOnStandardScenarioIds?: readonly LiveTransportStandardScenarioId[];
177-scenarios: readonly LiveTransportScenarioDefinition<TId>[];
178-}) {
179-const coverage: LiveTransportStandardScenarioId[] = [];
180-const seen = new Set<LiveTransportStandardScenarioId>();
181-const append = (id: LiveTransportStandardScenarioId | undefined) => {
182-if (!id || seen.has(id)) {
183-return;
184-}
185-seen.add(id);
186-coverage.push(id);
187-};
188-189-assertKnownStandardScenarioIds(params.alwaysOnStandardScenarioIds ?? []);
190-for (const id of params.alwaysOnStandardScenarioIds ?? []) {
191-append(id);
192-}
193-for (const scenario of params.scenarios) {
194-if (scenario.standardId) {
195-assertKnownStandardScenarioIds([scenario.standardId]);
196-}
197-append(scenario.standardId);
198-}
199-return coverage;
200-}
201-202-export function findMissingLiveTransportStandardScenarios(params: {
203-coveredStandardScenarioIds: readonly LiveTransportStandardScenarioId[];
204-expectedStandardScenarioIds: readonly LiveTransportStandardScenarioId[];
205-}) {
206-assertKnownStandardScenarioIds(params.coveredStandardScenarioIds);
207-assertKnownStandardScenarioIds(params.expectedStandardScenarioIds);
208-const covered = new Set(params.coveredStandardScenarioIds);
209-return params.expectedStandardScenarioIds.filter((id) => !covered.has(id));
210-}
211-21279export function buildLiveTransportCoverageLaneSummaries(
21380lanes: readonly LiveTransportCoverageLane[] = LIVE_TRANSPORT_COVERAGE_LANES,
21481): LiveTransportCoverageLaneSummary[] {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。