create-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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-loopengine",
3
- "version": "0.1.33",
3
+ "version": "0.1.34",
4
4
  "description": "Scaffold a new loopengine agent project — a runnable HTTP server with one example agent, in your own repo.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -868,7 +868,18 @@ async function handleEditAgent(req: IncomingMessage, res: ServerResponse, agentN
868
868
  }
869
869
  updateAgent(agentName, { config: configPatch, createModelCall })
870
870
 
871
- res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify(await describeAgent(getEntry(agentName)!)))
871
+ // Same "compute before writeHead" reasoning as the GET .../config
872
+ // route above — describeAgent can throw (a broken tools/index.ts
873
+ // import), and chaining it straight into .end()'s argument would send
874
+ // a 200 status before finding that out.
875
+ let described: Record<string, unknown>
876
+ try {
877
+ described = await describeAgent(getEntry(agentName)!)
878
+ } catch (err) {
879
+ res.writeHead(500, { 'content-type': 'application/json' }).end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }))
880
+ return
881
+ }
882
+ res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify(described))
872
883
  }
873
884
 
874
885
  // Backs the Skills tab's edit form (GET .../skills/:skillId to populate
@@ -2087,7 +2098,23 @@ const server = createServer(async (req, res) => {
2087
2098
  res.writeHead(404, { 'content-type': 'application/json' }).end(JSON.stringify({ error: `unknown agent '${agentName}'` }))
2088
2099
  return
2089
2100
  }
2090
- res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify(await describeAgent(entry)))
2101
+ // describeAgent dynamically imports this agent's own tools/index.ts
2102
+ // (loadDefaultTools) — a broken import there (a bad tool file, a
2103
+ // dependency the agent's own code needs but doesn't have) throws.
2104
+ // Computed before writeHead, not chained directly into .end() as an
2105
+ // argument — chaining would send the 200 status line first, then
2106
+ // throw while still computing the body, leaving the connection
2107
+ // open with headers sent but no body ever written (a client-side
2108
+ // "Unexpected end of JSON input", not a clear error) instead of a
2109
+ // real 500 with an actual message.
2110
+ let described: Record<string, unknown>
2111
+ try {
2112
+ described = await describeAgent(entry)
2113
+ } catch (err) {
2114
+ res.writeHead(500, { 'content-type': 'application/json' }).end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }))
2115
+ return
2116
+ }
2117
+ res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify(described))
2091
2118
  return
2092
2119
  }
2093
2120