Files
isokit/studio/index.html
T
grabowski 1a1b62d475
Deploy web Studio / deploy (push) Successful in 3m3s
studio: agent window, a chat with a model that edits the scene
✦ Agent in the Studio's top bar opens a floating chat window. The model
(any OpenAI-compatible endpoint with tool calling; default B4L's inference
server, https://inference.p0.contact/v1) gets the 15 MCP tools plus two page
tools (select_object, set_view) and the Studio's state (selection, level,
rotation) in its system prompt. Answers and reasoning stream in; tool calls
show as rows with arguments and results; object ids link to the object;
Stop ends a turn; Undo takes the agent's edits back. The window moves by
its title bar and resizes at its top-left corner.

- studio/agent.js: shared by both front ends (waits for studio.js's
  isokit:studio event); MCP over /mcp or isokit.mcp in the web Studio
- isokit studio: /api/agent/{config,models,chat} relay the calls on their
  own threads (ureq, chunked and flushed per read), so the key stays on the
  machine and the endpoint needs no CORS; settings from ISOKIT_LLM_URL /
  _KEY / _MODEL or agent.json in the user's config folder
- web Studio: calls the endpoint from the page with a key kept in the
  browser; build_web.py --agent-url names a same-site relay as default; the
  deploy builds with /llm/v1, which deploy/Caddyfile forwards to the
  inference server (its nginx refuses the CORS preflight)
- tools/mock_llm.py + tools/agent_checks.py: the agent window checks in both
  check_studio.py and check_web.py
2026-10-23 19:35:53 +07:00

81 lines
4.1 KiB
HTML
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.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>isokit Studio</title>
<script>
(function(){var t=null;try{t=localStorage.getItem("isokit-theme")}catch(e){}
if(t!=="light"&&t!=="dark")t=window.matchMedia&&matchMedia("(prefers-color-scheme: light)").matches?"light":"dark";
document.documentElement.setAttribute("data-theme",t);})();
</script>
<link rel="icon" type="image/svg+xml" href="/assets/studio/favicon.svg">
<link rel="stylesheet" href="/assets/viewer/isokit-view.css">
<link rel="stylesheet" href="/assets/theme.css">
<link rel="stylesheet" href="/assets/studio/studio.css">
</head>
<body>
<header class="st-head">
<b class="st-logo">isokit <span>Studio</span></b>
<span class="st-title" id="title"></span>
<span class="st-grow"></span>
<button type="button" id="undo" title="Undo (Ctrl+Z)" disabled>&#x21B6; Undo</button>
<button type="button" id="redo" title="Redo (Ctrl+Y)" disabled>&#x21B7; Redo</button>
<span class="st-save" id="save" title="Every change is saved to scene.json at once">Saved</span>
<span class="st-sep"></span>
<a class="st-btn" id="preview" href="/view" target="_blank" rel="noopener" title="The scene as visitors see it (live)">Preview</a>
<button type="button" id="build" title="Write the self-contained HTML page">Build page</button>
<button type="button" id="theme" title="Light / dark">&#x25D0;</button>
<button type="button" id="help" title="Keys and tips">?</button>
</header>
<main class="st-main">
<aside class="st-left">
<section class="st-panel">
<h2>Add <small>click, then click on the map</small></h2>
<input type="search" id="psearch" placeholder="Search objects…" autocomplete="off">
<div id="palette" class="st-palette"></div>
</section>
<section class="st-panel st-grow-panel">
<h2>Objects <small id="ocount"></small></h2>
<input type="search" id="osearch" placeholder="Filter…" autocomplete="off">
<ul id="objects" class="st-objects"></ul>
</section>
</aside>
<section class="st-centre">
<div id="view" class="iso-fill"></div>
<div class="st-hint" id="hint" hidden></div>
<footer class="st-status">
<span id="cursor">x – y –</span>
<label title="Snap positions to a grid">Snap
<select id="snap"><option value="0">off</option><option value="0.1">0.1 m</option><option value="0.5" selected>0.5 m</option><option value="1">1 m</option><option value="5">5 m</option></select>
</label>
<span class="st-grow"></span>
<button type="button" id="warnbtn" class="st-link" hidden></button>
<span id="stats"></span>
<a id="ver" class="st-ver" href="https://git.b4l.co.th/B4L/isokit" target="_blank" rel="noopener"></a>
</footer>
</section>
<aside class="st-right" id="right"></aside>
</main>
<div class="st-toast" id="toast" hidden></div>
<dialog id="helpdlg" class="st-dialog">
<h3>isokit Studio</h3>
<table>
<tr><th>Add</th><td>pick an object on the left, click on the map (Shift-click to place several)</td></tr>
<tr><th>Select</th><td>click it on the map or in the list</td></tr>
<tr><th>Move</th><td>drag it, or arrow keys (by the snap step)</td></tr>
<tr><th>Turn</th><td>R / Shift+R, or the ⟲ ⟳ buttons</td></tr>
<tr><th>Copy / delete</th><td>Ctrl+D / Delete</td></tr>
<tr><th>Undo / redo</th><td>Ctrl+Z / Ctrl+Y</td></tr>
<tr><th>View</th><td>drag the ground to pan, Ctrl + wheel or pinch to zoom, ↺ ↻ to rotate, levels to look inside</td></tr>
<tr><th>Agent</th><td>✦ Agent opens a chat with a language model that edits the scene for you; Undo takes its steps back. Drag the window by its title, resize it at the top-left corner</td></tr>
<tr><th>MCP</th><td>connect an AI agent over MCP; its edits appear here live (see the panel when nothing is selected)</td></tr>
</table>
<form method="dialog"><button>Close</button></form>
</dialog>
<script src="/assets/viewer/isokit-view.js"></script>
<script src="/assets/studio/studio.js"></script>
<script src="/assets/studio/agent.js"></script>
</body>
</html>