loopengine 0.1.2 → 0.1.3

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.
@@ -295,11 +295,15 @@ export interface AgentConfig {
295
295
  * Omit entirely and it defaults to importing
296
296
  * `agents/<name>/tools/index.{ts,js}` and using its exported `tools` —
297
297
  * this repo's own aggregation-file convention (see
298
- * `agents/customer-service/tools/index.ts`), resolved next to
299
- * `run-agent.ts` itself (not `process.cwd()`, unlike `skillsDirs`/
300
- * `rules` — that file is real compiled code, not data, so it has to be
301
- * found next to whichever build of `run-agent.ts` is actually running).
302
- * A missing file there is just `[]`, not an error — same
298
+ * `agents/customer-service/tools/index.ts`). Tried first next to
299
+ * `run-agent.ts` itself, since that file is real compiled code, not
300
+ * data — right when `agents/` is built alongside `core/` into the same
301
+ * `dist/` tree (this repo's own reference agents); falls back to
302
+ * `process.cwd()`, same as `skillsDirs`/`rules`, when nothing's built
303
+ * there — right for a project that only depends on the published
304
+ * package, whose own `agents/<name>/tools/` was never compiled into
305
+ * `node_modules/loopengine` at all.
306
+ * A missing file either place is just `[]`, not an error — same
303
307
  * missing-is-fine treatment `skillsDirs` gets. An agent that needs to
304
308
  * merge in tools from somewhere else too (e.g.
305
309
  * `agents/file-agent/index.ts`'s Composio-sourced ones) can't rely on
@@ -33,6 +33,23 @@ export { systemTools } from './system-tools/index.js';
33
33
  // tools/index.ts is real code that only exists compiled, at a different
34
34
  // relative location, once dist/ is what's actually running.
35
35
  const agentsRootDir = join(dirname(fileURLToPath(import.meta.url)), '..', 'agents');
36
+ // agentsRootDir above is right when agents/ is compiled alongside core/
37
+ // into the same dist/ tree (this repo's own reference agents; also this
38
+ // repo's own Dockerfile, which copies dist/agents/**/*.js this way) — but
39
+ // a project that only *depends on* the published loopengine package has
40
+ // no dist/agents/<name> inside node_modules/loopengine at all, just its
41
+ // own agents/<name>/ at the project root, found only via process.cwd(),
42
+ // the same way loadRules/skillsDirs already resolve their own (data, not
43
+ // code) defaults. Tried first since it's this repo's own existing,
44
+ // tested behavior; process.cwd() only kicks in when nothing's built
45
+ // there to find — so this repo's own agents are unaffected either way.
46
+ function resolveAgentCodeDir(name, subpath, indexRequired) {
47
+ const built = join(agentsRootDir, name, subpath);
48
+ const builtExists = indexRequired
49
+ ? existsSync(join(built, 'index.ts')) || existsSync(join(built, 'index.js'))
50
+ : existsSync(built);
51
+ return builtExists ? built : join(process.cwd(), 'agents', name, subpath);
52
+ }
36
53
  // Same "resolved relative to this file's own location" reasoning as
37
54
  // agentsRootDir above, but system-skills/ is a same-level sibling of
38
55
  // run-agent.ts itself (both live directly under core/ — see package.json's
@@ -157,7 +174,7 @@ async function loadToolsFromDir(toolsDir) {
157
174
  return [];
158
175
  }
159
176
  export async function loadDefaultTools(config) {
160
- return loadToolsFromDir(join(agentsRootDir, config.name, 'tools'));
177
+ return loadToolsFromDir(resolveAgentCodeDir(config.name, 'tools', true));
161
178
  }
162
179
  /** Every other folder-form default in this file (loadDefaultTools,
163
180
  * loadRules, the skillsDirs default below) resolves against
@@ -229,7 +246,7 @@ async function resolveSubagentConfig(config, dir) {
229
246
  * this can't cycle the way a hand-wired agentAsTool(getEntry(...)) call
230
247
  * elsewhere could. */
231
248
  export async function loadSubagentAsTools(config) {
232
- const subagentsDir = join(agentsRootDir, config.name, 'subagents');
249
+ const subagentsDir = resolveAgentCodeDir(config.name, 'subagents', false);
233
250
  if (!existsSync(subagentsDir))
234
251
  return [];
235
252
  const tools = [];
@@ -280,7 +297,7 @@ async function buildTurnContext(config, modelCall, options) {
280
297
  askUserTool,
281
298
  ...(config.tools ?? (await loadDefaultTools(config))),
282
299
  ...(await loadSubagentAsTools(config)),
283
- ...(await loadGatewayToolsFromDir(join(agentsRootDir, config.name))),
300
+ ...(await loadGatewayToolsFromDir(join(process.cwd(), 'agents', config.name))),
284
301
  ]);
285
302
  // Omitted entirely (undefined): default to this agent's own
286
303
  // agents/<name>/skills — the folder-form convention every agent in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loopengine",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "description": "Runtime for tool-using AI agents with a transparent ReAct loop.",
6
6
  "license": "MIT",