Deploy web Studio / deploy (push) Successful in 3m3s
✦ 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
81 lines
4.1 KiB
HTML
81 lines
4.1 KiB
HTML
<!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>↶ Undo</button>
|
||
<button type="button" id="redo" title="Redo (Ctrl+Y)" disabled>↷ 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">◐</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>
|