Replace the elicitation path with a plain Petrinaut-to-Flue chat. - #9382
Replace the elicitation path with a plain Petrinaut-to-Flue chat.#9382lunelson wants to merge 6 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
PR SummaryMedium Risk Overview Conversation identity is now principal + panel conversation id → SHA-256 Flue instance id, with Dependencies and tests drop Petrinaut local demo pins a stable conversation id per net, hydrates from Reviewed by Cursor Bugbot for commit 00e16a5. Bugbot is set up for automated code reviews on this repo. Configure here. |
| ? flueHistory.messages | ||
| : currentNetId | ||
| ? aiMessagesByNetId[currentNetId] | ||
| : undefined, |
There was a problem hiding this comment.
Flue history never hydrates the panel
High Severity
GET /api/chat history is applied by swapping aiAssistant.messages after mount, but Petrinaut's useChat only reads that prop as initial state. The panel therefore keeps the first paint's localStorage (or empty) transcript and never reconciles to Flue, so reload and cross-client turns do not reconstruct the conversation from server history.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 7d400c4. Configure here.
| }); | ||
| }, | ||
| }), | ||
| [aiMessagesByNetId, currentNetId, setAiMessagesByNetId], |
There was a problem hiding this comment.
Clear chat keeps the Flue conversation
High Severity
Clearing the assistant only deletes the localStorage cache. The per-net conversationId is unchanged, so the next send still targets the same Flue instance. The model continues the old thread even though the panel looks empty, and a later successful history load would restore the wiped transcript.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 7d400c4. Configure here.
| return { messages: [] }; | ||
| } | ||
| return { messages: snapshotToUiMessages(snapshot) }; | ||
| }; |
There was a problem hiding this comment.
History failures look like empty chats
Medium Severity
loadHistory catches every history() failure and returns HTTP 200 with messages: []. The panel treats a successful GET as authoritative Flue state, so a missing instance, timeout, or Flue error is indistinguishable from a brand-new conversation and can wipe the visible transcript.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 7d400c4. Configure here.
Benchmark results
|
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 2002 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 1002 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: high, policies: 3314 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: medium, policies: 1527 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 2078 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 1033 | Flame Graph |
policy_resolution_medium
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 102 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 52 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: high, policies: 269 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: medium, policies: 108 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 133 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 63 | Flame Graph |
policy_resolution_none
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 2 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 2 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 8 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 3 | Flame Graph |
policy_resolution_small
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 52 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 26 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: high, policies: 94 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: medium, policies: 27 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 66 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 29 | Flame Graph |
read_scaling_complete
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_id;one_depth | 1 entities | Flame Graph | |
| entity_by_id;one_depth | 10 entities | Flame Graph | |
| entity_by_id;one_depth | 25 entities | Flame Graph | |
| entity_by_id;one_depth | 5 entities | Flame Graph | |
| entity_by_id;one_depth | 50 entities | Flame Graph | |
| entity_by_id;two_depth | 1 entities | Flame Graph | |
| entity_by_id;two_depth | 10 entities | Flame Graph | |
| entity_by_id;two_depth | 25 entities | Flame Graph | |
| entity_by_id;two_depth | 5 entities | Flame Graph | |
| entity_by_id;two_depth | 50 entities | Flame Graph | |
| entity_by_id;zero_depth | 1 entities | Flame Graph | |
| entity_by_id;zero_depth | 10 entities | Flame Graph | |
| entity_by_id;zero_depth | 25 entities | Flame Graph | |
| entity_by_id;zero_depth | 5 entities | Flame Graph | |
| entity_by_id;zero_depth | 50 entities | Flame Graph |
read_scaling_linkless
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_id | 1 entities | Flame Graph | |
| entity_by_id | 10 entities | Flame Graph | |
| entity_by_id | 100 entities | Flame Graph | |
| entity_by_id | 1000 entities | Flame Graph | |
| entity_by_id | 10000 entities | Flame Graph |
representative_read_entity
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/block/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1
|
Flame Graph |
representative_read_entity_type
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| get_entity_type_by_id | Account ID: bf5a9ef5-dc3b-43cf-a291-6210c0321eba
|
Flame Graph |
representative_read_multiple_entities
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_property | traversal_paths=0 | 0 | |
| entity_by_property | traversal_paths=255 | 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true | |
| link_by_source_by_property | traversal_paths=0 | 0 | |
| link_by_source_by_property | traversal_paths=255 | 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true |
scenarios
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| full_test | query-limited | Flame Graph | |
| full_test | query-unlimited | Flame Graph | |
| linked_queries | query-limited | Flame Graph | |
| linked_queries | query-unlimited | Flame Graph |
Mission 1 needs a durable conversation through the real panel before capture lands, so /api/chat now mounts one Flue agent with a server tool, a read-only client-tool resume, and Flue history as the log. Co-authored-by: Cursor <cursoragent@cursor.com>
…ries. The agent module stays a thin hook composition; skills, subagents, and channels sit empty until they are used. Co-authored-by: Cursor <cursoragent@cursor.com>
…uth. The Flue tool now shares petrinaut-core's catalog instead of a free string, and yarn dev:brunch builds the panel's workspace libraries first. Co-authored-by: Cursor <cursoragent@cursor.com>
… them. The conversation projector now maps data-part and message-metadata, fails compilation on new Flue chunk types, and keeps the same parts in history reconstruction. Co-authored-by: Cursor <cursoragent@cursor.com>
The mounted agent URL is no longer a capability hash; later concerns move to the mission scratchpad so Mission 1 stays the only execution authority. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
69dac29 to
b06ac00
Compare
7d400c4 to
00e16a5
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 5 total unresolved issues (including 3 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 00e16a5. Configure here.
| return part.output; | ||
| } | ||
| return clientOutput; | ||
| }; |
There was a problem hiding this comment.
Pending client tools hydrate as complete
Medium Severity
When a client tool is still awaiting a browser result, resolveToolOutput falls back to the { awaiting: "client" } sentinel and toolPartFrom emits output-available. Reload hydration then looks like the tool already finished, so the panel will not re-run it or POST a client-tool-result, and that Flue turn stays blocked.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 00e16a5. Configure here.
| }, | ||
| }, | ||
| write, | ||
| ); |
There was a problem hiding this comment.
Turns drop the idempotency key
Medium Severity
runUserTurn and runClientToolResume hash identity and dispatch the text or signal, but they never forward idempotencyKey. The previous elicitor path passed that key into agent.dispatch, and the transport still computes it. Retried POSTs can therefore run the same Flue turn twice.
Reviewed by Cursor Bugbot for commit 00e16a5. Configure here.



🌟 What is the purpose of this PR?
🔗 Related links
🚫 Blocked by
🔍 What does this change?
Pre-Merge Checklist 🚀
🚢 Has this modified a publishable library?
This PR:
📜 Does this require a change to the docs?
The changes in this PR:
🕸️ Does this require a change to the Turbo Graph?
The changes in this PR:
turbo.json's have been updated to reflect this🐾 Next steps
🛡 What tests cover this?
❓ How to test this?
📹 Demo