cortad 0.1.3 → 0.1.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/local.mjs +18 -5
- package/package.json +4 -1
package/local.mjs
CHANGED
|
@@ -149,8 +149,13 @@ function envOrigins(envFiles) {
|
|
|
149
149
|
const THROUGHPUT = /(RATE_?LIMIT|DAILY_LIMIT|HOURLY_LIMIT|MINUTE_LIMIT|REQUESTS_PER|TOKEN_BUDGET|MAX_SSE|MAX_CONCURRENT|THROTTLE|_RPM$|_RPS$|_QPS$)/;
|
|
150
150
|
const GUARDED = /(AUTH|LOGIN|PASSWORD|BREAKER|LOCKOUT|ATTEMPT|FAIL|BAN|BLOCK)/;
|
|
151
151
|
const SWITCH = /_(?:ENABLED|DISABLED|ENABLE|DISABLE)$|^(?:ENABLE|DISABLE)_/;
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
// Limit-shaped names the code itself reads (process.env.GUEST_DAILY_LIMIT, os.environ.get("RATE_LIMIT_RPM"))
|
|
153
|
+
// count too: a limit with a default in code and no line in .env is the one that closes on a run.
|
|
154
|
+
const ENV_READ = /(?:process\.env(?:\.|\[\s*['"])|os\.(?:environ\.get|getenv)\(\s*['"]|os\.environ\[\s*['"]|\benv\(\s*['"]|Deno\.env\.get\(\s*['"])([A-Z][A-Z0-9_]*)/g;
|
|
155
|
+
const lifted = (name) => (/(TOKEN_BUDGET|TOKENS)/.test(name) ? "1000000000" : "1000000");
|
|
156
|
+
const liftable = (name) => THROUGHPUT.test(name) && !GUARDED.test(name) && !SWITCH.test(name);
|
|
157
|
+
function liftedLimits(envFiles, sources = []) {
|
|
158
|
+
const out = {};
|
|
154
159
|
for (const file of envFiles) {
|
|
155
160
|
let text = "";
|
|
156
161
|
try { text = readFileSync(file, "utf8"); } catch { continue; }
|
|
@@ -159,10 +164,16 @@ function liftedLimits(envFiles) {
|
|
|
159
164
|
if (!m) continue;
|
|
160
165
|
const [, name, raw] = m;
|
|
161
166
|
const value = raw.trim().replace(/^(['"])(.*)\1$/, "$2");
|
|
162
|
-
if (
|
|
167
|
+
if (liftable(name) && /^\d+$/.test(value)) out[name] = lifted(name);
|
|
163
168
|
}
|
|
164
169
|
}
|
|
165
|
-
|
|
170
|
+
for (const file of sources) {
|
|
171
|
+
if (!/\.(?:[cm]?[jt]sx?|py|go|rb|php|rs)$/.test(file)) continue;
|
|
172
|
+
let text = "";
|
|
173
|
+
try { if (statSync(file).size > 512_000) continue; text = readFileSync(file, "utf8"); } catch { continue; }
|
|
174
|
+
for (const m of text.matchAll(ENV_READ)) if (liftable(m[1]) && !(m[1] in out)) out[m[1]] = lifted(m[1]);
|
|
175
|
+
}
|
|
176
|
+
return out;
|
|
166
177
|
}
|
|
167
178
|
let secrets = [];
|
|
168
179
|
let identities = null;
|
|
@@ -335,6 +346,7 @@ async function startApp() {
|
|
|
335
346
|
const wanted = Number(flag("--port"));
|
|
336
347
|
if (wanted) {
|
|
337
348
|
if (!(await answers(wanted))) fail(`nothing is answering on port ${wanted}. Start your app first, then run this again.`);
|
|
349
|
+
say("your app was already running, so its request limits stay as they are; if it answers 429, stop it and run this without --port and they are raised for the session");
|
|
338
350
|
return { port: wanted, cmd: null };
|
|
339
351
|
}
|
|
340
352
|
const plan = startPlan({ root, typed: flag("--start"), onPath });
|
|
@@ -343,7 +355,7 @@ async function startApp() {
|
|
|
343
355
|
appDir = plan?.cwd ?? root;
|
|
344
356
|
pinned = pinnedNode();
|
|
345
357
|
if (plan?.within) say(`your app is in ${plan.within}, started there with: ${cmd}`);
|
|
346
|
-
const lifted = liftedLimits(envFiles);
|
|
358
|
+
const lifted = liftedLimits(envFiles, files.map((f) => join(root, f)));
|
|
347
359
|
if (Object.keys(lifted).length) say(`higher request limits for this session: ${Object.keys(lifted).join(", ")}`);
|
|
348
360
|
launched = { cmd, lifted };
|
|
349
361
|
step(`starting your app: ${cmd}`);
|
|
@@ -480,6 +492,7 @@ if (explain) {
|
|
|
480
492
|
`not sent anything git ignores, env files (${envFiles.length} here: ${envFiles.slice(0, 6).map(rel).join(", ") || "none"}), key files, data files, node_modules, .git`,
|
|
481
493
|
`env files read here only: to hide their values in replies, and to sign in a test account`,
|
|
482
494
|
`would start ${flag("--port") ? `nothing: uses your app on port ${flag("--port")}` : plan ? `${plan.cmd} (in ${rel(plan.cwd)})` : "asks you how your app starts"}`,
|
|
495
|
+
`would raise ${flag("--port") ? "nothing: your app's own request limits stay as they are" : `${Object.keys(liftedLimits(envFiles, files.map((f) => join(root, f)))).join(", ") || "no request limits found"} (for this session only)`}`,
|
|
483
496
|
`loads into app lib/trace.cjs (Node) or lib/pyhook/sitecustomize.py (Python): records the one request during which your app calls a model`,
|
|
484
497
|
`agent edits in your files, each with an undo kept in ~/.cortad/checkpoints; git is never touched`,
|
|
485
498
|
`agent shell confined by the OS: your project and toolchains only, writes to temp and build folders, localhost only`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cortad",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Connects the AI app on your machine to Cortad for test conversations. No dependencies.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"cortad": "local.mjs"
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"lib/trace.cjs",
|
|
19
19
|
"local.mjs"
|
|
20
20
|
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"test": "node --test lib/*.test.mjs"
|
|
23
|
+
},
|
|
21
24
|
"engines": {
|
|
22
25
|
"node": ">=20"
|
|
23
26
|
},
|