TidGi-Desktop/features/agent.feature
linonetwo 0312a49925 feat: Implement background task management for agent instances
- Added functionality to restore heartbeat timers and alarms for active agents upon service initialization.
- Introduced methods to retrieve active background tasks and cancel them via the UI.
- Enhanced alarm clock tool to persist alarm data in the database, ensuring alarms survive app restarts.
- Updated agent instance schema to include scheduled alarm data.
- Modified prompt concatenation logic to support context window size for message history.
- Removed system prompt parameter from model parameters schema and related components.
- Improved UI to display and manage background tasks, including heartbeat and alarm details.
2026-03-05 18:27:21 +08:00

197 lines
16 KiB
Gherkin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Feature: Agent Workflow - Tool Usage and Multi-Round Conversation
As a user
I want to use an intelligent agent to search wiki content
So that I can get AI-powered explanations of wiki entries
Background:
Given I add test ai settings
# Start mock OpenAI server with no rules - rules will be added per scenario
And I have started the mock OpenAI server without rules
Then I launch the TidGi application
And I wait for the page to load completely
And I should see a "page body" element with selector "body"
# Navigate to agent workspace for all scenarios
And I click on "agent workspace button and new tab button" elements with selectors:
| element description | selector |
| agent workspace | [data-testid='workspace-agent'] |
| new tab button | [data-tab-id='new-tab-button'] |
@agent @mockOpenAI
Scenario: Wiki-search tool usage
# Add scenario-specific responses to the mock server
Given I add mock OpenAI responses:
| response | stream |
| <tool_use name="wiki-search">{"workspaceName":"-VPTqPdNOEZHGO5vkwllY","filter":"[title[Index]]"}</tool_use> | false |
| TiddlyWiki Index 访 | false |
# Proceed with agent workflow in main window
# Step 1: Click new tab button
When I click on a "new tab button" element with selector "[data-tab-id='new-tab-button']"
And I should see a "search interface" element with selector ".aa-Autocomplete"
# Step 2: Click search box and wait for autocomplete
When I click on a "search input box" element with selector ".aa-Input"
And I should see an "autocomplete panel" element with selector ".aa-Panel"
# Step 3: Select agent from autocomplete (not new tab)
When I click on an "agent suggestion" element with selector '[data-autocomplete-source-id="agentsSource"] .aa-ItemWrapper'
And I should see a "message input box" element with selector "[data-testid='agent-message-input']"
# Step 4: Send message to agent - using generic steps combination
When I click on a "message input textarea" element with selector "[data-testid='agent-message-input']"
When I type " wiki index " in "chat input" element with selector "[data-testid='agent-message-input']"
And I press "Enter" key
Then I should see 4 messages in chat history
# Verify the last message contains the AI explanation about Index
And I should see "explanation in last message and explanation about edit" elements with selectors:
| element description | selector |
| explanation in last message | [data-testid='message-bubble']:has-text('Index') |
| explanation about edit | [data-testid='message-bubble']:has-text('') |
@agent @mockOpenAI
Scenario: Wiki operation
# Add scenario-specific responses to the mock server
Given I add mock OpenAI responses:
| response | stream |
| <tool_use name="wiki-operation">{"workspaceName":"test-expected-to-fail","operation":"wiki-add-tiddler","title":"testNote","text":"test"}</tool_use> | false |
| <tool_use name="wiki-operation">{"workspaceName":"wiki","operation":"wiki-add-tiddler","title":"test","text":""}</tool_use>使 wiki | false |
| wiki "test" | false |
# Step 1: Start a fresh tab and run the two-round wiki operation flow
When I click on a "new tab button" element with selector "[data-tab-id='new-tab-button']"
And I should see a "search interface" element with selector ".aa-Autocomplete"
# Step 2: Click search box and wait for autocomplete
When I click on a "search input box" element with selector ".aa-Input"
And I should see an "autocomplete panel" element with selector ".aa-Panel"
# Step 3: Select agent from autocomplete (not new tab)
When I click on an "agent suggestion" element with selector '[data-autocomplete-source-id="agentsSource"] .aa-ItemWrapper'
And I should see a "message input box" element with selector "[data-testid='agent-message-input']"
# First round: try create note using test-expected-to-fail workspace (expected to fail)
When I click on a "message input textarea" element with selector "[data-testid='agent-message-input']"
When I type " wiki test" in "chat input" element with selector "[data-testid='agent-message-input']"
And I press "Enter" key
Then I should see 6 messages in chat history
# Verify error and success messages
And I should see "workspace not exist error and success in last message and wiki workspace in last message" elements with selectors:
| element description | selector |
| workspace not exist error | [data-testid='message-bubble']:has-text('test-expected-to-fail'):has-text('') |
| success in last message | [data-testid='message-bubble']:has-text('') |
| wiki workspace in last message | [data-testid='message-bubble']:has-text('wiki') |
@agent
Scenario: Create default agent from New Tab quick access
When I click on "new tab button and create default agent button" elements with selectors:
| element description | selector |
| new tab button | [data-tab-id='new-tab-button'] |
| create default agent button | [data-testid='create-default-agent-button'] |
And I should see a "message input box" element with selector "[data-testid='agent-message-input']"
@agent
Scenario: Close all tabs then create default agent from fallback page
# Ensure starting from black/fallback page with no open tabs
# Open tab list dropdown and close tabs from there
Given I click on a "new tab button" element with selector "[data-tab-id='new-tab-button']"
When I click on a "tab list dropdown" element with selector "[data-testid='tab-list-button']"
When I click all "close tab button" elements matching selector "[data-testid^='tab-close-']"
# When there is no active tab, this is "fallback new tab", it has same thing as new tab.
And I should see "new tab button and Create Default Agent" elements with selectors:
| element description | selector |
| new tab button | [data-tab-id='new-tab-button'] |
| Create Default Agent | [data-testid='create-default-agent-button'] |
When I click on a "new tab button" element with selector "[data-tab-id='new-tab-button']"
And I should see a "Create Default Agent" element with selector "[data-testid='create-default-agent-button']"
When I click on a "create default agent button" element with selector "[data-testid='create-default-agent-button']"
And I should see a "message input box" element with selector "[data-testid='agent-message-input']"
# Close remaining tabs via dropdown
Then I click on a "tab list dropdown" element with selector "[data-testid='tab-list-button']"
Then I click all "close tab button" elements matching selector "[data-testid^='tab-close-']"
@agent @mockOpenAI
Scenario: Streamed assistant response can be cancelled mid-stream and send button returns
# Add scenario-specific responses to the mock server
Given I add mock OpenAI responses:
| response | stream |
| partial_chunk_1<stream_split>partial_chunk_2<stream_split>partial_chunk_3<stream_split>partial_chunk_4 | true |
And I click on "new tab button and create default agent button" elements with selectors:
| element description | selector |
| new tab button | [data-tab-id='new-tab-button'] |
| create default agent button | [data-testid='create-default-agent-button'] |
And I should see a "message input box" element with selector "[data-testid='agent-message-input']"
When I click on a "message input textarea" element with selector "[data-testid='agent-message-input']"
When I type "Start long streaming" in "chat input" element with selector "[data-testid='agent-message-input']"
And I press "Enter" key
# Wait for streaming container to appear and contain the first chunk
Then I should see "assistant streaming container and partial assistant text and cancel icon" elements with selectors:
| element description | selector |
| assistant streaming container | [data-testid='assistant-streaming-text'] |
| partial assistant text | *:has-text('partial_chunk_1') |
| cancel icon | [data-testid='cancel-icon'] |
# Click cancel button mid-stream
When I click on a "cancel button" element with selector "[data-testid='agent-send-button']"
# Verify send button returned and stream stopped (no further chunks)
Then I should see "send icon and send button" elements with selectors:
| element description | selector |
| send icon | [data-testid='send-icon'] |
| send button | [data-testid='agent-send-button']|
And I should not see a "partial chunk 4 text" element with selector "text='partial_chunk_4'"
@agent @mockOpenAI
Scenario: Wiki tiddler attachment with rendered content
# Add scenario-specific responses to the mock server
Given I add mock OpenAI responses:
| response | stream |
| wiki | false |
# First, navigate to wiki workspace and create a test tiddler with wikitext content
When I click on a "default wiki workspace button" element with selector "div[data-testid^='workspace-']:has-text('wiki')"
Then the browser view should be loaded and visible
And I wait for "SSE backend ready" log marker "[test-id-SSE_READY]"
# Create a new tiddler with wikitext syntax
When I execute TiddlyWiki code in browser view: "$tw.wiki.addTiddler(new $tw.Tiddler({title: 'TestAttachmentTiddler', text: '!!WikiTestHeader\\n\\nThis is a test with WikiTestContentMarker123', type: 'text/vnd.tiddlywiki'}))"
# Navigate to agent workspace and create agent
When I click on "agent workspace button and create default agent button" elements with selectors:
| element description | selector |
| agent workspace button | [data-testid='workspace-agent'] |
| create default agent button | [data-testid='create-default-agent-button'] |
And I should see a "message input box" element with selector "[data-testid='agent-message-input']"
# Click attachment button to open autocomplete
When I click on a "attach button" element with selector "[data-testid='agent-attach-button']"
# Autocomplete should open showing image option + tiddler options
And I should see "attachment autocomplete input and attachment listbox" elements with selectors:
| element description | selector |
| attachment autocomplete input | [data-testid='attachment-autocomplete-input'] |
| attachment listbox | [data-testid='attachment-listbox'] |
# Click on our test tiddler option
When I click on a "test tiddler option" element with selector "[data-testid='attachment-option-tiddler-TestAttachmentTiddler']"
# Verify the chip is displayed
Then I should see a "wiki tiddler chip" element with selector "[data-testid='wiki-tiddler-chip-0']"
# Type message and send
When I click on a "message input textarea" element with selector "[data-testid='agent-message-input']"
When I type "" in "chat input" element with selector "[data-testid='agent-message-input']"
And I press "Enter" key
# Verify the mock server received the rendered content (wikitext converted to plain text)
Then the last AI request user message should contain "WikiTestHeader\n\nThis is a test with WikiTestContentMarker123"
# Verify wikitext was converted to plain text (!! becomes "Header", not raw !!)
And the last AI request user message should not contain "!!"
@agent @mockOpenAI @askQuestion
Scenario: Ask-question tool renders interactive UI and raw XML is hidden
Given I add mock OpenAI responses:
| response | stream |
| wikitiddler <tool_use name="ask-question">{"question":"Which workspace?","inputType":"single-select","options":[{"label":"My Wiki"},{"label":"Work Wiki"}],"allowFreeform":true}</tool_use> tiddler | false |
| My Wiki | false |
When I click on "create default agent button" elements with selectors:
| element description | selector |
| create default agent button | [data-testid='create-default-agent-button'] |
And I should see a "message input box" element with selector "[data-testid='agent-message-input']"
When I click on a "message input textarea" element with selector "[data-testid='agent-message-input']"
When I type "" in "chat input" element with selector "[data-testid='agent-message-input']"
And I press "Enter" key
# The ask-question tool result should be rendered as an interactive UI, not raw XML
Then I should see an "ask question container" element with selector "[data-testid='ask-question-container']"
And I should see "question text and option chips" elements with selectors:
| element description | selector |
| question text | *:has-text('Which workspace?') |
| option chip 1 | [data-testid='ask-question-option-0'] |
| option chip 2 | [data-testid='ask-question-option-1'] |
# Raw XML tags should NOT be visible in any message
And I should not see a "raw tool use xml" element with selector "*:has-text('<tool_use')"
And I should not see a "raw ask question tag" element with selector "*:has-text('<ask-question')"
# Click on an option to answer
When I click on a "first option" element with selector "[data-testid='ask-question-option-0']"
# Agent should continue with a second round
Then I should see an "agent response after answer" element with selector "[data-testid='message-bubble']:has-text('My Wiki')"