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 +12 -9
- package/package.json +1 -1
- package/template/README.md +5 -4
- package/template/agent-registry.ts +17 -14
- package/template/agents/example-agent.ts +3 -2
- package/template/package.json +1 -1
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
|
|
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 —
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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.
|
|
64
|
-
|
|
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
package/template/README.md
CHANGED
|
@@ -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.
|
|
35
|
-
`
|
|
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
|
|
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
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
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
|
|
14
|
-
|
|
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
|
|
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
|
|
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
|
|
3
|
-
//
|
|
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 = {
|