@alisio/core 0.1.0-alpha.10 → 0.1.0-alpha.11

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
@@ -1,9 +1,24 @@
1
1
  # @alisio/core
2
2
 
3
- Embeddable core of [Alisio](https://github.com/GustavoGutierrez/alisio): the agent tool loop, structured
4
- context compaction, the OpenAI-compatible provider (Chat Completions and Responses), local tools with
5
- explicit permissions, the MCP client, the plugin host (with hook timeouts and failure isolation) and a
6
- SQLite session store. Runs on Node.js >= 22.16 (`node:sqlite` with FTS5) and on Bun.
3
+ **The embeddable core of [Alisio](https://github.com/GustavoGutierrez/alisio): a provider-agnostic
4
+ agent you can drive from your own program.** No TUI, no CLI — just the tool loop, compaction, MCP
5
+ and plugin host as a library.
6
+
7
+ ## What it is
8
+
9
+ `@alisio/core` wires the agent tool loop, structured context compaction, the OpenAI-compatible
10
+ provider (Chat Completions and Responses), local tools behind explicit permissions, the MCP client,
11
+ the plugin host (hook timeouts and failure isolation) and a SQLite session store into one
12
+ `createApplication` entry point. It runs on Node.js >= 22.16 (`node:sqlite` with FTS5) and on Bun,
13
+ and uses only portable Node APIs.
14
+
15
+ ## Installation
16
+
17
+ ```sh
18
+ npm i @alisio/core # or: pnpm add @alisio/core · bun add @alisio/core
19
+ ```
20
+
21
+ ## Quick start
7
22
 
8
23
  ```ts
9
24
  import { createApplication } from "@alisio/core";
@@ -18,8 +33,38 @@ try {
18
33
  }
19
34
  ```
20
35
 
36
+ ## What you get
37
+
38
+ - **Runner**: `AgentRunner` with turn limits, timeouts, token budgets and versioned `RunEvent`
39
+ output (`schemaVersion: 1`).
40
+ - **Context compaction**: `planCompaction`, `summarize`, `renderCheckpoint`,
41
+ `shouldCompactContext` and checkpoint helpers; memory plugins hook in via `CompactionHooks`.
42
+ - **Providers**: `ProviderRegistry` / `ActiveProvider` for OpenAI-compatible, DeepSeek, OpenCode
43
+ Console and OpenCode Go; `ProviderSettingsStore` for non-secret profiles plus a separate
44
+ credentials store.
45
+ - **Local tools**: reads by default, `--allow-write`/`--allow-process`-style policy, path checks
46
+ and standard tools (`ToolRegistry`, `registerStandard`).
47
+ - **MCP**: `McpConnector`, server discovery and tool projection.
48
+ - **Plugin host**: `PluginHost` with built-in plugin catalogs, npm install (`installPlugin`,
49
+ `cliInstall`), hook timeouts and failure isolation.
50
+ - **Sessions**: `SQLiteStore` with reconciliation and crash recovery.
51
+ - **Skills and prompts**: `Skills`, `ProjectContext` (`AGENTS.md`), `loadPromptTemplates`.
52
+ - **Trust**: `resolveTrust` / `setTrust` / `listTrust` for per-directory project trust.
53
+ - **Startup screen**: reusable `renderStartup` sections and the default mascot.
54
+
21
55
  Built-in plugins are opt-in for embedders: pass `builtins` (the `alisio` CLI wires
22
- `@alisio/plugin-memory`). See the [architecture](https://gustavogutierrez.github.io/alisio/architecture) and
23
- [configuration](https://gustavogutierrez.github.io/alisio/configuration) docs.
56
+ `@alisio/plugin-memory` and `@alisio/plugin-subagents`).
57
+
58
+ ## Docs
59
+
60
+ Architecture: <https://gustavogutierrez.github.io/alisio/architecture> ·
61
+ Configuration: <https://gustavogutierrez.github.io/alisio/configuration>.
62
+
63
+ ## Requirements
64
+
65
+ Node.js **>= 22.16** or Bun **>= 1.4.2**.
66
+
67
+ ## License
24
68
 
25
- Maintainer: Gustavo Gutiérrez · License: MIT
69
+ MIT. Maintained by Gustavo Gutiérrez Mercado. Source: <https://github.com/GustavoGutierrez/alisio> ·
70
+ npm: <https://www.npmjs.com/settings/alisio/packages>.
package/dist/config.js CHANGED
@@ -151,7 +151,7 @@ const configObjectSchema = z
151
151
  .default(() => ({ nativeToolType: "web_search" })),
152
152
  limits: z
153
153
  .object({
154
- maxTurns: z.number().int().min(1).max(100).default(20),
154
+ maxTurns: z.number().int().min(1).max(100).default(100),
155
155
  timeoutMs: z.number().int().min(100).default(300000),
156
156
  maxContextChars: z.number().int().positive().default(800000),
157
157
  /**
@@ -163,7 +163,7 @@ const configObjectSchema = z
163
163
  maxTokens: z.number().int().positive().optional(),
164
164
  })
165
165
  .default(() => ({
166
- maxTurns: 20,
166
+ maxTurns: 100,
167
167
  timeoutMs: 300000,
168
168
  maxContextChars: 800000,
169
169
  maxOutputTokens: 16384,
@@ -348,7 +348,8 @@ export class AgentRunner {
348
348
  emit("run_started", { model });
349
349
  const budget = options.maxTokens ?? o.maxTokens ?? defaultTokenBudget(o.contextWindow?.(model));
350
350
  const compaction = o.compaction ?? {};
351
- for (let turn = 0; turn < (options.maxTurns ?? o.maxTurns ?? 20); turn++) {
351
+ const maxTurns = options.maxTurns ?? o.maxTurns ?? 100;
352
+ for (let turn = 0; turn < maxTurns; turn++) {
352
353
  combined.throwIfAborted();
353
354
  // Input queued while the run was working (e.g. a parent's message to a child).
354
355
  if (turn > 0)
@@ -606,7 +607,12 @@ export class AgentRunner {
606
607
  if (tokens >= budget)
607
608
  throw new Error("Token budget exhausted");
608
609
  }
609
- throw new Error("Maximum turns reached");
610
+ // Turn cap reached. This is NOT a failure: everything produced up to this point stays in
611
+ // the transcript and the run returns a successful-but-marked partial result, so the user
612
+ // can simply prompt again to continue in the same session. The real hard stops remain the
613
+ // token budget (`maxTokens`) and the timeout; the turn count is a safety rail.
614
+ emit("run_turns_exceeded", { turns: maxTurns, maxTurns });
615
+ return { sessionId, text: lastText, status: "turns-exceeded", usage: usageTotal };
610
616
  }
611
617
  catch (error) {
612
618
  // On cancellation report the abort reason, not the transport's secondary error.
@@ -160,8 +160,18 @@ export class ChildSessions {
160
160
  });
161
161
  usage.input += result.usage.input;
162
162
  usage.output += result.usage.output;
163
+ // A child that hit its turn limit still produced a usable partial result: it completes
164
+ // with a turnsExceeded marker instead of failing, so orchestration treats the text as
165
+ // partial output. state "failed" stays reserved for real errors/aborts.
166
+ const turnsExceeded = result.status === "turns-exceeded";
163
167
  this.o.store.updateSession(id, { status: "completed", usage });
164
- return { id, status: "completed", text: result.text, usage };
168
+ return {
169
+ id,
170
+ status: "completed",
171
+ text: result.text,
172
+ usage,
173
+ ...(turnsExceeded ? { turnsExceeded: true } : {}),
174
+ };
165
175
  }
166
176
  catch (error) {
167
177
  const aborted = this.cancelled.has(id) || signals.some((s) => s.aborted);
package/dist/version.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Reads the @alisio/core package version at runtime so the MCP client metadata stays in sync
3
- * with the published package. Resolves the manifest relative to the module (`src/version.ts` →
4
- * `../package.json` in the source tree; `dist/version.js` → `../package.json` when installed).
5
- * Standalone binaries inject ALISIO_PACKAGE_VERSION at build time (scripts/binary-build.ts).
3
+ * with the published package. The manifest is resolved by walking UP from the module directory
4
+ * until a package.json with a string `version` is found (bounded, any depth: module, then up to
5
+ * 8 parents), so a deeply nested call site like `src/mcp/connector.ts` resolves the same
6
+ * manifest as `src/version.ts`. Standalone binaries inject ALISIO_PACKAGE_VERSION at build time
7
+ * (scripts/binary-build.ts).
6
8
  */
7
9
  export declare function loadVersion(fromHere: string): string;
package/dist/version.js CHANGED
@@ -6,19 +6,48 @@ import { fileURLToPath } from "node:url";
6
6
  * A development marker, never a publish literal: it cannot silently desync from the package.
7
7
  */
8
8
  const FALLBACK = "dev";
9
+ /**
10
+ * How many parent directories the loader walks up before giving up. Bounded so a missing
11
+ * manifest can never make the lookup climb an unbounded path.
12
+ */
13
+ const MAX_PARENT_HOPS = 8;
14
+ /**
15
+ * Walks up from `dir` looking for a package manifest. Returns the version of the nearest
16
+ * manifest that declares a string `version`. `undefined` when no manifest with a version is
17
+ * reached within the bound.
18
+ */
19
+ function findManifestVersion(dir) {
20
+ let nearest;
21
+ let current = dir;
22
+ for (let hop = 0; hop <= MAX_PARENT_HOPS; hop++) {
23
+ try {
24
+ const parsed = JSON.parse(readFileSync(join(current, "package.json"), "utf8"));
25
+ if (typeof parsed.version === "string" && parsed.version)
26
+ nearest ??= parsed.version;
27
+ }
28
+ catch {
29
+ // No manifest here; keep walking up.
30
+ }
31
+ const parent = dirname(current);
32
+ if (parent === current)
33
+ break; // Filesystem root.
34
+ current = parent;
35
+ }
36
+ return nearest;
37
+ }
9
38
  /**
10
39
  * Reads the @alisio/core package version at runtime so the MCP client metadata stays in sync
11
- * with the published package. Resolves the manifest relative to the module (`src/version.ts` →
12
- * `../package.json` in the source tree; `dist/version.js` → `../package.json` when installed).
13
- * Standalone binaries inject ALISIO_PACKAGE_VERSION at build time (scripts/binary-build.ts).
40
+ * with the published package. The manifest is resolved by walking UP from the module directory
41
+ * until a package.json with a string `version` is found (bounded, any depth: module, then up to
42
+ * 8 parents), so a deeply nested call site like `src/mcp/connector.ts` resolves the same
43
+ * manifest as `src/version.ts`. Standalone binaries inject ALISIO_PACKAGE_VERSION at build time
44
+ * (scripts/binary-build.ts).
14
45
  */
15
46
  export function loadVersion(fromHere) {
16
47
  if (process.env.ALISIO_PACKAGE_VERSION)
17
48
  return process.env.ALISIO_PACKAGE_VERSION;
18
49
  try {
19
- const manifest = join(dirname(fileURLToPath(fromHere)), "..", "package.json");
20
- const parsed = JSON.parse(readFileSync(manifest, "utf8"));
21
- return typeof parsed.version === "string" && parsed.version ? parsed.version : FALLBACK;
50
+ return findManifestVersion(dirname(fileURLToPath(fromHere))) ?? FALLBACK;
22
51
  }
23
52
  catch {
24
53
  return FALLBACK;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alisio/core",
3
- "version": "0.1.0-alpha.10",
3
+ "version": "0.1.0-alpha.11",
4
4
  "description": "Embeddable provider-agnostic Alisio agent core: tool loop, context compaction, local tools, MCP, plugin host and SQLite session store. Runs on Node >=22.16 and Bun.",
5
5
  "author": "Gustavo Gutiérrez",
6
6
  "license": "MIT",
@@ -41,7 +41,7 @@
41
41
  "node": ">=22.16"
42
42
  },
43
43
  "dependencies": {
44
- "@alisio/sdk": "0.1.0-alpha.6",
44
+ "@alisio/sdk": "0.1.0-alpha.7",
45
45
  "@mixmark-io/domino": "2.2.0",
46
46
  "@modelcontextprotocol/client": "2.1.0",
47
47
  "ajv": "8.20.0",