@alisio/core 0.1.0-alpha.3 → 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/application.d.ts +6 -0
- package/dist/application.js +2 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +6 -1
- package/dist/core/compaction.d.ts +36 -1
- package/dist/core/compaction.js +66 -17
- package/dist/core/runner.d.ts +18 -1
- package/dist/core/runner.js +40 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/application.d.ts
CHANGED
|
@@ -167,6 +167,12 @@ export declare function createApplication(options?: AppOptions): Promise<{
|
|
|
167
167
|
runner: AgentRunner;
|
|
168
168
|
herdr: HerdrBridge;
|
|
169
169
|
contextWindow: (model: string) => number | undefined;
|
|
170
|
+
/** Effective context budget + compaction point shared by the runner and the TUI bar. */
|
|
171
|
+
contextBudget: (model: string) => {
|
|
172
|
+
total: number;
|
|
173
|
+
basis: "window" | "chars";
|
|
174
|
+
compactionAt: number;
|
|
175
|
+
};
|
|
170
176
|
loadModels: (signal: AbortSignal) => Promise<ModelInfo[]>;
|
|
171
177
|
/** Creates a provider for validation/model discovery without changing the active provider. */
|
|
172
178
|
probeProvider(id: string, profile: Record<string, import("@alisio/sdk").ProviderConfigurationValue>, credentials: Record<string, string>, signal: AbortSignal): Promise<ModelInfo[]>;
|
package/dist/application.js
CHANGED
|
@@ -635,6 +635,8 @@ export async function createApplication(options = {}) {
|
|
|
635
635
|
runner,
|
|
636
636
|
herdr,
|
|
637
637
|
contextWindow,
|
|
638
|
+
/** Effective context budget + compaction point shared by the runner and the TUI bar. */
|
|
639
|
+
contextBudget: (model) => runner.contextBudget(model),
|
|
638
640
|
loadModels,
|
|
639
641
|
/** Creates a provider for validation/model discovery without changing the active provider. */
|
|
640
642
|
async probeProvider(id, profile, credentials, signal) {
|
package/dist/config.d.ts
CHANGED
|
@@ -149,6 +149,7 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
|
|
|
149
149
|
auto: z.ZodDefault<z.ZodBoolean>;
|
|
150
150
|
threshold: z.ZodDefault<z.ZodNumber>;
|
|
151
151
|
keepTurns: z.ZodDefault<z.ZodNumber>;
|
|
152
|
+
maxOutputTokens: z.ZodDefault<z.ZodNumber>;
|
|
152
153
|
}, z.core.$strict>>;
|
|
153
154
|
websearch: z.ZodDefault<z.ZodObject<{
|
|
154
155
|
provider: z.ZodOptional<z.ZodEnum<{
|
|
@@ -206,6 +207,7 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
|
|
|
206
207
|
auto: boolean;
|
|
207
208
|
threshold: number;
|
|
208
209
|
keepTurns: number;
|
|
210
|
+
maxOutputTokens: number;
|
|
209
211
|
};
|
|
210
212
|
websearch: {
|
|
211
213
|
provider?: "brave" | "duckduckgo-instant" | "native" | "searxng" | "serpapi" | "tavily" | undefined;
|
|
@@ -337,6 +339,7 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
|
|
|
337
339
|
auto: boolean;
|
|
338
340
|
threshold: number;
|
|
339
341
|
keepTurns: number;
|
|
342
|
+
maxOutputTokens: number;
|
|
340
343
|
};
|
|
341
344
|
websearch: {
|
|
342
345
|
provider?: "brave" | "duckduckgo-instant" | "native" | "searxng" | "serpapi" | "tavily" | undefined;
|
package/dist/config.js
CHANGED
|
@@ -122,9 +122,14 @@ const configObjectSchema = z
|
|
|
122
122
|
auto: z.boolean().default(true),
|
|
123
123
|
threshold: z.number().min(0.1).max(0.99).default(0.85),
|
|
124
124
|
keepTurns: z.number().int().min(0).max(20).default(2),
|
|
125
|
+
/**
|
|
126
|
+
* Output token budget for the summarizer call. Larger than the agent-loop budget on
|
|
127
|
+
* purpose: a truncated summary is kept as partial, never re-run.
|
|
128
|
+
*/
|
|
129
|
+
maxOutputTokens: z.number().int().positive().default(16_000),
|
|
125
130
|
})
|
|
126
131
|
.strict()
|
|
127
|
-
.default(() => ({ auto: true, threshold: 0.85, keepTurns: 2 })),
|
|
132
|
+
.default(() => ({ auto: true, threshold: 0.85, keepTurns: 2, maxOutputTokens: 16_000 })),
|
|
128
133
|
websearch: z
|
|
129
134
|
.object({
|
|
130
135
|
provider: z
|
|
@@ -2,6 +2,36 @@ import type { CompactionCheckpoint, CompletionRequest, Message, ModelProvider }
|
|
|
2
2
|
/** Rough provider-agnostic estimate: ~4 characters per token. */
|
|
3
3
|
export declare function estimateTokens(value: string | Message[]): number;
|
|
4
4
|
export declare function shouldCompact(used: number, window: number | undefined, threshold: number): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Declared context windows above this many tokens are treated as unknown for auto-compaction and
|
|
7
|
+
* for the context bar: a `window * threshold` trigger would dwarf the char-budget fallback and
|
|
8
|
+
* hide real pressure (e.g. an 8M-token window with a default 160k-char budget would never even
|
|
9
|
+
* reach 2% before running out of space). Documented in docs/compaction.md.
|
|
10
|
+
*/
|
|
11
|
+
export declare const MAX_TRUSTED_WINDOW = 2000000;
|
|
12
|
+
export interface ContextBudget {
|
|
13
|
+
/** Effective total in tokens the context bar and auto-compaction measure against. */
|
|
14
|
+
total: number;
|
|
15
|
+
/** What the total is derived from: the model window, or the char-budget fallback. */
|
|
16
|
+
basis: "window" | "chars";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The single effective budget shared by the runner's auto-compaction and the TUI context bar.
|
|
20
|
+
* A known window (>= 1 token and <= MAX_TRUSTED_WINDOW) is used directly; otherwise the char
|
|
21
|
+
* budget is converted to estimated tokens (about 4 characters per token) so the bar fills where
|
|
22
|
+
* the char fallback actually compacts instead of showing an almost-empty bar next to an early
|
|
23
|
+
* compaction (the DeepSeek ~1M-window vs 160k-char budget mismatch).
|
|
24
|
+
*/
|
|
25
|
+
export declare function effectiveContextBudget(window: number | undefined, maxContextChars: number): ContextBudget;
|
|
26
|
+
/**
|
|
27
|
+
* Whether to auto-compact before the next model call. Uses ONE effective budget: a known window
|
|
28
|
+
* triggers at `used >= window * threshold`; an unknown or guard-bounded window falls back to the
|
|
29
|
+
* char budget (`estimatedChars / 4 >= maxContextChars / 4`, keeping the old ~4-characters-per-token
|
|
30
|
+
* protection). `used` (provider-reported when available) feeds the window branch and the context
|
|
31
|
+
* bar; `estimatedChars` is the raw character count of the next request and feeds the fallback, so
|
|
32
|
+
* a provider's token report can never push an unknown-window session into needless compaction.
|
|
33
|
+
*/
|
|
34
|
+
export declare function shouldCompactContext(used: number, estimatedChars: number, window: number | undefined, maxContextChars: number, threshold: number): boolean;
|
|
5
35
|
export interface CompactionOptions {
|
|
6
36
|
/** Recent user turns kept verbatim. */
|
|
7
37
|
keepTurns?: number;
|
|
@@ -31,6 +61,11 @@ export interface CheckpointOutput {
|
|
|
31
61
|
text: string;
|
|
32
62
|
}
|
|
33
63
|
export declare function parseCheckpointOutput(raw: string, fields?: string[]): CheckpointOutput;
|
|
64
|
+
export interface TextCompletion {
|
|
65
|
+
text: string;
|
|
66
|
+
/** Provider reported an output-token cut (finish "length"): text may be partial. */
|
|
67
|
+
truncated: boolean;
|
|
68
|
+
}
|
|
34
69
|
export declare function summarize(provider: ModelProvider, request: {
|
|
35
70
|
instructions: string;
|
|
36
71
|
messages: Message[];
|
|
@@ -39,7 +74,7 @@ export declare function summarize(provider: ModelProvider, request: {
|
|
|
39
74
|
maxOutputTokens: number;
|
|
40
75
|
signal: AbortSignal;
|
|
41
76
|
sessionId?: string;
|
|
42
|
-
}): Promise<
|
|
77
|
+
}): Promise<TextCompletion>;
|
|
43
78
|
/** Narrow provider-agnostic completion used by compaction and the plugin model service. */
|
|
44
79
|
export declare function completeText(provider: ModelProvider, request: CompletionRequest & {
|
|
45
80
|
signal: AbortSignal;
|
package/dist/core/compaction.js
CHANGED
|
@@ -7,6 +7,39 @@ export function estimateTokens(value) {
|
|
|
7
7
|
export function shouldCompact(used, window, threshold) {
|
|
8
8
|
return !!window && window > 0 && used >= window * threshold;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Declared context windows above this many tokens are treated as unknown for auto-compaction and
|
|
12
|
+
* for the context bar: a `window * threshold` trigger would dwarf the char-budget fallback and
|
|
13
|
+
* hide real pressure (e.g. an 8M-token window with a default 160k-char budget would never even
|
|
14
|
+
* reach 2% before running out of space). Documented in docs/compaction.md.
|
|
15
|
+
*/
|
|
16
|
+
export const MAX_TRUSTED_WINDOW = 2_000_000;
|
|
17
|
+
/**
|
|
18
|
+
* The single effective budget shared by the runner's auto-compaction and the TUI context bar.
|
|
19
|
+
* A known window (>= 1 token and <= MAX_TRUSTED_WINDOW) is used directly; otherwise the char
|
|
20
|
+
* budget is converted to estimated tokens (about 4 characters per token) so the bar fills where
|
|
21
|
+
* the char fallback actually compacts instead of showing an almost-empty bar next to an early
|
|
22
|
+
* compaction (the DeepSeek ~1M-window vs 160k-char budget mismatch).
|
|
23
|
+
*/
|
|
24
|
+
export function effectiveContextBudget(window, maxContextChars) {
|
|
25
|
+
if (window !== undefined && window > 0 && window <= MAX_TRUSTED_WINDOW)
|
|
26
|
+
return { total: window, basis: "window" };
|
|
27
|
+
return { total: Math.max(1, Math.round(maxContextChars / 4)), basis: "chars" };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Whether to auto-compact before the next model call. Uses ONE effective budget: a known window
|
|
31
|
+
* triggers at `used >= window * threshold`; an unknown or guard-bounded window falls back to the
|
|
32
|
+
* char budget (`estimatedChars / 4 >= maxContextChars / 4`, keeping the old ~4-characters-per-token
|
|
33
|
+
* protection). `used` (provider-reported when available) feeds the window branch and the context
|
|
34
|
+
* bar; `estimatedChars` is the raw character count of the next request and feeds the fallback, so
|
|
35
|
+
* a provider's token report can never push an unknown-window session into needless compaction.
|
|
36
|
+
*/
|
|
37
|
+
export function shouldCompactContext(used, estimatedChars, window, maxContextChars, threshold) {
|
|
38
|
+
const budget = effectiveContextBudget(window, maxContextChars);
|
|
39
|
+
if (budget.basis === "window")
|
|
40
|
+
return used >= budget.total * threshold;
|
|
41
|
+
return estimatedChars / 4 >= budget.total;
|
|
42
|
+
}
|
|
10
43
|
/**
|
|
11
44
|
* Indexes where history can be split without separating an assistant tool call from its
|
|
12
45
|
* results: every call before the index is answered before the index, and the kept part
|
|
@@ -154,26 +187,41 @@ export async function summarize(provider, request) {
|
|
|
154
187
|
const focus = request.focus?.trim()
|
|
155
188
|
? `\n\nAdditional focus requested by the user: ${request.focus.trim()}`
|
|
156
189
|
: "";
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
190
|
+
let completion;
|
|
191
|
+
try {
|
|
192
|
+
completion = await completeTextWithMeta(provider, {
|
|
193
|
+
system: request.instructions,
|
|
194
|
+
messages: [
|
|
195
|
+
{
|
|
196
|
+
role: "user",
|
|
197
|
+
text: `Checkpoint this session transcript.${focus}\n\n<transcript>\n${serializeForSummary(request.messages)}\n</transcript>`,
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
maxTokens: request.maxOutputTokens,
|
|
201
|
+
signal: request.signal,
|
|
202
|
+
...(request.model ? { model: request.model } : {}),
|
|
203
|
+
...(request.sessionId ? { sessionId: request.sessionId } : {}),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
// The adapters report an empty "length" cut with a message about max output tokens.
|
|
208
|
+
if (!request.signal.aborted && String(error).includes("max output tokens"))
|
|
209
|
+
throw new Error("Compaction summary was cut off before any usable text was produced; raise compaction.maxOutputTokens");
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
if (completion.truncated && !completion.text)
|
|
213
|
+
throw new Error("Compaction summary was cut off before any usable text was produced; raise compaction.maxOutputTokens");
|
|
214
|
+
if (!completion.text)
|
|
171
215
|
throw new Error("Summarizer returned an empty summary");
|
|
172
|
-
return
|
|
216
|
+
return completion;
|
|
173
217
|
}
|
|
174
218
|
/** Narrow provider-agnostic completion used by compaction and the plugin model service. */
|
|
175
219
|
export async function completeText(provider, request) {
|
|
176
|
-
|
|
220
|
+
return (await completeTextWithMeta(provider, request)).text;
|
|
221
|
+
}
|
|
222
|
+
/** Like `completeText`, but also reports whether the provider cut the response by tokens. */
|
|
223
|
+
async function completeTextWithMeta(provider, request) {
|
|
224
|
+
let text = "", completed = false, truncated = false;
|
|
177
225
|
for await (const event of provider.stream({
|
|
178
226
|
instructions: request.system,
|
|
179
227
|
messages: request.messages.map((m) => m.role === "user"
|
|
@@ -188,6 +236,7 @@ export async function completeText(provider, request) {
|
|
|
188
236
|
request.signal.throwIfAborted();
|
|
189
237
|
if (event.type === "completed") {
|
|
190
238
|
completed = true;
|
|
239
|
+
truncated = event.message.truncated === true;
|
|
191
240
|
text = event.message.text || text;
|
|
192
241
|
}
|
|
193
242
|
else if (event.type === "text_delta")
|
|
@@ -195,7 +244,7 @@ export async function completeText(provider, request) {
|
|
|
195
244
|
}
|
|
196
245
|
if (!completed)
|
|
197
246
|
throw new Error("Completion ended without a completed response");
|
|
198
|
-
return text.trim();
|
|
247
|
+
return { text: text.trim(), truncated };
|
|
199
248
|
}
|
|
200
249
|
export function summaryMessage(body, replaced) {
|
|
201
250
|
return {
|
package/dist/core/runner.d.ts
CHANGED
|
@@ -6,6 +6,11 @@ export interface CompactionSettings {
|
|
|
6
6
|
auto?: boolean;
|
|
7
7
|
threshold?: number;
|
|
8
8
|
keepTurns?: number;
|
|
9
|
+
/**
|
|
10
|
+
* Per-call output token budget for the summarizer. Defaults to 4096 when unset; never falls
|
|
11
|
+
* back to the agent-loop `maxOutputTokens`. A truncated summary is accepted as partial.
|
|
12
|
+
*/
|
|
13
|
+
maxOutputTokens?: number;
|
|
9
14
|
}
|
|
10
15
|
export interface RunnerOptions {
|
|
11
16
|
/** Provider bound to this persisted session. */
|
|
@@ -23,7 +28,8 @@ export interface RunnerOptions {
|
|
|
23
28
|
maxTokens?: number;
|
|
24
29
|
onEvent?: (event: RunEvent) => void;
|
|
25
30
|
readConcurrency?: number;
|
|
26
|
-
/** Context window in tokens for a model, when known.
|
|
31
|
+
/** Context window in tokens for a model, when known. Drives auto-compaction at `threshold`; when
|
|
32
|
+
* unknown (or absurdly large, see `MAX_TRUSTED_WINDOW`) the char budget falls back. */
|
|
27
33
|
contextWindow?: (model: string) => number | undefined;
|
|
28
34
|
compaction?: CompactionSettings;
|
|
29
35
|
/** When set, write/process tools not allowed by the policy are offered and ask first. */
|
|
@@ -101,6 +107,17 @@ export declare class AgentRunner {
|
|
|
101
107
|
private toolsText;
|
|
102
108
|
/** Estimated tokens the next request of a session would send. */
|
|
103
109
|
estimateContext(sessionId: string): Promise<number>;
|
|
110
|
+
/**
|
|
111
|
+
* The effective context budget a session's auto-compaction and the TUI context bar both use:
|
|
112
|
+
* the model window when known (and not beyond `MAX_TRUSTED_WINDOW`), otherwise the char budget
|
|
113
|
+
* converted to estimated tokens. `compactionAt` is the percentage of `total` where auto
|
|
114
|
+
* compaction triggers, so the bar turns red exactly where the engine compacts.
|
|
115
|
+
*/
|
|
116
|
+
contextBudget(model: string): {
|
|
117
|
+
total: number;
|
|
118
|
+
basis: "window" | "chars";
|
|
119
|
+
compactionAt: number;
|
|
120
|
+
};
|
|
104
121
|
/** Change the model used by subsequent turns of a session; recorded in the store. */
|
|
105
122
|
setModel(sessionId: string, model: string): void;
|
|
106
123
|
/** Manually compact a session outside a run. */
|
package/dist/core/runner.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { textResult, } from "@alisio/sdk";
|
|
2
|
-
import { checkpointInstructions, estimateTokens, parseCheckpointOutput, planCompaction,
|
|
2
|
+
import { checkpointInstructions, effectiveContextBudget, estimateTokens, parseCheckpointOutput, planCompaction, shouldCompactContext, summarize, summaryMessage, } from "./compaction.js";
|
|
3
3
|
/**
|
|
4
4
|
* Default cumulative token budget for one run: several context windows (each turn re-sends the
|
|
5
5
|
* context), clamped; 1M tokens when the window is unknown.
|
|
@@ -111,6 +111,21 @@ export class AgentRunner {
|
|
|
111
111
|
estimateTokens(this.options.store.messages(sessionId)) +
|
|
112
112
|
estimateTokens(this.toolsText(this.availableTools())));
|
|
113
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* The effective context budget a session's auto-compaction and the TUI context bar both use:
|
|
116
|
+
* the model window when known (and not beyond `MAX_TRUSTED_WINDOW`), otherwise the char budget
|
|
117
|
+
* converted to estimated tokens. `compactionAt` is the percentage of `total` where auto
|
|
118
|
+
* compaction triggers, so the bar turns red exactly where the engine compacts.
|
|
119
|
+
*/
|
|
120
|
+
contextBudget(model) {
|
|
121
|
+
const budget = effectiveContextBudget(this.options.contextWindow?.(model), this.options.maxContextChars ?? 160_000);
|
|
122
|
+
return {
|
|
123
|
+
...budget,
|
|
124
|
+
compactionAt: budget.basis === "window"
|
|
125
|
+
? Math.round((this.options.compaction?.threshold ?? 0.85) * 100)
|
|
126
|
+
: 100,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
114
129
|
/** Change the model used by subsequent turns of a session; recorded in the store. */
|
|
115
130
|
setModel(sessionId, model) {
|
|
116
131
|
const id = model.trim();
|
|
@@ -183,12 +198,12 @@ export class AgentRunner {
|
|
|
183
198
|
reportFailures(contribution.failures);
|
|
184
199
|
const fields = Object.fromEntries(Object.entries(contribution.fields).map(([name, f]) => [name, f.description]));
|
|
185
200
|
const provider = await (o.providerFor?.(o.store.get(sessionId)) ?? o.provider);
|
|
186
|
-
const raw = await summarize(provider, {
|
|
201
|
+
const { text: raw, truncated: summaryTruncated } = await summarize(provider, {
|
|
187
202
|
instructions: checkpointInstructions(contribution.instructions, fields),
|
|
188
203
|
messages: plan.summarized,
|
|
189
204
|
focus,
|
|
190
205
|
model,
|
|
191
|
-
maxOutputTokens: o.maxOutputTokens ?? 4096,
|
|
206
|
+
maxOutputTokens: o.compaction?.maxOutputTokens ?? 4096,
|
|
192
207
|
signal,
|
|
193
208
|
sessionId,
|
|
194
209
|
});
|
|
@@ -230,6 +245,7 @@ export class AgentRunner {
|
|
|
230
245
|
summarizedTokens: estimateTokens(plan.summarized),
|
|
231
246
|
checkpointTokens: estimateTokens(summary.text),
|
|
232
247
|
plugins: after.reports,
|
|
248
|
+
...(summaryTruncated ? { partial: true } : {}),
|
|
233
249
|
});
|
|
234
250
|
return { replaced: plan.cut, before, after: afterTokens, summary };
|
|
235
251
|
}
|
|
@@ -327,10 +343,12 @@ export class AgentRunner {
|
|
|
327
343
|
? last.tokens + estimateTokens(messages.slice(last.count))
|
|
328
344
|
: estimateTokens(instructions) + estimateTokens(messages) + estimateTokens(toolsText);
|
|
329
345
|
};
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
346
|
+
// One effective budget: a known window triggers at `used >= window * threshold`; an
|
|
347
|
+
// unknown (or absurdly large, see MAX_TRUSTED_WINDOW) window falls back to the char
|
|
348
|
+
// estimate (`chars / 4 >= maxContextChars / 4`). `maxContextChars` below stays as the
|
|
349
|
+
// post-compaction hard limit.
|
|
350
|
+
if (compaction.auto !== false &&
|
|
351
|
+
shouldCompactContext(used(), chars(), o.contextWindow?.(model), o.maxContextChars ?? 160_000, compaction.threshold ?? 0.85)) {
|
|
334
352
|
await this.compactLocked(sessionId, emit, model, combined, "auto");
|
|
335
353
|
instructions = await withPersona();
|
|
336
354
|
messages = o.store.messages(sessionId);
|
|
@@ -338,6 +356,7 @@ export class AgentRunner {
|
|
|
338
356
|
if (chars() > (o.maxContextChars ?? 160_000))
|
|
339
357
|
throw new Error("Context budget exceeded and compaction could not reduce it; start a new session.");
|
|
340
358
|
let completion;
|
|
359
|
+
let truncated = false;
|
|
341
360
|
let usage;
|
|
342
361
|
for await (const e of provider.stream({
|
|
343
362
|
instructions,
|
|
@@ -358,6 +377,7 @@ export class AgentRunner {
|
|
|
358
377
|
if (completion)
|
|
359
378
|
throw new Error("Provider emitted multiple completions");
|
|
360
379
|
completion = e.message;
|
|
380
|
+
truncated = e.message.truncated === true;
|
|
361
381
|
usage = e.usage;
|
|
362
382
|
tokens += (e.usage?.input ?? 0) + (e.usage?.output ?? 0);
|
|
363
383
|
usageTotal.input += e.usage?.input ?? 0;
|
|
@@ -389,7 +409,19 @@ export class AgentRunner {
|
|
|
389
409
|
...(usage ? { usage } : {}),
|
|
390
410
|
});
|
|
391
411
|
if (!completion.calls.length) {
|
|
392
|
-
|
|
412
|
+
const final = {
|
|
413
|
+
tokens,
|
|
414
|
+
text: lastText,
|
|
415
|
+
};
|
|
416
|
+
if (truncated) {
|
|
417
|
+
// The adapter kept a usable answer, but the token budget cut it off.
|
|
418
|
+
emit("response_truncated", {
|
|
419
|
+
turn: turn + 1,
|
|
420
|
+
maxOutputTokens: o.maxOutputTokens ?? 4096,
|
|
421
|
+
});
|
|
422
|
+
final.truncated = true;
|
|
423
|
+
}
|
|
424
|
+
emit("run_completed", final);
|
|
393
425
|
return { sessionId, text: lastText, status: "completed", usage: usageTotal };
|
|
394
426
|
}
|
|
395
427
|
const prepared = completion.calls.map((call) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export * from "@alisio/sdk";
|
|
3
3
|
export { type AppOptions, type BuiltinContext, type BuiltinPlugin, createApplication, enabledBuiltins, type PluginCatalogEntry, type PluginCatalogStatus, } from "./application.ts";
|
|
4
4
|
export { type Config, type ConfigLoadResult, type ConfigProvenance, configFile, configHome, configSchema, type LoadedConfig, loadConfig, loadConfigWithProvenance, type McpServerSource, overridesSavedProviderProfile, setMcpServerEnabled, setProjectPluginEnabled, setProjectSkillEnabled, stateHome, } from "./config.ts";
|
|
5
|
-
export { checkpointInstructions, completeText, estimateTokens, parseCheckpointOutput, planCompaction, renderCheckpoint, serializeForSummary, shouldCompact, } from "./core/compaction.ts";
|
|
5
|
+
export { type ContextBudget, checkpointInstructions, completeText, effectiveContextBudget, estimateTokens, MAX_TRUSTED_WINDOW, parseCheckpointOutput, planCompaction, renderCheckpoint, serializeForSummary, shouldCompact, shouldCompactContext, summarize, } from "./core/compaction.ts";
|
|
6
6
|
export type { ApprovalDecision, ApprovalHandler, ApprovalRequest, ContextSource, HookFailure, Policy, RunnerExtensions, Session, SessionStore, } from "./core/contracts.ts";
|
|
7
7
|
export { ToolRegistry } from "./core/registry.ts";
|
|
8
8
|
export { AgentRunner, type CompactionResult, defaultTokenBudget, type RunnerOptions, type RunOptions, } from "./core/runner.ts";
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export * from "@alisio/sdk";
|
|
3
3
|
export { createApplication, enabledBuiltins, } from "./application.js";
|
|
4
4
|
export { configFile, configHome, configSchema, loadConfig, loadConfigWithProvenance, overridesSavedProviderProfile, setMcpServerEnabled, setProjectPluginEnabled, setProjectSkillEnabled, stateHome, } from "./config.js";
|
|
5
|
-
export { checkpointInstructions, completeText, estimateTokens, parseCheckpointOutput, planCompaction, renderCheckpoint, serializeForSummary, shouldCompact, } from "./core/compaction.js";
|
|
5
|
+
export { checkpointInstructions, completeText, effectiveContextBudget, estimateTokens, MAX_TRUSTED_WINDOW, parseCheckpointOutput, planCompaction, renderCheckpoint, serializeForSummary, shouldCompact, shouldCompactContext, summarize, } from "./core/compaction.js";
|
|
6
6
|
export { ToolRegistry } from "./core/registry.js";
|
|
7
7
|
export { AgentRunner, defaultTokenBudget, } from "./core/runner.js";
|
|
8
8
|
export { ExtensionRegistry } from "./extensions/registry.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alisio/core",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.5",
|
|
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.
|
|
44
|
+
"@alisio/sdk": "0.1.0-alpha.5",
|
|
45
45
|
"@mixmark-io/domino": "2.2.0",
|
|
46
46
|
"@modelcontextprotocol/client": "2.1.0",
|
|
47
47
|
"ajv": "8.20.0",
|