@alisio/alisio-code 0.1.0-alpha.27 → 0.1.0-alpha.28
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/dist/main.js +13 -1
- package/dist/tui/settings.d.ts +2 -1
- package/dist/tui/settings.js +5 -4
- package/dist/tui/state.d.ts +5 -0
- package/dist/tui/state.js +14 -5
- package/package.json +5 -5
package/dist/main.js
CHANGED
|
@@ -131,6 +131,10 @@ async function run(cmd, prompt, sessionId) {
|
|
|
131
131
|
const retry = event.data;
|
|
132
132
|
process.stderr.write(`\nThe model did not respond; retrying (${retry.attempt}/${retry.of})…\n`);
|
|
133
133
|
}
|
|
134
|
+
else if (event.type === "truncation_recovery") {
|
|
135
|
+
const recovery = event.data;
|
|
136
|
+
process.stderr.write(`\nThe response was cut off by the output limit; retrying in smaller steps (${recovery.attempt}/${recovery.of})…\n`);
|
|
137
|
+
}
|
|
134
138
|
else if (event.type === "tool_started")
|
|
135
139
|
process.stderr.write(`\n→ ${event.data.name}\n`);
|
|
136
140
|
else if (event.type === "artifact_published")
|
|
@@ -318,7 +322,7 @@ program
|
|
|
318
322
|
console.log('To generate AGENTS.md for this project, run /init inside alisio (or: alisio run "/init" --allow-write).');
|
|
319
323
|
});
|
|
320
324
|
program.command("doctor").action(async (_opts, cmd) => {
|
|
321
|
-
const { findWorkspace, loadConfigWithProvenance, overridesSavedProviderProfile, ProviderSettingsStore, RIPGREP_INSTALL_HINT, which, } = await import("@alisio/core");
|
|
325
|
+
const { DEFAULT_MAX_OUTPUT_TOKENS, findWorkspace, loadConfigWithProvenance, MAX_AUTO_OUTPUT_TOKENS, overridesSavedProviderProfile, ProviderSettingsStore, RIPGREP_INSTALL_HINT, which, } = await import("@alisio/core");
|
|
322
326
|
const o = options(cmd);
|
|
323
327
|
const workspace = await findWorkspace(o.cwd ?? process.cwd());
|
|
324
328
|
const { config, provenance } = await loadConfigWithProvenance(workspace, {
|
|
@@ -341,6 +345,14 @@ program.command("doctor").action(async (_opts, cmd) => {
|
|
|
341
345
|
workspace,
|
|
342
346
|
git: (await which("git")) ?? null,
|
|
343
347
|
ripgrep: (await which("rg")) ?? null,
|
|
348
|
+
// The per-request output budget is resolved when a run starts, from the model's catalog;
|
|
349
|
+
// doctor does not contact the provider, so it reports what the configuration decides.
|
|
350
|
+
outputTokens: config.limits.maxOutputTokens !== undefined
|
|
351
|
+
? { limit: config.limits.maxOutputTokens, source: "set by you (limits.maxOutputTokens)" }
|
|
352
|
+
: {
|
|
353
|
+
limit: null,
|
|
354
|
+
source: `the model catalog's declared limit (capped at ${MAX_AUTO_OUTPUT_TOKENS}), else ${DEFAULT_MAX_OUTPUT_TOKENS}`,
|
|
355
|
+
},
|
|
344
356
|
provider: {
|
|
345
357
|
id: useSaved ? saved.profile.provider : "openai-compatible",
|
|
346
358
|
baseURL: useSaved ? saved.profile.values.baseURL : config.provider.baseURL,
|
package/dist/tui/settings.d.ts
CHANGED
|
@@ -50,7 +50,8 @@ export interface SettingsConfigView {
|
|
|
50
50
|
};
|
|
51
51
|
limits: {
|
|
52
52
|
maxTurns: number;
|
|
53
|
-
|
|
53
|
+
/** Only present when the user set it; unset means "the model's declared limit, else 16384". */
|
|
54
|
+
maxOutputTokens?: number | undefined;
|
|
54
55
|
maxContextChars: number;
|
|
55
56
|
timeoutMs: number;
|
|
56
57
|
};
|
package/dist/tui/settings.js
CHANGED
|
@@ -12,7 +12,7 @@ export const WEBSEARCH_PROVIDERS = [
|
|
|
12
12
|
export const defaultConfig = {
|
|
13
13
|
compaction: { auto: true, threshold: 0.85, keepTurns: 2, maxOutputTokens: 16_000 },
|
|
14
14
|
context: { claudeMdFallback: false, maxBytes: 32 * 1024 },
|
|
15
|
-
limits: { maxTurns: 100,
|
|
15
|
+
limits: { maxTurns: 100, maxContextChars: 800_000, timeoutMs: 300_000 },
|
|
16
16
|
tui: { paddingX: 1, contentPaddingX: 2, skillSlashCommands: true },
|
|
17
17
|
mcp: { allow: false },
|
|
18
18
|
websearch: { provider: undefined },
|
|
@@ -125,9 +125,10 @@ export const SETTINGS_DEFINITIONS = [
|
|
|
125
125
|
label: "Agent max output tokens",
|
|
126
126
|
category: "Limits",
|
|
127
127
|
valueType: "number",
|
|
128
|
-
values: [1_024, 2_048, 4_096, 8_192, 16_384],
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
values: [1_024, 2_048, 4_096, 8_192, 16_384, 32_768, 65_536],
|
|
129
|
+
// Unset: each request uses the model's declared limit (capped at 65536), else 16384.
|
|
130
|
+
read: (config) => config.limits.maxOutputTokens ?? 16_384,
|
|
131
|
+
description: "Per-call output token budget for agent turns. While you leave it unchanged, each request uses the output limit the model's catalog declares (capped at 65536), or 16384 when it declares none; a value set here always wins. A cut response shows a notice suggesting a higher value. Applied from the next run.",
|
|
131
132
|
},
|
|
132
133
|
{
|
|
133
134
|
id: "limits.maxContextChars",
|
package/dist/tui/state.d.ts
CHANGED
|
@@ -348,6 +348,11 @@ export interface ViewState {
|
|
|
348
348
|
attempt: number;
|
|
349
349
|
of: number;
|
|
350
350
|
};
|
|
351
|
+
/** The response was cut by the output limit and is requested again (`truncation_recovery`). */
|
|
352
|
+
recovery?: {
|
|
353
|
+
attempt: number;
|
|
354
|
+
of: number;
|
|
355
|
+
};
|
|
351
356
|
model: string;
|
|
352
357
|
/** Context size in tokens: provider-reported, or estimated (`~`). */
|
|
353
358
|
context?: {
|
package/dist/tui/state.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Pure presentation logic for the TUI: formatting, command parsing and the reduction of
|
|
3
3
|
* versioned runner events into a view model. No terminal or pi-tui imports here.
|
|
4
4
|
*/
|
|
5
|
-
import { CommandCatalog } from "@alisio/core";
|
|
5
|
+
import { CommandCatalog, describeOutputLimitSource } from "@alisio/core";
|
|
6
6
|
const trimZero = (value) => value.replace(/\.0$/, "");
|
|
7
7
|
export function formatTokens(n) {
|
|
8
8
|
if (!Number.isFinite(n) || n < 0)
|
|
@@ -583,7 +583,7 @@ export function reduceEvent(state, event) {
|
|
|
583
583
|
event.type === "run_cancelled" ||
|
|
584
584
|
event.type === "run_turns_exceeded";
|
|
585
585
|
if (terminal) {
|
|
586
|
-
const { lastEventAt: _ended, retry: _retry, ...rest } = next;
|
|
586
|
+
const { lastEventAt: _ended, retry: _retry, recovery: _recovery, ...rest } = next;
|
|
587
587
|
return rest;
|
|
588
588
|
}
|
|
589
589
|
return { ...next, lastEventAt: Date.parse(event.timestamp) || Date.now() };
|
|
@@ -612,6 +612,11 @@ export function runPhase(view) {
|
|
|
612
612
|
label: `the model did not respond; retrying (${view.retry.attempt}/${view.retry.of})`,
|
|
613
613
|
silentByDesign: false,
|
|
614
614
|
};
|
|
615
|
+
if (view.recovery)
|
|
616
|
+
return {
|
|
617
|
+
label: `the response was cut off; retrying in smaller steps (${view.recovery.attempt}/${view.recovery.of})`,
|
|
618
|
+
silentByDesign: false,
|
|
619
|
+
};
|
|
615
620
|
const tool = view.items.findLast((i) => i.kind === "tool" && i.status !== "ok" && i.status !== "error");
|
|
616
621
|
if (tool?.kind === "tool") {
|
|
617
622
|
const name = tool.name.replace(/^p_[0-9a-f]{10}_/, "");
|
|
@@ -658,8 +663,8 @@ const RETRY_ENDERS = new Set([
|
|
|
658
663
|
"compaction_started",
|
|
659
664
|
]);
|
|
660
665
|
function reduceEventItems(state, event) {
|
|
661
|
-
if (state.retry && RETRY_ENDERS.has(event.type)) {
|
|
662
|
-
const { retry: _retry, ...rest } = state;
|
|
666
|
+
if ((state.retry || state.recovery) && RETRY_ENDERS.has(event.type)) {
|
|
667
|
+
const { retry: _retry, recovery: _recovery, ...rest } = state;
|
|
663
668
|
return reduceEventItems(rest, event);
|
|
664
669
|
}
|
|
665
670
|
const d = (event.data ?? {});
|
|
@@ -764,6 +769,8 @@ function reduceEventItems(state, event) {
|
|
|
764
769
|
}
|
|
765
770
|
return ended;
|
|
766
771
|
}
|
|
772
|
+
case "truncation_recovery":
|
|
773
|
+
return { ...state, recovery: { attempt: Number(d.attempt) || 1, of: Number(d.of) || 1 } };
|
|
767
774
|
case "request_retry":
|
|
768
775
|
return { ...state, retry: { attempt: Number(d.attempt) || 1, of: Number(d.of) || 1 } };
|
|
769
776
|
case "compaction_started":
|
|
@@ -807,7 +814,9 @@ function reduceEventItems(state, event) {
|
|
|
807
814
|
case "response_truncated":
|
|
808
815
|
return addItem(state, {
|
|
809
816
|
kind: "notice",
|
|
810
|
-
text:
|
|
817
|
+
text: `Response cut by max output tokens${typeof d.maxOutputTokens === "number"
|
|
818
|
+
? ` (${d.maxOutputTokens} tokens, ${describeOutputLimitSource(d.source)})`
|
|
819
|
+
: ""} — the answer may be incomplete. Raise limits.maxOutputTokens (/settings → Agent max output tokens) to allow longer answers.`,
|
|
811
820
|
});
|
|
812
821
|
case "model_changed":
|
|
813
822
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alisio/alisio-code",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.28",
|
|
4
4
|
"description": "Alisio: an extensible, provider-agnostic coding-agent harness for your terminal. TUI, OpenAI-compatible providers, permissioned local tools, context compaction, persistent memory and a typed plugin SDK.",
|
|
5
5
|
"author": "Gustavo Gutiérrez",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,12 +45,12 @@
|
|
|
45
45
|
"alisio": "./dist/main.js"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@alisio/core": "0.1.0-alpha.
|
|
48
|
+
"@alisio/core": "0.1.0-alpha.24",
|
|
49
49
|
"@alisio/plugin-memory": "0.1.0-alpha.9",
|
|
50
|
-
"@alisio/plugin-openai-compatible": "0.1.0-alpha.
|
|
50
|
+
"@alisio/plugin-openai-compatible": "0.1.0-alpha.10",
|
|
51
51
|
"@alisio/plugin-subagents": "0.1.0-alpha.11",
|
|
52
|
-
"@alisio/sdk": "0.1.0-alpha.
|
|
53
|
-
"@alisio/server": "0.1.0-alpha.
|
|
52
|
+
"@alisio/sdk": "0.1.0-alpha.20",
|
|
53
|
+
"@alisio/server": "0.1.0-alpha.8",
|
|
54
54
|
"@earendil-works/pi-tui": "0.87.1",
|
|
55
55
|
"commander": "15.0.0"
|
|
56
56
|
},
|