@alisio/alisio-code 0.1.0-alpha.4 → 0.1.0-alpha.5
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/tui/app.js +7 -5
- package/dist/tui/components.d.ts +3 -3
- package/dist/tui/components.js +6 -6
- package/dist/tui/state.d.ts +11 -2
- package/dist/tui/state.js +20 -7
- package/package.json +9 -9
package/dist/tui/app.js
CHANGED
|
@@ -183,8 +183,10 @@ export async function runTui(options) {
|
|
|
183
183
|
path.unshift(cur.label);
|
|
184
184
|
const siblings = nodes.filter((n) => n.parentId === node.parentId);
|
|
185
185
|
const child = viewedState();
|
|
186
|
-
const
|
|
187
|
-
const pct = child?.context &&
|
|
186
|
+
const budget = app.contextBudget(child?.model ?? view.model);
|
|
187
|
+
const pct = child?.context && budget
|
|
188
|
+
? ` · ctx ${Math.round((child.context.used / budget.total) * 100)}%`
|
|
189
|
+
: "";
|
|
188
190
|
const tokens = child
|
|
189
191
|
? ` · ↑${formatTokens(child.stats.input)} ↓${formatTokens(child.stats.output)}`
|
|
190
192
|
: "";
|
|
@@ -195,7 +197,7 @@ export async function runTui(options) {
|
|
|
195
197
|
: panelState.focus === "view"
|
|
196
198
|
? viewHint()
|
|
197
199
|
: undefined;
|
|
198
|
-
const footer = new Footer(() => viewedState() ?? view, () => app.
|
|
200
|
+
const footer = new Footer(() => viewedState() ?? view, () => app.contextBudget((viewedState() ?? view).model), () => panelHint() ?? hint, () => [...app.plugins.status.values()].map((s) => s.text));
|
|
199
201
|
const treePanel = new TreePanel(() => {
|
|
200
202
|
const entry = panelEntry();
|
|
201
203
|
if (!entry)
|
|
@@ -866,7 +868,7 @@ export async function runTui(options) {
|
|
|
866
868
|
};
|
|
867
869
|
const statsReport = () => {
|
|
868
870
|
const s = view.stats;
|
|
869
|
-
const
|
|
871
|
+
const budget = app.contextBudget(view.model);
|
|
870
872
|
const tools = Object.entries(s.tools)
|
|
871
873
|
.map(([name, t]) => `| \`${name}\` | ${t.calls} | ${t.errors} |`)
|
|
872
874
|
.join("\n");
|
|
@@ -878,7 +880,7 @@ export async function runTui(options) {
|
|
|
878
880
|
`- Tokens: in ${formatTokens(s.input)} · out ${formatTokens(s.output)} · cached ${formatTokens(s.cached)}`,
|
|
879
881
|
`- Runs: ${s.runs} · turns: ${s.turns}${s.lastRunMs !== undefined ? ` · last run ${formatDuration(s.lastRunMs)}` : ""}`,
|
|
880
882
|
`- Duration: ${formatDuration(Date.now() - s.startedAt)}`,
|
|
881
|
-
`- Context: ${formatContext(view.context?.used ?? 0,
|
|
883
|
+
`- Context: ${formatContext(view.context?.used ?? 0, budget?.total, view.context?.estimated ?? true, budget?.basis)}`,
|
|
882
884
|
"",
|
|
883
885
|
tools ? `| Tool | Calls | Errors |\n| --- | --- | --- |\n${tools}` : "No tool calls yet.",
|
|
884
886
|
"",
|
package/dist/tui/components.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { PanelNode } from "@alisio/sdk";
|
|
|
2
2
|
import { type Component, Container } from "@earendil-works/pi-tui";
|
|
3
3
|
import { type PendingAttachment } from "./attachments.ts";
|
|
4
4
|
import { type QuestionPanelState, type QuestionSpec } from "./questions.ts";
|
|
5
|
-
import { type TranscriptItem, type ViewState } from "./state.ts";
|
|
5
|
+
import { type ContextBudget, type TranscriptItem, type ViewState } from "./state.ts";
|
|
6
6
|
export declare const SPINNER: string[];
|
|
7
7
|
/** Shared animation clock advanced by the app while work is running. */
|
|
8
8
|
export declare const clock: {
|
|
@@ -31,10 +31,10 @@ export declare class Header implements Component {
|
|
|
31
31
|
}
|
|
32
32
|
export declare class Footer implements Component {
|
|
33
33
|
private view;
|
|
34
|
-
private
|
|
34
|
+
private budget;
|
|
35
35
|
private hint;
|
|
36
36
|
private statuses;
|
|
37
|
-
constructor(view: () => ViewState,
|
|
37
|
+
constructor(view: () => ViewState, budget: () => ContextBudget | undefined, hint: () => string | undefined, statuses?: () => string[]);
|
|
38
38
|
invalidate(): void;
|
|
39
39
|
render(width: number): string[];
|
|
40
40
|
}
|
package/dist/tui/components.js
CHANGED
|
@@ -60,20 +60,20 @@ export class Header {
|
|
|
60
60
|
}
|
|
61
61
|
export class Footer {
|
|
62
62
|
view;
|
|
63
|
-
|
|
63
|
+
budget;
|
|
64
64
|
hint;
|
|
65
65
|
statuses;
|
|
66
|
-
constructor(view,
|
|
66
|
+
constructor(view, budget, hint, statuses = () => []) {
|
|
67
67
|
this.view = view;
|
|
68
|
-
this.
|
|
68
|
+
this.budget = budget;
|
|
69
69
|
this.hint = hint;
|
|
70
70
|
this.statuses = statuses;
|
|
71
71
|
}
|
|
72
72
|
invalidate() { }
|
|
73
73
|
render(width) {
|
|
74
|
-
const v = this.view(),
|
|
74
|
+
const v = this.view(), budget = this.budget(), total = budget?.total, used = v.context?.used ?? 0, estimated = v.context?.estimated ?? true;
|
|
75
75
|
const pct = contextPercent(used, total);
|
|
76
|
-
const level = contextLevel(pct ?? 0);
|
|
76
|
+
const level = contextLevel(pct ?? 0, budget?.compactionAt ?? 85);
|
|
77
77
|
const cells = 10, filled = pct === undefined ? 0 : Math.min(cells, Math.round((pct / 100) * cells));
|
|
78
78
|
const bar = pct === undefined
|
|
79
79
|
? style.gray("░".repeat(cells))
|
|
@@ -86,7 +86,7 @@ export class Footer {
|
|
|
86
86
|
const s = v.stats;
|
|
87
87
|
const segments = [
|
|
88
88
|
{
|
|
89
|
-
text: `ctx ${formatContext(used, total, estimated)}`,
|
|
89
|
+
text: `ctx ${formatContext(used, total, estimated, budget?.basis)}`,
|
|
90
90
|
priority: 10,
|
|
91
91
|
paint: pct === undefined ? style.gray : levelColor(level),
|
|
92
92
|
},
|
package/dist/tui/state.d.ts
CHANGED
|
@@ -84,9 +84,18 @@ export declare function configuredProviderModelItems(catalogs: ProviderCatalogVi
|
|
|
84
84
|
provider: string;
|
|
85
85
|
model: string;
|
|
86
86
|
}): ConfiguredProviderModelItem[];
|
|
87
|
-
export declare function contextLevel(pct: number): Level;
|
|
87
|
+
export declare function contextLevel(pct: number, compactionAt?: number): Level;
|
|
88
88
|
export declare function contextPercent(used: number, total: number | undefined): number | undefined;
|
|
89
|
-
|
|
89
|
+
/** The effective total the context bar measures against, and what it is derived from. */
|
|
90
|
+
export interface ContextBudget {
|
|
91
|
+
/** Effective total in tokens (model window, or the char budget converted to tokens). */
|
|
92
|
+
total: number;
|
|
93
|
+
/** Basis of the total: the model's context window, or the char-budget fallback. */
|
|
94
|
+
basis: "window" | "chars";
|
|
95
|
+
/** Percentage of `total` at which the engine auto-compacts; the bar turns red there. */
|
|
96
|
+
compactionAt: number;
|
|
97
|
+
}
|
|
98
|
+
export declare function formatContext(used: number, total: number | undefined, estimated: boolean, basis?: "window" | "chars"): string;
|
|
90
99
|
export declare function formatDuration(ms: number): string;
|
|
91
100
|
export declare const textWidth: (text: string) => number;
|
|
92
101
|
export declare function truncatePlain(text: string, width: number): string;
|
package/dist/tui/state.js
CHANGED
|
@@ -117,18 +117,23 @@ export function configuredProviderModelItems(catalogs, current) {
|
|
|
117
117
|
}
|
|
118
118
|
return items;
|
|
119
119
|
}
|
|
120
|
-
export function contextLevel(pct) {
|
|
121
|
-
|
|
120
|
+
export function contextLevel(pct, compactionAt = 85) {
|
|
121
|
+
// Warning band starts a quarter below the auto-compaction point; danger is exactly there.
|
|
122
|
+
const warn = Math.max(0, compactionAt - 25);
|
|
123
|
+
return pct < warn ? "ok" : pct < compactionAt ? "warn" : "danger";
|
|
122
124
|
}
|
|
123
125
|
export function contextPercent(used, total) {
|
|
124
126
|
return total && total > 0 ? (used / total) * 100 : undefined;
|
|
125
127
|
}
|
|
126
|
-
export function formatContext(used, total, estimated) {
|
|
128
|
+
export function formatContext(used, total, estimated, basis) {
|
|
127
129
|
const prefix = `${estimated ? "~" : ""}${formatTokens(used)} / `;
|
|
128
130
|
const pct = contextPercent(used, total);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
131
|
+
if (pct === undefined || !total)
|
|
132
|
+
return `${prefix}unknown`;
|
|
133
|
+
// The `~` marks an estimate; the "char budget" suffix tells the user the bar is measured
|
|
134
|
+
// against the fallback (est. tokens from limits.maxContextChars), not a model window.
|
|
135
|
+
const basisSuffix = basis === "chars" ? " char budget" : "";
|
|
136
|
+
return `${prefix}${formatTokens(total)} (${Math.round(pct)}%)${basisSuffix}`;
|
|
132
137
|
}
|
|
133
138
|
export function formatDuration(ms) {
|
|
134
139
|
if (ms < 1000)
|
|
@@ -461,6 +466,9 @@ export function reduceEvent(state, event) {
|
|
|
461
466
|
const checkpoint = typeof d.summarizedTokens === "number" && typeof d.checkpointTokens === "number"
|
|
462
467
|
? ` · checkpoint ~${formatTokens(d.summarizedTokens)} → ~${formatTokens(d.checkpointTokens)} tokens`
|
|
463
468
|
: "";
|
|
469
|
+
const partial = d.partial
|
|
470
|
+
? " · partial: the summary was cut by max output tokens; consider raising compaction.maxOutputTokens"
|
|
471
|
+
: "";
|
|
464
472
|
return addItem({
|
|
465
473
|
...state,
|
|
466
474
|
compacting: false,
|
|
@@ -468,7 +476,7 @@ export function reduceEvent(state, event) {
|
|
|
468
476
|
}, {
|
|
469
477
|
kind: "notice",
|
|
470
478
|
text: [
|
|
471
|
-
`Context compacted (${String(d.reason ?? "manual")}): ${String(d.replaced ?? 0)} messages summarized, ~${formatTokens(Number(d.before ?? 0))} → ~${formatTokens(Number(d.after ?? 0))} tokens${checkpoint}`,
|
|
479
|
+
`Context compacted (${String(d.reason ?? "manual")}): ${String(d.replaced ?? 0)} messages summarized, ~${formatTokens(Number(d.before ?? 0))} → ~${formatTokens(Number(d.after ?? 0))} tokens${checkpoint}${partial}`,
|
|
472
480
|
...reports,
|
|
473
481
|
].join("\n"),
|
|
474
482
|
});
|
|
@@ -487,6 +495,11 @@ export function reduceEvent(state, event) {
|
|
|
487
495
|
return addItem({ ...state, compacting: false }, { kind: "notice", text: `Compaction skipped: ${String(d.detail ?? "nothing to compact")}` });
|
|
488
496
|
case "compaction_failed":
|
|
489
497
|
return addItem({ ...state, compacting: false }, { kind: "error", text: `Compaction failed: ${String(d.error ?? "unknown error")}` });
|
|
498
|
+
case "response_truncated":
|
|
499
|
+
return addItem(state, {
|
|
500
|
+
kind: "notice",
|
|
501
|
+
text: "Response cut by max output tokens — the answer may be incomplete. Raise limits.maxOutputTokens to allow longer answers.",
|
|
502
|
+
});
|
|
490
503
|
case "model_changed":
|
|
491
504
|
return {
|
|
492
505
|
...state,
|
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.5",
|
|
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,14 +45,14 @@
|
|
|
45
45
|
"alisio": "./dist/main.js"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@alisio/core": "0.1.0-alpha.
|
|
49
|
-
"@alisio/plugin-deepseek": "0.1.0-alpha.
|
|
50
|
-
"@alisio/plugin-memory": "0.1.0-alpha.
|
|
51
|
-
"@alisio/plugin-openai-compatible": "0.1.0-alpha.
|
|
52
|
-
"@alisio/plugin-opencode": "0.1.0-alpha.
|
|
53
|
-
"@alisio/plugin-opencode-go": "0.1.0-alpha.
|
|
54
|
-
"@alisio/plugin-subagents": "0.1.0-alpha.
|
|
55
|
-
"@alisio/sdk": "0.1.0-alpha.
|
|
48
|
+
"@alisio/core": "0.1.0-alpha.5",
|
|
49
|
+
"@alisio/plugin-deepseek": "0.1.0-alpha.5",
|
|
50
|
+
"@alisio/plugin-memory": "0.1.0-alpha.5",
|
|
51
|
+
"@alisio/plugin-openai-compatible": "0.1.0-alpha.5",
|
|
52
|
+
"@alisio/plugin-opencode": "0.1.0-alpha.5",
|
|
53
|
+
"@alisio/plugin-opencode-go": "0.1.0-alpha.5",
|
|
54
|
+
"@alisio/plugin-subagents": "0.1.0-alpha.5",
|
|
55
|
+
"@alisio/sdk": "0.1.0-alpha.5",
|
|
56
56
|
"@earendil-works/pi-tui": "0.87.1",
|
|
57
57
|
"commander": "15.0.0"
|
|
58
58
|
},
|