@wenathlan/extension 1.1.56 → 1.1.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +699 -20
- package/dist/index.js.map +4 -4
- package/dist/llm.d.ts +238 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/memory.d.ts +66 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/modelroute.d.ts +43 -0
- package/dist/modelroute.d.ts.map +1 -0
- package/dist/policy.d.ts +32 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/promptlibrary.d.ts +33 -0
- package/dist/promptlibrary.d.ts.map +1 -0
- package/dist/protocol.d.ts +58 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/types.d.ts +191 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +922 -20
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js.map +1 -1
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +11 -0
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +3 -1
- package/extension/dist/sidepanel.js +376 -0
- package/extension/dist/sidepanel.js.map +2 -2
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Devthink review</title><link rel="stylesheet" href="style.css"></head>
|
|
4
|
-
<body><main class="wide"><header><p class="eyebrow">REVIEW GATE</p><h1>Plan before action</h1><p>Every browser operation remains blocked until the user reviews and approves it here.</p></header><label for="objective">Objective</label><textarea id="objective" rows="4" placeholder="Describe a browser task to turn into a reviewable plan."></textarea><div class="actions"><button id="localplan">Create local observation plan</button><button id="remoteplan" class="secondary">Ask configured endpoint</button><button id="diagnostic" class="secondary">Capture local diagnostics</button></div
|
|
4
|
+
<body><main class="wide"><header><p class="eyebrow">REVIEW GATE</p><h1>Plan before action</h1><p>Every browser operation remains blocked until the user reviews and approves it here.</p></header><label for="objective">Objective</label><textarea id="objective" rows="4" placeholder="Describe a browser task to turn into a reviewable plan."></textarea><div class="actions"><button id="localplan">Create local observation plan</button><button id="remoteplan" class="secondary">Ask configured endpoint</button><button id="diagnostic" class="secondary">Capture local diagnostics</button></div>
|
|
5
|
+
<div class="actions"><input id="command" placeholder="Ask any connected model in plain language" aria-label="Natural language command"><button id="commandsend" class="secondary">Ask model</button><span id="intentbadge" class="muted"></span></div><p id="status" role="status">Loading session state.</p><p id="capabilitiestext" role="status" class="muted">Optional capabilities unknown.</p><section><h2>Current plan</h2><progress id="planprogress" max="1" value="0"></progress><div id="plan" class="panel"></div></section><section><h2>Clickable map</h2><ol id="map" class="audit maplist"></ol></section><section><h2>Navigation trail</h2><ol id="trail" class="audit"></ol></section><section><h2>Navigation state</h2><div id="navigation" class="panel"></div></section><section><h2>Tabs and windows</h2><div id="tabswindows" class="panel"></div></section><section><h2>Forms and data</h2><div id="forms" class="panel"></div></section><section><h2>Files and downloads</h2><div id="files" class="panel"></div></section><section><h2>Capture gallery</h2><div id="captures" class="panel"></div></section><section><h2>Media</h2><div id="media" class="panel"></div></section><section><h2>Network calls</h2><div id="calls" class="panel"></div></section><section><h2>Network view</h2><div id="netview" class="panel"></div></section><section><h2>Traffic control</h2><div id="traffic" class="panel"></div></section><section><h2>Run timeline</h2><div id="timeline" class="panel"></div></section><section><h2>Debugger</h2><div id="debugger" class="panel"></div></section><section><h2>Profiling</h2><div id="profiling" class="panel"></div></section><section><h2>Emulation</h2><div id="emulation" class="panel"></div></section><section><h2>Sessions</h2><div id="sessions" class="panel"></div></section><section><h2>Workflows</h2><div id="workflows" class="panel"></div></section><section><h2>Workflow editor</h2><div id="workfloweditor" class="panel"></div></section><section><h2>Triggers</h2><div id="triggers" class="panel"></div></section><section><h2>Agent protocol</h2><div id="agentprotocol" class="panel"></div></section>
|
|
6
|
+
<section><h2>Models</h2><div id="models" class="panel"></div></section><section><h2>Console diff</h2><div id="consolediff" class="panel"></div></section><section><h2>Datasets</h2><div id="datasets" class="panel"></div></section><section><h2>Consent banners</h2><div id="banners" class="panel"></div></section><section><h2>Accessibility tree</h2><div id="a11y" class="panel"></div></section><section><h2>Reader view</h2><div id="reader" class="panel"></div></section><section><h2>Detected shapes</h2><ol id="detections" class="audit maplist"></ol></section><section><h2>Watch stream</h2><ol id="stream" class="audit"></ol></section><section><h2>Snapshot diffs</h2><div id="diffs" class="panel"></div></section><section><h2>Derived selectors</h2><ol id="selectors" class="audit maplist"></ol></section><section><h2>Structured diagnostics</h2><ul id="diagnostics" class="audit"></ul></section><section><h2>Local audit</h2><ol id="audit" class="audit"></ol></section></main><script type="module" src="sidepanel.js"></script></body>
|
|
5
7
|
</html>
|
|
@@ -393,6 +393,10 @@ var workflowsroot = document.querySelector("#workflows");
|
|
|
393
393
|
var workfloweditorroot = document.querySelector("#workfloweditor");
|
|
394
394
|
var triggersroot = document.querySelector("#triggers");
|
|
395
395
|
var agentprotocolroot = document.querySelector("#agentprotocol");
|
|
396
|
+
var modelsroot = document.querySelector("#models");
|
|
397
|
+
var commandinput = document.querySelector("#command");
|
|
398
|
+
var commandbutton = document.querySelector("#commandsend");
|
|
399
|
+
var intentbadge = document.querySelector("#intentbadge");
|
|
396
400
|
var triggerview = { manual: void 0, history: void 0 };
|
|
397
401
|
var sessionsview = { term: "", window: "all", diffselection: [], restorereview: void 0, importreview: void 0 };
|
|
398
402
|
var workflowview = { review: void 0, selected: "" };
|
|
@@ -2876,6 +2880,7 @@ async function refresh() {
|
|
|
2876
2880
|
renderworkfloweditor(context);
|
|
2877
2881
|
rendertriggers(context);
|
|
2878
2882
|
renderagentprotocol(context);
|
|
2883
|
+
rendermodels(context);
|
|
2879
2884
|
renderconsolediff();
|
|
2880
2885
|
renderaudit(context.audit);
|
|
2881
2886
|
rendercapabilities(context.capabilities);
|
|
@@ -2889,6 +2894,13 @@ async function create(kind) {
|
|
|
2889
2894
|
localbutton?.addEventListener("click", () => create("proposelocal").catch((error) => status(error instanceof Error ? error.message : String(error), true)));
|
|
2890
2895
|
remotebutton?.addEventListener("click", () => create("proposeremote").catch((error) => status(error instanceof Error ? error.message : String(error), true)));
|
|
2891
2896
|
diagnosticbutton?.addEventListener("click", () => request({ kind: "diagnostic" }).then(() => refresh()).catch((error) => status(error instanceof Error ? error.message : String(error), true)));
|
|
2897
|
+
commandbutton?.addEventListener("click", () => request({ kind: "llmcommand", text: commandinput?.value ?? "" }).then(() => {
|
|
2898
|
+
status("The model parsed the command; the intent badge shows the classification.");
|
|
2899
|
+
return refresh();
|
|
2900
|
+
}).catch((error) => status(error instanceof Error ? error.message : String(error), true)));
|
|
2901
|
+
commandinput?.addEventListener("keydown", (event) => {
|
|
2902
|
+
if (event.key === "Enter") commandbutton?.click();
|
|
2903
|
+
});
|
|
2892
2904
|
refresh().catch((error) => status(error instanceof Error ? error.message : String(error), true));
|
|
2893
2905
|
function renderprofiling(context) {
|
|
2894
2906
|
if (!profilingroot) return;
|
|
@@ -5165,4 +5177,368 @@ function renderagentprotocol(context) {
|
|
|
5165
5177
|
}
|
|
5166
5178
|
agentprotocolroot.append(callsbox);
|
|
5167
5179
|
}
|
|
5180
|
+
function rendermodels(context) {
|
|
5181
|
+
if (!modelsroot) return;
|
|
5182
|
+
modelsroot.replaceChildren();
|
|
5183
|
+
const llm = context.llm;
|
|
5184
|
+
if (!llm) {
|
|
5185
|
+
const empty = document.createElement("p");
|
|
5186
|
+
empty.textContent = "The models state is unknown.";
|
|
5187
|
+
modelsroot.append(empty);
|
|
5188
|
+
return;
|
|
5189
|
+
}
|
|
5190
|
+
const head = document.createElement("p");
|
|
5191
|
+
head.textContent = `${llm.providers.length} provider${llm.providers.length === 1 ? "" : "s"} \xB7 ${llm.routes.length} route${llm.routes.length === 1 ? "" : "s"} \xB7 ${llm.usage.calls} model call${llm.usage.calls === 1 ? "" : "s"} with ${llm.usage.totaltokens} tokens${llm.budget !== void 0 ? ` against the ceiling` : " and no ceiling"}.`;
|
|
5192
|
+
modelsroot.append(head);
|
|
5193
|
+
const providersbox = document.createElement("details");
|
|
5194
|
+
providersbox.className = "sessiongroup";
|
|
5195
|
+
providersbox.open = true;
|
|
5196
|
+
const providersummary = document.createElement("summary");
|
|
5197
|
+
providersummary.textContent = `Providers (${llm.providers.length})`;
|
|
5198
|
+
providersbox.append(providersummary);
|
|
5199
|
+
for (const provider of llm.providers) {
|
|
5200
|
+
const row = document.createElement("div");
|
|
5201
|
+
row.className = "sessionrow";
|
|
5202
|
+
const info = document.createElement("p");
|
|
5203
|
+
info.textContent = `${provider.name} \xB7 ${provider.style} \xB7 ${provider.status}${provider.lastcheckedat !== void 0 ? ` (checked ${new Date(provider.lastcheckedat).toLocaleTimeString()})` : ""}${provider.authref !== void 0 ? ` \xB7 key ${provider.authref.name}` : " \xB7 no key"}${provider.costpermilliontokens !== void 0 ? ` \xB7 ${provider.costpermilliontokens} per million tokens` : ""}.`;
|
|
5204
|
+
row.append(info);
|
|
5205
|
+
const actions = document.createElement("div");
|
|
5206
|
+
actions.className = "actions";
|
|
5207
|
+
const nameinput = document.createElement("input");
|
|
5208
|
+
nameinput.value = provider.name;
|
|
5209
|
+
nameinput.placeholder = "name";
|
|
5210
|
+
const endpointinput = document.createElement("input");
|
|
5211
|
+
endpointinput.value = provider.endpoint;
|
|
5212
|
+
endpointinput.placeholder = "endpoint url";
|
|
5213
|
+
const styleselect = document.createElement("select");
|
|
5214
|
+
for (const style of ["chatcompletions", "responses", "messages", "gemini"]) {
|
|
5215
|
+
const option = document.createElement("option");
|
|
5216
|
+
option.value = style;
|
|
5217
|
+
option.textContent = style;
|
|
5218
|
+
option.selected = provider.style === style;
|
|
5219
|
+
styleselect.append(option);
|
|
5220
|
+
}
|
|
5221
|
+
const modelsinput = document.createElement("input");
|
|
5222
|
+
modelsinput.value = provider.models.join(", ");
|
|
5223
|
+
modelsinput.placeholder = "models, comma separated";
|
|
5224
|
+
const keyinput = document.createElement("input");
|
|
5225
|
+
keyinput.placeholder = "stored key name";
|
|
5226
|
+
actions.append(nameinput, " ", endpointinput, " ", styleselect, " ", modelsinput, " ", keyinput, " ", button("Save", async () => {
|
|
5227
|
+
await request({ kind: "llmproviders", id: provider.id, name: nameinput.value, endpoint: endpointinput.value, style: styleselect.value, models: modelsinput.value.split(",").map((model) => model.trim()).filter((model) => model !== ""), ...keyinput.value.trim() !== "" ? { authrefname: keyinput.value.trim() } : {} });
|
|
5228
|
+
status(`Saved the provider ${nameinput.value}.`);
|
|
5229
|
+
await refresh();
|
|
5230
|
+
}), " ", button("Test call", async () => {
|
|
5231
|
+
await request({ kind: "llmtestprovider", id: provider.id });
|
|
5232
|
+
status(`The test call of ${provider.name} answered.`);
|
|
5233
|
+
await refresh();
|
|
5234
|
+
}), " ", button("Remove", async () => {
|
|
5235
|
+
await request({ kind: "llmproviders", id: provider.id, remove: true });
|
|
5236
|
+
status(`Removed the provider ${provider.name}.`);
|
|
5237
|
+
await refresh();
|
|
5238
|
+
}));
|
|
5239
|
+
row.append(actions);
|
|
5240
|
+
providersbox.append(row);
|
|
5241
|
+
}
|
|
5242
|
+
const addrow = document.createElement("div");
|
|
5243
|
+
addrow.className = "actions";
|
|
5244
|
+
const addname = document.createElement("input");
|
|
5245
|
+
addname.placeholder = "new provider name";
|
|
5246
|
+
const addendpoint = document.createElement("input");
|
|
5247
|
+
addendpoint.placeholder = "endpoint url";
|
|
5248
|
+
const addstyle = document.createElement("select");
|
|
5249
|
+
for (const style of ["chatcompletions", "responses", "messages", "gemini"]) {
|
|
5250
|
+
const option = document.createElement("option");
|
|
5251
|
+
option.value = style;
|
|
5252
|
+
option.textContent = style;
|
|
5253
|
+
addstyle.append(option);
|
|
5254
|
+
}
|
|
5255
|
+
const addmodels = document.createElement("input");
|
|
5256
|
+
addmodels.placeholder = "models, comma separated";
|
|
5257
|
+
const addkey = document.createElement("input");
|
|
5258
|
+
addkey.placeholder = "stored key name";
|
|
5259
|
+
addrow.append(addname, " ", addendpoint, " ", addstyle, " ", addmodels, " ", addkey, " ", button("Add provider", async () => {
|
|
5260
|
+
await request({ kind: "llmproviders", name: addname.value, endpoint: addendpoint.value, style: addstyle.value, models: addmodels.value.split(",").map((model) => model.trim()).filter((model) => model !== ""), ...addkey.value.trim() !== "" ? { authrefname: addkey.value.trim() } : {} });
|
|
5261
|
+
status(`Added the provider ${addname.value}; nothing is hardcoded so any gateway works.`);
|
|
5262
|
+
await refresh();
|
|
5263
|
+
}));
|
|
5264
|
+
providersbox.append(addrow);
|
|
5265
|
+
modelsroot.append(providersbox);
|
|
5266
|
+
const localbox = document.createElement("details");
|
|
5267
|
+
localbox.className = "sessiongroup";
|
|
5268
|
+
localbox.open = true;
|
|
5269
|
+
const localsummary = document.createElement("summary");
|
|
5270
|
+
localsummary.textContent = "Local model endpoint";
|
|
5271
|
+
localbox.append(localsummary);
|
|
5272
|
+
const localinfo = document.createElement("p");
|
|
5273
|
+
localinfo.textContent = llm.local !== void 0 ? `${llm.local.endpoint} with ${llm.local.model} (${llm.local.style})${llm.local.health !== void 0 ? ` \xB7 health ${llm.local.health.ok ? "ok" : `failing: ${llm.local.health.detail ?? "unknown"}`}` : " \xB7 no health check yet"}.` : "No local endpoint configured; local inference keeps sensitive extractions on the machine.";
|
|
5274
|
+
localbox.append(localinfo);
|
|
5275
|
+
const localactions = document.createElement("div");
|
|
5276
|
+
localactions.className = "actions";
|
|
5277
|
+
const localendpoint = document.createElement("input");
|
|
5278
|
+
localendpoint.placeholder = "local endpoint url";
|
|
5279
|
+
localendpoint.value = llm.local?.endpoint ?? "";
|
|
5280
|
+
const localmodel = document.createElement("input");
|
|
5281
|
+
localmodel.placeholder = "model name";
|
|
5282
|
+
localmodel.value = llm.local?.model ?? "";
|
|
5283
|
+
const localstyle = document.createElement("select");
|
|
5284
|
+
for (const style of ["chatcompletions", "responses", "messages", "gemini"]) {
|
|
5285
|
+
const option = document.createElement("option");
|
|
5286
|
+
option.value = style;
|
|
5287
|
+
option.textContent = style;
|
|
5288
|
+
option.selected = llm.local?.style === style;
|
|
5289
|
+
localstyle.append(option);
|
|
5290
|
+
}
|
|
5291
|
+
localactions.append(localendpoint, " ", localmodel, " ", localstyle, " ", button("Save local", async () => {
|
|
5292
|
+
await request({ kind: "llmlocal", endpoint: localendpoint.value, model: localmodel.value, style: localstyle.value });
|
|
5293
|
+
status("Saved the local model endpoint; the calls never leave the machine.");
|
|
5294
|
+
await refresh();
|
|
5295
|
+
}), " ", button("Health check", async () => {
|
|
5296
|
+
await request({ kind: "llmlocal", check: true });
|
|
5297
|
+
status("The local health check ran; the result rides the endpoint line.");
|
|
5298
|
+
await refresh();
|
|
5299
|
+
}));
|
|
5300
|
+
localbox.append(localactions);
|
|
5301
|
+
modelsroot.append(localbox);
|
|
5302
|
+
const routesbox = document.createElement("details");
|
|
5303
|
+
routesbox.className = "sessiongroup";
|
|
5304
|
+
routesbox.open = true;
|
|
5305
|
+
const routesummary = document.createElement("summary");
|
|
5306
|
+
routesummary.textContent = `Model routes (${llm.routes.length})`;
|
|
5307
|
+
routesbox.append(routesummary);
|
|
5308
|
+
for (const task of llm.tasks) {
|
|
5309
|
+
const row = document.createElement("div");
|
|
5310
|
+
row.className = "sessionrow";
|
|
5311
|
+
const info = document.createElement("p");
|
|
5312
|
+
info.textContent = `${task.kind}: ${task.provider !== void 0 ? `${task.provider} with ${task.model}` : "unrouted; the user picks the pair"}.`;
|
|
5313
|
+
row.append(info);
|
|
5314
|
+
const actions = document.createElement("div");
|
|
5315
|
+
actions.className = "actions";
|
|
5316
|
+
const providerselect = document.createElement("select");
|
|
5317
|
+
for (const provider of llm.providers) {
|
|
5318
|
+
const option = document.createElement("option");
|
|
5319
|
+
option.value = provider.id;
|
|
5320
|
+
option.textContent = provider.name;
|
|
5321
|
+
providerselect.append(option);
|
|
5322
|
+
}
|
|
5323
|
+
const modelinput = document.createElement("input");
|
|
5324
|
+
modelinput.placeholder = "model";
|
|
5325
|
+
const fallbackselect = document.createElement("select");
|
|
5326
|
+
const noneoption = document.createElement("option");
|
|
5327
|
+
noneoption.value = "";
|
|
5328
|
+
noneoption.textContent = "no fallback";
|
|
5329
|
+
fallbackselect.append(noneoption);
|
|
5330
|
+
for (const provider of llm.providers) {
|
|
5331
|
+
const option = document.createElement("option");
|
|
5332
|
+
option.value = provider.id;
|
|
5333
|
+
option.textContent = provider.name;
|
|
5334
|
+
fallbackselect.append(option);
|
|
5335
|
+
}
|
|
5336
|
+
const fallbackmodel = document.createElement("input");
|
|
5337
|
+
fallbackmodel.placeholder = "fallback model";
|
|
5338
|
+
actions.append(providerselect, " ", modelinput, " ", fallbackselect, " ", fallbackmodel, " ", button("Route", async () => {
|
|
5339
|
+
await request({ kind: "llmroutes", taskkind: task.kind, providerid: providerselect.value, model: modelinput.value, ...fallbackselect.value !== "" ? { fallbackproviderid: fallbackselect.value, fallbackmodel: fallbackmodel.value } : {} });
|
|
5340
|
+
status(`Routed the ${task.kind} task kind.`);
|
|
5341
|
+
await refresh();
|
|
5342
|
+
}), " ", button("Unroute", async () => {
|
|
5343
|
+
await request({ kind: "llmroutes", taskkind: task.kind, remove: true });
|
|
5344
|
+
status(`Removed the route of the ${task.kind} task kind.`);
|
|
5345
|
+
await refresh();
|
|
5346
|
+
}));
|
|
5347
|
+
row.append(actions);
|
|
5348
|
+
routesbox.append(row);
|
|
5349
|
+
}
|
|
5350
|
+
if (llm.routehistory.length > 0) {
|
|
5351
|
+
const history = document.createElement("p");
|
|
5352
|
+
history.textContent = `Route revisions: ${llm.routehistory.slice(0, 5).map((entry) => `${entry.kind} r${entry.revision} ${entry.providerid}/${entry.model}`).join(" \xB7 ")}.`;
|
|
5353
|
+
routesbox.append(history);
|
|
5354
|
+
}
|
|
5355
|
+
modelsroot.append(routesbox);
|
|
5356
|
+
if (llm.parse !== void 0) {
|
|
5357
|
+
const badge = document.createElement("p");
|
|
5358
|
+
badge.textContent = `Last command: ${llm.parse.intent} at confidence ${Math.round(llm.parse.confidence * 100)}%${llm.parse.entities.length > 0 ? ` with ${llm.parse.entities.map((entity) => `${entity.name}=${entity.value}`).join(", ")}` : ""}${llm.parse.model !== void 0 ? ` parsed by ${llm.parse.model}` : " parsed locally"}.`;
|
|
5359
|
+
modelsroot.append(badge);
|
|
5360
|
+
if (intentbadge) intentbadge.textContent = `${llm.parse.intent} ${Math.round(llm.parse.confidence * 100)}%`;
|
|
5361
|
+
} else if (intentbadge) intentbadge.textContent = "";
|
|
5362
|
+
const draftsbox = document.createElement("details");
|
|
5363
|
+
draftsbox.className = "sessiongroup";
|
|
5364
|
+
draftsbox.open = true;
|
|
5365
|
+
const draftsummary = document.createElement("summary");
|
|
5366
|
+
draftsummary.textContent = `Model drafted plans (${llm.drafts.length})`;
|
|
5367
|
+
draftsbox.append(draftsummary);
|
|
5368
|
+
for (const draft of llm.drafts.slice(0, 5)) {
|
|
5369
|
+
const card = document.createElement("div");
|
|
5370
|
+
card.className = "sessionrow";
|
|
5371
|
+
const info = document.createElement("p");
|
|
5372
|
+
info.textContent = `${draft.goal} \xB7 ${draft.steps.length} steps \xB7 ${draft.state}${draft.lintfindings.length > 0 ? ` \xB7 ${draft.lintfindings.length} grammar finding${draft.lintfindings.length === 1 ? "" : "s"}` : " \xB7 clean grammar"} \xB7 by ${draft.model}.`;
|
|
5373
|
+
card.append(info);
|
|
5374
|
+
const edits = [];
|
|
5375
|
+
for (const step of draft.steps) {
|
|
5376
|
+
const steprow = document.createElement("div");
|
|
5377
|
+
steprow.className = "actions";
|
|
5378
|
+
const kindinput = document.createElement("input");
|
|
5379
|
+
kindinput.value = step.kind;
|
|
5380
|
+
kindinput.placeholder = "kind";
|
|
5381
|
+
const targetinput = document.createElement("input");
|
|
5382
|
+
targetinput.value = step.target ?? "";
|
|
5383
|
+
targetinput.placeholder = "target";
|
|
5384
|
+
const valueinput = document.createElement("input");
|
|
5385
|
+
valueinput.value = step.value ?? "";
|
|
5386
|
+
valueinput.placeholder = "value";
|
|
5387
|
+
const summaryinput = document.createElement("input");
|
|
5388
|
+
summaryinput.value = step.summary;
|
|
5389
|
+
summaryinput.placeholder = "summary";
|
|
5390
|
+
steprow.append(kindinput, " ", targetinput, " ", valueinput, " ", summaryinput);
|
|
5391
|
+
card.append(steprow);
|
|
5392
|
+
edits.push({ id: step.id, kind: kindinput, target: targetinput, value: valueinput, summary: summaryinput });
|
|
5393
|
+
}
|
|
5394
|
+
if (draft.openquestions.length > 0) {
|
|
5395
|
+
const questions = document.createElement("p");
|
|
5396
|
+
questions.textContent = `Open questions: ${draft.openquestions.join(" | ")}`;
|
|
5397
|
+
card.append(questions);
|
|
5398
|
+
}
|
|
5399
|
+
if (draft.lintfindings.length > 0) {
|
|
5400
|
+
const findings = document.createElement("p");
|
|
5401
|
+
findings.textContent = `Grammar findings: ${draft.lintfindings.join(" ")}`;
|
|
5402
|
+
card.append(findings);
|
|
5403
|
+
}
|
|
5404
|
+
const actions = document.createElement("div");
|
|
5405
|
+
actions.className = "actions";
|
|
5406
|
+
actions.append(button("Approve draft", async () => {
|
|
5407
|
+
await request({ kind: "llmdraftdecision", draftid: draft.id, approve: true, steps: edits.map((edit) => ({ id: edit.id, kind: edit.kind.value, ...edit.target.value.trim() !== "" ? { target: edit.target.value } : {}, ...edit.value.value.trim() !== "" ? { value: edit.value.value } : {}, summary: edit.summary.value })) });
|
|
5408
|
+
status("The approved draft became a pending plan that still passes the same plan review.");
|
|
5409
|
+
await refresh();
|
|
5410
|
+
}), " ", button("Reject draft", async () => {
|
|
5411
|
+
await request({ kind: "llmdraftdecision", draftid: draft.id });
|
|
5412
|
+
status("The draft is rejected and stays for the audit trail.");
|
|
5413
|
+
await refresh();
|
|
5414
|
+
}), " ", button("Replan failed tail", async () => {
|
|
5415
|
+
await request({ kind: "llmreplan", draftid: draft.id, failedstepids: edits.slice(-1).map((edit) => edit.id), reason: "The last step failed and the model replans the tail." });
|
|
5416
|
+
status("The model replanned the failed tail; the fresh review waits.");
|
|
5417
|
+
await refresh();
|
|
5418
|
+
}));
|
|
5419
|
+
card.append(actions);
|
|
5420
|
+
draftsbox.append(card);
|
|
5421
|
+
}
|
|
5422
|
+
modelsroot.append(draftsbox);
|
|
5423
|
+
const replansbox = document.createElement("details");
|
|
5424
|
+
replansbox.className = "sessiongroup";
|
|
5425
|
+
replansbox.open = true;
|
|
5426
|
+
const replansummary = document.createElement("summary");
|
|
5427
|
+
replansummary.textContent = `Replans (${llm.replans.length})`;
|
|
5428
|
+
replansbox.append(replansummary);
|
|
5429
|
+
for (const replan of llm.replans.slice(0, 5)) {
|
|
5430
|
+
const card = document.createElement("div");
|
|
5431
|
+
card.className = "sessionrow";
|
|
5432
|
+
const info = document.createElement("p");
|
|
5433
|
+
info.textContent = `${replan.reason} \xB7 keeps ${replan.completedstepids.length} completed step${replan.completedstepids.length === 1 ? "" : "s"} \xB7 ${replan.state}.`;
|
|
5434
|
+
card.append(info);
|
|
5435
|
+
for (const step of replan.tail) {
|
|
5436
|
+
const tail = document.createElement("p");
|
|
5437
|
+
tail.textContent = `\u21BB ${step.id} ${step.kind}: ${step.summary} \u2014 fresh review required`;
|
|
5438
|
+
card.append(tail);
|
|
5439
|
+
}
|
|
5440
|
+
const actions = document.createElement("div");
|
|
5441
|
+
actions.className = "actions";
|
|
5442
|
+
actions.append(button("Approve fresh review", async () => {
|
|
5443
|
+
await request({ kind: "llmreplandecision", replanid: replan.id, approve: true });
|
|
5444
|
+
status("The approved replan became a pending plan with the changed tail under the same plan review.");
|
|
5445
|
+
await refresh();
|
|
5446
|
+
}), " ", button("Reject replan", async () => {
|
|
5447
|
+
await request({ kind: "llmreplandecision", replanid: replan.id });
|
|
5448
|
+
status("The replan is rejected and stays for the audit trail.");
|
|
5449
|
+
await refresh();
|
|
5450
|
+
}));
|
|
5451
|
+
card.append(actions);
|
|
5452
|
+
replansbox.append(card);
|
|
5453
|
+
}
|
|
5454
|
+
modelsroot.append(replansbox);
|
|
5455
|
+
const notesbox = document.createElement("details");
|
|
5456
|
+
notesbox.className = "sessiongroup";
|
|
5457
|
+
const notesummary = document.createElement("summary");
|
|
5458
|
+
notesummary.textContent = `Reflection notes (${llm.notes.length})`;
|
|
5459
|
+
notesbox.append(notesummary);
|
|
5460
|
+
for (const note of llm.notes.slice(0, 5)) {
|
|
5461
|
+
const row = document.createElement("p");
|
|
5462
|
+
row.textContent = `Step ${note.stepid} (${note.runid}): ${note.outcome} \u2014 lesson ${note.lesson} \u2014 next ${note.advice} \xB7 by ${note.model}.`;
|
|
5463
|
+
notesbox.append(row);
|
|
5464
|
+
}
|
|
5465
|
+
modelsroot.append(notesbox);
|
|
5466
|
+
const budgetbox = document.createElement("details");
|
|
5467
|
+
budgetbox.className = "sessiongroup";
|
|
5468
|
+
budgetbox.open = true;
|
|
5469
|
+
const budgetsummary = document.createElement("summary");
|
|
5470
|
+
budgetsummary.textContent = "Cost budget";
|
|
5471
|
+
budgetbox.append(budgetsummary);
|
|
5472
|
+
const meter = document.createElement("progress");
|
|
5473
|
+
meter.max = llm.budget?.maxtokens ?? (llm.usage.totaltokens || 1);
|
|
5474
|
+
meter.value = Math.min(llm.usage.totaltokens, Number(meter.max));
|
|
5475
|
+
budgetbox.append(meter);
|
|
5476
|
+
const budgetinfo = document.createElement("p");
|
|
5477
|
+
budgetinfo.textContent = `${llm.usage.totaltokens} tokens (${llm.usage.prompttokens} prompt and ${llm.usage.completiontokens} completion) and ${llm.usage.cost.toFixed(4)} cost over ${llm.usage.calls} call${llm.usage.calls === 1 ? "" : "s"}${llm.budget?.maxtokens !== void 0 ? ` against the ${llm.budget.maxtokens} token ceiling` : " with no token ceiling"}${llm.budget?.maxcost !== void 0 ? ` and the ${llm.budget.maxcost} ${llm.budget.currency ?? ""} cost ceiling` : ""}; a reached ceiling halts and asks.`;
|
|
5478
|
+
budgetbox.append(budgetinfo);
|
|
5479
|
+
const budgetactions = document.createElement("div");
|
|
5480
|
+
budgetactions.className = "actions";
|
|
5481
|
+
const tokensinput = document.createElement("input");
|
|
5482
|
+
tokensinput.placeholder = "token ceiling";
|
|
5483
|
+
const costinput = document.createElement("input");
|
|
5484
|
+
costinput.placeholder = "cost ceiling";
|
|
5485
|
+
const currencyinput = document.createElement("input");
|
|
5486
|
+
currencyinput.placeholder = "currency";
|
|
5487
|
+
budgetactions.append(tokensinput, " ", costinput, " ", currencyinput, " ", button("Set budget", async () => {
|
|
5488
|
+
await request({ kind: "llmbudget", ...tokensinput.value.trim() !== "" ? { maxtokens: Number(tokensinput.value) } : {}, ...costinput.value.trim() !== "" ? { maxcost: Number(costinput.value) } : {}, ...currencyinput.value.trim() !== "" ? { currency: currencyinput.value } : {} });
|
|
5489
|
+
status("Saved the cost budget; every ceiling stays the user choice.");
|
|
5490
|
+
await refresh();
|
|
5491
|
+
}), " ", button("Remove budget", async () => {
|
|
5492
|
+
await request({ kind: "llmbudget", remove: true });
|
|
5493
|
+
status("The cost budget is gone; the runs stay unbounded.");
|
|
5494
|
+
await refresh();
|
|
5495
|
+
}));
|
|
5496
|
+
budgetbox.append(budgetactions);
|
|
5497
|
+
modelsroot.append(budgetbox);
|
|
5498
|
+
const templatesbox = document.createElement("details");
|
|
5499
|
+
templatesbox.className = "sessiongroup";
|
|
5500
|
+
const templatesummary = document.createElement("summary");
|
|
5501
|
+
templatesummary.textContent = `Prompt library (${llm.templates.length})`;
|
|
5502
|
+
templatesbox.append(templatesummary);
|
|
5503
|
+
for (const template of llm.templates.slice(0, 8)) {
|
|
5504
|
+
const row = document.createElement("p");
|
|
5505
|
+
row.textContent = `${template.name} v${template.version} \xB7 variables ${template.variables.join(", ") || "none"}${template.notes !== void 0 ? ` \xB7 ${template.notes}` : ""}: ${template.body.slice(0, 120)}${template.body.length > 120 ? "\u2026" : ""}`;
|
|
5506
|
+
templatesbox.append(row);
|
|
5507
|
+
}
|
|
5508
|
+
const templateactions = document.createElement("div");
|
|
5509
|
+
templateactions.className = "actions";
|
|
5510
|
+
const templatename = document.createElement("input");
|
|
5511
|
+
templatename.placeholder = "template name";
|
|
5512
|
+
const templatebody = document.createElement("input");
|
|
5513
|
+
templatebody.placeholder = "body with {{variables}}";
|
|
5514
|
+
const templatenotes = document.createElement("input");
|
|
5515
|
+
templatenotes.placeholder = "change notes";
|
|
5516
|
+
templateactions.append(templatename, " ", templatebody, " ", templatenotes, " ", button("Save template", async () => {
|
|
5517
|
+
await request({ kind: "llmtemplate", name: templatename.value, body: templatebody.value, ...templatenotes.value.trim() !== "" ? { notes: templatenotes.value } : {} });
|
|
5518
|
+
status("Saved the template version with its change notes.");
|
|
5519
|
+
await refresh();
|
|
5520
|
+
}), " ", button("Remove template", async () => {
|
|
5521
|
+
await request({ kind: "llmtemplate", name: templatename.value, remove: true });
|
|
5522
|
+
status("Removed every version of the template.");
|
|
5523
|
+
await refresh();
|
|
5524
|
+
}));
|
|
5525
|
+
templatesbox.append(templateactions);
|
|
5526
|
+
modelsroot.append(templatesbox);
|
|
5527
|
+
const guardbox = document.createElement("details");
|
|
5528
|
+
guardbox.className = "sessiongroup";
|
|
5529
|
+
const guardsummary = document.createElement("summary");
|
|
5530
|
+
guardsummary.textContent = `Guard refusals (${llm.guardnotices.length})`;
|
|
5531
|
+
guardbox.append(guardsummary);
|
|
5532
|
+
for (const notice of llm.guardnotices.slice(0, 5)) {
|
|
5533
|
+
const row = document.createElement("p");
|
|
5534
|
+
row.textContent = `${notice.verdict} after ${notice.attempts} attempt${notice.attempts === 1 ? "" : "s"}: ${notice.reason ?? "the output failed its guard"}.`;
|
|
5535
|
+
guardbox.append(row);
|
|
5536
|
+
}
|
|
5537
|
+
if (llm.guardnotices.length === 0) {
|
|
5538
|
+
const row = document.createElement("p");
|
|
5539
|
+
row.textContent = "No guard refusal yet; invalid model output never executes.";
|
|
5540
|
+
guardbox.append(row);
|
|
5541
|
+
}
|
|
5542
|
+
modelsroot.append(guardbox);
|
|
5543
|
+
}
|
|
5168
5544
|
//# sourceMappingURL=sidepanel.js.map
|