jaitus 0.3.2 → 0.3.3
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/package.json +2 -2
- package/src/api.js +7 -0
- package/src/index.js +14 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jaitus",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Jaitus — a coding agent in your terminal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"node": ">=20"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
|
-
"test": "node tests/source-sanity.js && node tests/rules.js && node tests/run.js && node tests/commands.js && node tests/login.js && node tests/session.js && node tests/openUrl.js && node tests/ink-tui.js && node tests/tui-render.js && node tests/mouse-e2e.js && node tests/environment.js && node tests/update.js && node tests/continuation.js",
|
|
19
|
+
"test": "node tests/source-sanity.js && node tests/rules.js && node tests/run.js && node tests/commands.js && node tests/login.js && node tests/session.js && node tests/openUrl.js && node tests/ink-tui.js && node tests/tui-render.js && node tests/mouse-e2e.js && node tests/environment.js && node tests/update.js && node tests/continuation.js && node tests/context-budget.js",
|
|
20
20
|
"preview": "node scripts/tui-preview.js",
|
|
21
21
|
"prepublishOnly": "npm test"
|
|
22
22
|
},
|
package/src/api.js
CHANGED
|
@@ -10,6 +10,10 @@ import { fromGatewayBody, fromNetwork, JaitusError } from './errors.js';
|
|
|
10
10
|
|
|
11
11
|
export class NotSignedIn extends Error {}
|
|
12
12
|
|
|
13
|
+
// The context window the gateway last advertised, or null before it has been asked.
|
|
14
|
+
let contextWindowSeen = null;
|
|
15
|
+
export const advertisedContextWindow = () => contextWindowSeen;
|
|
16
|
+
|
|
13
17
|
export function createClient() {
|
|
14
18
|
const { baseUrl } = endpoints();
|
|
15
19
|
if (!signedIn()) throw new NotSignedIn('Not signed in. Run `jaitus login` first.');
|
|
@@ -63,6 +67,9 @@ export function createClient() {
|
|
|
63
67
|
const body = await res.json().catch(() => ({}));
|
|
64
68
|
if (!res.ok) throw fromGatewayBody(res.status, body, { requestId: res.headers.get('x-request-id') || '' });
|
|
65
69
|
const models = (body?.data || []).map((m) => m?.id).filter(Boolean);
|
|
70
|
+
// How much conversation fits, as the gateway computed it for this account.
|
|
71
|
+
const ctx = (body?.data || []).map((m) => Number(m?.context_window)).find((n) => n > 0);
|
|
72
|
+
if (ctx) contextWindowSeen = ctx;
|
|
66
73
|
// An empty list is a service fault, not something the user can fix — and naming
|
|
67
74
|
// the gateway's model map to them would be naming our internals.
|
|
68
75
|
if (!models.length) throw new JaitusError({ code: 'unavailable', status: 502 });
|
package/src/index.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import path from 'node:path';
|
|
10
10
|
import fs from 'node:fs';
|
|
11
11
|
import { spawn, spawnSync } from 'node:child_process';
|
|
12
|
-
import { createClient, NotSignedIn } from './api.js';
|
|
12
|
+
import { createClient, NotSignedIn, advertisedContextWindow } from './api.js';
|
|
13
13
|
import { fromResponse, isJaitusError } from './errors.js';
|
|
14
14
|
import { signedIn } from './session.js';
|
|
15
15
|
import {
|
|
@@ -300,10 +300,18 @@ function gitBranch(cwd) {
|
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
-
//
|
|
304
|
-
//
|
|
305
|
-
//
|
|
306
|
-
const
|
|
303
|
+
// How much conversation a session carries before it is compacted. The gateway works it
|
|
304
|
+
// out from the providers' real limits and the admin's cap, and advertises it on its
|
|
305
|
+
// model list; this floor is only used until that answer arrives, or if it never does.
|
|
306
|
+
const CONTEXT_FALLBACK = 128_000;
|
|
307
|
+
let CONTEXT_BUDGET = CONTEXT_FALLBACK;
|
|
308
|
+
async function loadContextBudget(client) {
|
|
309
|
+
try {
|
|
310
|
+
if (!advertisedContextWindow()) await client.models();
|
|
311
|
+
CONTEXT_BUDGET = advertisedContextWindow() || CONTEXT_FALLBACK;
|
|
312
|
+
} catch { /* keep the floor */ }
|
|
313
|
+
return CONTEXT_BUDGET;
|
|
314
|
+
}
|
|
307
315
|
|
|
308
316
|
// Compact at this fraction of the budget. Low enough that the summarisation request
|
|
309
317
|
// itself still fits comfortably, high enough that a normal session never sees it.
|
|
@@ -548,6 +556,7 @@ async function session({ flags }) {
|
|
|
548
556
|
let [model, device] = await Promise.all([
|
|
549
557
|
resolveModel(client, flags.model),
|
|
550
558
|
probeDevice({}).catch(() => ({ vt: !!process.stdout.isTTY, sixel: false })),
|
|
559
|
+
loadContextBudget(client),
|
|
551
560
|
]);
|
|
552
561
|
// Degrade on EVIDENCE, not on silence.
|
|
553
562
|
//
|