Files
cleveragents-core/features/session_workflow_coverage_boost.feature
T
hurui200320 0e4a140f53 feat(session): implement real LLM actor invocation in session tell
Replace the M3 echo-stub with real orchestrator-based LLM invocation via SessionWorkflow, wiring LangChainSessionCaller → ToolCallingRuntime.run_tool_loop(). Includes token tracking, cost estimation, streaming support, and A2A protocol compliance.

ISSUES CLOSED: #5784
2026-05-09 08:29:29 +00:00

106 lines
5.5 KiB
Gherkin

Feature: Session workflow coverage boost
Coverage boost for session_workflow.py helper functions (M1, n4).
Background:
Given the session workflow coverage environment is set up
# _extract_content
Scenario: _extract_content extracts text from content attribute
Given coverage boost a mock response with content "hello world"
When coverage boost _extract_content is called
Then coverage boost the extracted result should be "hello world"
Scenario: _extract_content falls back to text attribute
Given coverage boost a mock response with text "from text attr" and no content
When coverage boost _extract_content is called
Then coverage boost the extracted result should be "from text attr"
Scenario: _extract_content handles list content
Given coverage boost a mock response with list content containing text dicts and plain strings
When coverage boost _extract_content is called
Then coverage boost the result should contain the concatenated texts
Scenario: _extract_content falls back to str for unknown types
Given coverage boost a mock response with no content or text attribute
When coverage boost _extract_content is called
Then coverage boost the result should be a string
# _extract_token_usage
Scenario: _extract_token_usage reads from response_metadata.usage
Given coverage boost a mock response with response_metadata usage input_tokens=100 output_tokens=50
When coverage boost _extract_token_usage is called
Then coverage boost input tokens should be 100 and output tokens should be 50
Scenario: _extract_token_usage reads from response_metadata.token_usage
Given coverage boost a mock response with response_metadata token_usage input_tokens=200 output_tokens=100
When coverage boost _extract_token_usage is called
Then coverage boost input tokens should be 200 and output tokens should be 100
Scenario: _extract_token_usage reads prompt_tokens and completion_tokens
Given coverage boost a mock response with response_metadata usage prompt_tokens=300 completion_tokens=150
When coverage boost _extract_token_usage is called
Then coverage boost input tokens should be 300 and output tokens should be 150
Scenario: _extract_token_usage reads from usage_metadata
Given coverage boost a mock response with usage_metadata input_tokens=400 output_tokens=200
When coverage boost _extract_token_usage is called
Then coverage boost input tokens should be 400 and output tokens should be 200
Scenario: _extract_token_usage returns zeros for no metadata
Given coverage boost a mock response with no usage metadata
When coverage boost _extract_token_usage is called
Then coverage boost input tokens should be 0 and output tokens should be 0
# _estimate_cost
Scenario: _estimate_cost computes cost from token counts
Given coverage boost input tokens 1000 and output tokens 500
When coverage boost _estimate_cost is called
Then coverage boost the estimated cost should be positive
# _history_to_langchain_messages
Scenario: _history_to_langchain_messages converts all roles
Given coverage boost session messages with roles SYSTEM, USER, ASSISTANT, and TOOL
When coverage boost _history_to_langchain_messages is called
Then coverage boost the result should contain SystemMessage, HumanMessage, AIMessage, and ToolMessage
Scenario: _history_to_langchain_messages treats unknown role as human
Given coverage boost a session message with an unknown role
When coverage boost _history_to_langchain_messages is called
Then coverage boost the result should contain a HumanMessage
Scenario: _history_to_langchain_messages handles empty list
Given coverage boost an empty list of session messages
When coverage boost _history_to_langchain_messages is called
Then coverage boost the result should be an empty list
# LangChainSessionCaller.invoke() tool_results branch
Scenario: LangChainSessionCaller.invoke appends tool results
Given coverage boost a LangChainSessionCaller with a stub LLM and empty history
When coverage boost invoke is called with tool_results containing one success and one failure
Then coverage boost the accumulated messages should include tool result messages
# LangChainSessionCaller.invoke() with tool_calls in response
Scenario: LangChainSessionCaller.invoke extracts tool calls from response
Given coverage boost a LangChainSessionCaller with a stub LLM that returns tool calls
When coverage boost invoke is called for the first time
Then coverage boost the LLMResponse should contain the extracted tool calls
# _build_lc_messages_from_history
Scenario: _build_lc_messages_from_history adds system prompt when absent
Given coverage boost a SessionWorkflow with a stub service and no registry
And coverage boost session history without a system message
When coverage boost _build_lc_messages_from_history is called with a prompt
Then coverage boost the first message should be a SystemMessage with the session system prompt
# _MinimalStubLLM
Scenario: _MinimalStubLLM.invoke returns stub response
Given coverage boost a _MinimalStubLLM instance
When coverage boost invoke on the stub is called
Then coverage boost the stub response content should be "(no LLM configured)"
And coverage boost the stub response should have empty tool_calls
Scenario: _MinimalStubLLM.stream yields stub chunk
Given coverage boost a _MinimalStubLLM instance
When coverage boost stream on the stub is called
Then coverage boost it should yield a chunk with content "(no LLM configured)"