Add performance and reliability QA gates (#2283)

* Add performance and reliability QA gates

* test(skills): prepare user path performance gate

* test(skills): add debug chat load gate

* test(skills): extend fake provider load profiles

* test(skills): add debug chat timing and isolation probes

* test(skills): clarify manual QA perf gates
This commit is contained in:
huanghuoguoguo
2026-06-25 13:02:44 +00:00
committed by GitHub
parent 20636ac432
commit 5b2826fa49
52 changed files with 6974 additions and 42 deletions
@@ -0,0 +1,84 @@
id: langbot-fake-provider-debug-chat-cross-pipeline-isolation
title: "LangBot Debug Chat fake-provider cross-pipeline isolation probe"
mode: probe
area: reliability
type: reliability
priority: p1
risk: high
ci_eligible: false
tags:
- reliability
- debug-chat
- websocket
- fake-provider
- isolation
- concurrency
- metrics
skills:
- langbot-env-setup
- langbot-testing
env:
- LANGBOT_BACKEND_URL
- LANGBOT_FRONTEND_URL
- LANGBOT_E2E_LOGIN_USER
automation: skills/langbot-testing/probes/langbot-debug-chat-cross-pipeline-isolation.mjs
automation_env:
- LANGBOT_BACKEND_URL
- LANGBOT_E2E_LOGIN_USER
- LANGBOT_FAKE_PROVIDER_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_A_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_A_NAME
- LANGBOT_FAKE_PROVIDER_PIPELINE_B_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_B_NAME
automation_debug_chat_load_requests: "6"
automation_debug_chat_load_concurrency: "4"
automation_debug_chat_load_timeout_ms: "30000"
automation_debug_chat_load_response_p95_ms: "5000"
automation_debug_chat_load_max_error_rate: "0"
automation_debug_chat_load_prompt_template: '请只回复 "{expected}",不要解释,不要添加其他字符。'
automation_debug_chat_load_stream: "true"
automation_debug_chat_load_reset: "true"
metrics_thresholds_json: '{"cross_pipeline_leak_count":{"max":0},"response_p95_ms":{"max":5000},"error_rate":{"max":0}}'
load_profile_json: '{"requests_per_pipeline":6,"pipelines":2,"concurrency":4,"path":"Pipeline Debug Chat WebSocket","provider":"controlled fake OpenAI-compatible provider","metric":"cross-pipeline response isolation and send-to-final-assistant-response"}'
setup_automation:
- "node:scripts/e2e/ensure-fake-provider-cross-pipelines.mjs --write-env"
setup_provides_env:
- LANGBOT_FAKE_PROVIDER_URL
- LANGBOT_FAKE_PROVIDER_BASE_URL
- LANGBOT_FAKE_PROVIDER_PID
- LANGBOT_FAKE_PROVIDER_PIPELINE_A_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_A_NAME
- LANGBOT_FAKE_PROVIDER_PIPELINE_B_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_B_NAME
steps:
- "Start or reuse the local fake OpenAI-compatible provider."
- "Create or update two local-agent pipelines that both point at the controlled fake provider."
- "Reset both Debug Chat sessions and the fake-provider request log."
- "Open concurrent WebSocket Debug Chat connections to both pipelines and send unique pipeline-scoped response tokens."
checks:
- "automation-result.json status is pass only when every request receives its own expected token and cross_pipeline_leak_count is zero."
- "metrics_summary includes by_pipeline status counts, fake-provider request count, and LangBot/provider timing estimates."
- "samples.json contains per-request pipeline labels so any leak can be attributed to the receiving pipeline."
evidence_required:
- metrics
- network
- api_diagnostic
- filesystem
diagnostics:
- "This probe targets Debug Chat isolation under concurrent traffic from two pipelines."
- "It is designed to expose regressions where global pipeline state causes one pipeline's assistant response to be delivered to another pipeline's Debug Chat session."
- "Same-pipeline foreign responses are tolerated because Debug Chat intentionally broadcasts within the same pipeline/session; cross-pipeline tokens are never tolerated."
- "Known product bug: current releases may fail this probe because Debug Chat replies can read singleton WebSocket proxy pipeline state after another pipeline overwrites it. See https://github.com/langbot-app/LangBot/issues/2286."
expected_failures:
- "https://github.com/langbot-app/LangBot/issues/2286"
success_patterns:
- "Debug Chat cross-pipeline isolation probe passed"
failure_patterns:
- "cross_pipeline_leak"
- "Timed out after"
- "WebSocket connection error"
- "Final assistant response did not include"
troubleshooting:
- backend-not-listening
- debug-chat-history-contaminates-automation
- local-agent-model-route-unavailable
@@ -0,0 +1,95 @@
id: langbot-fake-provider-debug-chat-fault-recovery
title: "LangBot Debug Chat fake-provider fault recovery probe"
mode: probe
area: reliability
type: chaos
priority: p1
risk: high
ci_eligible: false
tags:
- reliability
- chaos
- debug-chat
- websocket
- fake-provider
- fault-injection
- metrics
skills:
- langbot-env-setup
- langbot-testing
env:
- LANGBOT_BACKEND_URL
- LANGBOT_FRONTEND_URL
- LANGBOT_E2E_LOGIN_USER
automation: skills/langbot-testing/probes/langbot-debug-chat-concurrency.mjs
automation_env:
- LANGBOT_BACKEND_URL
- LANGBOT_E2E_LOGIN_USER
- LANGBOT_FAKE_PROVIDER_PIPELINE_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_NAME
automation_pipeline_url_env: LANGBOT_FAKE_PROVIDER_PIPELINE_URL
automation_pipeline_name_env: LANGBOT_FAKE_PROVIDER_PIPELINE_NAME
automation_debug_chat_load_requests: "6"
automation_debug_chat_load_concurrency: "1"
automation_debug_chat_load_timeout_ms: "15000"
automation_debug_chat_load_response_p95_ms: "5000"
automation_debug_chat_load_max_error_rate: "0"
automation_debug_chat_load_min_ok_count: "6"
automation_debug_chat_load_min_provider_fault_count: "2"
automation_debug_chat_load_expected_prefix: "FAULTQA"
automation_debug_chat_load_prompt_template: '请只回复 "{expected}",不要解释,不要添加其他字符。'
automation_debug_chat_load_stream: "true"
automation_debug_chat_load_reset: "true"
automation_debug_chat_load_fail_on_final_mismatch: "true"
automation_fake_provider_first_token_delay_ms: "25"
automation_fake_provider_chunk_delay_ms: "10"
automation_fake_provider_chunk_count: "0"
automation_fake_provider_fail_first_n: "2"
automation_fake_provider_fail_every_n: "0"
automation_fake_provider_fault_status: "503"
metrics_thresholds_json: '{"response_p95_ms":{"max":5000},"error_rate":{"max":0},"ok_count_min":{"min":6},"fake_provider_fault_count_min":{"min":2}}'
fault_model_json: '{"provider_fault":"HTTP 503 for first 2 fake-provider chat completions after reset","expected_behavior":"LangBot retries or otherwise recovers from bounded provider failures so every Debug Chat request receives its expected response without backend crash."}'
load_profile_json: '{"requests":6,"concurrency":1,"path":"Pipeline Debug Chat WebSocket","provider":"controlled fake OpenAI-compatible provider","classification":"fault-recovery-not-throughput-benchmark"}'
setup_automation:
- "node:scripts/e2e/ensure-fake-provider-pipeline.mjs --write-env"
setup_provides_env:
- LANGBOT_FAKE_PROVIDER_URL
- LANGBOT_FAKE_PROVIDER_BASE_URL
- LANGBOT_FAKE_PROVIDER_PID
- LANGBOT_FAKE_PROVIDER_PROVIDER_UUID
- LANGBOT_FAKE_PROVIDER_MODEL_UUID
- LANGBOT_FAKE_PROVIDER_PIPELINE_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_NAME
steps:
- "Configure the local fake provider to return HTTP 503 for the first two chat completions after reset."
- "Create or update the LangBot provider, model, and local-agent pipeline that points at the fake provider."
- "Reset the target Debug Chat session and fake-provider request counter."
- "Send a sequential Debug Chat batch and verify later requests recover after the injected provider faults."
checks:
- "automation-result.json status is pass when the fake provider records at least two injected faults, every Debug Chat request succeeds, and total user-visible error rate stays at zero."
- "metrics_summary includes fake_provider_fault_count and status_counts for the same run window."
- "backend logs show request handling for the same run window without unexpected Traceback or task-leak findings."
evidence_required:
- metrics
- network
- api_diagnostic
- filesystem
diagnostics:
- "This is a fault-recovery probe, not a throughput benchmark."
- "Provider faults may be retried inside the provider/requester path; judge this case by fake_provider_fault_count plus user-visible success/error metrics."
- "The profile uses concurrency 1 because Debug Chat broadcasts assistant responses to every connection in a session, and failed responses do not carry the unique success token needed for concurrent attribution."
success_patterns:
- "Debug Chat WebSocket concurrency probe passed"
- "Streaming completed"
failure_patterns:
- "fake_provider_fault"
- "HTTP 503"
- "Timed out after"
- "All models failed during streaming setup"
expected_failures:
- "fake_provider_fault"
- "HTTP 503"
troubleshooting:
- backend-not-listening
- debug-chat-history-contaminates-automation
- local-agent-model-route-unavailable
@@ -0,0 +1,81 @@
id: langbot-fake-provider-debug-chat-load
title: "LangBot Debug Chat controlled fake-provider load probe"
mode: probe
area: performance
type: performance
priority: p1
risk: medium
ci_eligible: false
tags:
- performance
- debug-chat
- websocket
- fake-provider
- load
- metrics
skills:
- langbot-env-setup
- langbot-testing
env:
- LANGBOT_BACKEND_URL
- LANGBOT_FRONTEND_URL
- LANGBOT_E2E_LOGIN_USER
automation: skills/langbot-testing/probes/langbot-debug-chat-concurrency.mjs
automation_env:
- LANGBOT_BACKEND_URL
- LANGBOT_E2E_LOGIN_USER
- LANGBOT_FAKE_PROVIDER_PIPELINE_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_NAME
automation_pipeline_url_env: LANGBOT_FAKE_PROVIDER_PIPELINE_URL
automation_pipeline_name_env: LANGBOT_FAKE_PROVIDER_PIPELINE_NAME
automation_debug_chat_load_requests: "12"
automation_debug_chat_load_concurrency: "4"
automation_debug_chat_load_timeout_ms: "30000"
automation_debug_chat_load_response_p95_ms: "5000"
automation_debug_chat_load_first_response_p95_ms: "3000"
automation_debug_chat_load_max_error_rate: "0"
automation_debug_chat_load_expected_prefix: "FAKEQA"
automation_debug_chat_load_prompt_template: '请只回复 "{expected}",不要解释,不要添加其他字符。'
automation_debug_chat_load_stream: "true"
automation_debug_chat_load_reset: "true"
metrics_thresholds_json: '{"response_p95_ms":{"max":5000},"first_response_p95_ms":{"max":3000},"error_rate":{"max":0}}'
load_profile_json: '{"requests":12,"concurrency":4,"path":"Pipeline Debug Chat WebSocket","provider":"controlled fake OpenAI-compatible provider","metric":"send-to-final-assistant-response"}'
setup_automation:
- "node:scripts/e2e/ensure-fake-provider-pipeline.mjs --write-env"
setup_provides_env:
- LANGBOT_FAKE_PROVIDER_URL
- LANGBOT_FAKE_PROVIDER_BASE_URL
- LANGBOT_FAKE_PROVIDER_PID
- LANGBOT_FAKE_PROVIDER_PROVIDER_UUID
- LANGBOT_FAKE_PROVIDER_MODEL_UUID
- LANGBOT_FAKE_PROVIDER_PIPELINE_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_NAME
steps:
- "Start or reuse the local fake OpenAI-compatible provider."
- "Create or update the LangBot provider, model, and local-agent pipeline that points at the fake provider."
- "Reset the target Debug Chat session."
- "Open concurrent WebSocket Debug Chat connections and send unique deterministic prompts through the real backend pipeline."
checks:
- "automation-result.json status is pass when every request receives its own expected assistant response."
- "metrics_summary includes request count, concurrency, p50/p95 response latency, first response latency, throughput, and error rate."
- "thresholds_summary shows response_p95_ms, first_response_p95_ms, and error_rate pass."
evidence_required:
- metrics
- network
- api_diagnostic
- filesystem
diagnostics:
- "This probe removes external model latency from the measurement; it still exercises the live LangBot backend, provider requester, local-agent runner, pipeline, and Debug Chat WebSocket adapter."
- "Use this as the repeatable message-path baseline before comparing against Space or another real provider."
success_patterns:
- "Debug Chat WebSocket concurrency probe passed"
- "Streaming completed"
failure_patterns:
- "WebSocket connection error"
- "Timed out after"
- "Final assistant response did not include"
- "All models failed during streaming setup"
troubleshooting:
- backend-not-listening
- debug-chat-history-contaminates-automation
- local-agent-model-route-unavailable
@@ -0,0 +1,88 @@
id: langbot-fake-provider-debug-chat-slow-load
title: "LangBot Debug Chat slow fake-provider load probe"
mode: probe
area: performance
type: performance
priority: p1
risk: medium
ci_eligible: false
tags:
- performance
- debug-chat
- websocket
- fake-provider
- slow-provider
- load
- metrics
skills:
- langbot-env-setup
- langbot-testing
env:
- LANGBOT_BACKEND_URL
- LANGBOT_FRONTEND_URL
- LANGBOT_E2E_LOGIN_USER
automation: skills/langbot-testing/probes/langbot-debug-chat-concurrency.mjs
automation_env:
- LANGBOT_BACKEND_URL
- LANGBOT_E2E_LOGIN_USER
- LANGBOT_FAKE_PROVIDER_PIPELINE_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_NAME
automation_pipeline_url_env: LANGBOT_FAKE_PROVIDER_PIPELINE_URL
automation_pipeline_name_env: LANGBOT_FAKE_PROVIDER_PIPELINE_NAME
automation_debug_chat_load_requests: "8"
automation_debug_chat_load_concurrency: "4"
automation_debug_chat_load_timeout_ms: "45000"
automation_debug_chat_load_response_p95_ms: "10000"
automation_debug_chat_load_first_response_p95_ms: "7000"
automation_debug_chat_load_max_error_rate: "0"
automation_debug_chat_load_expected_prefix: "SLOWQA"
automation_debug_chat_load_prompt_template: '请只回复 "{expected}",不要解释,不要添加其他字符。'
automation_debug_chat_load_stream: "true"
automation_debug_chat_load_reset: "true"
automation_fake_provider_first_token_delay_ms: "1000"
automation_fake_provider_chunk_delay_ms: "250"
automation_fake_provider_chunk_count: "4"
automation_fake_provider_fail_first_n: "0"
automation_fake_provider_fail_every_n: "0"
automation_fake_provider_fault_status: "500"
metrics_thresholds_json: '{"response_p95_ms":{"max":10000},"first_response_p95_ms":{"max":7000},"error_rate":{"max":0}}'
load_profile_json: '{"requests":8,"concurrency":4,"path":"Pipeline Debug Chat WebSocket","provider":"controlled slow fake OpenAI-compatible provider","metric":"send-to-final-assistant-response","provider_profile":{"first_token_delay_ms":1000,"chunk_delay_ms":250,"chunk_count":4}}'
setup_automation:
- "node:scripts/e2e/ensure-fake-provider-pipeline.mjs --write-env"
setup_provides_env:
- LANGBOT_FAKE_PROVIDER_URL
- LANGBOT_FAKE_PROVIDER_BASE_URL
- LANGBOT_FAKE_PROVIDER_PID
- LANGBOT_FAKE_PROVIDER_PROVIDER_UUID
- LANGBOT_FAKE_PROVIDER_MODEL_UUID
- LANGBOT_FAKE_PROVIDER_PIPELINE_URL
- LANGBOT_FAKE_PROVIDER_PIPELINE_NAME
steps:
- "Configure the local fake provider with deterministic slow streaming latency."
- "Create or update the LangBot provider, model, and local-agent pipeline that points at the fake provider."
- "Reset the target Debug Chat session."
- "Open concurrent WebSocket Debug Chat connections and send unique deterministic prompts through the real backend pipeline."
checks:
- "automation-result.json status is pass when every request receives its own expected assistant response."
- "metrics_summary shows zero errors under the slow-provider profile."
- "thresholds_summary shows response_p95_ms, first_response_p95_ms, and error_rate pass."
evidence_required:
- metrics
- network
- api_diagnostic
- filesystem
diagnostics:
- "This probe keeps the model deterministic while injecting provider latency, so it catches backend timeout, streaming, and WebSocket backpressure issues without Space variability."
- "Compare with langbot-fake-provider-debug-chat-load to separate fixed LangBot overhead from provider-latency amplification."
success_patterns:
- "Debug Chat WebSocket concurrency probe passed"
- "Streaming completed"
failure_patterns:
- "WebSocket connection error"
- "Timed out after"
- "Final assistant response did not include"
- "All models failed during streaming setup"
troubleshooting:
- backend-not-listening
- debug-chat-history-contaminates-automation
- local-agent-model-route-unavailable
@@ -0,0 +1,35 @@
id: langbot-fault-taxonomy-contract
title: "LangBot fault taxonomy and cleanup contract"
mode: probe
area: reliability
type: chaos
priority: p1
risk: medium
ci_eligible: true
tags:
- reliability
- chaos
- contract
- synthetic
skills:
- langbot-testing
automation: skills/langbot-testing/probes/langbot-fault-taxonomy-contract.mjs
fault_model_json: '{"kind":"taxonomy-contract","destructive":false,"scenarios":["provider-timeout","plugin-runtime-disconnect","mcp-stdio-server-exit","operator-missing-login","transient-marketplace-timeout"]}'
steps:
- "Run `rtk bin/lbs test run langbot-fault-taxonomy-contract --dry-run` first; remove `--dry-run` after checking the evidence directory."
- "Automation validates that representative fault scenarios declare target, injected fault, expected status, recovery check, and cleanup."
- "Review metrics.json, fault-model.json, and automation-result.json under LBS_EVIDENCE_DIR."
checks:
- "automation-result.json status is pass."
- "Every scenario has an expected status in pass, fail, blocked, env_issue, or flaky."
- "Every scenario declares a cleanup action and recovery check."
evidence_required:
- metrics
- filesystem
diagnostics:
- "This is a non-destructive taxonomy contract probe; it does not inject real runtime faults."
- "Use it as a gate before adding live chaos cases that kill runtimes, route traffic through a proxy, or disrupt a backend dependency."
success_patterns:
- "Fault taxonomy contract declares status"
failure_patterns:
- "missing required scenario fields"
@@ -0,0 +1,42 @@
id: langbot-live-backend-latency
title: "LangBot live backend basic latency probe"
mode: probe
area: performance
type: performance
priority: p1
risk: medium
ci_eligible: false
tags:
- performance
- live-backend
- latency
- metrics
skills:
- langbot-testing
env:
- LANGBOT_BACKEND_URL
automation: skills/langbot-testing/probes/langbot-live-backend-latency.mjs
metrics_thresholds_json: '{"backend_p95_ms":{"max":1000},"error_rate":{"max":0}}'
load_profile_json: '{"requests":12,"concurrency":2,"endpoints":["/healthz"]}'
steps:
- "Confirm the selected LangBot backend is the intended test target."
- "Run `rtk bin/lbs test run langbot-live-backend-latency --dry-run` first; remove `--dry-run` after checking LANGBOT_BACKEND_URL and evidence directory."
- "Automation sends a small request batch to LANGBOT_BACKEND_URL/healthz and records latency, status counts, and network errors."
checks:
- "automation-result.json status is pass when the backend responds and p95/error-rate thresholds pass."
- "automation-result.json status is env_issue when the backend is not reachable."
- "metrics.json and network.log are written under LBS_EVIDENCE_DIR."
evidence_required:
- metrics
- network
- api_diagnostic
- filesystem
diagnostics:
- "This probe measures backend health endpoint reachability latency only; it does not cover model/provider, browser, Debug Chat, RAG, or plugin runtime latency."
success_patterns:
- "Live backend latency probe passed"
failure_patterns:
- "Backend did not respond"
- "breached latency or error-rate thresholds"
troubleshooting:
- socks-proxy-without-socksio
@@ -0,0 +1,45 @@
id: langbot-live-backend-log-health
title: "LangBot live backend log health probe"
mode: probe
area: reliability
type: reliability
priority: p1
risk: medium
ci_eligible: false
tags:
- reliability
- live-backend
- backend-log
- metrics
skills:
- langbot-testing
env:
- LANGBOT_BACKEND_URL
automation: skills/langbot-testing/probes/langbot-live-backend-log-health.mjs
metrics_thresholds_json: '{"fail_count":{"max":0}}'
load_profile_json: '{"lookback_seconds":300,"log_source":"LANGBOT_BACKEND_LOG or latest LANGBOT_REPO/data/logs/langbot-*.log"}'
steps:
- "Confirm the selected LangBot backend log belongs to the intended test target."
- "Run `rtk bin/lbs test run langbot-live-backend-log-health --dry-run` first; remove `--dry-run` after checking evidence directory and log source."
- "Automation scans the recent backend log window for fail-severity runtime findings such as Traceback, ImportError, ERROR, unclosed sessions, and unawaited coroutines."
checks:
- "automation-result.json status is pass only when fail_count is 0."
- "metrics_summary includes scanned_line_count, fail_count, warning_count, and finding_count."
- "findings.json and scanned-backend.log are written under LBS_EVIDENCE_DIR."
evidence_required:
- metrics
- backend_log
- filesystem
diagnostics:
- "Set LANGBOT_BACKEND_LOG to an explicit log path when the latest log file is not the run target."
- "Set LANGBOT_BACKEND_LOG_SINCE or LANGBOT_BACKEND_LOG_LOOKBACK_SECONDS to control the scan window."
- "This probe measures runtime log health; it does not prove user-facing Debug Chat, plugin, model, or RAG behavior."
success_patterns:
- "Live backend log health passed"
failure_patterns:
- "Traceback"
- "ImportError"
- "ERROR"
- "unclosed"
troubleshooting:
- socks-proxy-without-socksio
@@ -0,0 +1,44 @@
id: langbot-live-control-plane-api
title: "LangBot live control-plane API probe"
mode: probe
area: performance
type: performance
priority: p1
risk: medium
ci_eligible: false
tags:
- performance
- reliability
- live-backend
- control-plane
- metrics
skills:
- langbot-testing
env:
- LANGBOT_BACKEND_URL
automation: skills/langbot-testing/probes/langbot-live-control-plane-api.mjs
metrics_thresholds_json: '{"error_rate":{"max":0},"response_shape_failures":{"max":0},"healthz_p95_ms":{"max":500},"system_info_p95_ms":{"max":1000}}'
load_profile_json: '{"requests":20,"concurrency":4,"endpoints":["/healthz","/api/v1/system/info"],"auth_required":false}'
steps:
- "Confirm the selected LangBot backend is the intended test target."
- "Run `rtk bin/lbs test run langbot-live-control-plane-api --dry-run` first; remove `--dry-run` after checking LANGBOT_BACKEND_URL and evidence directory."
- "Automation sends a small request batch to /healthz and /api/v1/system/info, then validates status code, JSON shape, and latency budgets."
checks:
- "automation-result.json status is pass when every control-plane request returns HTTP 200, JSON code 0, and required response fields."
- "metrics_summary includes per-endpoint p50/p95 latency, error rate, status counts, and response_shape_failures."
- "thresholds_summary shows error_rate, response_shape_failures, healthz_p95_ms, and system_info_p95_ms all pass."
evidence_required:
- metrics
- network
- api_diagnostic
- filesystem
diagnostics:
- "This probe measures unauthenticated backend control-plane readiness; it does not cover authenticated UI flows, Debug Chat, model calls, plugins, or RAG."
- "A system_info shape failure usually means the API contract or startup state changed and should be investigated before treating latency as healthy."
success_patterns:
- "Live control-plane API probe passed"
failure_patterns:
- "Backend did not respond"
- "breached shape, latency, or error-rate thresholds"
troubleshooting:
- socks-proxy-without-socksio
@@ -0,0 +1,37 @@
id: langbot-overhead-accounting-contract
title: "LangBot overhead accounting metrics contract"
mode: probe
area: performance
type: performance
priority: p1
risk: medium
ci_eligible: true
tags:
- performance
- metrics
- contract
- synthetic
skills:
- langbot-testing
automation: skills/langbot-testing/probes/langbot-overhead-accounting-contract.mjs
metrics_thresholds_json: '{"sample_count":{"min":50},"langbot_overhead_p95_ms":{"max":25},"accounting_gap_max_ms":{"max":0.001}}'
load_profile_json: '{"kind":"synthetic-overhead-accounting","samples":80,"external_latency_segments":["provider","external_tool","network"]}'
steps:
- "Run `rtk bin/lbs test run langbot-overhead-accounting-contract --dry-run` first; remove `--dry-run` after checking the evidence directory."
- "Automation generates deterministic message-path latency samples and separates LangBot overhead from provider/tool/network latency."
- "Review metrics.json, thresholds.json, resource-log.json, and automation-result.json under LBS_EVIDENCE_DIR."
checks:
- "automation-result.json status is pass."
- "metrics_summary includes sample_count, langbot_overhead_p95_ms, e2e_latency_p95_ms, external_latency_p95_ms, and accounting_gap_max_ms."
- "thresholds_summary shows sample_count, langbot_overhead_p95_ms, and accounting_gap_max_ms all pass."
evidence_required:
- metrics
- resource_log
- filesystem
diagnostics:
- "This is a synthetic contract probe for the QA harness; it is not live product performance."
- "Use it to verify that reports can carry overhead accounting metrics before running live backend or browser performance probes."
success_patterns:
- "Overhead accounting contract passed"
failure_patterns:
- "breached one or more thresholds"
@@ -0,0 +1,84 @@
id: langbot-space-debug-chat-concurrency-smoke
title: "LangBot Debug Chat real Space-provider concurrency smoke"
mode: probe
area: performance
type: performance
priority: p1
risk: high
ci_eligible: false
tags:
- performance
- debug-chat
- websocket
- space
- live-provider
- smoke
- metrics
skills:
- langbot-env-setup
- langbot-testing
env:
- LANGBOT_BACKEND_URL
- LANGBOT_FRONTEND_URL
- LANGBOT_E2E_LOGIN_USER
automation: skills/langbot-testing/probes/langbot-debug-chat-concurrency.mjs
automation_env:
- LANGBOT_BACKEND_URL
- LANGBOT_E2E_LOGIN_USER
- LANGBOT_LOCAL_AGENT_PIPELINE_URL
- LANGBOT_LOCAL_AGENT_PIPELINE_NAME
automation_pipeline_url_env: LANGBOT_LOCAL_AGENT_PIPELINE_URL
automation_pipeline_name_env: LANGBOT_LOCAL_AGENT_PIPELINE_NAME
automation_debug_chat_load_requests: "3"
automation_debug_chat_load_concurrency: "2"
automation_debug_chat_load_timeout_ms: "120000"
automation_debug_chat_load_response_p95_ms: "120000"
automation_debug_chat_load_max_error_rate: "0"
automation_debug_chat_load_expected_prefix: "SPACEQA"
automation_debug_chat_load_prompt_template: '请只回复 "{expected}",不要解释,不要添加其他字符。'
automation_debug_chat_load_stream: "true"
automation_debug_chat_load_reset: "true"
metrics_thresholds_json: '{"response_p95_ms":{"max":120000},"error_rate":{"max":0}}'
load_profile_json: '{"requests":3,"concurrency":2,"path":"Pipeline Debug Chat WebSocket","provider":"LangBot Space model route","metric":"send-to-final-assistant-response","classification":"smoke-not-benchmark"}'
setup_automation:
- "node:scripts/e2e/ensure-local-agent-pipeline.mjs --write-env"
setup_provides_env:
- LANGBOT_PIPELINE_URL
- LANGBOT_PIPELINE_NAME
- LANGBOT_LOCAL_AGENT_PIPELINE_URL
- LANGBOT_LOCAL_AGENT_PIPELINE_NAME
- LANGBOT_LOCAL_AGENT_MODEL_UUID
- LANGBOT_E2E_MODEL_UUID
preconditions:
- "The selected local LangBot instance is safe for a low-volume real Space model smoke run."
- "Treat Space/provider/network failures as environment or dependency findings until fake-provider baseline evidence separates LangBot overhead."
steps:
- "Prepare a local-agent pipeline with a tested Space model and fallback models."
- "Reset the target Debug Chat session."
- "Open a small number of concurrent WebSocket Debug Chat connections and send unique deterministic prompts through the live Space provider path."
checks:
- "automation-result.json status is pass when every request receives its own expected assistant response."
- "metrics_summary includes request count, concurrency, p95 response latency, throughput, and error rate."
- "The report classifies the result as a live-provider smoke, not a stable LangBot overhead benchmark."
evidence_required:
- metrics
- network
- api_diagnostic
- filesystem
diagnostics:
- "This probe measures real user-path latency through Space and includes provider latency, model behavior, and network effects."
- "Compare with langbot-fake-provider-debug-chat-load before attributing slow or failed runs to LangBot itself."
success_patterns:
- "Debug Chat WebSocket concurrency probe passed"
- "Streaming completed"
failure_patterns:
- "invalid api key"
- "WebSocket connection error"
- "Timed out after"
- "Final assistant response did not include"
- "All models failed during streaming setup"
troubleshooting:
- local-agent-model-route-unavailable
- marketplace-network-flaky
- proxy-env-mismatch
- telemetry-proxy-noise
@@ -0,0 +1,80 @@
id: pipeline-debug-chat-performance
title: "Pipeline Debug Chat user-path performance probe"
mode: agent-browser
area: pipeline
type: performance
priority: p1
risk: medium
ci_eligible: false
tags:
- performance
- pipeline
- debug-chat
- user-path
- metrics
skills:
- langbot-env-setup
- langbot-testing
env:
- LANGBOT_FRONTEND_URL
- LANGBOT_BACKEND_URL
env_any:
- LANGBOT_PIPELINE_URL|LANGBOT_PIPELINE_NAME
automation: scripts/e2e/pipeline-debug-chat.mjs
automation_env:
- LANGBOT_FRONTEND_URL
- LANGBOT_BACKEND_URL
- LANGBOT_BROWSER_PROFILE
- LANGBOT_CHROMIUM_EXECUTABLE
- LANGBOT_E2E_PROMPT
- LANGBOT_E2E_EXPECTED_TEXT
- LANGBOT_E2E_RESPONSE_TIMEOUT_MS
automation_env_any:
- LANGBOT_PIPELINE_URL|LANGBOT_PIPELINE_NAME
automation_prompt: "请只回复 OK,用于性能测试。"
automation_expected_text: "OK"
automation_response_timeout_ms: "120000"
automation_reset_debug_chat: "true"
automation_debug_chat_response_p95_ms: "120000"
automation_debug_chat_max_error_rate: "0"
metrics_thresholds_json: '{"response_p95_ms":{"max":120000},"error_rate":{"max":0}}'
load_profile_json: '{"prompts":1,"browser":true,"path":"Pipeline Debug Chat","metric":"send-to-visible-completion"}'
setup_automation:
- "node:scripts/e2e/ensure-local-agent-pipeline.mjs --write-env"
setup_provides_env:
- LANGBOT_PIPELINE_URL
- LANGBOT_PIPELINE_NAME
preconditions:
- "LANGBOT_PIPELINE_URL or LANGBOT_PIPELINE_NAME points to the pipeline intended for this Debug Chat performance run."
- "The target pipeline is safe to reset Debug Chat history for this run."
- "The target pipeline has a known-good runner/model; provider latency should be interpreted separately from LangBot overhead."
steps:
- "Open LANGBOT_FRONTEND_URL with the prepared browser profile."
- "Open the target pipeline and select Debug Chat."
- "Reset Debug Chat history through the backend API when configured."
- "Send the deterministic prompt and wait for the expected assistant response."
checks:
- "automation-result.json status is pass when the expected assistant response appears."
- "metrics_summary includes response_p50_ms, response_p95_ms, error_rate, and total_duration_ms."
- "thresholds_summary shows response_p95_ms and error_rate pass."
evidence_required:
- ui
- screenshot
- console
- network
- metrics
diagnostics:
- "This case measures browser-visible send-to-completion latency; it does not split provider latency from LangBot overhead."
- "Use backend logs and provider diagnostics to explain slow runs before calling them LangBot regressions."
success_patterns:
- "Processing request from person_websocket"
- "Streaming completed"
failure_patterns:
- "Action invoke_llm_stream call timed out"
- "Task exception was never retrieved"
- "All models failed during streaming setup"
troubleshooting:
- debug-chat-history-contaminates-automation
- local-agent-model-route-unavailable
- plugin-runtime-timeout
- proxy-env-mismatch