feat(scenario): BisonFi support - #10
Open
bakasura980 wants to merge 5 commits into
Open
Conversation
…he simnet clock (#1) * fix(studio): stop scenario saves from destroying override data Renaming a scenario or editing its description rebuilt the whole backend document from a lossy UI projection — values: {}, a dummy pubkey, fabricated templateIds, tags: [] — and PATCH is a full replace, so real content was wiped. Layered fixes: - flattenOverrideValues collects both value shapes: flat backend keys and nested UI edits reachable through modifiedFields (nested edits were silently dropped before); - buildUpdatePayload mirrors the editor sync payload: real override id, templateId, values, account, fetchBeforeUse and tags are carried through; - the shared OverridePayload type spreads the untouched backend override (ScenarioAction.original) first, so fields the UI does not edit — enabled today, anything added later — survive by construction; - scenario tags load from the list endpoint: GET /v1/scenarios/{id} has never existed and the SPA fallback answered it with HTML 200, so tags never loaded and every editor sync wiped them server-side. Also ignores wheel scrolling over the editor's focused number inputs — the browser's scroll-to-increment default silently changed typed values. * fix(studio): compute time travel from the surfnet clock Date-mode time travel used Date.now(), but the simulated clock drifts from the wall clock (pauses, prior jumps, slot-paced ticking): the first jump silently absorbed the accumulated drift, and consecutive jumps moved the clock by seconds while claiming days. The jump target now derives from the Clock sysvar via the new lib/surfnet-clock.ts helper (SYSVAR_CLOCK_PUBKEY, jsonParsed), covered by request-pinning tests. The dialog also previews the landing time live (1s polling while open), pre-blocks backward jumps with a friendly message and a disabled Jump button, and surfaces backend rejections and non-OK HTTP responses instead of staying silent. * fix(studio): commit inline edits once instead of PATCHing per keystroke The scenario title and description inputs sent a full-replace PATCH on every keystroke against live-rerendered state, which made typing nearly impossible and produced a request storm. The new DraftField keeps a local draft and commits once on Enter/blur; Escape cancels the edit and stops propagation so cancelling no longer closes the whole detail pane; empty values are ignored unless explicitly allowed (description). * chore(studio): refresh AI chat models OpenAI: gpt-5.6-luna/terra/sol. reasoning_effort is 'none' because gpt-5.6 rejects function tools with reasoning enabled on /v1/chat/completions; re-enabling it means migrating this client to /v1/responses. Anthropic: claude-haiku-4-5 / claude-sonnet-5 / claude-opus-5, with max_tokens raised 4096 -> 16000 since Claude 5 models think by default and the cap covers thinking plus response. Stored model ids from the removed list fall back through the existing getModelById guard. The system prompt points models at search_constant_options for constant values. * test(studio): move the network API test out of pages/ and exclude .next A vitest file living under src/pages/api compiled into a real production endpoint (/api/network/network.test), and vitest picked up compiled .next artifacts after any production build, failing the suite. The test now lives in src/__tests__ and .next/** is excluded from the runner. * refactor(studio): move reasoning effort into the model config Review feedback: reasoning_effort was hardcoded in streamOpenAIResponse for every model. It now lives on the model entry (reasoningEffort), so enabling reasoning for a future model is a config change; unlisted models fall back to 'none' since gpt-5.6 rejects function tools with reasoning enabled on /v1/chat/completions. * fix(studio): resolve fetchSurfnetClockSeconds to null on network errors Review feedback: the signature promises Promise<number | null>, but a downed surfnet made the promise reject instead. Failures now resolve to null, matching how both callers already treat an unreadable clock.
…#2) * feat(studio): download a scenario as JSON The editor's download button had no handler at all — the icon was decorative. It now saves the scenario in the shape POST /v1/scenarios accepts, so a scenario can survive the restart that otherwise wipes it. Values pass through lossless-json to keep i64 fields exact, and a failure shows a message in the play bar instead of only a console line. * fix(studio): surface why an AI generation stopped The Claude stream exited silently on any stop reason other than tool_use, so a generation cut short by the output cap looked like nothing had happened. It now names the reason — output budget, refusal, or tool rounds exhausted — and max_tokens goes from 16000 to 32000, since these models think by default and the cap covers thinking plus the answer (it is a ceiling, not a reservation). * feat(studio): import a scenario from a downloaded file The + button becomes a menu: new scenario, or import a file saved by the download button. An import gets a fresh id, and lossless-json keeps i64 exact. * fix(studio): open the detail pane for a newly created scenario A page opened without an id marked the deep-link resolver as initialized and never reset it once an id arrived, so the first create needed a page reload. * feat(studio): keep Claude's thinking blocks and cache the prompt prefix Thinking blocks now go back with the tool results as the API requires; dropping them silently disabled thinking for the rest of the turn. A cache breakpoint on the system prompt and on the newest block lets later rounds read the prefix instead of paying for it again. * fix(studio): keep u64/u128 precision in scenario and snapshot JSON Scenario override values are Solana u64/u128 fields that native JSON rounds. Route load, edit, save (PATCH), Play (registerScenario) and localStorage through lossless-json so large integers stay exact. Snapshot download now emits the bare account map (result.value) that surfpool restore expects. Adds tests for the edit/save/register payloads and the snapshot download shape. * feat(studio): OpenAI Responses API + thinking toggle Move streamOpenAIResponse to /v1/responses so reasoning and function tools coexist: flat tools, store:true, reasoning.effort (medium on, none off), and previous_response_id continuation. An interrupted stream (no response.completed or no response id) is now an error, not a silent success. Add a Thinking toggle (default on) for OpenAI and Claude Sonnet/Opus; it stays visible but disabled for Fable 5 (always thinks) and non-reasoning providers. Drop Claude Haiku 4.5, add Fable 5, send thinking:{type:disabled} only for Sonnet/Opus when off, and handle model_context_window_exceeded. Raise the tool loop cap to 8 so a retriable tool error does not exhaust the drill-down. Also tidy the bar: cap protocol chips at 5 with a +N count and stop the model box wrapping.
bakasura980
changed the base branch from
develop
to
feat/scenarios/protocols/kamino
September 3, 2026 13:47
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Greptile Summary
This PR adds BisonFi support to Studio scenarios.
Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR Service[Scenario template service] --> Editor[Scenario editor] Editor --> Filter[BisonFi allow-list] Filter --> Fields[IDL or raw-layout fields] Fields --> Action[Configurable scenario action] Example[BisonFi arbitrage example] --> Editor Icon[BisonFi protocol icon] --> ActionReviews (3): Last reviewed commit: "Merge and fix conflicts" | Re-trigger Greptile
Context used: