create-loopengine 0.1.3 → 0.1.4

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 CHANGED
@@ -42,7 +42,7 @@ A real, standalone project — its own `package.json` depending on
42
42
 
43
43
  ```
44
44
  package.json Depends on loopengine — your project, not a fork
45
- agent-registry.ts Maps agent name -> {config, createModelCall}, one line per agent
45
+ agent-registry.ts Auto-discovers agents/*.ts by AgentConfig.name — nothing to edit here
46
46
  agents/example-agent.ts Starter agent: persona, one tool, one permission rule
47
47
  adapters/http.ts HTTP API (streaming + non-streaming), routes by agent name
48
48
  adapters/cli.ts Command-line adapter
@@ -50,18 +50,21 @@ adapters/cli.ts Command-line adapter
50
50
  ```
51
51
 
52
52
  The registry is multi-agent-capable from the start — seeded with one
53
- example agent, not architecturally limited to one — so adding a second
54
- agent later is one file plus one line in `agent-registry.ts`, not a
55
- rewrite. See [loopengine's own README](https://github.com/evanyan22/loopengine)
56
- for the full `AgentConfig` surface: permission rules, skills, context-budget
57
- recovery, and how to wire a real model (Anthropic or OpenAI, both included).
53
+ example agent, not architecturally limited to one — built on loopengine's
54
+ own `discoverAgents`: it scans `agents/` and keys each entry by
55
+ `AgentConfig.name`, not the filename, so adding a second agent later is
56
+ one new file, not a rewrite and not a registry edit either. See
57
+ [loopengine's own README](https://github.com/evanyan22/loopengine) for the
58
+ full `AgentConfig` surface: permission rules, skills, context-budget
59
+ recovery, and how to wire a real model (Anthropic, OpenAI, or DeepSeek —
60
+ all three included).
58
61
 
59
62
  ## Add another agent
60
63
 
61
64
  1. Copy `agents/example-agent.ts` to `agents/your-agent.ts` and edit its
62
- `systemPrompt`, `tools`, and `rules`.
63
- 2. Register it in `agent-registry.ts` — one line, same shape as
64
- `example-agent`.
65
+ `name`, `systemPrompt`, `tools`, and `rules`.
66
+ 2. That's it — `agent-registry.ts` discovers it automatically, no
67
+ registration step.
65
68
  3. Call it at `/agents/your-agent/messages`.
66
69
 
67
70
  ## Adding external tools via Composio
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-loopengine",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
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",
@@ -30,15 +30,16 @@ npm run cli -- --agent example-agent "what is the weather in Boston?"
30
30
  ## Add another agent
31
31
 
32
32
  1. Copy `agents/example-agent.ts` to `agents/your-agent.ts` and edit its
33
- `systemPrompt`, `tools`, and `rules`.
34
- 2. Register it in `agent-registry.ts` — one line, same shape as
35
- `example-agent`.
33
+ `name`, `systemPrompt`, `tools`, and `rules`.
34
+ 2. That's it — `agent-registry.ts` discovers it automatically by
35
+ `AgentConfig.name`, no registration step. Nothing to edit, no import to
36
+ add, no adapter change.
36
37
  3. Call it at `/agents/your-agent/messages`.
37
38
 
38
39
  ## Project layout
39
40
 
40
41
  ```
41
- agent-registry.ts Maps agent name -> {config, createModelCall}
42
+ agent-registry.ts Auto-discovers agents/*.ts by AgentConfig.name — nothing to edit here
42
43
  agents/example-agent.ts Starter agent: persona, one tool, one permission rule
43
44
  adapters/http.ts HTTP API (streaming + non-streaming)
44
45
  adapters/cli.ts Command-line adapter
@@ -1,24 +1,27 @@
1
1
  // Every adapter resolves "which agent" through this — the thing that
2
- // makes agents pluggable. Defining a new agent means adding one line here;
3
- // no adapter changes needed.
4
- import type { AgentConfig, ModelCall } from 'loopengine'
5
- import { config as exampleAgentConfig, createModelCall as createExampleAgentModelCall } from './agents/example-agent.js'
2
+ // makes agents pluggable. Defining a new agent means adding a file to
3
+ // agents/ that exports `config` and `createModelCall` — nothing here or
4
+ // in any adapter needs to change; discoverAgents scans that directory and
5
+ // keys each entry by AgentConfig.name (not the filename) at import time.
6
+ import { dirname, join } from 'node:path'
7
+ import { fileURLToPath } from 'node:url'
8
+ import { discoverAgents, type AgentModule } from 'loopengine'
6
9
 
7
- export interface RegistryEntry {
8
- config: AgentConfig
9
- /** Factory, not a shared instance — a fresh ModelCall per request/session. */
10
- createModelCall: () => ModelCall
11
- }
10
+ export type RegistryEntry = AgentModule
12
11
 
13
- const entries: Record<string, RegistryEntry> = {
14
- 'example-agent': { config: exampleAgentConfig, createModelCall: createExampleAgentModelCall },
15
- }
12
+ const agentsDir = join(dirname(fileURLToPath(import.meta.url)), 'agents')
13
+
14
+ // Top-level await: ESM guarantees an importer's own evaluation (adapters/
15
+ // http.ts, adapters/cli.ts) waits for this module's top-level await to
16
+ // settle first, so listAgents()/getEntry() below can stay synchronous —
17
+ // no adapter needs to know discovery is async under the hood.
18
+ const entries = await discoverAgents(agentsDir)
16
19
 
17
20
  export function listAgents(): string[] {
18
- return Object.keys(entries)
21
+ return [...entries.keys()]
19
22
  }
20
23
 
21
24
  /** undefined for an unknown agent name. */
22
25
  export function getEntry(name: string): RegistryEntry | undefined {
23
- return entries[name]
26
+ return entries.get(name)
24
27
  }
@@ -1,6 +1,7 @@
1
1
  // A starting point, not a template to copy verbatim: real persona, real
2
- // tool, real permission rule. Add more agents by copying this file and
3
- // registering the new one in agent-registry.ts.
2
+ // tool, real permission rule. Add more agents by copying this file into
3
+ // agents/ under a new filename and a new AgentConfig.name — agent-registry.ts
4
+ // discovers it automatically, nothing to register by hand.
4
5
  import { createAnthropicModelCall, type AgentConfig, type ModelCall } from 'loopengine'
5
6
 
6
7
  export const config: AgentConfig = {
@@ -9,7 +9,7 @@
9
9
  "cli": "tsx adapters/cli.ts"
10
10
  },
11
11
  "dependencies": {
12
- "loopengine": "^0.0.4"
12
+ "loopengine": "^0.0.6"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@types/node": "^22.10.0",