-
Notifications
You must be signed in to change notification settings - Fork 225
test(e2e): add view state isolation tests and update webview coverage #1186
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
Draft
easonLiangWorldedtech
wants to merge
4
commits into
Zoo-Code-Org:main
Choose a base branch
from
easonLiangWorldedtech:feat/view-local-state-base-4
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.
Draft
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
4c3e1db
feat(webview): add viewStateId generation and persistence infrastructure
easonliang28 f77fd55
feat(webview): persist viewStates in ClineProvider with setValues method
easonliang28 cf9437b
feat(api): add task control and global state APIs
easonliang28 b91a36a
test(e2e): add view state isolation tests and update webview coverage
easonliang28 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| import type { ChatCompletionRequest, ChatMessage, LLMock } from "@copilotkit/aimock" | ||
|
|
||
| const TASKS = ["A", "B", "C"] as const | ||
| const ROUNDS = 10 | ||
|
|
||
| const MODE_SEQUENCES: Record<(typeof TASKS)[number], string[]> = { | ||
| A: ["ask", "debug", "architect", "orchestrator", "code", "ask", "debug", "architect", "orchestrator", "code"], | ||
| B: ["debug", "architect", "orchestrator", "code", "ask", "debug", "architect", "orchestrator", "code", "ask"], | ||
| C: ["architect", "orchestrator", "code", "ask", "debug", "architect", "orchestrator", "code", "ask", "debug"], | ||
| } | ||
|
|
||
| const markerFor = (taskName: (typeof TASKS)[number]) => `FOLLOWUP_MODE_ISOLATION_${taskName}` | ||
| const answerFor = (taskName: (typeof TASKS)[number], round: number) => `${taskName} follow-up round ${round}` | ||
| const callIdFor = (taskName: (typeof TASKS)[number], round: number) => | ||
| `call_followup_mode_${taskName.toLowerCase()}_${String(round).padStart(2, "0")}` | ||
|
|
||
| const lastToolResultContains = (req: ChatCompletionRequest, toolCallId: string, expected: string[]) => { | ||
| const messages = Array.isArray(req?.messages) ? req.messages : [] | ||
| const toolMessage = messages.filter((message: ChatMessage) => message?.role === "tool").at(-1) | ||
| const content = toolMessage?.content | ||
|
|
||
| return ( | ||
| toolMessage?.tool_call_id === toolCallId && | ||
| typeof content === "string" && | ||
| expected.every((text) => content.includes(text)) | ||
| ) | ||
| } | ||
|
|
||
| const followupToolCall = (taskName: (typeof TASKS)[number], round: number) => ({ | ||
| name: "ask_followup_question", | ||
| arguments: JSON.stringify({ | ||
| question: `Task ${taskName}: choose mode for round ${round}`, | ||
| follow_up: [ | ||
| { | ||
| text: answerFor(taskName, round), | ||
| mode: MODE_SEQUENCES[taskName][round - 1], | ||
| }, | ||
| ], | ||
| }), | ||
| id: callIdFor(taskName, round), | ||
| }) | ||
|
|
||
| export const getFollowupModeIsolationPlan = () => | ||
| TASKS.map((taskName) => ({ | ||
| taskName, | ||
| marker: markerFor(taskName), | ||
| rounds: MODE_SEQUENCES[taskName].map((mode, index) => ({ | ||
| round: index + 1, | ||
| answer: answerFor(taskName, index + 1), | ||
| mode, | ||
| })), | ||
| })) | ||
|
|
||
| export function addViewStateFixtures(mock: InstanceType<typeof LLMock>) { | ||
| for (const taskName of TASKS) { | ||
| mock.addFixture({ | ||
| match: { | ||
| userMessage: markerFor(taskName), | ||
| }, | ||
| response: { | ||
| toolCalls: [followupToolCall(taskName, 1)], | ||
| }, | ||
| }) | ||
|
|
||
| for (let round = 1; round < ROUNDS; round++) { | ||
| mock.addFixture({ | ||
| match: { | ||
| predicate: (req) => | ||
| lastToolResultContains(req, callIdFor(taskName, round), [answerFor(taskName, round)]), | ||
| }, | ||
| response: { | ||
| toolCalls: [followupToolCall(taskName, round + 1)], | ||
| }, | ||
| }) | ||
| } | ||
|
|
||
| mock.addFixture({ | ||
| match: { | ||
| predicate: (req) => | ||
| lastToolResultContains(req, callIdFor(taskName, ROUNDS), [answerFor(taskName, ROUNDS)]), | ||
| }, | ||
| response: { | ||
| toolCalls: [ | ||
| { | ||
| name: "attempt_completion", | ||
| arguments: JSON.stringify({ | ||
| result: `Task ${taskName} completed ${ROUNDS} follow-up mode switches.`, | ||
| }), | ||
| id: `call_followup_mode_${taskName.toLowerCase()}_complete`, | ||
| }, | ||
| ], | ||
| }, | ||
| }) | ||
| } | ||
| } |
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.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: Zoo-Code-Org/Zoo-Code
Length of output: 204
🏁 Script executed:
Repository: Zoo-Code-Org/Zoo-Code
Length of output: 10721
🏁 Script executed:
Repository: Zoo-Code-Org/Zoo-Code
Length of output: 50378
🏁 Script executed:
Repository: Zoo-Code-Org/Zoo-Code
Length of output: 667
🌐 Web query:
@copilotkit/aimock LLMock addFixture fixture matching order predicate userMessage model documentation💡 Result:
In
@copilotkit/aimock(formerly@copilotkit/llmock), the LLMock fixture matching system prioritizes the order in which fixtures are added [1][2]. Fixtures are evaluated in the order they appear in the internal list [1]. Key matching mechanisms include: Fixture Matching Order and Addition - Precedence: When multiple fixtures might match a request, the one added earliest to the server typically takes precedence if they are in the same registry [1]. - Programmatic Control: You can use mockServer.prependFixture to insert a fixture at the beginning of the list (index 0) to ensure it is evaluated before previously registered file-based or programmatic fixtures [1]. - Appending: Standard addFixture or shorthand methods (like.onMessage) generally append to the list [2]. Matching Criteria (Match Object) You can define a fixture using a match object, which supports several properties [2]: - userMessage: Matches based on the user's input (typically as a substring) [1][2]. - model: Restricts the fixture to a specific model identifier [2]. - predicate: A function that receives the request and returns a boolean [2]. This is the most flexible way to match, allowing you to check message roles (e.g., tool results), headers, or other request metadata [1][2]. Because predicates cannot be serialized, they must be registered programmatically rather than via JSON files [2]. Summary of Methods: - Shorthand methods like mock.onMessage(userMessage, response) or mock.on(matchObject, response) simplify registration [2]. - For complex logic, use mock.addFixture({ match: { predicate:... }, response:... }) [2]. - Use mock.prependFixture if you need a catch-all or high-priority override (e.g., handling tool-result messages) to trigger before standard fixtures [1]. Documentation Note: The class name remains LLMock for backward compatibility following the package rename from@copilotkit/llmockto@copilotkit/aimock[3][4]. Refer to the official aimock documentation for the most current API details [5][6].Citations:
🏁 Script executed:
Repository: Zoo-Code-Org/Zoo-Code
Length of output: 50378
Remove the broad
/^<environment_details>/fixture now that both switch flows match by tool call ID.mock.addFixture()registers in evaluation order, so the new tool-result predicates added before this regex fixture already cover the ask turn foropenai/gpt-4.1. Keep only thecall_modes_switch_002request scoped bytoolResultContains(req, "call_modes_switch_002", []); delete the broad regex fixture that reuses the Ask response ID.🤖 Prompt for AI Agents