create-loopengine 0.1.58 → 0.1.59

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.58",
3
+ "version": "0.1.59",
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",
@@ -153,6 +153,9 @@ import {
153
153
  searchPublicAbilities,
154
154
  fetchLatestAbilityVersion,
155
155
  describeModelProviders,
156
+ setModelProviderKey,
157
+ clearModelProviderKey,
158
+ ModelKeyError,
156
159
  describeGateways,
157
160
  scaffoldAgent,
158
161
  AgentNameError,
@@ -2982,7 +2985,31 @@ const server = createServer(async (req, res) => {
2982
2985
  return
2983
2986
  }
2984
2987
  if (req.method === 'GET' && pathname === '/config/models') {
2985
- res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify(describeModelProviders(listAgents(), (name) => getEntry(name)?.config)))
2988
+ res.writeHead(200, { 'content-type': 'application/json' }).end(
2989
+ JSON.stringify({ ...describeModelProviders(listAgents(), (name) => getEntry(name)?.config), canSave: secretsProtected }),
2990
+ )
2991
+ return
2992
+ }
2993
+ // A provider's API key, from the Models page: write-only, never read
2994
+ // back. Same rule as the Environment tab: refused on a server with no
2995
+ // auth, since anyone who could reach it could replace the key.
2996
+ const modelKeyMatch = (req.method === 'PUT' || req.method === 'DELETE') && pathname.match(/^\/config\/models\/([a-z]+)\/key$/)
2997
+ if (modelKeyMatch) {
2998
+ if (!secretsProtected) {
2999
+ res.writeHead(403, { 'content-type': 'application/json' }).end(
3000
+ JSON.stringify({ error: 'Refusing to store an API key without LOOPENGINE_ADMIN_AUTH configured: set it first, or put the key in .env.' }),
3001
+ )
3002
+ return
3003
+ }
3004
+ try {
3005
+ if (req.method === 'PUT') await setModelProviderKey(modelKeyMatch[1], (await readJsonBody(req)).key)
3006
+ else await clearModelProviderKey(modelKeyMatch[1])
3007
+ } catch (err) {
3008
+ const status = err instanceof ModelKeyError ? 400 : 500
3009
+ res.writeHead(status, { 'content-type': 'application/json' }).end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }))
3010
+ return
3011
+ }
3012
+ res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify({ ok: true }))
2986
3013
  return
2987
3014
  }
2988
3015
  if (req.method === 'GET' && pathname === '/config/gateways') {
@@ -9,7 +9,7 @@
9
9
  "cli": "tsx adapters/cli.ts"
10
10
  },
11
11
  "dependencies": {
12
- "loopengine": "^0.1.73",
12
+ "loopengine": "^0.1.74",
13
13
  "actauth": "^0.0.12"
14
14
  },
15
15
  "devDependencies": {