@vincemakes/kiso-code 0.50.0 → 0.51.0
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/chat.js +5 -2
- package/dist/config.d.ts +28 -0
- package/dist/config.js +61 -1
- package/dist/create-coding-agent.js +4 -1
- package/dist/dispatch.js +3 -1
- package/dist/index.js +2 -1
- package/dist/replay.js +5 -1
- package/dist/resume.js +1 -1
- package/dist/state.d.ts +3 -1
- package/dist/state.js +15 -1
- package/dist/task-notice.d.ts +7 -0
- package/dist/task-notice.js +13 -0
- package/package.json +14 -14
package/dist/chat.js
CHANGED
|
@@ -9,7 +9,7 @@ import { escapeTerminal, cacheHitPct, decodeRate, palette, renderEvent, renderRe
|
|
|
9
9
|
import { askView, coldResumeLine, coldResumeView, deletionRiskHint, editFileHunksDiff, hunksOf, writeFileDiff } from "@vincemakes/kiso-tui";
|
|
10
10
|
import { canonicalTargetPath, isProtectedPath, protectedIdentity, shellProgressPath } from "@vincemakes/kiso-tools-node";
|
|
11
11
|
import { deliveryLines, liveTasks, lostToldOf, mergedConfig, queuedSwitchLines, setExitTasks, tasksFor, taskWhatOf } from "./state.js";
|
|
12
|
-
import { budgetSpentLine, taskCounts, taskNoticeLines, taskNoticeRows, tasksForDisplay } from "./task-notice.js";
|
|
12
|
+
import { budgetSpentLine, cappedWaitLine, taskCounts, taskNoticeLines, taskNoticeRows, tasksForDisplay } from "./task-notice.js";
|
|
13
13
|
import { current as inRunCompaction, takeKept as takeKeptCompaction } from "./in-run-compaction.js";
|
|
14
14
|
import { echoText } from "@vincemakes/kiso-tui-cells/render";
|
|
15
15
|
import { canonicalizeUsage, RunClosedError } from "@vincemakes/kiso-runtime";
|
|
@@ -1063,6 +1063,9 @@ onInputLanded) {
|
|
|
1063
1063
|
reason = m[1];
|
|
1064
1064
|
}
|
|
1065
1065
|
body.toolResult(ev.callId, { content: text, isError: ev.isError, reason, ...((ev.tags ?? []).includes("created") ? { created: true } : {}) });
|
|
1066
|
+
const capped = ev.isError ? null : cappedWaitLine(text);
|
|
1067
|
+
if (capped !== null)
|
|
1068
|
+
body.notice(capped);
|
|
1066
1069
|
break;
|
|
1067
1070
|
}
|
|
1068
1071
|
case "text_delta":
|
|
@@ -1642,7 +1645,7 @@ export async function chat(session, faux, input, autoCompact, nav, seed) {
|
|
|
1642
1645
|
dock.setLive(liveRow(compactingStatus(runGlyph, summary.rounds, summary.tokens, Math.round((Date.now() - summary.since) / 1000), W - 20, retryOnRow(), summary.progress, "auto"), ["esc stops"], W));
|
|
1643
1646
|
return;
|
|
1644
1647
|
}
|
|
1645
|
-
dock.setLive(workingRow(runGlyph, runStart, runUsage.out,
|
|
1648
|
+
dock.setLive(workingRow(runGlyph, runStart, runUsage.out, rowWidth(), retryOnRow(), detachableNow()));
|
|
1646
1649
|
dock.setBar(barFor(session, { tokPerSec: lastTokPerSec, tasks: taskCountsNow() }));
|
|
1647
1650
|
};
|
|
1648
1651
|
// W19: under plan the idle row makes the posture unmistakable — the W4
|
package/dist/config.d.ts
CHANGED
|
@@ -31,6 +31,20 @@
|
|
|
31
31
|
* with an invalid value is likewise loud; unknown top-level keys are
|
|
32
32
|
* ignored (forward compatibility).
|
|
33
33
|
*/
|
|
34
|
+
/** The reasoning-effort levels a profile may declare: the registry's own
|
|
35
|
+
* vocabulary (without `default`, which is "send nothing"). */
|
|
36
|
+
declare const EFFORT_LEVELS: readonly ["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"];
|
|
37
|
+
type EffortLevel = (typeof EFFORT_LEVELS)[number];
|
|
38
|
+
/** A profile's own claim about its route's effort levels (the same kind of
|
|
39
|
+
* claim as `contextWindow`: yours, not ours). */
|
|
40
|
+
export interface ProfileEffort {
|
|
41
|
+
readonly levels: readonly EffortLevel[];
|
|
42
|
+
/** the level the route uses when none is sent; omit or null = unknown */
|
|
43
|
+
readonly default?: EffortLevel | null;
|
|
44
|
+
/** the route's spelling where it differs from the level's name, e.g.
|
|
45
|
+
* `{ "none": "off" }`; each key must be one of `levels` */
|
|
46
|
+
readonly values?: Readonly<Partial<Record<EffortLevel, string>>>;
|
|
47
|
+
}
|
|
34
48
|
/** OR-1: `openai-responses` is a DIALECT, not a vendor — the same kind
|
|
35
49
|
* drives the first-party Responses API and the ChatGPT subscription
|
|
36
50
|
* backend, and which one it is follows the profile's baseUrl (and so
|
|
@@ -67,6 +81,15 @@ export interface ModelProfile {
|
|
|
67
81
|
* registry, where every figure has to carry a source.
|
|
68
82
|
*/
|
|
69
83
|
readonly contextWindow?: number;
|
|
84
|
+
/**
|
|
85
|
+
* The reasoning-effort levels this profile's route accepts, for a route
|
|
86
|
+
* the registry has no row for (a gateway, a new model). It enables the
|
|
87
|
+
* effort picker and the `/model <profile> <level>` form; the levels are
|
|
88
|
+
* YOUR claim. A route that refuses a level answers 400, and nothing here
|
|
89
|
+
* hides it. `kiso`'s own table wins nowhere over this: your declaration
|
|
90
|
+
* replaces the registry's levels for this model at this endpoint.
|
|
91
|
+
*/
|
|
92
|
+
readonly effort?: ProfileEffort;
|
|
70
93
|
/**
|
|
71
94
|
* What this endpoint FORWARDS to, when `baseUrl` is a local proxy — a URL
|
|
72
95
|
* (`https://gateway.example/v1`) or a name (`my gateway`). It never
|
|
@@ -88,6 +111,10 @@ export interface ModelProfile {
|
|
|
88
111
|
*/
|
|
89
112
|
readonly headers?: Readonly<Record<string, string>>;
|
|
90
113
|
}
|
|
114
|
+
/** Hand every profile's declared effort levels to the registry's lookup
|
|
115
|
+
* (called once, right after the config is merged). A profile without a
|
|
116
|
+
* declaration is not touched, and one that declares nothing changes nothing. */
|
|
117
|
+
export declare function applyEffortDeclarations(cfg: KisoConfig): void;
|
|
91
118
|
export interface AutoCompactConfig {
|
|
92
119
|
readonly thresholdRatio: number;
|
|
93
120
|
}
|
|
@@ -228,3 +255,4 @@ export declare function resolveAutoCompact(merged: KisoConfig): AutoCompactConfi
|
|
|
228
255
|
* gate, and it could not anyway, since an untrusted project's config is
|
|
229
256
|
* never read. */
|
|
230
257
|
export declare function resolveProjectTrustPolicy(merged: KisoConfig): "ask" | "never";
|
|
258
|
+
export {};
|
package/dist/config.js
CHANGED
|
@@ -37,7 +37,10 @@ import { join, win32 } from "node:path";
|
|
|
37
37
|
import { kisoHome } from "./state.js";
|
|
38
38
|
import { MODE_VALUES, parseMode } from "./mode.js";
|
|
39
39
|
import { AuthError, effectiveBaseUrl, endpointCredentialId, getCredential, providerIdOf } from "./auth/credentials.js";
|
|
40
|
-
import { BUILTIN_MANIFESTS } from "@vincemakes/kiso-runtime/internal";
|
|
40
|
+
import { BUILTIN_MANIFESTS, declareEffort } from "@vincemakes/kiso-runtime/internal";
|
|
41
|
+
/** The reasoning-effort levels a profile may declare: the registry's own
|
|
42
|
+
* vocabulary (without `default`, which is "send nothing"). */
|
|
43
|
+
const EFFORT_LEVELS = ["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"];
|
|
41
44
|
/** Header names a profile may not set: credentials (a key never lives in the
|
|
42
45
|
* config file) and the framing the adapter owns. */
|
|
43
46
|
const REFUSED_HEADERS = new Set(["authorization", "proxy-authorization", "x-api-key", "api-key", "cookie", "host", "content-length", "content-type", "transfer-encoding", "connection"]);
|
|
@@ -59,6 +62,61 @@ function parseHeaders(field, raw, fail) {
|
|
|
59
62
|
}
|
|
60
63
|
return out;
|
|
61
64
|
}
|
|
65
|
+
function parseEffort(field, raw, fail) {
|
|
66
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
67
|
+
fail(field, "expected an object: { levels: [...], default?: ..., values?: { ... } }");
|
|
68
|
+
const o = raw;
|
|
69
|
+
for (const k of Object.keys(o))
|
|
70
|
+
if (k !== "levels" && k !== "default" && k !== "values")
|
|
71
|
+
fail(`${field}.${k}`, "unknown key (levels, default and values are the only ones)");
|
|
72
|
+
const known = (v) => typeof v === "string" && EFFORT_LEVELS.includes(v);
|
|
73
|
+
if (!Array.isArray(o.levels) || o.levels.length === 0 || o.levels.length > EFFORT_LEVELS.length)
|
|
74
|
+
fail(`${field}.levels`, `expected 1 to ${EFFORT_LEVELS.length} levels`);
|
|
75
|
+
const levels = [];
|
|
76
|
+
for (const l of o.levels) {
|
|
77
|
+
if (!known(l))
|
|
78
|
+
fail(`${field}.levels`, `${JSON.stringify(l)} is not a level (${EFFORT_LEVELS.join(", ")})`);
|
|
79
|
+
if (levels.includes(l))
|
|
80
|
+
fail(`${field}.levels`, `${l} is listed twice`);
|
|
81
|
+
levels.push(l);
|
|
82
|
+
}
|
|
83
|
+
let def;
|
|
84
|
+
if (o.default !== undefined && o.default !== null) {
|
|
85
|
+
if (!known(o.default) || !levels.includes(o.default))
|
|
86
|
+
fail(`${field}.default`, "expected null or one of the listed levels");
|
|
87
|
+
def = o.default;
|
|
88
|
+
}
|
|
89
|
+
else if (o.default === null)
|
|
90
|
+
def = null;
|
|
91
|
+
let values;
|
|
92
|
+
if (o.values !== undefined) {
|
|
93
|
+
if (o.values === null || typeof o.values !== "object" || Array.isArray(o.values))
|
|
94
|
+
fail(`${field}.values`, "expected an object of level names to the route's spelling");
|
|
95
|
+
values = {};
|
|
96
|
+
for (const [k, v] of Object.entries(o.values)) {
|
|
97
|
+
if (!known(k) || !levels.includes(k))
|
|
98
|
+
fail(`${field}.values.${k}`, "expected one of the listed levels");
|
|
99
|
+
if (typeof v !== "string" || !/^[A-Za-z0-9_.-]{1,24}$/.test(v))
|
|
100
|
+
fail(`${field}.values.${k}`, "expected a short word (letters, digits, . _ -)");
|
|
101
|
+
values[k] = v;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return { levels, ...(def !== undefined ? { default: def } : {}), ...(values !== undefined ? { values } : {}) };
|
|
105
|
+
}
|
|
106
|
+
/** Hand every profile's declared effort levels to the registry's lookup
|
|
107
|
+
* (called once, right after the config is merged). A profile without a
|
|
108
|
+
* declaration is not touched, and one that declares nothing changes nothing. */
|
|
109
|
+
export function applyEffortDeclarations(cfg) {
|
|
110
|
+
for (const profile of Object.values(cfg.models ?? {})) {
|
|
111
|
+
if (profile.effort === undefined)
|
|
112
|
+
continue;
|
|
113
|
+
declareEffort(profile.model, profile.baseUrl, {
|
|
114
|
+
levels: profile.effort.levels,
|
|
115
|
+
default: profile.effort.default ?? null,
|
|
116
|
+
...(profile.effort.values !== undefined ? { values: profile.effort.values } : {}),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
62
120
|
const KINDS = ["openai-compat", "anthropic", "openai-responses"];
|
|
63
121
|
export class ConfigError extends Error {
|
|
64
122
|
}
|
|
@@ -192,6 +250,7 @@ export function parseConfig(text, source) {
|
|
|
192
250
|
if (p.upstream !== undefined && (typeof p.upstream !== "string" || p.upstream.trim() === ""))
|
|
193
251
|
fail(`models.${name}.upstream`, "expected the URL or name of what this endpoint forwards to");
|
|
194
252
|
const headers = p.headers === undefined ? undefined : parseHeaders(`models.${name}.headers`, p.headers, fail);
|
|
253
|
+
const effort = p.effort === undefined ? undefined : parseEffort(`models.${name}.effort`, p.effort, fail);
|
|
195
254
|
models[name] = {
|
|
196
255
|
kind: p.kind,
|
|
197
256
|
model: p.model,
|
|
@@ -202,6 +261,7 @@ export function parseConfig(text, source) {
|
|
|
202
261
|
...(typeof p.contextWindow === "number" ? { contextWindow: p.contextWindow } : {}),
|
|
203
262
|
...(typeof p.upstream === "string" ? { upstream: p.upstream.trim() } : {}),
|
|
204
263
|
...(headers !== undefined ? { headers } : {}),
|
|
264
|
+
...(effort !== undefined ? { effort } : {}),
|
|
205
265
|
};
|
|
206
266
|
}
|
|
207
267
|
out.models = models;
|
|
@@ -14,7 +14,7 @@ import { migrationNotice, pendingLegacyIds, planMigration, runMigration } from "
|
|
|
14
14
|
import { askUi, resolveProjectTrust } from "./trust-ui.js";
|
|
15
15
|
import { isFirstRun, scaffoldFirstRun } from "./first-run.js";
|
|
16
16
|
import { fauxSkip, readFauxScript } from "./faux-glue.js";
|
|
17
|
-
import { loadProjectConfig, loadUserConfig, mergeConfigs, resolveContextWindow, resolveModel } from "./config.js";
|
|
17
|
+
import { applyEffortDeclarations, loadProjectConfig, loadUserConfig, mergeConfigs, resolveContextWindow, resolveModel } from "./config.js";
|
|
18
18
|
import { builtInLayer } from "./builtin.js";
|
|
19
19
|
import { recordLearnedWindow, useLearnedWindows } from "./learned-windows.js";
|
|
20
20
|
import { compactionDiscardedNotice, contextWindowTokens, knownContextWindow, unknownWindowNotice, windowLearnedNotice } from "./chat.js";
|
|
@@ -163,6 +163,9 @@ export async function createCodingAgent(sessionId, input, modelFlag) {
|
|
|
163
163
|
const userCfg = loadUserConfig();
|
|
164
164
|
const projectCfg = loadProjectConfig(process.cwd(), project !== null);
|
|
165
165
|
const merged = mergeConfigs(userCfg, projectCfg);
|
|
166
|
+
// a profile's own effort levels reach the registry's lookup before the
|
|
167
|
+
// picker, `/model <profile> <level>` or a resumed session reads them
|
|
168
|
+
applyEffortDeclarations(merged);
|
|
166
169
|
// 0.40.6: /settings names each value's layer from these
|
|
167
170
|
settingsLayers.user = userCfg;
|
|
168
171
|
settingsLayers.project = projectCfg;
|
package/dist/dispatch.js
CHANGED
|
@@ -100,7 +100,9 @@ function effortAxis(p) {
|
|
|
100
100
|
// cursor could NOT land where the previous selection asked.
|
|
101
101
|
...(carried !== undefined && carried !== "default" && carriedIdx < 0 && defaultIdx >= 0
|
|
102
102
|
? { levelNote: `effort ${carried} \u2192 ${levels[defaultIdx]}: this model's default (it has no ${carried})` }
|
|
103
|
-
:
|
|
103
|
+
: effort.declared === true
|
|
104
|
+
? { levelNote: "levels declared in your profile" }
|
|
105
|
+
: {}),
|
|
104
106
|
};
|
|
105
107
|
}
|
|
106
108
|
/** What signs a profile in, for the listing: `stored key` when a key in
|
package/dist/index.js
CHANGED
|
@@ -45,7 +45,7 @@ import { activeStoreDir, setActiveStoreDir, agentModel, atFiles, body, bodyLog,
|
|
|
45
45
|
import { fauxSkip, readFauxScript } from "./faux-glue.js";
|
|
46
46
|
import { barFor, chat, contextWindowTokens, displayCtxRatio, microcompactThresholdFor, statusModelLabel } from "./chat.js";
|
|
47
47
|
import { preferences, usePreferences } from "./preferences.js";
|
|
48
|
-
import { settingsLayers, setChildTurnBudget, stopAllTasks, tasksFor } from "./state.js";
|
|
48
|
+
import { settingsLayers, setChildTurnBudget, setPrintRun, stopAllTasks, tasksFor } from "./state.js";
|
|
49
49
|
import { tasksForDisplay } from "./task-notice.js";
|
|
50
50
|
import { finishChild } from "./child-result.js";
|
|
51
51
|
import { loadUserConfig, resolveAutoCompact } from "./config.js";
|
|
@@ -1305,6 +1305,7 @@ async function main() {
|
|
|
1305
1305
|
process.exit(2);
|
|
1306
1306
|
}
|
|
1307
1307
|
args.splice(printIdx, 2);
|
|
1308
|
+
setPrintRun();
|
|
1308
1309
|
}
|
|
1309
1310
|
// merge round B: --model <profile|provider/model> — the top of the model
|
|
1310
1311
|
// precedence chain; the value flows into createCodingAgent's config resolution.
|
package/dist/replay.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import { echoText } from "@vincemakes/kiso-tui-cells/render";
|
|
23
23
|
import { bandHeader } from "@vincemakes/kiso-tui-cells/strings";
|
|
24
|
-
import { taskNoticeLines, taskNoticeRows, taskWhat } from "./task-notice.js";
|
|
24
|
+
import { cappedWaitLine, taskNoticeLines, taskNoticeRows, taskWhat } from "./task-notice.js";
|
|
25
25
|
/** How many turns stay on screen in full. */
|
|
26
26
|
const FULL_TURNS = 2;
|
|
27
27
|
/** A user turn's opening line, or null when this input does not open one
|
|
@@ -101,6 +101,10 @@ function replayTurn(body, turn, tasks) {
|
|
|
101
101
|
const created = (e.tags ?? []).includes("created");
|
|
102
102
|
body.toolResult(String(e.callId), { content: text, isError: e.isError === true, reason, untimed: true, ...(created ? { created: true } : {}) });
|
|
103
103
|
results.add(String(e.callId));
|
|
104
|
+
// 0.50.1: the capped wait's TASK row, as the live run drew it
|
|
105
|
+
const capped = e.isError === true ? null : cappedWaitLine(text);
|
|
106
|
+
if (capped !== null)
|
|
107
|
+
body.notice(capped);
|
|
104
108
|
break;
|
|
105
109
|
}
|
|
106
110
|
case "text_delta":
|
package/dist/resume.js
CHANGED
|
@@ -32,7 +32,7 @@ export async function resume(session, prompt, faux, input) {
|
|
|
32
32
|
runUsage = u;
|
|
33
33
|
if (!dock.active)
|
|
34
34
|
return;
|
|
35
|
-
dock.setLive(workingRow(runGlyph, runStart, u.out,
|
|
35
|
+
dock.setLive(workingRow(runGlyph, runStart, u.out, width(), retryOnRow()));
|
|
36
36
|
dock.setBar(barFor(session, { tokPerSec: null }));
|
|
37
37
|
};
|
|
38
38
|
const paintIdle = () => {
|
package/dist/state.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export declare function kisoHome(): string;
|
|
|
29
29
|
* these state setters have run.
|
|
30
30
|
*/
|
|
31
31
|
export declare function secretEnvNamesOf(models: Readonly<Record<string, unknown>>): readonly string[];
|
|
32
|
+
export declare function setPrintRun(): void;
|
|
32
33
|
export declare function codingToolOptions(): {
|
|
33
34
|
readonly workspaceRoot: string;
|
|
34
35
|
readonly excludeRoots: readonly string[];
|
|
@@ -37,7 +38,8 @@ export declare function codingToolOptions(): {
|
|
|
37
38
|
readonly tasks: (sessionId: string | undefined) => ShellTasks | undefined;
|
|
38
39
|
readonly observedRevision: (sessionId: string | undefined, full: string, kind?: "edit" | "write") => string | undefined;
|
|
39
40
|
readonly limits?: {
|
|
40
|
-
readonly minForegroundMs
|
|
41
|
+
readonly minForegroundMs?: number;
|
|
42
|
+
readonly maxForegroundMs?: number;
|
|
41
43
|
};
|
|
42
44
|
};
|
|
43
45
|
/** Amendment 8: what a session's task ran — a lost task's transcript row
|
package/dist/state.js
CHANGED
|
@@ -43,11 +43,25 @@ export function secretEnvNamesOf(models) {
|
|
|
43
43
|
.filter((n) => typeof n === "string" && n.length > 0)),
|
|
44
44
|
];
|
|
45
45
|
}
|
|
46
|
+
/** 0.50.1 (ADR-0058 Amendment 16): `kiso -p` runs with nobody watching and
|
|
47
|
+
* stops its tasks when the one turn ends, so the foreground wait keeps the
|
|
48
|
+
* model's value — no ceiling. Set once, where `-p` is parsed. */
|
|
49
|
+
let printRun = false;
|
|
50
|
+
export function setPrintRun() {
|
|
51
|
+
printRun = true;
|
|
52
|
+
}
|
|
46
53
|
export function codingToolOptions() {
|
|
47
54
|
// KISO_MIN_FOREGROUND_MS — the test rigs' knob (like KISO_AUTO_DETACH_MS):
|
|
48
55
|
// the least foreground wait (ADR-0058 Amendment 10, default 60 s). The
|
|
49
56
|
// rigs that promote a command by a short wait lower it; nothing else does.
|
|
50
57
|
const minForeground = Number.parseInt(process.env.KISO_MIN_FOREGROUND_MS ?? "", 10);
|
|
58
|
+
// KISO_MAX_FOREGROUND_MS — the rigs' knob for the ceiling (Amendment 15,
|
|
59
|
+
// default 5 min). `-p` has none whatever the knob says (Amendment 16).
|
|
60
|
+
const maxForeground = Number.parseInt(process.env.KISO_MAX_FOREGROUND_MS ?? "", 10);
|
|
61
|
+
const limits = {
|
|
62
|
+
...(Number.isFinite(minForeground) && minForeground >= 0 ? { minForegroundMs: minForeground } : {}),
|
|
63
|
+
...(printRun ? { maxForegroundMs: 0 } : Number.isFinite(maxForeground) && maxForeground >= 0 ? { maxForegroundMs: maxForeground } : {}),
|
|
64
|
+
};
|
|
51
65
|
return {
|
|
52
66
|
workspaceRoot: process.cwd(),
|
|
53
67
|
excludeRoots: [kisoHome()],
|
|
@@ -55,7 +69,7 @@ export function codingToolOptions() {
|
|
|
55
69
|
protectedFiles: protectedFiles(),
|
|
56
70
|
tasks: tasksFor,
|
|
57
71
|
observedRevision: observedRevisionFromLog,
|
|
58
|
-
...(
|
|
72
|
+
...(Object.keys(limits).length > 0 ? { limits } : {}),
|
|
59
73
|
};
|
|
60
74
|
}
|
|
61
75
|
/** ADR-0058 (3b): one TaskManager per session, its directory beside the
|
package/dist/task-notice.d.ts
CHANGED
|
@@ -7,6 +7,13 @@ import type { NoticeMark } from "@vincemakes/kiso-tui";
|
|
|
7
7
|
* (<what>) — ` — the parenthesis only when the command is known — and the
|
|
8
8
|
* LAST ` — ` part opening with "it may still be running". One line each. */
|
|
9
9
|
export declare function taskNoticeLines(items: readonly TaskDeliveryItem[], what?: (taskId: string) => string | undefined): string[];
|
|
10
|
+
/** 0.50.1: a command promoted at the foreground ceiling — its shell result
|
|
11
|
+
* opens `still running after <wait> ms (the limit; you asked <asked> ms);
|
|
12
|
+
* continued as background task <id>` — is said to the person as one TASK
|
|
13
|
+
* row: `t3 · moved to the background at the 5m limit · asked 6m 40s`. Only
|
|
14
|
+
* this case: every other promotion stays rowless (the task-start row is
|
|
15
|
+
* deferred, owner 2026-10-14). */
|
|
16
|
+
export declare function cappedWaitLine(result: string): string | null;
|
|
10
17
|
/** Finding 0480-F9: the chain budget is spent — said to the person once,
|
|
11
18
|
* so a chain that went quiet on its budget does not look idle. */
|
|
12
19
|
export declare function budgetSpentLine(info: {
|
package/dist/task-notice.js
CHANGED
|
@@ -36,6 +36,19 @@ export function taskNoticeLines(items, what) {
|
|
|
36
36
|
}
|
|
37
37
|
return rows;
|
|
38
38
|
}
|
|
39
|
+
/** 0.50.1: a command promoted at the foreground ceiling — its shell result
|
|
40
|
+
* opens `still running after <wait> ms (the limit; you asked <asked> ms);
|
|
41
|
+
* continued as background task <id>` — is said to the person as one TASK
|
|
42
|
+
* row: `t3 · moved to the background at the 5m limit · asked 6m 40s`. Only
|
|
43
|
+
* this case: every other promotion stays rowless (the task-start row is
|
|
44
|
+
* deferred, owner 2026-10-14). */
|
|
45
|
+
export function cappedWaitLine(result) {
|
|
46
|
+
const m = /^still running after (\d+) ms \(the limit; you asked (\d+) ms\); continued as background task (\S+) /.exec(result);
|
|
47
|
+
if (m === null)
|
|
48
|
+
return null;
|
|
49
|
+
const limit = elapsedLabel(Number(m[1]) / 1000).replace(/(?<=m) 0s$/, "");
|
|
50
|
+
return `✦ task ${m[3]} · moved to the background at the ${limit} limit · asked ${elapsedLabel(Number(m[2]) / 1000)}`;
|
|
51
|
+
}
|
|
39
52
|
/** Finding 0480-F9: the chain budget is spent — said to the person once,
|
|
40
53
|
* so a chain that went quiet on its budget does not look idle. */
|
|
41
54
|
export function budgetSpentLine(info) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-code",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.51.0",
|
|
4
4
|
"description": "kiso-code \u2014 the coding agent on kiso, the durable runtime for AI agents: kiso chat / kiso resume / kiso sessions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,19 +18,19 @@
|
|
|
18
18
|
"test": "vitest run"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@vincemakes/kiso-ask-ext": "0.
|
|
22
|
-
"@vincemakes/kiso-core": "0.
|
|
23
|
-
"@vincemakes/kiso-evals": "0.
|
|
24
|
-
"@vincemakes/kiso-mcp-ext": "0.
|
|
25
|
-
"@vincemakes/kiso-provider-anthropic": "0.
|
|
26
|
-
"@vincemakes/kiso-provider-openai": "0.
|
|
27
|
-
"@vincemakes/kiso-provider-openai-responses": "0.
|
|
28
|
-
"@vincemakes/kiso-runtime": "0.
|
|
29
|
-
"@vincemakes/kiso-skills-ext": "0.
|
|
30
|
-
"@vincemakes/kiso-subagent-ext": "0.
|
|
31
|
-
"@vincemakes/kiso-tools-node": "0.
|
|
32
|
-
"@vincemakes/kiso-tui": "0.
|
|
33
|
-
"@vincemakes/kiso-tui-cells": "0.
|
|
21
|
+
"@vincemakes/kiso-ask-ext": "0.51.0",
|
|
22
|
+
"@vincemakes/kiso-core": "0.51.0",
|
|
23
|
+
"@vincemakes/kiso-evals": "0.51.0",
|
|
24
|
+
"@vincemakes/kiso-mcp-ext": "0.51.0",
|
|
25
|
+
"@vincemakes/kiso-provider-anthropic": "0.51.0",
|
|
26
|
+
"@vincemakes/kiso-provider-openai": "0.51.0",
|
|
27
|
+
"@vincemakes/kiso-provider-openai-responses": "0.51.0",
|
|
28
|
+
"@vincemakes/kiso-runtime": "0.51.0",
|
|
29
|
+
"@vincemakes/kiso-skills-ext": "0.51.0",
|
|
30
|
+
"@vincemakes/kiso-subagent-ext": "0.51.0",
|
|
31
|
+
"@vincemakes/kiso-tools-node": "0.51.0",
|
|
32
|
+
"@vincemakes/kiso-tui": "0.51.0",
|
|
33
|
+
"@vincemakes/kiso-tui-cells": "0.51.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^26.1.2",
|