-
Notifications
You must be signed in to change notification settings - Fork 101
LCORE-2230: behave step definitions for the conversation-compaction feature #2612
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
max-svistunov
wants to merge
3
commits into
lightspeed-core:main
Choose a base branch
from
max-svistunov:lcore-2230-compaction-step-definitions
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
047fa67
LCORE-1673: e2e feature file for conversation compaction (no step imp…
max-svistunov a547bf2
LCORE-1673: make the compaction crossing deterministic and cut the fe…
max-svistunov 42e5eca
LCORE-2230: behave step definitions for the conversation-compaction f…
max-svistunov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
tests/e2e/configuration/library-mode/lightspeed-stack-compaction-disabled.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| name: Lightspeed Core Service (LCS) | ||
| service: | ||
| host: 0.0.0.0 | ||
| port: 8080 | ||
| auth_enabled: false | ||
| workers: 1 | ||
| color_log: true | ||
| access_log: true | ||
| ogx: | ||
| # Library mode - embeds OGX as library | ||
| use_as_library_client: true | ||
| # Unified mode: run.yaml (materialized per provider by CI/the harness) | ||
| # is consumed as the synthesis profile instead of the legacy two-file path. | ||
| config: | ||
| profile: run.yaml | ||
| user_data_collection: | ||
| feedback_enabled: true | ||
| feedback_storage: "/tmp/data/feedback" | ||
| transcripts_enabled: true | ||
| transcripts_storage: "/tmp/data/transcripts" | ||
| authentication: | ||
| module: "noop" | ||
| inference: | ||
| default_provider: openai | ||
| default_model: gpt-4o-mini | ||
| # Compaction e2e (LCORE-1673): a deliberately small window for every | ||
| # model the e2e workflows run against, so the third query of the | ||
| # compaction scenarios crosses the trigger threshold. The real windows | ||
| # are far larger; this only drives the local estimate, never the provider. | ||
| # The vLLM-backed runs (rhaiis, rhelai) take the model id from an env | ||
| # var, and context_windows keys are not env-substituted, so they are | ||
| # not listed and skip the token-based trigger. | ||
| context_windows: | ||
| openai/gpt-4o-mini: 2000 | ||
| azure/gpt-4o-mini: 2000 | ||
| google-vertex/publishers/google/models/gemini-2.5-flash: 2000 | ||
| watsonx/meta-llama/llama-3-3-70b-instruct: 2000 | ||
| aws-bedrock/deepseek.v3-v1:0: 2000 | ||
| rag: | ||
| byok: | ||
| stores: | ||
| - rag_id: e2e-test-docs | ||
| backend: faiss | ||
| embedding_model: sentence-transformers/all-mpnet-base-v2 | ||
| embedding_dimension: 768 | ||
| vector_db_id: ${env.FAISS_VECTOR_STORE_ID} | ||
| db_path: ${env.KV_RAG_PATH:=~/.llama/storage/rag/kv_store.db} | ||
| score_multiplier: 1.0 | ||
| retrieval: | ||
| tool: | ||
| sources: | ||
| - e2e-test-docs | ||
|
|
||
| # Same small window and threshold as lightspeed-stack-compaction.yaml, but | ||
| # compaction switched off: context_status must stay "full" past the | ||
| # threshold (enabled is a full off-switch). | ||
| compaction: | ||
| enabled: false | ||
| threshold_ratio: 0.1 | ||
| token_floor: 100 | ||
| buffer_turns: 1 | ||
60 changes: 60 additions & 0 deletions
60
tests/e2e/configuration/library-mode/lightspeed-stack-compaction.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| name: Lightspeed Core Service (LCS) | ||
| service: | ||
| host: 0.0.0.0 | ||
| port: 8080 | ||
| auth_enabled: false | ||
| workers: 1 | ||
| color_log: true | ||
| access_log: true | ||
| ogx: | ||
| # Library mode - embeds OGX as library | ||
| use_as_library_client: true | ||
| # Unified mode: run.yaml (materialized per provider by CI/the harness) | ||
| # is consumed as the synthesis profile instead of the legacy two-file path. | ||
| config: | ||
| profile: run.yaml | ||
| user_data_collection: | ||
| feedback_enabled: true | ||
| feedback_storage: "/tmp/data/feedback" | ||
| transcripts_enabled: true | ||
| transcripts_storage: "/tmp/data/transcripts" | ||
| authentication: | ||
| module: "noop" | ||
| inference: | ||
| default_provider: openai | ||
| default_model: gpt-4o-mini | ||
| # Compaction e2e (LCORE-1673): a deliberately small window for every | ||
| # model the e2e workflows run against, so the third query of the | ||
| # compaction scenarios crosses the trigger threshold. The real windows | ||
| # are far larger; this only drives the local estimate, never the provider. | ||
| # The vLLM-backed runs (rhaiis, rhelai) take the model id from an env | ||
| # var, and context_windows keys are not env-substituted, so they are | ||
| # not listed and skip the token-based trigger. | ||
| context_windows: | ||
| openai/gpt-4o-mini: 2000 | ||
| azure/gpt-4o-mini: 2000 | ||
| google-vertex/publishers/google/models/gemini-2.5-flash: 2000 | ||
| watsonx/meta-llama/llama-3-3-70b-instruct: 2000 | ||
| aws-bedrock/deepseek.v3-v1:0: 2000 | ||
| rag: | ||
| byok: | ||
| stores: | ||
| - rag_id: e2e-test-docs | ||
| backend: faiss | ||
| embedding_model: sentence-transformers/all-mpnet-base-v2 | ||
| embedding_dimension: 768 | ||
| vector_db_id: ${env.FAISS_VECTOR_STORE_ID} | ||
| db_path: ${env.KV_RAG_PATH:=~/.llama/storage/rag/kv_store.db} | ||
| score_multiplier: 1.0 | ||
| retrieval: | ||
| tool: | ||
| sources: | ||
| - e2e-test-docs | ||
|
|
||
| # Compaction on with a low threshold: 10% of the 2000-token window, | ||
| # above a 100-token floor, keeping one recent turn verbatim. | ||
| compaction: | ||
| enabled: true | ||
| threshold_ratio: 0.1 | ||
| token_floor: 100 | ||
| buffer_turns: 1 |
59 changes: 59 additions & 0 deletions
59
tests/e2e/configuration/server-mode/lightspeed-stack-compaction-disabled.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| name: Lightspeed Core Service (LCS) | ||
| service: | ||
| host: 0.0.0.0 | ||
| port: 8080 | ||
| auth_enabled: false | ||
| workers: 1 | ||
| color_log: true | ||
| access_log: true | ||
| ogx: | ||
| # Server mode - connects to separate OGX service | ||
| use_as_library_client: false | ||
| url: http://${env.E2E_OGX_HOSTNAME}:8321 | ||
| api_key: xyzzy | ||
| user_data_collection: | ||
| feedback_enabled: true | ||
| feedback_storage: "/tmp/data/feedback" | ||
| transcripts_enabled: true | ||
| transcripts_storage: "/tmp/data/transcripts" | ||
| authentication: | ||
| module: "noop" | ||
| inference: | ||
| default_provider: openai | ||
| default_model: gpt-4o-mini | ||
| # Compaction e2e (LCORE-1673): a deliberately small window for every | ||
| # model the e2e workflows run against, so the third query of the | ||
| # compaction scenarios crosses the trigger threshold. The real windows | ||
| # are far larger; this only drives the local estimate, never the provider. | ||
| # The vLLM-backed runs (rhaiis, rhelai) take the model id from an env | ||
| # var, and context_windows keys are not env-substituted, so they are | ||
| # not listed and skip the token-based trigger. | ||
| context_windows: | ||
| openai/gpt-4o-mini: 2000 | ||
| azure/gpt-4o-mini: 2000 | ||
| google-vertex/publishers/google/models/gemini-2.5-flash: 2000 | ||
| watsonx/meta-llama/llama-3-3-70b-instruct: 2000 | ||
| aws-bedrock/deepseek.v3-v1:0: 2000 | ||
| rag: | ||
| byok: | ||
| stores: | ||
| - rag_id: e2e-test-docs | ||
| backend: faiss | ||
| embedding_model: sentence-transformers/all-mpnet-base-v2 | ||
| embedding_dimension: 768 | ||
| vector_db_id: ${env.FAISS_VECTOR_STORE_ID} | ||
| db_path: ${env.KV_RAG_PATH:=~/.llama/storage/rag/kv_store.db} | ||
| score_multiplier: 1.0 | ||
| retrieval: | ||
| tool: | ||
| sources: | ||
| - e2e-test-docs | ||
|
|
||
| # Same small window and threshold as lightspeed-stack-compaction.yaml, but | ||
| # compaction switched off: context_status must stay "full" past the | ||
| # threshold (enabled is a full off-switch). | ||
| compaction: | ||
| enabled: false | ||
| threshold_ratio: 0.1 | ||
| token_floor: 100 | ||
| buffer_turns: 1 |
58 changes: 58 additions & 0 deletions
58
tests/e2e/configuration/server-mode/lightspeed-stack-compaction.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| name: Lightspeed Core Service (LCS) | ||
| service: | ||
| host: 0.0.0.0 | ||
| port: 8080 | ||
| auth_enabled: false | ||
| workers: 1 | ||
| color_log: true | ||
| access_log: true | ||
| ogx: | ||
| # Server mode - connects to separate OGX service | ||
| use_as_library_client: false | ||
| url: http://${env.E2E_OGX_HOSTNAME}:8321 | ||
| api_key: xyzzy | ||
| user_data_collection: | ||
| feedback_enabled: true | ||
| feedback_storage: "/tmp/data/feedback" | ||
| transcripts_enabled: true | ||
| transcripts_storage: "/tmp/data/transcripts" | ||
| authentication: | ||
| module: "noop" | ||
| inference: | ||
| default_provider: openai | ||
| default_model: gpt-4o-mini | ||
| # Compaction e2e (LCORE-1673): a deliberately small window for every | ||
| # model the e2e workflows run against, so the third query of the | ||
| # compaction scenarios crosses the trigger threshold. The real windows | ||
| # are far larger; this only drives the local estimate, never the provider. | ||
| # The vLLM-backed runs (rhaiis, rhelai) take the model id from an env | ||
| # var, and context_windows keys are not env-substituted, so they are | ||
| # not listed and skip the token-based trigger. | ||
| context_windows: | ||
| openai/gpt-4o-mini: 2000 | ||
| azure/gpt-4o-mini: 2000 | ||
| google-vertex/publishers/google/models/gemini-2.5-flash: 2000 | ||
| watsonx/meta-llama/llama-3-3-70b-instruct: 2000 | ||
| aws-bedrock/deepseek.v3-v1:0: 2000 | ||
| rag: | ||
| byok: | ||
| stores: | ||
| - rag_id: e2e-test-docs | ||
| backend: faiss | ||
| embedding_model: sentence-transformers/all-mpnet-base-v2 | ||
| embedding_dimension: 768 | ||
| vector_db_id: ${env.FAISS_VECTOR_STORE_ID} | ||
| db_path: ${env.KV_RAG_PATH:=~/.llama/storage/rag/kv_store.db} | ||
| score_multiplier: 1.0 | ||
| retrieval: | ||
| tool: | ||
| sources: | ||
| - e2e-test-docs | ||
|
|
||
| # Compaction on with a low threshold: 10% of the 2000-token window, | ||
| # above a 100-token floor, keeping one recent turn verbatim. | ||
| compaction: | ||
| enabled: true | ||
| threshold_ratio: 0.1 | ||
| token_floor: 100 | ||
| buffer_turns: 1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| @cfg_compaction | ||
| Feature: Conversation compaction | ||
|
|
||
| Once the estimated input crosses the configured share of the model's | ||
| context window, older turns are summarized before the request reaches | ||
| the model. The compaction fixtures register a 2000-token window with a | ||
| 10% threshold and keep one recent turn verbatim, so a long third query | ||
| is what crosses it: turn one ends up in the summary, turn two stays in | ||
| the verbatim buffer, and the third query asks for a fact from each. | ||
|
|
||
| Background: | ||
| Given The service is started locally | ||
| And The system is in default state | ||
| And REST API service prefix is /v1 | ||
| And the Lightspeed stack configuration directory is "tests/e2e/configuration" | ||
|
|
||
|
|
||
| Scenario: the third query crosses the threshold, older turns are summarized, recall and history survive | ||
| Given The service uses the lightspeed-stack-compaction.yaml configuration | ||
| And the active model has a registered context window | ||
| And The service is restarted | ||
| When I use "query" to ask question | ||
| """ | ||
| {"query": "My OpenShift cluster is named aurora-prod-7. Remember that name and reply with OK only.", "model": "{MODEL}", "provider": "{PROVIDER}"} | ||
| """ | ||
| Then The status code of the response is 200 | ||
| And The response context_status is "full" | ||
| And I store conversation details | ||
| When I use "query" to ask question with same conversation_id | ||
| """ | ||
| {"query": "My application namespace is called blue-lagoon. Remember that name too and reply with OK only.", "model": "{MODEL}", "provider": "{PROVIDER}"} | ||
| """ | ||
| Then The status code of the response is 200 | ||
| And The response context_status is "full" | ||
| When I use "query" to ask question with same conversation_id | ||
| """ | ||
| {"query": "Some background on my environment first, no need to comment on it. The cluster runs on bare metal in two racks with three control plane nodes and nine worker nodes, all on the same subnet behind a pair of hardware load balancers. Storage is provided by an external Ceph cluster exposed through the CSI driver, with three storage classes for block, file and object access. Ingress is handled by the default router with two replicas pinned to the infra nodes, and TLS certificates are issued by an internal certificate authority and rotated every ninety days. Monitoring uses the built-in Prometheus stack with a remote write to a central Thanos instance, and alerts are routed to an on-call rotation through a webhook receiver. The image registry is the internal one, backed by an object storage bucket, and images are mirrored from an upstream registry once a day by a scheduled job. Upgrades follow the stable channel, one minor version at a time, and are rehearsed on a staging cluster of the same shape a week before production. Backups of etcd are taken hourly and copied off-site nightly. Now the question: what is the name of my cluster and what is the name of my application namespace? Reply with the two names only, separated by a comma.", "model": "{MODEL}", "provider": "{PROVIDER}"} | ||
| """ | ||
| Then The status code of the response is 200 | ||
| And The response context_status is "summarized" | ||
| And The response contains following fragments | ||
| | Fragments in LLM response | | ||
| | aurora-prod-7 | | ||
| | blue-lagoon | | ||
| When I use REST API conversation endpoint with conversation_id from above using HTTP GET method | ||
| Then The status code of the response is 200 | ||
| And The conversation history includes the following user queries | ||
| | User query | | ||
| | My OpenShift cluster is named aurora-prod-7. Remember that name and reply with OK only. | | ||
| | My application namespace is called blue-lagoon. Remember that name too and reply with OK only. | | ||
|
|
||
|
|
||
| Scenario: the native stream announces compaction on the query that crosses the threshold | ||
| Given The service uses the lightspeed-stack-compaction.yaml configuration | ||
| And the active model has a registered context window | ||
| And The service is restarted | ||
| When I use "streaming_query" to ask question | ||
| """ | ||
| {"query": "My OpenShift cluster is named aurora-prod-7. Remember that name and reply with OK only.", "model": "{MODEL}", "provider": "{PROVIDER}"} | ||
| """ | ||
| Then The status code of the response is 200 | ||
| And I wait for the response to be completed | ||
| And The streamed response end event has context_status "full" | ||
| And I store conversation details | ||
| When I use "streaming_query" to ask question with same conversation_id | ||
| """ | ||
| {"query": "My application namespace is called blue-lagoon. Remember that name too and reply with OK only.", "model": "{MODEL}", "provider": "{PROVIDER}"} | ||
| """ | ||
| Then The status code of the response is 200 | ||
| And I wait for the response to be completed | ||
| And The streamed response end event has context_status "full" | ||
| When I use "streaming_query" to ask question with same conversation_id | ||
| """ | ||
| {"query": "Some background on my environment first, no need to comment on it. The cluster runs on bare metal in two racks with three control plane nodes and nine worker nodes, all on the same subnet behind a pair of hardware load balancers. Storage is provided by an external Ceph cluster exposed through the CSI driver, with three storage classes for block, file and object access. Ingress is handled by the default router with two replicas pinned to the infra nodes, and TLS certificates are issued by an internal certificate authority and rotated every ninety days. Monitoring uses the built-in Prometheus stack with a remote write to a central Thanos instance, and alerts are routed to an on-call rotation through a webhook receiver. The image registry is the internal one, backed by an object storage bucket, and images are mirrored from an upstream registry once a day by a scheduled job. Upgrades follow the stable channel, one minor version at a time, and are rehearsed on a staging cluster of the same shape a week before production. Backups of etcd are taken hourly and copied off-site nightly. Now the question: what is the name of my cluster and what is the name of my application namespace? Reply with the two names only, separated by a comma.", "model": "{MODEL}", "provider": "{PROVIDER}"} | ||
| """ | ||
| Then The status code of the response is 200 | ||
| And I wait for the response to be completed | ||
| And The streamed response contains a compaction event before the first token | ||
| And The streamed response end event has context_status "summarized" | ||
|
|
||
|
|
||
| Scenario: compaction stays off when disabled, even past the threshold | ||
| Given The service uses the lightspeed-stack-compaction-disabled.yaml configuration | ||
| And the active model has a registered context window | ||
| And The service is restarted | ||
| When I use "query" to ask question | ||
| """ | ||
| {"query": "My OpenShift cluster is named aurora-prod-7. Remember that name and reply with OK only.", "model": "{MODEL}", "provider": "{PROVIDER}"} | ||
| """ | ||
| Then The status code of the response is 200 | ||
| And I store conversation details | ||
| When I use "query" to ask question with same conversation_id | ||
| """ | ||
| {"query": "My application namespace is called blue-lagoon. Remember that name too and reply with OK only.", "model": "{MODEL}", "provider": "{PROVIDER}"} | ||
| """ | ||
| Then The status code of the response is 200 | ||
| When I use "query" to ask question with same conversation_id | ||
| """ | ||
| {"query": "Some background on my environment first, no need to comment on it. The cluster runs on bare metal in two racks with three control plane nodes and nine worker nodes, all on the same subnet behind a pair of hardware load balancers. Storage is provided by an external Ceph cluster exposed through the CSI driver, with three storage classes for block, file and object access. Ingress is handled by the default router with two replicas pinned to the infra nodes, and TLS certificates are issued by an internal certificate authority and rotated every ninety days. Monitoring uses the built-in Prometheus stack with a remote write to a central Thanos instance, and alerts are routed to an on-call rotation through a webhook receiver. The image registry is the internal one, backed by an object storage bucket, and images are mirrored from an upstream registry once a day by a scheduled job. Upgrades follow the stable channel, one minor version at a time, and are rehearsed on a staging cluster of the same shape a week before production. Backups of etcd are taken hourly and copied off-site nightly. Now the question: what is the name of my cluster and what is the name of my application namespace? Reply with the two names only, separated by a comma.", "model": "{MODEL}", "provider": "{PROVIDER}"} | ||
| """ | ||
| Then The status code of the response is 200 | ||
| And The response context_status is "full" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🤖 get_repo_knowledge executed:
get_repo_knowledge lightspeed-core/lightspeed-stack /tmp/coderabbit-repo-knowledge/lightspeed-core-lightspeed-stack-d57c5c34/learnings /tmp/coderabbit-repo-knowledge/lightspeed-core-lightspeed-stack-d57c5c34/conventionsLength of output: 23804
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 50389
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 50388
🏁 Script executed:
Repository: lightspeed-core/lightspeed-stack
Length of output: 47196
Security Misconfiguration (CWE-306): Missing Authentication for Critical Function
Reachability: External · Exploitability: Moderate
Restrict unauthenticated E2E service exposure. These four compaction fixtures disable authentication, while both Compose files publish port
8080on all host interfaces. Bind the published ports to127.0.0.1:8080:8080, or enable authentication for these fixtures.📍 Affects 4 files
tests/e2e/configuration/library-mode/lightspeed-stack-compaction-disabled.yaml#L5-L5(this comment)tests/e2e/configuration/library-mode/lightspeed-stack-compaction.yaml#L5-L5tests/e2e/configuration/server-mode/lightspeed-stack-compaction-disabled.yaml#L5-L5tests/e2e/configuration/server-mode/lightspeed-stack-compaction.yaml#L5-L5🤖 Prompt for AI Agents
Source: Coding guidelines