@cryer/star-cli 0.3.3 → 0.3.4
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/README.md +3 -1
- package/README.zh-CN.md +3 -1
- package/dist/{chunk-3L6QKJM4.js → chunk-K3R42LOX.js} +207 -69
- package/dist/chunk-K3R42LOX.js.map +1 -0
- package/dist/{loop-TQ7GFTTE.js → loop-SDZVEQND.js} +2 -2
- package/dist/main.js +28 -126
- package/dist/main.js.map +1 -1
- package/package.json +25 -16
- package/dist/chunk-3L6QKJM4.js.map +0 -1
- /package/dist/{loop-TQ7GFTTE.js.map → loop-SDZVEQND.js.map} +0 -0
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
AgentLoop,
|
|
4
4
|
PLAN_MODE_PROMPT
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-K3R42LOX.js";
|
|
6
6
|
import "./chunk-B6P4VUBE.js";
|
|
7
7
|
export {
|
|
8
8
|
AgentLoop,
|
|
9
9
|
PLAN_MODE_PROMPT
|
|
10
10
|
};
|
|
11
|
-
//# sourceMappingURL=loop-
|
|
11
|
+
//# sourceMappingURL=loop-SDZVEQND.js.map
|
package/dist/main.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
AgentLoop,
|
|
4
|
+
ConfigSchema,
|
|
4
5
|
MAX_IMAGE_DIMENSION,
|
|
5
6
|
SKIP_DIRS,
|
|
6
7
|
TodoStore,
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
collectCommitContext,
|
|
14
15
|
collectWorkingDiff,
|
|
15
16
|
compactMessages,
|
|
17
|
+
contextWindowTokens,
|
|
16
18
|
createDefaultRegistry,
|
|
17
19
|
createIgnorePredicate,
|
|
18
20
|
defaultAgentTasks,
|
|
@@ -20,6 +22,7 @@ import {
|
|
|
20
22
|
diffTreeNames,
|
|
21
23
|
discoverSkills,
|
|
22
24
|
estimateTokens,
|
|
25
|
+
formatAgentTaskUpdate,
|
|
23
26
|
formatTaskFinished,
|
|
24
27
|
formatTaskList,
|
|
25
28
|
formatTaskStarted,
|
|
@@ -41,7 +44,7 @@ import {
|
|
|
41
44
|
resolveSnapshotContent,
|
|
42
45
|
rewindToSnapshot,
|
|
43
46
|
summarizeMessages
|
|
44
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-K3R42LOX.js";
|
|
45
48
|
import {
|
|
46
49
|
envFilePath,
|
|
47
50
|
globalConfigPath,
|
|
@@ -598,113 +601,6 @@ async function savePermissionMode(mode) {
|
|
|
598
601
|
await writeFileAtomic(filePath, upsertTopLevelKeyText(content, "permissionMode", mode));
|
|
599
602
|
}
|
|
600
603
|
|
|
601
|
-
// src/config/schema.ts
|
|
602
|
-
import { z } from "zod";
|
|
603
|
-
var ProviderConfigSchema = z.object({
|
|
604
|
-
name: z.string(),
|
|
605
|
-
// openai-responses talks to the Responses API (/responses) instead of chat
|
|
606
|
-
// completions — the wire format codex uses, and the native API of
|
|
607
|
-
// reasoning-model relays that otherwise hide reasoning behind empty chat
|
|
608
|
-
// completions. streamChat sends strictSchemas:false + store:false with it.
|
|
609
|
-
protocol: z.enum(["openai-compatible", "anthropic", "openai-responses"]).default("openai-compatible"),
|
|
610
|
-
baseURL: z.string(),
|
|
611
|
-
apiKeyEnv: z.string().optional(),
|
|
612
|
-
apiKey: z.string().optional(),
|
|
613
|
-
headers: z.record(z.string()).optional()
|
|
614
|
-
});
|
|
615
|
-
var ModelConfigSchema = z.object({
|
|
616
|
-
name: z.string(),
|
|
617
|
-
provider: z.string(),
|
|
618
|
-
model: z.string(),
|
|
619
|
-
maxTokens: z.number().int().positive().optional(),
|
|
620
|
-
// Per-model context window; overrides the top-level contextMaxTokens for
|
|
621
|
-
// compaction and the status bar when set.
|
|
622
|
-
contextMaxTokens: z.number().int().positive().optional(),
|
|
623
|
-
// Cost estimation needs BOTH prices (USD per 1M tokens); with only one set
|
|
624
|
-
// the model is treated as unpriced.
|
|
625
|
-
promptPrice: z.number().nonnegative().optional(),
|
|
626
|
-
completionPrice: z.number().nonnegative().optional(),
|
|
627
|
-
// Optional price (USD per 1M tokens) for cache-read prompt tokens. When
|
|
628
|
-
// unset, OpenAI-style cached tokens bill at promptPrice and Anthropic-style
|
|
629
|
-
// cache reads are not billed — set this for accurate cache pricing.
|
|
630
|
-
cacheReadPrice: z.number().nonnegative().optional()
|
|
631
|
-
});
|
|
632
|
-
var PermissionsConfigSchema = z.object({
|
|
633
|
-
allow: z.array(z.string()).default([]),
|
|
634
|
-
deny: z.array(z.string()).default([])
|
|
635
|
-
});
|
|
636
|
-
var HookConfigSchema = z.object({
|
|
637
|
-
event: z.enum(["PreToolUse", "PostToolUse", "Stop"]),
|
|
638
|
-
matcher: z.string().refine(
|
|
639
|
-
(pattern) => {
|
|
640
|
-
try {
|
|
641
|
-
new RegExp(pattern);
|
|
642
|
-
return true;
|
|
643
|
-
} catch {
|
|
644
|
-
return false;
|
|
645
|
-
}
|
|
646
|
-
},
|
|
647
|
-
{ message: "invalid regular expression" }
|
|
648
|
-
).optional(),
|
|
649
|
-
command: z.string().min(1),
|
|
650
|
-
timeoutSec: z.number().positive().default(30)
|
|
651
|
-
});
|
|
652
|
-
var ConfigSchema = z.object({
|
|
653
|
-
defaultModel: z.string().default(""),
|
|
654
|
-
permissionMode: z.enum(["auto", "ask", "readonly", "yolo", "plan"]).default("ask"),
|
|
655
|
-
providers: z.array(ProviderConfigSchema).default([]),
|
|
656
|
-
models: z.array(ModelConfigSchema).default([]),
|
|
657
|
-
maxSteps: z.number().int().positive().default(50),
|
|
658
|
-
contextMaxTokens: z.number().int().positive().default(1e5),
|
|
659
|
-
// Seconds without any stream part before a stalled response is ended
|
|
660
|
-
// gracefully (some relays never send the terminal chunks). Applies once
|
|
661
|
-
// streaming has started; the first part gets a longer, fixed allowance.
|
|
662
|
-
streamIdleTimeoutSec: z.number().positive().default(20),
|
|
663
|
-
// Seconds to wait for the very first stream part before giving up; slow
|
|
664
|
-
// thinking-model relays can buffer for minutes before sending anything.
|
|
665
|
-
streamFirstChunkTimeoutSec: z.number().positive().default(300),
|
|
666
|
-
// Extra attempts per model request when a stream fails transiently
|
|
667
|
-
// (network error, 429/5xx, idle watchdog cutoff) or comes back empty, so a
|
|
668
|
-
// relay hiccup does not silently end a half-finished turn. 0 disables.
|
|
669
|
-
// The wait between attempts honors Retry-After headers and otherwise backs
|
|
670
|
-
// off exponentially with jitter (llm/retry.ts); retries after a
|
|
671
|
-
// timeout/empty failure also scale both stream timeouts up (attempt number
|
|
672
|
-
// ×, capped at 3x) since the relay is likely overloaded.
|
|
673
|
-
streamMaxRetries: z.number().int().min(0).default(3),
|
|
674
|
-
// How many consecutive unproductive replies may be nudged before the turn
|
|
675
|
-
// is handed back: a text-only reply that announces pending work ("我将…",
|
|
676
|
-
// "I will…") or answers a nudge with more words, or an empty reply that
|
|
677
|
-
// survived the stream retry budget (steered with a nudge — a changed
|
|
678
|
-
// request — since identical resends already failed). Tool calls reset the
|
|
679
|
-
// count, so a productive task keeps going; exhaustion surfaces a notice
|
|
680
|
-
// instead of stopping silently. Never fires in plan mode. 0 disables.
|
|
681
|
-
maxAutoContinues: z.number().int().min(0).default(2),
|
|
682
|
-
contextCompaction: z.enum(["summary", "truncate"]).default("summary"),
|
|
683
|
-
// Optional per-session dollar budget; when set, the REPL stops the session
|
|
684
|
-
// once the estimated cost for the session reaches this amount.
|
|
685
|
-
sessionBudgetUsd: z.number().positive().optional(),
|
|
686
|
-
// Terminal bell (REPL only): ring when a turn takes longer than
|
|
687
|
-
// notifyBellThresholdSec, and when a background task finishes.
|
|
688
|
-
// STAR_NO_NOTIFY=1 disables without touching the config.
|
|
689
|
-
notifyBell: z.boolean().default(true),
|
|
690
|
-
notifyBellThresholdSec: z.number().positive().default(10),
|
|
691
|
-
permissions: PermissionsConfigSchema.default({ allow: [], deny: [] }),
|
|
692
|
-
hooks: z.array(HookConfigSchema).default([]),
|
|
693
|
-
// Consecutive identical tool calls (same tool + same arguments) allowed
|
|
694
|
-
// before the loop refuses to execute the repeat and tells the model to
|
|
695
|
-
// change approach — a guard against agents stuck retrying a failing call
|
|
696
|
-
// (opencode's doom_loop). 0 disables.
|
|
697
|
-
doomLoopThreshold: z.number().int().min(0).default(3),
|
|
698
|
-
// Track the whole working tree with an internal git repo (outside the
|
|
699
|
-
// user's .git) at every turn boundary, so /undo and /redo can restore
|
|
700
|
-
// changes made by ANY tool (bash included), not just write_file/edit_file.
|
|
701
|
-
// Falls back silently to per-file snapshots when git is unavailable.
|
|
702
|
-
gitSnapshots: z.boolean().default(true)
|
|
703
|
-
});
|
|
704
|
-
function contextWindowTokens(config, modelName) {
|
|
705
|
-
return config.models.find((m) => m.name === modelName)?.contextMaxTokens ?? config.contextMaxTokens;
|
|
706
|
-
}
|
|
707
|
-
|
|
708
604
|
// src/llm/provider.ts
|
|
709
605
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
710
606
|
import { createOpenAI } from "@ai-sdk/openai";
|
|
@@ -1688,10 +1584,10 @@ async function compactSession(opts) {
|
|
|
1688
1584
|
};
|
|
1689
1585
|
}
|
|
1690
1586
|
const beforeTokens = estimateTokens(messages);
|
|
1691
|
-
const compacted = compactMessages(messages, config.contextMaxTokens);
|
|
1587
|
+
const compacted = compactMessages(messages, config.contextMaxTokens, { force: true });
|
|
1692
1588
|
if (!compacted.compacted) {
|
|
1693
1589
|
return {
|
|
1694
|
-
message: `Nothing to compact:
|
|
1590
|
+
message: `Nothing to compact: history is too short to drop a whole turn (~${beforeTokens} estimated tokens).`,
|
|
1695
1591
|
compacted: false
|
|
1696
1592
|
};
|
|
1697
1593
|
}
|
|
@@ -5003,11 +4899,7 @@ function Repl({
|
|
|
5003
4899
|
};
|
|
5004
4900
|
const onAgentUpdate = (task) => {
|
|
5005
4901
|
setBgLabels(runningTaskLabels());
|
|
5006
|
-
|
|
5007
|
-
pushMessage(
|
|
5008
|
-
"system",
|
|
5009
|
-
task.status === "running" ? `Background subagent ${task.id} started${label}` : `Background subagent ${task.id} ${task.status}${label}`
|
|
5010
|
-
);
|
|
4902
|
+
pushMessage("system", toTerminalSafe(formatAgentTaskUpdate(task)));
|
|
5011
4903
|
if (task.status !== "running") {
|
|
5012
4904
|
notifyBell({
|
|
5013
4905
|
enabled: configRef.current.notifyBell,
|
|
@@ -5638,18 +5530,26 @@ ${estimateCost(usageRef.current, modelNameRef.current, modelConfig)}`;
|
|
|
5638
5530
|
} catch {
|
|
5639
5531
|
summaryModel = null;
|
|
5640
5532
|
}
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5533
|
+
tickerStopRef.current = startTicker((tick) => setSpinnerTick(tick));
|
|
5534
|
+
setActivity("compacting context\u2026");
|
|
5535
|
+
try {
|
|
5536
|
+
const result = await compactSession({
|
|
5537
|
+
backend: backendRef.current,
|
|
5538
|
+
sessionStore: sessionStoreRef.current,
|
|
5539
|
+
config,
|
|
5540
|
+
model: summaryModel
|
|
5541
|
+
});
|
|
5542
|
+
if (result.compacted && result.messages) {
|
|
5543
|
+
const display = buildDisplayMessages(result.messages);
|
|
5544
|
+
nextIdRef.current = display.length;
|
|
5545
|
+
applyMessages(display);
|
|
5546
|
+
}
|
|
5547
|
+
return result.message;
|
|
5548
|
+
} finally {
|
|
5549
|
+
tickerStopRef.current?.();
|
|
5550
|
+
tickerStopRef.current = null;
|
|
5551
|
+
setActivity(null);
|
|
5651
5552
|
}
|
|
5652
|
-
return result.message;
|
|
5653
5553
|
},
|
|
5654
5554
|
exportSession: (arg) => exportSession({
|
|
5655
5555
|
backend: backendRef.current,
|
|
@@ -5821,6 +5721,7 @@ ${plan.affected.length} file change(s) will be reverted, ${messageCount} message
|
|
|
5821
5721
|
`models (${config.models.length}): ${config.models.map((m) => m.name).join(", ") || "(none)"}`,
|
|
5822
5722
|
`maxSteps: ${config.maxSteps}`,
|
|
5823
5723
|
`contextMaxTokens: ${config.contextMaxTokens}`,
|
|
5724
|
+
`compactThresholdTokens: ${config.compactThresholdTokens ?? "(context window)"}`,
|
|
5824
5725
|
`streamIdleTimeoutSec: ${config.streamIdleTimeoutSec}`,
|
|
5825
5726
|
`streamFirstChunkTimeoutSec: ${config.streamFirstChunkTimeoutSec}`,
|
|
5826
5727
|
`streamMaxRetries: ${config.streamMaxRetries}`,
|
|
@@ -6099,6 +6000,7 @@ var PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
|
6099
6000
|
"models",
|
|
6100
6001
|
"maxSteps",
|
|
6101
6002
|
"contextMaxTokens",
|
|
6003
|
+
"compactThresholdTokens",
|
|
6102
6004
|
"streamIdleTimeoutSec",
|
|
6103
6005
|
"streamFirstChunkTimeoutSec",
|
|
6104
6006
|
"streamMaxRetries",
|