loopengine 0.1.33 → 0.1.34

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.
@@ -2187,9 +2187,14 @@ export const agentsConfigPageHtml = `<!doctype html>
2187
2187
  // so only Overview is left needing a re-fetch.
2188
2188
  function refreshOverviewPanel(name) {
2189
2189
  fetch('/agents/' + encodeURIComponent(name) + '/config')
2190
- .then(function (r) { return r.json(); })
2191
- .then(function (cfg) {
2190
+ .then(function (r) { return r.json().then(function (j) { return { ok: r.ok, body: j }; }); })
2191
+ .then(function (result) {
2192
2192
  if (currentName !== name) return;
2193
+ // A non-ok body is {error: "..."}, not a real config — bail out
2194
+ // to the catch below rather than rendering it as one (same risk
2195
+ // selectAgent's own /config fetch has — see its own comment).
2196
+ if (!result.ok) throw new Error(result.body.error || 'request failed');
2197
+ var cfg = result.body;
2193
2198
  currentCfg = cfg;
2194
2199
  var overviewPanel = detail.querySelector('[data-tab-panel="overview"]');
2195
2200
  if (overviewPanel) {
@@ -2225,9 +2230,13 @@ export const agentsConfigPageHtml = `<!doctype html>
2225
2230
  // re-rendering both it and Overview from a fresh /config fetch.
2226
2231
  function refreshSkillsDependentPanels(name) {
2227
2232
  fetch('/agents/' + encodeURIComponent(name) + '/config')
2228
- .then(function (r) { return r.json(); })
2229
- .then(function (cfg) {
2233
+ .then(function (r) { return r.json().then(function (j) { return { ok: r.ok, body: j }; }); })
2234
+ .then(function (result) {
2230
2235
  if (currentName !== name) return;
2236
+ // Same "don't render an {error: ...} body as if it were a real
2237
+ // config" guard as refreshOverviewPanel/selectAgent above.
2238
+ if (!result.ok) throw new Error(result.body.error || 'request failed');
2239
+ var cfg = result.body;
2231
2240
  currentCfg = cfg;
2232
2241
  var overviewPanel = detail.querySelector('[data-tab-panel="overview"]');
2233
2242
  var skillsPanel = skillsPanelEl();
@@ -2295,10 +2304,18 @@ export const agentsConfigPageHtml = `<!doctype html>
2295
2304
  empty.style.display = 'none';
2296
2305
  detail.style.display = 'block';
2297
2306
  fetch('/agents/' + encodeURIComponent(name) + '/config')
2298
- .then(function (r) { return r.json(); })
2299
- .then(function (cfg) {
2307
+ .then(function (r) { return r.json().then(function (j) { return { ok: r.ok, body: j }; }); })
2308
+ .then(function (result) {
2300
2309
  if (currentName !== name) return;
2301
- renderDetail(cfg);
2310
+ // A non-ok response's body is {error: "..."}, not a real config
2311
+ // — rendering it as one would crash somewhere deep in
2312
+ // renderDetail (e.g. reading .model.provider off an object with
2313
+ // no .model at all) with a confusing, unrelated-looking message
2314
+ // instead of the actual server-side error this route already
2315
+ // went out of its way to surface clearly (see handleAgentConfig
2316
+ // Get's own doc comment).
2317
+ if (!result.ok) throw new Error(result.body.error || 'request failed');
2318
+ renderDetail(result.body);
2302
2319
  })
2303
2320
  .catch(function (err) {
2304
2321
  if (currentName !== name) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loopengine",
3
- "version": "0.1.33",
3
+ "version": "0.1.34",
4
4
  "type": "module",
5
5
  "description": "Runtime for tool-using AI agents with a transparent ReAct loop.",
6
6
  "license": "MIT",