@charzhu/openjaw-agent 0.2.5 → 0.2.7
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/main.js +1028 -320
- package/dist/main.js.map +4 -4
- package/package.json +1 -2
package/dist/main.js
CHANGED
|
@@ -123,6 +123,7 @@ function loadAgentConfig() {
|
|
|
123
123
|
temperature: parsedLlm?.temperature ?? DEFAULT_CONFIG.llm.temperature,
|
|
124
124
|
computer_use: parsedLlm?.computer_use ?? DEFAULT_CONFIG.llm.computer_use,
|
|
125
125
|
use_responses_api: parsedLlm?.use_responses_api ?? DEFAULT_CONFIG.llm.use_responses_api,
|
|
126
|
+
model_reasoning_effort: parsedLlm?.model_reasoning_effort,
|
|
126
127
|
openai_tool_mode: parsedLlm?.openai_tool_mode ?? DEFAULT_CONFIG.llm.openai_tool_mode,
|
|
127
128
|
openai_max_tools: parsedLlm?.openai_max_tools ?? DEFAULT_CONFIG.llm.openai_max_tools,
|
|
128
129
|
openai_mcp_max_tools: parsedLlm?.openai_mcp_max_tools,
|
|
@@ -1973,6 +1974,55 @@ var init_provider_auth = __esm({
|
|
|
1973
1974
|
}
|
|
1974
1975
|
});
|
|
1975
1976
|
|
|
1977
|
+
// src/providers/types.ts
|
|
1978
|
+
function isReasoningEffort(value) {
|
|
1979
|
+
return REASONING_EFFORTS.includes(value);
|
|
1980
|
+
}
|
|
1981
|
+
function reasoningEffortLabel(effort) {
|
|
1982
|
+
switch (effort) {
|
|
1983
|
+
case "none":
|
|
1984
|
+
return "None";
|
|
1985
|
+
case "minimal":
|
|
1986
|
+
return "Minimal";
|
|
1987
|
+
case "low":
|
|
1988
|
+
return "Low";
|
|
1989
|
+
case "medium":
|
|
1990
|
+
return "Medium";
|
|
1991
|
+
case "high":
|
|
1992
|
+
return "High";
|
|
1993
|
+
case "xhigh":
|
|
1994
|
+
return "Extra high";
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
function normalizeReasoningEfforts(values) {
|
|
1998
|
+
if (!Array.isArray(values)) return [];
|
|
1999
|
+
const efforts = [];
|
|
2000
|
+
for (const item of values) {
|
|
2001
|
+
if (typeof item !== "string" || !isReasoningEffort(item)) continue;
|
|
2002
|
+
if (!efforts.includes(item)) efforts.push(item);
|
|
2003
|
+
}
|
|
2004
|
+
return efforts;
|
|
2005
|
+
}
|
|
2006
|
+
function defaultReasoningEffort(efforts) {
|
|
2007
|
+
if (efforts.length === 0) return void 0;
|
|
2008
|
+
return efforts.includes("medium") ? "medium" : efforts[0];
|
|
2009
|
+
}
|
|
2010
|
+
function orderedReasoningEfforts(efforts) {
|
|
2011
|
+
return REASONING_EFFORTS.filter((effort) => efforts.includes(effort));
|
|
2012
|
+
}
|
|
2013
|
+
var REASONING_EFFORTS;
|
|
2014
|
+
var init_types = __esm({
|
|
2015
|
+
"src/providers/types.ts"() {
|
|
2016
|
+
"use strict";
|
|
2017
|
+
REASONING_EFFORTS = ["none", "minimal", "low", "medium", "high", "xhigh"];
|
|
2018
|
+
__name(isReasoningEffort, "isReasoningEffort");
|
|
2019
|
+
__name(reasoningEffortLabel, "reasoningEffortLabel");
|
|
2020
|
+
__name(normalizeReasoningEfforts, "normalizeReasoningEfforts");
|
|
2021
|
+
__name(defaultReasoningEffort, "defaultReasoningEffort");
|
|
2022
|
+
__name(orderedReasoningEfforts, "orderedReasoningEfforts");
|
|
2023
|
+
}
|
|
2024
|
+
});
|
|
2025
|
+
|
|
1976
2026
|
// src/providers/copilot.ts
|
|
1977
2027
|
function normalizeCopilotEnterpriseDomain(value) {
|
|
1978
2028
|
return value.replace(/^https?:\/\//, "").replace(/\/+$/, "");
|
|
@@ -2063,20 +2113,67 @@ function safeJsonParse(value) {
|
|
|
2063
2113
|
return {};
|
|
2064
2114
|
}
|
|
2065
2115
|
}
|
|
2066
|
-
function
|
|
2116
|
+
function valueAtPath(value, path3) {
|
|
2117
|
+
let current = value;
|
|
2118
|
+
for (const key of path3) {
|
|
2119
|
+
if (!current || typeof current !== "object" || Array.isArray(current)) return void 0;
|
|
2120
|
+
current = current[key];
|
|
2121
|
+
}
|
|
2122
|
+
return current;
|
|
2123
|
+
}
|
|
2124
|
+
function firstPositiveIntegerAtAny(value, paths2) {
|
|
2125
|
+
for (const path3 of paths2) {
|
|
2126
|
+
const candidate = valueAtPath(value, path3);
|
|
2127
|
+
if (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate <= 0) continue;
|
|
2128
|
+
return Math.trunc(candidate);
|
|
2129
|
+
}
|
|
2130
|
+
return void 0;
|
|
2131
|
+
}
|
|
2132
|
+
function readCopilotContextWindow(capabilities) {
|
|
2133
|
+
return firstPositiveIntegerAtAny(capabilities, [
|
|
2134
|
+
["limits", "max_context_window_tokens"],
|
|
2135
|
+
["limits", "maxContextWindowTokens"],
|
|
2136
|
+
["limits", "max_prompt_tokens"],
|
|
2137
|
+
["max_context_window_tokens"],
|
|
2138
|
+
["maxContextWindowTokens"],
|
|
2139
|
+
["context_window"],
|
|
2140
|
+
["contextWindow"]
|
|
2141
|
+
]);
|
|
2142
|
+
}
|
|
2143
|
+
function readCopilotOutputTokens(capabilities) {
|
|
2144
|
+
return firstPositiveIntegerAtAny(capabilities, [
|
|
2145
|
+
["limits", "max_output_tokens"],
|
|
2146
|
+
["limits", "maxOutputTokens"],
|
|
2147
|
+
["max_output_tokens"],
|
|
2148
|
+
["maxOutputTokens"]
|
|
2149
|
+
]);
|
|
2150
|
+
}
|
|
2151
|
+
function readCopilotReasoningEfforts(capabilities) {
|
|
2152
|
+
return normalizeReasoningEfforts(valueAtPath(capabilities, ["supports", "reasoning_effort"]));
|
|
2153
|
+
}
|
|
2154
|
+
function buildReasoning(effort, modelInfo) {
|
|
2155
|
+
const supported = modelInfo?.supportedReasoningEfforts?.map((option) => option.effort) ?? [];
|
|
2156
|
+
const selected = effort && supported.includes(effort) ? effort : void 0;
|
|
2157
|
+
const effective = selected ?? modelInfo?.defaultReasoningEffort;
|
|
2158
|
+
return effective ? { effort: effective } : void 0;
|
|
2159
|
+
}
|
|
2160
|
+
function parseCopilotModels(body) {
|
|
2067
2161
|
const items = Array.isArray(body.data) ? body.data : [];
|
|
2068
2162
|
const models = [];
|
|
2069
2163
|
for (const item of items) {
|
|
2070
2164
|
if (!item.id || item.model_picker_enabled === false || item.policy?.state === "disabled") continue;
|
|
2071
2165
|
const visionMedia = item.capabilities?.limits?.vision?.supported_media_types ?? [];
|
|
2166
|
+
const supportedReasoning = readCopilotReasoningEfforts(item.capabilities);
|
|
2072
2167
|
models.push({
|
|
2073
2168
|
id: item.id,
|
|
2074
2169
|
name: item.name,
|
|
2075
2170
|
supportedEndpoints: item.supported_endpoints ?? [],
|
|
2076
2171
|
supportsVision: item.capabilities?.supports?.vision === true || visionMedia.some((media) => media.startsWith("image/")),
|
|
2077
2172
|
supportsToolCalls: item.capabilities?.supports?.tool_calls !== false,
|
|
2078
|
-
contextWindow: item.capabilities
|
|
2079
|
-
outputTokens: item.capabilities
|
|
2173
|
+
contextWindow: readCopilotContextWindow(item.capabilities),
|
|
2174
|
+
outputTokens: readCopilotOutputTokens(item.capabilities),
|
|
2175
|
+
supportedReasoningEfforts: supportedReasoning.map((effort) => ({ effort, description: effort })),
|
|
2176
|
+
defaultReasoningEffort: defaultReasoningEffort(supportedReasoning)
|
|
2080
2177
|
});
|
|
2081
2178
|
}
|
|
2082
2179
|
return models;
|
|
@@ -2086,6 +2183,7 @@ var init_copilot = __esm({
|
|
|
2086
2183
|
"src/providers/copilot.ts"() {
|
|
2087
2184
|
"use strict";
|
|
2088
2185
|
init_provider_auth();
|
|
2186
|
+
init_types();
|
|
2089
2187
|
COPILOT_PROVIDER = "github-copilot";
|
|
2090
2188
|
USER_AGENT = "openjaw-agent/0.1.0";
|
|
2091
2189
|
OPENAI_TOOL_NAME2 = /^[A-Za-z0-9_-]{1,64}$/;
|
|
@@ -2100,7 +2198,13 @@ var init_copilot = __esm({
|
|
|
2100
2198
|
__name(hasImageContent, "hasImageContent");
|
|
2101
2199
|
__name(openAIUserContent, "openAIUserContent");
|
|
2102
2200
|
__name(safeJsonParse, "safeJsonParse");
|
|
2103
|
-
__name(
|
|
2201
|
+
__name(valueAtPath, "valueAtPath");
|
|
2202
|
+
__name(firstPositiveIntegerAtAny, "firstPositiveIntegerAtAny");
|
|
2203
|
+
__name(readCopilotContextWindow, "readCopilotContextWindow");
|
|
2204
|
+
__name(readCopilotOutputTokens, "readCopilotOutputTokens");
|
|
2205
|
+
__name(readCopilotReasoningEfforts, "readCopilotReasoningEfforts");
|
|
2206
|
+
__name(buildReasoning, "buildReasoning");
|
|
2207
|
+
__name(parseCopilotModels, "parseCopilotModels");
|
|
2104
2208
|
CopilotProvider = class {
|
|
2105
2209
|
static {
|
|
2106
2210
|
__name(this, "CopilotProvider");
|
|
@@ -2113,7 +2217,14 @@ var init_copilot = __esm({
|
|
|
2113
2217
|
}
|
|
2114
2218
|
async listModels() {
|
|
2115
2219
|
const models = await this.fetchModelInfo();
|
|
2116
|
-
return models.map((model) => ({
|
|
2220
|
+
return models.map((model) => ({
|
|
2221
|
+
id: model.id,
|
|
2222
|
+
name: model.name ?? model.id,
|
|
2223
|
+
contextWindow: model.contextWindow,
|
|
2224
|
+
outputTokens: model.outputTokens,
|
|
2225
|
+
supportedReasoningEfforts: model.supportedReasoningEfforts,
|
|
2226
|
+
defaultReasoningEffort: model.defaultReasoningEffort
|
|
2227
|
+
}));
|
|
2117
2228
|
}
|
|
2118
2229
|
async chat(options) {
|
|
2119
2230
|
const modelInfo = await this.resolveModelInfo(this.config.model);
|
|
@@ -2121,7 +2232,7 @@ var init_copilot = __esm({
|
|
|
2121
2232
|
return this.chatAnthropicMessages(options);
|
|
2122
2233
|
}
|
|
2123
2234
|
if (this.shouldRouteToResponses(modelInfo)) {
|
|
2124
|
-
return this.chatResponses(options);
|
|
2235
|
+
return this.chatResponses(options, modelInfo);
|
|
2125
2236
|
}
|
|
2126
2237
|
return this.chatCompletions(options);
|
|
2127
2238
|
}
|
|
@@ -2178,7 +2289,7 @@ var init_copilot = __esm({
|
|
|
2178
2289
|
throw new Error(`GitHub Copilot models error: ${res.status}${detail ? ` ${detail.slice(0, 160)}` : ""}`);
|
|
2179
2290
|
}
|
|
2180
2291
|
const parsed = await res.json();
|
|
2181
|
-
const models =
|
|
2292
|
+
const models = parseCopilotModels(parsed);
|
|
2182
2293
|
this.modelCache = new Map(models.map((model) => [model.id, model]));
|
|
2183
2294
|
return models;
|
|
2184
2295
|
}
|
|
@@ -2294,12 +2405,14 @@ var init_copilot = __esm({
|
|
|
2294
2405
|
}
|
|
2295
2406
|
return input;
|
|
2296
2407
|
}
|
|
2297
|
-
async chatResponses(options) {
|
|
2408
|
+
async chatResponses(options, modelInfo) {
|
|
2409
|
+
const reasoning = buildReasoning(options.reasoningEffort, modelInfo);
|
|
2298
2410
|
const requestBody = {
|
|
2299
2411
|
model: this.config.model,
|
|
2300
2412
|
input: this.buildResponsesInput(options),
|
|
2301
2413
|
instructions: Array.isArray(options.systemPrompt) ? options.systemPrompt.map((block) => block.text).join("\n\n") : options.systemPrompt,
|
|
2302
|
-
tools: options.tools.length > 0 ? options.tools.map(toResponsesTool) : void 0
|
|
2414
|
+
tools: options.tools.length > 0 ? options.tools.map(toResponsesTool) : void 0,
|
|
2415
|
+
...reasoning && { reasoning, include: ["reasoning.encrypted_content"] }
|
|
2303
2416
|
};
|
|
2304
2417
|
const res = await fetch(`${this.baseUrl()}/responses`, {
|
|
2305
2418
|
method: "POST",
|
|
@@ -2690,8 +2803,45 @@ var init_cost_tracker = __esm({
|
|
|
2690
2803
|
}
|
|
2691
2804
|
});
|
|
2692
2805
|
|
|
2806
|
+
// src/domain/usage.ts
|
|
2807
|
+
var ZERO, contextPercent, formatContextPercent;
|
|
2808
|
+
var init_usage = __esm({
|
|
2809
|
+
"src/domain/usage.ts"() {
|
|
2810
|
+
"use strict";
|
|
2811
|
+
ZERO = { calls: 0, input: 0, output: 0, total: 0 };
|
|
2812
|
+
contextPercent = /* @__PURE__ */ __name((used, max) => {
|
|
2813
|
+
if (!Number.isFinite(used) || !Number.isFinite(max) || used <= 0 || max <= 0) {
|
|
2814
|
+
return 0;
|
|
2815
|
+
}
|
|
2816
|
+
const raw = used / max * 100;
|
|
2817
|
+
return raw < 10 ? Math.round(raw * 10) / 10 : Math.round(raw);
|
|
2818
|
+
}, "contextPercent");
|
|
2819
|
+
formatContextPercent = /* @__PURE__ */ __name((pct) => {
|
|
2820
|
+
if (pct == null || !Number.isFinite(pct) || pct <= 0) {
|
|
2821
|
+
return "0%";
|
|
2822
|
+
}
|
|
2823
|
+
if (pct < 0.1) {
|
|
2824
|
+
return "<0.1%";
|
|
2825
|
+
}
|
|
2826
|
+
if (pct < 10) {
|
|
2827
|
+
return `${pct.toFixed(1).replace(/\.0$/, "")}%`;
|
|
2828
|
+
}
|
|
2829
|
+
return `${Math.round(pct)}%`;
|
|
2830
|
+
}, "formatContextPercent");
|
|
2831
|
+
}
|
|
2832
|
+
});
|
|
2833
|
+
|
|
2693
2834
|
// src/context-manager.ts
|
|
2694
|
-
function
|
|
2835
|
+
function contextKey(provider, model) {
|
|
2836
|
+
return `${provider}\0${model}`;
|
|
2837
|
+
}
|
|
2838
|
+
function normalizeContextWindow(value) {
|
|
2839
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return void 0;
|
|
2840
|
+
return Math.trunc(value);
|
|
2841
|
+
}
|
|
2842
|
+
function getContextWindow(model, metadata) {
|
|
2843
|
+
const liveContextWindow = normalizeContextWindow(metadata?.contextWindow);
|
|
2844
|
+
if (liveContextWindow !== void 0) return liveContextWindow;
|
|
2695
2845
|
if (CONTEXT_WINDOWS[model]) return CONTEXT_WINDOWS[model];
|
|
2696
2846
|
for (const [key, size] of Object.entries(CONTEXT_WINDOWS)) {
|
|
2697
2847
|
if (model.startsWith(key)) return size;
|
|
@@ -2702,6 +2852,7 @@ var CONTEXT_WINDOWS, DEFAULT_CONTEXT_WINDOW, ContextManager;
|
|
|
2702
2852
|
var init_context_manager = __esm({
|
|
2703
2853
|
"src/context-manager.ts"() {
|
|
2704
2854
|
"use strict";
|
|
2855
|
+
init_usage();
|
|
2705
2856
|
CONTEXT_WINDOWS = {
|
|
2706
2857
|
"claude-sonnet-4": 2e5,
|
|
2707
2858
|
"claude-sonnet-4.5": 2e5,
|
|
@@ -2716,13 +2867,46 @@ var init_context_manager = __esm({
|
|
|
2716
2867
|
"gpt-4o": 128e3
|
|
2717
2868
|
};
|
|
2718
2869
|
DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
2870
|
+
__name(contextKey, "contextKey");
|
|
2871
|
+
__name(normalizeContextWindow, "normalizeContextWindow");
|
|
2719
2872
|
__name(getContextWindow, "getContextWindow");
|
|
2720
2873
|
ContextManager = class {
|
|
2721
2874
|
static {
|
|
2722
2875
|
__name(this, "ContextManager");
|
|
2723
2876
|
}
|
|
2724
2877
|
lastTotalTokens = 0;
|
|
2725
|
-
|
|
2878
|
+
activeProvider = null;
|
|
2879
|
+
liveModelContextWindows = /* @__PURE__ */ new Map();
|
|
2880
|
+
setActiveProvider(provider) {
|
|
2881
|
+
this.activeProvider = provider;
|
|
2882
|
+
}
|
|
2883
|
+
setProviderModelMetadata(provider, models) {
|
|
2884
|
+
const prefix = `${provider}\0`;
|
|
2885
|
+
for (const key of [...this.liveModelContextWindows.keys()]) {
|
|
2886
|
+
if (key.startsWith(prefix)) this.liveModelContextWindows.delete(key);
|
|
2887
|
+
}
|
|
2888
|
+
for (const model of models ?? []) {
|
|
2889
|
+
const contextWindow = normalizeContextWindow(model.contextWindow);
|
|
2890
|
+
if (contextWindow !== void 0) {
|
|
2891
|
+
this.liveModelContextWindows.set(contextKey(provider, model.id), contextWindow);
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
clearProviderModelMetadata(provider) {
|
|
2896
|
+
if (!provider) {
|
|
2897
|
+
this.liveModelContextWindows.clear();
|
|
2898
|
+
return;
|
|
2899
|
+
}
|
|
2900
|
+
const prefix = `${provider}\0`;
|
|
2901
|
+
for (const key of [...this.liveModelContextWindows.keys()]) {
|
|
2902
|
+
if (key.startsWith(prefix)) this.liveModelContextWindows.delete(key);
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
getContextWindow(model) {
|
|
2906
|
+
const liveContextWindow = this.activeProvider ? this.liveModelContextWindows.get(contextKey(this.activeProvider, model)) : void 0;
|
|
2907
|
+
return getContextWindow(model, { contextWindow: liveContextWindow });
|
|
2908
|
+
}
|
|
2909
|
+
/** Update latest effective context footprint from actual API response usage. */
|
|
2726
2910
|
updateFromUsage(usage2) {
|
|
2727
2911
|
this.lastTotalTokens = usage2.inputTokens + usage2.outputTokens + usage2.cacheReadTokens + usage2.cacheCreationTokens;
|
|
2728
2912
|
}
|
|
@@ -2733,7 +2917,7 @@ var init_context_manager = __esm({
|
|
|
2733
2917
|
/** Get warning level based on model context window */
|
|
2734
2918
|
getWarningLevel(model, newContentChars = 0) {
|
|
2735
2919
|
const estimated = this.getEstimatedTokens(newContentChars);
|
|
2736
|
-
const limit = getContextWindow(model);
|
|
2920
|
+
const limit = this.getContextWindow(model);
|
|
2737
2921
|
const ratio = estimated / limit;
|
|
2738
2922
|
if (ratio > 0.95) return "critical";
|
|
2739
2923
|
if (ratio > 0.85) return "warning";
|
|
@@ -2741,12 +2925,12 @@ var init_context_manager = __esm({
|
|
|
2741
2925
|
}
|
|
2742
2926
|
/** Get context usage as percentage */
|
|
2743
2927
|
getUsagePercent(model) {
|
|
2744
|
-
const limit = getContextWindow(model);
|
|
2745
|
-
return
|
|
2928
|
+
const limit = this.getContextWindow(model);
|
|
2929
|
+
return contextPercent(this.lastTotalTokens, limit);
|
|
2746
2930
|
}
|
|
2747
2931
|
/** Format context display string */
|
|
2748
2932
|
formatContext(model) {
|
|
2749
|
-
const limit = getContextWindow(model);
|
|
2933
|
+
const limit = this.getContextWindow(model);
|
|
2750
2934
|
const fmt2 = /* @__PURE__ */ __name((n) => n >= 1e3 ? `${(n / 1e3).toFixed(0)}K` : String(n), "fmt");
|
|
2751
2935
|
const pct = this.getUsagePercent(model);
|
|
2752
2936
|
return `${fmt2(this.lastTotalTokens)}/${fmt2(limit)} (${pct}%)`;
|
|
@@ -3096,7 +3280,6 @@ var init_context_compressor = __esm({
|
|
|
3096
3280
|
"src/context-compressor.ts"() {
|
|
3097
3281
|
"use strict";
|
|
3098
3282
|
init_providers();
|
|
3099
|
-
init_context_manager();
|
|
3100
3283
|
DEFAULT_COMPRESSION_THRESHOLD = 0.7;
|
|
3101
3284
|
PROTECTED_HEAD = 3;
|
|
3102
3285
|
PROTECTED_TAIL_TOKENS = 2e4;
|
|
@@ -3188,7 +3371,7 @@ Rules:
|
|
|
3188
3371
|
shouldCompress(threshold) {
|
|
3189
3372
|
const t = threshold ?? this.config.llm.compression_threshold ?? DEFAULT_COMPRESSION_THRESHOLD;
|
|
3190
3373
|
const model = this.config.llm.model;
|
|
3191
|
-
const limit = getContextWindow(model);
|
|
3374
|
+
const limit = this.contextManager.getContextWindow(model);
|
|
3192
3375
|
const current = this.contextManager.getEstimatedTokens();
|
|
3193
3376
|
const ratio = current / limit;
|
|
3194
3377
|
if (ratio < t) return false;
|
|
@@ -3281,7 +3464,7 @@ ${summary}
|
|
|
3281
3464
|
async _summarize(middle, _systemPrompt) {
|
|
3282
3465
|
const auxProvider = this._getAuxProvider();
|
|
3283
3466
|
const middleText = buildMiddleText(middle);
|
|
3284
|
-
const contextWindow = getContextWindow(this.config.llm.model);
|
|
3467
|
+
const contextWindow = this.contextManager.getContextWindow(this.config.llm.model);
|
|
3285
3468
|
const targetTokens = Math.max(
|
|
3286
3469
|
SUMMARY_MIN_TOKENS,
|
|
3287
3470
|
Math.min(SUMMARY_MAX_TOKENS, Math.floor(contextWindow * SUMMARY_PCT))
|
|
@@ -4129,6 +4312,7 @@ var init_agent_loop = __esm({
|
|
|
4129
4312
|
cacheMonitor;
|
|
4130
4313
|
telemetry;
|
|
4131
4314
|
contextCompressor;
|
|
4315
|
+
liveModelMetadata = /* @__PURE__ */ new Map();
|
|
4132
4316
|
_compactedOnResume = false;
|
|
4133
4317
|
_toolRoundsInRun = 0;
|
|
4134
4318
|
_skillSuggested = false;
|
|
@@ -4146,6 +4330,7 @@ var init_agent_loop = __esm({
|
|
|
4146
4330
|
this.provider = createProvider(config);
|
|
4147
4331
|
this.costTracker = new CostTracker();
|
|
4148
4332
|
this.contextManager = new ContextManager();
|
|
4333
|
+
this.contextManager.setActiveProvider(config.llm.provider);
|
|
4149
4334
|
this.cacheMonitor = new CacheMonitor();
|
|
4150
4335
|
this.telemetry = new Telemetry("pending");
|
|
4151
4336
|
if (resumeSessionId) {
|
|
@@ -4162,6 +4347,7 @@ var init_agent_loop = __esm({
|
|
|
4162
4347
|
this.telemetry = new Telemetry(this.session.id);
|
|
4163
4348
|
this.telemetry.recordSessionStart(config.llm.model, config.llm.provider);
|
|
4164
4349
|
this.contextCompressor = new ContextCompressor(config, this.contextManager, this.telemetry);
|
|
4350
|
+
void this.refreshActiveModelMetadata();
|
|
4165
4351
|
}
|
|
4166
4352
|
get tools() {
|
|
4167
4353
|
return this.toolRegistry;
|
|
@@ -4191,6 +4377,9 @@ var init_agent_loop = __esm({
|
|
|
4191
4377
|
}
|
|
4192
4378
|
return this.config.llm.provider;
|
|
4193
4379
|
}
|
|
4380
|
+
get reasoningEffort() {
|
|
4381
|
+
return this.config.llm.model_reasoning_effort;
|
|
4382
|
+
}
|
|
4194
4383
|
/**
|
|
4195
4384
|
* Provide the user's response to an ask_user question.
|
|
4196
4385
|
* Called by Chat.tsx or bridges when the user answers.
|
|
@@ -4208,7 +4397,7 @@ var init_agent_loop = __esm({
|
|
|
4208
4397
|
return this._waitingForAskUserFlag;
|
|
4209
4398
|
}
|
|
4210
4399
|
/** Switch provider and/or model at runtime */
|
|
4211
|
-
switchModel(provider, model) {
|
|
4400
|
+
switchModel(provider, model, reasoningEffort) {
|
|
4212
4401
|
let baseUrl = this.config.llm.base_url;
|
|
4213
4402
|
if (baseUrl) {
|
|
4214
4403
|
if (provider === "openai" && baseUrl.includes("/api/anthropic")) {
|
|
@@ -4223,14 +4412,26 @@ var init_agent_loop = __esm({
|
|
|
4223
4412
|
}
|
|
4224
4413
|
this.config = {
|
|
4225
4414
|
...this.config,
|
|
4226
|
-
llm: { ...this.config.llm, provider, model, base_url: baseUrl }
|
|
4415
|
+
llm: { ...this.config.llm, provider, model, base_url: baseUrl, model_reasoning_effort: reasoningEffort }
|
|
4227
4416
|
};
|
|
4228
4417
|
this.provider = createProvider(this.config);
|
|
4418
|
+
this.contextManager.setActiveProvider(provider);
|
|
4229
4419
|
this._toolExposureState = createToolExposureState();
|
|
4230
4420
|
this.session.provider = provider;
|
|
4231
4421
|
this.session.model = model;
|
|
4232
4422
|
saveSession(this.session);
|
|
4233
4423
|
saveAgentConfig(this.config);
|
|
4424
|
+
void this.refreshActiveModelMetadata();
|
|
4425
|
+
}
|
|
4426
|
+
updateReasoningEffort(reasoningEffort) {
|
|
4427
|
+
this.config = {
|
|
4428
|
+
...this.config,
|
|
4429
|
+
llm: { ...this.config.llm, model_reasoning_effort: reasoningEffort }
|
|
4430
|
+
};
|
|
4431
|
+
this.session.provider = this.config.llm.provider;
|
|
4432
|
+
this.session.model = this.config.llm.model;
|
|
4433
|
+
saveSession(this.session);
|
|
4434
|
+
saveAgentConfig(this.config);
|
|
4234
4435
|
}
|
|
4235
4436
|
/** Apply provider config changes that are not expressible as a model-only switch. */
|
|
4236
4437
|
updateProviderConfig(updates) {
|
|
@@ -4239,15 +4440,53 @@ var init_agent_loop = __esm({
|
|
|
4239
4440
|
llm: { ...this.config.llm, ...updates }
|
|
4240
4441
|
};
|
|
4241
4442
|
this.provider = createProvider(this.config);
|
|
4443
|
+
this.contextManager.setActiveProvider(this.config.llm.provider);
|
|
4242
4444
|
this._toolExposureState = createToolExposureState();
|
|
4243
4445
|
this.session.provider = this.config.llm.provider;
|
|
4244
4446
|
this.session.model = this.config.llm.model;
|
|
4245
4447
|
saveSession(this.session);
|
|
4246
4448
|
saveAgentConfig(this.config);
|
|
4449
|
+
void this.refreshActiveModelMetadata();
|
|
4247
4450
|
}
|
|
4248
4451
|
/** List available models from the current provider's API */
|
|
4249
4452
|
async listModels() {
|
|
4250
|
-
|
|
4453
|
+
const models = await this.provider.listModels?.() ?? null;
|
|
4454
|
+
if (models) this.setProviderModelMetadata(this.config.llm.provider, models);
|
|
4455
|
+
return models;
|
|
4456
|
+
}
|
|
4457
|
+
setProviderModelMetadata(provider, models) {
|
|
4458
|
+
const prefix = `${provider}\0`;
|
|
4459
|
+
for (const key of [...this.liveModelMetadata.keys()]) {
|
|
4460
|
+
if (key.startsWith(prefix)) this.liveModelMetadata.delete(key);
|
|
4461
|
+
}
|
|
4462
|
+
for (const model of models ?? []) {
|
|
4463
|
+
this.liveModelMetadata.set(`${provider}\0${model.id}`, model);
|
|
4464
|
+
}
|
|
4465
|
+
this.contextManager.setProviderModelMetadata(provider, models);
|
|
4466
|
+
}
|
|
4467
|
+
getActiveModelMetadata(model = this.config.llm.model) {
|
|
4468
|
+
return this.getModelMetadata(this.config.llm.provider, model);
|
|
4469
|
+
}
|
|
4470
|
+
getModelMetadata(provider, model) {
|
|
4471
|
+
return this.liveModelMetadata.get(`${provider}\0${model}`);
|
|
4472
|
+
}
|
|
4473
|
+
async refreshActiveModelMetadata() {
|
|
4474
|
+
const providerName = this.config.llm.provider;
|
|
4475
|
+
const provider = this.provider;
|
|
4476
|
+
this.contextManager.setActiveProvider(providerName);
|
|
4477
|
+
if (providerName !== "github-copilot") return;
|
|
4478
|
+
try {
|
|
4479
|
+
const models = await provider.listModels?.() ?? null;
|
|
4480
|
+
if (models) {
|
|
4481
|
+
this.setProviderModelMetadata(providerName, models);
|
|
4482
|
+
} else {
|
|
4483
|
+
this.setProviderModelMetadata(providerName, null);
|
|
4484
|
+
this.contextManager.clearProviderModelMetadata(providerName);
|
|
4485
|
+
}
|
|
4486
|
+
} catch {
|
|
4487
|
+
this.setProviderModelMetadata(providerName, null);
|
|
4488
|
+
this.contextManager.clearProviderModelMetadata(providerName);
|
|
4489
|
+
}
|
|
4251
4490
|
}
|
|
4252
4491
|
async listAllModels() {
|
|
4253
4492
|
const { STATIC_MODELS: STATIC_MODELS2 } = await Promise.resolve().then(() => (init_models_static(), models_static_exports));
|
|
@@ -4278,13 +4517,16 @@ var init_agent_loop = __esm({
|
|
|
4278
4517
|
const seen = /* @__PURE__ */ new Set();
|
|
4279
4518
|
if (live && live.length > 0) {
|
|
4280
4519
|
sources[currentProvider] = { source: "live" };
|
|
4520
|
+
this.setProviderModelMetadata(currentProvider, live);
|
|
4281
4521
|
for (const m of live) {
|
|
4282
4522
|
if (seen.has(m.id)) continue;
|
|
4283
4523
|
seen.add(m.id);
|
|
4284
|
-
models.push({ provider: currentProvider, id: m.id, name: m.name, source: "live" });
|
|
4524
|
+
models.push({ provider: currentProvider, id: m.id, name: m.name, contextWindow: m.contextWindow, outputTokens: m.outputTokens, source: "live" });
|
|
4285
4525
|
}
|
|
4286
4526
|
} else {
|
|
4287
4527
|
sources[currentProvider] = { source: "static", error: lastError };
|
|
4528
|
+
this.setProviderModelMetadata(currentProvider, null);
|
|
4529
|
+
this.contextManager.clearProviderModelMetadata(currentProvider);
|
|
4288
4530
|
for (const m of STATIC_MODELS2[currentProvider]) {
|
|
4289
4531
|
if (seen.has(m.id)) continue;
|
|
4290
4532
|
seen.add(m.id);
|
|
@@ -4328,13 +4570,16 @@ var init_agent_loop = __esm({
|
|
|
4328
4570
|
const seen = new Set(models.filter((m) => m.provider === provider && !m.group).map((m) => m.id));
|
|
4329
4571
|
if (live && live.length > 0) {
|
|
4330
4572
|
sources[provider] = { source: "live" };
|
|
4573
|
+
this.setProviderModelMetadata(provider, live);
|
|
4331
4574
|
for (const m of live) {
|
|
4332
4575
|
if (seen.has(m.id)) continue;
|
|
4333
4576
|
seen.add(m.id);
|
|
4334
|
-
models.push({ provider, id: m.id, name: m.name, source: "live" });
|
|
4577
|
+
models.push({ provider, id: m.id, name: m.name, contextWindow: m.contextWindow, outputTokens: m.outputTokens, source: "live" });
|
|
4335
4578
|
}
|
|
4336
4579
|
} else {
|
|
4337
4580
|
sources[provider] = { source: "static", error: lastError };
|
|
4581
|
+
this.setProviderModelMetadata(provider, null);
|
|
4582
|
+
this.contextManager.clearProviderModelMetadata(provider);
|
|
4338
4583
|
for (const m of STATIC_MODELS2[provider]) {
|
|
4339
4584
|
if (seen.has(m.id)) continue;
|
|
4340
4585
|
seen.add(m.id);
|
|
@@ -4592,6 +4837,7 @@ ${summary}
|
|
|
4592
4837
|
messages,
|
|
4593
4838
|
tools,
|
|
4594
4839
|
signal,
|
|
4840
|
+
reasoningEffort: this.config.llm.model_reasoning_effort,
|
|
4595
4841
|
debug: {
|
|
4596
4842
|
toolMode: exposure.mode,
|
|
4597
4843
|
fullToolCount: exposure.fullToolCount,
|
|
@@ -8760,9 +9006,9 @@ var init_outlook_graph = __esm({
|
|
|
8760
9006
|
const wellKnown = WELL_KNOWN_FOLDERS[lower];
|
|
8761
9007
|
if (wellKnown)
|
|
8762
9008
|
return wellKnown;
|
|
8763
|
-
const
|
|
8764
|
-
if (
|
|
8765
|
-
return
|
|
9009
|
+
const cached7 = this.folderIdCache.get(lower);
|
|
9010
|
+
if (cached7)
|
|
9011
|
+
return cached7;
|
|
8766
9012
|
try {
|
|
8767
9013
|
const result = await this.graphGet(`/me/mailFolders?$filter=displayName eq '${folderName.replace(/'/g, "''")}'&$top=1`);
|
|
8768
9014
|
if (result.value.length > 0) {
|
|
@@ -9120,9 +9366,9 @@ var init_db = __esm({
|
|
|
9120
9366
|
import { createHash as createHash2 } from "node:crypto";
|
|
9121
9367
|
function encodeAtom(word, dim2 = HRR_DIM) {
|
|
9122
9368
|
const cacheKey = `${word}:${dim2}`;
|
|
9123
|
-
const
|
|
9124
|
-
if (
|
|
9125
|
-
return
|
|
9369
|
+
const cached7 = atomCache.get(cacheKey);
|
|
9370
|
+
if (cached7)
|
|
9371
|
+
return cached7;
|
|
9126
9372
|
const phases = new Float64Array(dim2);
|
|
9127
9373
|
const bytesNeeded = dim2 * 4;
|
|
9128
9374
|
const chunks = [];
|
|
@@ -12338,9 +12584,9 @@ ${loopContent}` : loopContent;
|
|
|
12338
12584
|
*/
|
|
12339
12585
|
async findChannelByName(searchTerm) {
|
|
12340
12586
|
const searchLower = searchTerm.toLowerCase();
|
|
12341
|
-
const
|
|
12342
|
-
if (
|
|
12343
|
-
return { ...
|
|
12587
|
+
const cached7 = this.channelIdCache.get(searchLower);
|
|
12588
|
+
if (cached7) {
|
|
12589
|
+
return { ...cached7, displayName: searchTerm };
|
|
12344
12590
|
}
|
|
12345
12591
|
try {
|
|
12346
12592
|
const teamsData = await this.graphGet("/v1.0/me/joinedTeams");
|
|
@@ -12520,9 +12766,9 @@ ${loopContent}` : loopContent;
|
|
|
12520
12766
|
* Results are cached per chat ID.
|
|
12521
12767
|
*/
|
|
12522
12768
|
async getChatMembers(chatOrChannelId) {
|
|
12523
|
-
const
|
|
12524
|
-
if (
|
|
12525
|
-
return
|
|
12769
|
+
const cached7 = this.chatMembersCache.get(chatOrChannelId);
|
|
12770
|
+
if (cached7)
|
|
12771
|
+
return cached7;
|
|
12526
12772
|
try {
|
|
12527
12773
|
let endpoint;
|
|
12528
12774
|
if (this.contextType === "channel" && this.currentChannelTeamId && chatOrChannelId === this.currentChannelId) {
|
|
@@ -12760,9 +13006,9 @@ ${loopContent}` : loopContent;
|
|
|
12760
13006
|
*/
|
|
12761
13007
|
async resolveChannelIds(teamName, channelName) {
|
|
12762
13008
|
const cacheKey = `${teamName}/${channelName}`;
|
|
12763
|
-
const
|
|
12764
|
-
if (
|
|
12765
|
-
return
|
|
13009
|
+
const cached7 = this.channelIdCache.get(cacheKey);
|
|
13010
|
+
if (cached7)
|
|
13011
|
+
return cached7;
|
|
12766
13012
|
const teamsData = await this.graphGet("/v1.0/me/joinedTeams");
|
|
12767
13013
|
const team = teamsData.value?.find((t) => t.displayName.toLowerCase() === teamName.toLowerCase());
|
|
12768
13014
|
if (!team) {
|
|
@@ -19754,38 +20000,64 @@ var init_frontmatter = __esm({
|
|
|
19754
20000
|
});
|
|
19755
20001
|
|
|
19756
20002
|
// src/skills/registry.ts
|
|
19757
|
-
import { existsSync as existsSync14, readFileSync as readFileSync14, readdirSync as readdirSync2 } from "node:fs";
|
|
20003
|
+
import { existsSync as existsSync14, readFileSync as readFileSync14, readdirSync as readdirSync2, statSync } from "node:fs";
|
|
19758
20004
|
import { join as join22 } from "node:path";
|
|
19759
20005
|
import { homedir as homedir12 } from "node:os";
|
|
20006
|
+
function skillRoots() {
|
|
20007
|
+
return rootsOverride ?? { bundledDir: packageSkillsDir(), userDir: DEFAULT_USER_DIR };
|
|
20008
|
+
}
|
|
19760
20009
|
function discoverSkills() {
|
|
19761
|
-
|
|
20010
|
+
const signature = buildRegistrySignature();
|
|
20011
|
+
if (cachedSkills?.signature === signature) return cachedSkills.skills;
|
|
20012
|
+
const roots = skillRoots();
|
|
19762
20013
|
const byName2 = /* @__PURE__ */ new Map();
|
|
19763
|
-
|
|
19764
|
-
|
|
19765
|
-
|
|
19766
|
-
|
|
20014
|
+
loadFlatSkillsFromDir(roots.bundledDir, "bundled", 0, byName2);
|
|
20015
|
+
loadFlatSkillsFromDir(roots.userDir, "user", 1, byName2);
|
|
20016
|
+
loadPackagedSkillsFromDir(roots.userDir, byName2);
|
|
20017
|
+
const skills = [...byName2.values()].map((entry) => entry.skill).sort((a, b) => a.name.localeCompare(b.name));
|
|
20018
|
+
cachedSkills = { signature, skills };
|
|
20019
|
+
return skills;
|
|
19767
20020
|
}
|
|
19768
20021
|
function loadSkillBody(skillName) {
|
|
19769
|
-
const
|
|
19770
|
-
const skill = skills.find((s) => s.name === skillName);
|
|
20022
|
+
const skill = findSkill(skillName);
|
|
19771
20023
|
if (!skill) return null;
|
|
19772
20024
|
try {
|
|
19773
20025
|
const content = readFileSync14(skill.filePath, "utf-8").trim();
|
|
19774
|
-
const parsed = parseSkillFile(content, skill.name
|
|
20026
|
+
const parsed = parseSkillFile(content, `${skill.name}.md`);
|
|
19775
20027
|
return parsed.body;
|
|
19776
20028
|
} catch {
|
|
19777
20029
|
return null;
|
|
19778
20030
|
}
|
|
19779
20031
|
}
|
|
20032
|
+
function loadSkillPrompt(skillName) {
|
|
20033
|
+
const skill = findSkill(skillName);
|
|
20034
|
+
const body = skill ? loadSkillBody(skill.name) : null;
|
|
20035
|
+
if (!skill || !body) return null;
|
|
20036
|
+
return `# Skill Runtime Context
|
|
20037
|
+
|
|
20038
|
+
Skill name: ${skill.name}
|
|
20039
|
+
Skill file: ${skill.filePath}
|
|
20040
|
+
Skill root directory: ${skill.rootDir}
|
|
20041
|
+
|
|
20042
|
+
${body}`;
|
|
20043
|
+
}
|
|
19780
20044
|
function findSkill(name) {
|
|
19781
20045
|
const skills = discoverSkills();
|
|
19782
|
-
const
|
|
20046
|
+
const normalized = normalizeSkillName(name);
|
|
20047
|
+
const exact = skills.find((s) => s.name === normalized);
|
|
19783
20048
|
if (exact) return exact;
|
|
19784
|
-
const
|
|
19785
|
-
const ci = skills.find((s) => s.name.toLowerCase() === lower);
|
|
20049
|
+
const ci = skills.find((s) => s.name.toLowerCase() === normalized.toLowerCase());
|
|
19786
20050
|
if (ci) return ci;
|
|
19787
|
-
const
|
|
19788
|
-
return
|
|
20051
|
+
const matches = findSkillMatches(normalized);
|
|
20052
|
+
return matches.length === 1 ? matches[0] : null;
|
|
20053
|
+
}
|
|
20054
|
+
function findSkillMatches(name) {
|
|
20055
|
+
const normalized = normalizeSkillName(name).toLowerCase();
|
|
20056
|
+
if (!normalized) return [];
|
|
20057
|
+
return discoverSkills().filter((skill) => {
|
|
20058
|
+
const skillName = skill.name.toLowerCase();
|
|
20059
|
+
return skillName.startsWith(normalized) || normalized.startsWith(skillName);
|
|
20060
|
+
});
|
|
19789
20061
|
}
|
|
19790
20062
|
function getSkillListing() {
|
|
19791
20063
|
const skills = discoverSkills();
|
|
@@ -19800,52 +20072,145 @@ function getSkillListing() {
|
|
|
19800
20072
|
function clearSkillRegistry() {
|
|
19801
20073
|
cachedSkills = null;
|
|
19802
20074
|
}
|
|
19803
|
-
function
|
|
19804
|
-
|
|
20075
|
+
function normalizeSkillName(name) {
|
|
20076
|
+
return name.trim().replace(/^\/+/, "").toLowerCase();
|
|
20077
|
+
}
|
|
20078
|
+
function loadFlatSkillsFromDir(dir2, source, priority, out) {
|
|
20079
|
+
for (const entry of safeReadDir(dir2)) {
|
|
20080
|
+
if (!entry.isFile() || !isMarkdown(entry.name)) continue;
|
|
20081
|
+
const filePath = join22(dir2, entry.name);
|
|
20082
|
+
const skill = parseSkillAtPath(filePath, dir2, entry.name, source, entry.name);
|
|
20083
|
+
if (skill) putSkill(out, skill, priority);
|
|
20084
|
+
}
|
|
20085
|
+
}
|
|
20086
|
+
function loadPackagedSkillsFromDir(dir2, out) {
|
|
20087
|
+
for (const entry of safeReadDir(dir2)) {
|
|
20088
|
+
if (!entry.isDirectory()) continue;
|
|
20089
|
+
const rootDir = join22(dir2, entry.name);
|
|
20090
|
+
const entrypoint = findPackageEntrypoint(rootDir);
|
|
20091
|
+
if (!entrypoint) continue;
|
|
20092
|
+
const filePath = join22(rootDir, entrypoint);
|
|
20093
|
+
const skill = parseSkillAtPath(filePath, rootDir, entrypoint, "user", `${entry.name}.md`);
|
|
20094
|
+
if (skill) putSkill(out, skill, 2);
|
|
20095
|
+
}
|
|
20096
|
+
}
|
|
20097
|
+
function findPackageEntrypoint(dir2) {
|
|
20098
|
+
const entries = safeReadDir(dir2).filter((entry) => entry.isFile());
|
|
20099
|
+
const entrypoint = ENTRYPOINT_NAMES.find((name) => entries.some((entry) => entry.name.toLowerCase() === name.toLowerCase()));
|
|
20100
|
+
if (entrypoint) return entries.find((entry) => entry.name.toLowerCase() === entrypoint.toLowerCase())?.name ?? entrypoint;
|
|
20101
|
+
const readme = entries.find((entry) => entry.name.toLowerCase() === "readme.md");
|
|
20102
|
+
if (readme) return readme.name;
|
|
20103
|
+
const markdown = entries.filter((entry) => isMarkdown(entry.name));
|
|
20104
|
+
return markdown.length === 1 ? markdown[0].name : null;
|
|
20105
|
+
}
|
|
20106
|
+
function parseSkillAtPath(filePath, rootDir, entrypoint, source, fallbackFilename) {
|
|
19805
20107
|
try {
|
|
19806
|
-
const
|
|
19807
|
-
|
|
19808
|
-
|
|
19809
|
-
|
|
19810
|
-
|
|
19811
|
-
|
|
19812
|
-
|
|
19813
|
-
|
|
19814
|
-
|
|
19815
|
-
|
|
19816
|
-
|
|
19817
|
-
|
|
19818
|
-
|
|
19819
|
-
|
|
19820
|
-
|
|
20108
|
+
const content = readFileSync14(filePath, "utf-8").trim();
|
|
20109
|
+
if (!content) return null;
|
|
20110
|
+
const parsed = parseSkillFile(content, fallbackFilename);
|
|
20111
|
+
const name = normalizeSkillName(parsed.meta.name);
|
|
20112
|
+
if (!name) return null;
|
|
20113
|
+
return {
|
|
20114
|
+
name,
|
|
20115
|
+
meta: { ...parsed.meta, name },
|
|
20116
|
+
filePath,
|
|
20117
|
+
rootDir,
|
|
20118
|
+
entrypoint,
|
|
20119
|
+
source,
|
|
20120
|
+
hasFrontmatter: parsed.hasFrontmatter
|
|
20121
|
+
};
|
|
20122
|
+
} catch {
|
|
20123
|
+
return null;
|
|
20124
|
+
}
|
|
20125
|
+
}
|
|
20126
|
+
function putSkill(out, skill, priority) {
|
|
20127
|
+
const existing = out.get(skill.name);
|
|
20128
|
+
if (!existing || priority >= existing.priority) {
|
|
20129
|
+
out.set(skill.name, { priority, skill });
|
|
20130
|
+
}
|
|
20131
|
+
}
|
|
20132
|
+
function safeReadDir(dir2) {
|
|
20133
|
+
if (!existsSync14(dir2)) return [];
|
|
20134
|
+
try {
|
|
20135
|
+
return readdirSync2(dir2, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
20136
|
+
} catch {
|
|
20137
|
+
return [];
|
|
20138
|
+
}
|
|
20139
|
+
}
|
|
20140
|
+
function buildRegistrySignature() {
|
|
20141
|
+
const roots = skillRoots();
|
|
20142
|
+
return [signatureForDir(roots.bundledDir), signatureForDir(roots.userDir)].join("|");
|
|
20143
|
+
}
|
|
20144
|
+
function signatureForDir(dir2) {
|
|
20145
|
+
if (!existsSync14(dir2)) return `${dir2}:missing`;
|
|
20146
|
+
const parts = [];
|
|
20147
|
+
try {
|
|
20148
|
+
for (const entry of safeReadDir(dir2)) {
|
|
20149
|
+
const fullPath = join22(dir2, entry.name);
|
|
20150
|
+
if (entry.isFile()) {
|
|
20151
|
+
if (!isMarkdown(entry.name)) continue;
|
|
20152
|
+
parts.push(fileSignature(fullPath, `f:${entry.name}`));
|
|
20153
|
+
} else if (entry.isDirectory()) {
|
|
20154
|
+
parts.push(fileSignature(fullPath, `d:${entry.name}`));
|
|
20155
|
+
for (const child of safeReadDir(fullPath)) {
|
|
20156
|
+
if (child.isFile() && isMarkdown(child.name)) {
|
|
20157
|
+
parts.push(fileSignature(join22(fullPath, child.name), `d:${entry.name}/${child.name}`));
|
|
20158
|
+
}
|
|
20159
|
+
}
|
|
19821
20160
|
}
|
|
19822
20161
|
}
|
|
19823
20162
|
} catch {
|
|
20163
|
+
return `${dir2}:unreadable`;
|
|
20164
|
+
}
|
|
20165
|
+
return `${dir2}:${parts.join(",")}`;
|
|
20166
|
+
}
|
|
20167
|
+
function isMarkdown(name) {
|
|
20168
|
+
return name.toLowerCase().endsWith(".md");
|
|
20169
|
+
}
|
|
20170
|
+
function fileSignature(path3, label) {
|
|
20171
|
+
try {
|
|
20172
|
+
const stat2 = statSync(path3);
|
|
20173
|
+
return `${label}:${stat2.mtimeMs}:${stat2.size}`;
|
|
20174
|
+
} catch {
|
|
20175
|
+
return `${label}:missing`;
|
|
19824
20176
|
}
|
|
19825
20177
|
}
|
|
19826
|
-
var
|
|
20178
|
+
var DEFAULT_USER_DIR, ENTRYPOINT_NAMES, cachedSkills, rootsOverride;
|
|
19827
20179
|
var init_registry2 = __esm({
|
|
19828
20180
|
"src/skills/registry.ts"() {
|
|
19829
20181
|
"use strict";
|
|
19830
20182
|
init_frontmatter();
|
|
19831
20183
|
init_packageRoot();
|
|
19832
|
-
|
|
20184
|
+
DEFAULT_USER_DIR = join22(homedir12(), ".openjaw-agent", "skills");
|
|
20185
|
+
ENTRYPOINT_NAMES = ["SKILL.md", "skill.md"];
|
|
19833
20186
|
cachedSkills = null;
|
|
20187
|
+
rootsOverride = null;
|
|
20188
|
+
__name(skillRoots, "skillRoots");
|
|
19834
20189
|
__name(discoverSkills, "discoverSkills");
|
|
19835
20190
|
__name(loadSkillBody, "loadSkillBody");
|
|
20191
|
+
__name(loadSkillPrompt, "loadSkillPrompt");
|
|
19836
20192
|
__name(findSkill, "findSkill");
|
|
20193
|
+
__name(findSkillMatches, "findSkillMatches");
|
|
19837
20194
|
__name(getSkillListing, "getSkillListing");
|
|
19838
20195
|
__name(clearSkillRegistry, "clearSkillRegistry");
|
|
19839
|
-
__name(
|
|
20196
|
+
__name(normalizeSkillName, "normalizeSkillName");
|
|
20197
|
+
__name(loadFlatSkillsFromDir, "loadFlatSkillsFromDir");
|
|
20198
|
+
__name(loadPackagedSkillsFromDir, "loadPackagedSkillsFromDir");
|
|
20199
|
+
__name(findPackageEntrypoint, "findPackageEntrypoint");
|
|
20200
|
+
__name(parseSkillAtPath, "parseSkillAtPath");
|
|
20201
|
+
__name(putSkill, "putSkill");
|
|
20202
|
+
__name(safeReadDir, "safeReadDir");
|
|
20203
|
+
__name(buildRegistrySignature, "buildRegistrySignature");
|
|
20204
|
+
__name(signatureForDir, "signatureForDir");
|
|
20205
|
+
__name(isMarkdown, "isMarkdown");
|
|
20206
|
+
__name(fileSignature, "fileSignature");
|
|
19840
20207
|
}
|
|
19841
20208
|
});
|
|
19842
20209
|
|
|
19843
20210
|
// src/prompts/skills.ts
|
|
19844
20211
|
function getSkillsSection() {
|
|
19845
|
-
if (cached7 !== void 0) return cached7;
|
|
19846
20212
|
const skills = discoverSkills();
|
|
19847
20213
|
if (skills.length === 0) {
|
|
19848
|
-
cached7 = null;
|
|
19849
20214
|
return null;
|
|
19850
20215
|
}
|
|
19851
20216
|
const listing = getSkillListing();
|
|
@@ -19860,15 +20225,17 @@ New skills must be saved to \`~/.openjaw-agent/skills/\` (user skills directory)
|
|
|
19860
20225
|
Do NOT write skills to the project's bundled skills/ directory.
|
|
19861
20226
|
|
|
19862
20227
|
${listing}`;
|
|
19863
|
-
|
|
19864
|
-
|
|
20228
|
+
return content;
|
|
20229
|
+
}
|
|
20230
|
+
function clearSkillsCache() {
|
|
20231
|
+
clearSkillRegistry();
|
|
19865
20232
|
}
|
|
19866
|
-
var cached7;
|
|
19867
20233
|
var init_skills = __esm({
|
|
19868
20234
|
"src/prompts/skills.ts"() {
|
|
19869
20235
|
"use strict";
|
|
19870
20236
|
init_registry2();
|
|
19871
20237
|
__name(getSkillsSection, "getSkillsSection");
|
|
20238
|
+
__name(clearSkillsCache, "clearSkillsCache");
|
|
19872
20239
|
}
|
|
19873
20240
|
});
|
|
19874
20241
|
|
|
@@ -20559,8 +20926,8 @@ Options: ${chunk.choices.join(" | ")}` : "";
|
|
|
20559
20926
|
if (fileName.startsWith("oj-") || fileName.endsWith(".log") || fileName.endsWith(".tmp")) continue;
|
|
20560
20927
|
if (existsSync16(resolvedPath)) {
|
|
20561
20928
|
try {
|
|
20562
|
-
const { statSync:
|
|
20563
|
-
const stat2 =
|
|
20929
|
+
const { statSync: statSync5 } = await import("node:fs");
|
|
20930
|
+
const stat2 = statSync5(resolvedPath);
|
|
20564
20931
|
if (stat2.isFile() && stat2.size < 50 * 1024 * 1024) {
|
|
20565
20932
|
const ext = resolvedPath.split(".").pop()?.toLowerCase() || "";
|
|
20566
20933
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
@@ -21412,10 +21779,10 @@ var init_mcp_client = __esm({
|
|
|
21412
21779
|
let tokenExpiry = 0;
|
|
21413
21780
|
if (copilotTokenFile) {
|
|
21414
21781
|
try {
|
|
21415
|
-
const
|
|
21416
|
-
cachedToken =
|
|
21417
|
-
cachedRefreshToken =
|
|
21418
|
-
tokenExpiry =
|
|
21782
|
+
const cached7 = JSON.parse(readFileSync17(copilotTokenFile, "utf-8"));
|
|
21783
|
+
cachedToken = cached7.accessToken;
|
|
21784
|
+
cachedRefreshToken = cached7.refreshToken;
|
|
21785
|
+
tokenExpiry = cached7.expiresAt || 0;
|
|
21419
21786
|
} catch {
|
|
21420
21787
|
}
|
|
21421
21788
|
}
|
|
@@ -26206,7 +26573,7 @@ function createSkillTool(config, toolRegistry, systemPromptFn) {
|
|
|
26206
26573
|
};
|
|
26207
26574
|
}
|
|
26208
26575
|
async function executeSkill(skillName, args, config, toolRegistry, systemPromptFn) {
|
|
26209
|
-
const body =
|
|
26576
|
+
const body = loadSkillPrompt(skillName);
|
|
26210
26577
|
if (!body) {
|
|
26211
26578
|
return { success: false, error: `Could not load skill content for "${skillName}"` };
|
|
26212
26579
|
}
|
|
@@ -26569,8 +26936,8 @@ var init_teams = __esm({
|
|
|
26569
26936
|
if (fileName.startsWith("oj-") || fileName.endsWith(".log") || fileName.endsWith(".tmp")) continue;
|
|
26570
26937
|
if (existsSync25(filePath)) {
|
|
26571
26938
|
try {
|
|
26572
|
-
const { statSync:
|
|
26573
|
-
const stat2 =
|
|
26939
|
+
const { statSync: statSync5 } = await import("node:fs");
|
|
26940
|
+
const stat2 = statSync5(filePath);
|
|
26574
26941
|
if (stat2.isFile() && stat2.size < 50 * 1024 * 1024) {
|
|
26575
26942
|
await this.sendFileToSelfChat(filePath);
|
|
26576
26943
|
sentFiles.add(filePath);
|
|
@@ -27129,8 +27496,8 @@ var init_feishu = __esm({
|
|
|
27129
27496
|
this.emit({ type: "system", content: `\u{1F50D} Found path: ${filePath} (exists: ${exists})` });
|
|
27130
27497
|
if (exists) {
|
|
27131
27498
|
try {
|
|
27132
|
-
const { statSync:
|
|
27133
|
-
const stat2 =
|
|
27499
|
+
const { statSync: statSync5 } = await import("node:fs");
|
|
27500
|
+
const stat2 = statSync5(filePath);
|
|
27134
27501
|
if (stat2.isFile() && stat2.size < 30 * 1024 * 1024) {
|
|
27135
27502
|
const fileType = this.getFeishuFileType(fileName);
|
|
27136
27503
|
this.emit({ type: "system", content: `\u{1F4E4} Uploading to Feishu: ${fileName} (${(stat2.size / 1024).toFixed(0)}KB, type=${fileType})` });
|
|
@@ -27226,7 +27593,7 @@ __export(wechat_exports, {
|
|
|
27226
27593
|
sniffMediaKind: () => sniffMediaKind,
|
|
27227
27594
|
validateMediaForUpload: () => validateMediaForUpload
|
|
27228
27595
|
});
|
|
27229
|
-
import { existsSync as existsSync27, readFileSync as readFileSync26, writeFileSync as writeFileSync18, unlinkSync as unlinkSync7, statSync as
|
|
27596
|
+
import { existsSync as existsSync27, readFileSync as readFileSync26, writeFileSync as writeFileSync18, unlinkSync as unlinkSync7, statSync as statSync3 } from "node:fs";
|
|
27230
27597
|
import { mkdirSync as mkdirSync16 } from "node:fs";
|
|
27231
27598
|
import { extname as extname3, join as join35 } from "node:path";
|
|
27232
27599
|
import { homedir as homedir21 } from "node:os";
|
|
@@ -28097,7 +28464,7 @@ Scan URL manually: ${qrUrl}` });
|
|
|
28097
28464
|
attemptedFiles.add(dedupKey);
|
|
28098
28465
|
attempted++;
|
|
28099
28466
|
try {
|
|
28100
|
-
const stat2 =
|
|
28467
|
+
const stat2 = statSync3(filePath);
|
|
28101
28468
|
if (!stat2.isFile() || stat2.size > 30 * 1024 * 1024) continue;
|
|
28102
28469
|
if (stat2.size === 0) {
|
|
28103
28470
|
this.emit({ type: "system", content: `\u26A0 WeChat skipped empty file: ${fileName}` });
|
|
@@ -29097,12 +29464,40 @@ var init_bootstrap = __esm({
|
|
|
29097
29464
|
}
|
|
29098
29465
|
});
|
|
29099
29466
|
|
|
29467
|
+
// src/usageSnapshot.ts
|
|
29468
|
+
function usageSnapshot(agentLoop) {
|
|
29469
|
+
const cost = agentLoop.costTracker.getSessionCost();
|
|
29470
|
+
const contextMax = agentLoop.contextManager.getContextWindow(agentLoop.model);
|
|
29471
|
+
const contextUsed = agentLoop.contextManager.lastPromptTokens;
|
|
29472
|
+
return {
|
|
29473
|
+
cache_read: cost.totalCacheReadTokens,
|
|
29474
|
+
cache_write: cost.totalCacheCreationTokens,
|
|
29475
|
+
calls: cost.turns,
|
|
29476
|
+
context_max: contextMax,
|
|
29477
|
+
context_percent: contextPercent(contextUsed, contextMax),
|
|
29478
|
+
context_used: contextUsed,
|
|
29479
|
+
cost_status: "estimated",
|
|
29480
|
+
cost_usd: cost.totalCostUSD,
|
|
29481
|
+
input: cost.totalInputTokens,
|
|
29482
|
+
model: agentLoop.model,
|
|
29483
|
+
output: cost.totalOutputTokens,
|
|
29484
|
+
total: cost.totalInputTokens + cost.totalOutputTokens + cost.totalCacheReadTokens + cost.totalCacheCreationTokens
|
|
29485
|
+
};
|
|
29486
|
+
}
|
|
29487
|
+
var init_usageSnapshot = __esm({
|
|
29488
|
+
"src/usageSnapshot.ts"() {
|
|
29489
|
+
"use strict";
|
|
29490
|
+
init_usage();
|
|
29491
|
+
__name(usageSnapshot, "usageSnapshot");
|
|
29492
|
+
}
|
|
29493
|
+
});
|
|
29494
|
+
|
|
29100
29495
|
// src/eventBridge.ts
|
|
29101
29496
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
29102
29497
|
async function streamAgentRun(options) {
|
|
29103
29498
|
const { agentLoop, bus, imageData, systemPrompt, text } = options;
|
|
29104
29499
|
const sid = agentLoop.sessionId;
|
|
29105
|
-
const state = newState();
|
|
29500
|
+
const state = newState(agentLoop);
|
|
29106
29501
|
bus.emitEvent({
|
|
29107
29502
|
payload: { kind: "thinking", text: "thinking\u2026" },
|
|
29108
29503
|
session_id: sid,
|
|
@@ -29192,11 +29587,13 @@ function translateChunk(chunk, state, bus, sid) {
|
|
|
29192
29587
|
}
|
|
29193
29588
|
}
|
|
29194
29589
|
}
|
|
29195
|
-
var newState, ensureMessageOpen, closeMessage;
|
|
29590
|
+
var newState, ensureMessageOpen, closeMessage, safeUsageSnapshot;
|
|
29196
29591
|
var init_eventBridge = __esm({
|
|
29197
29592
|
"src/eventBridge.ts"() {
|
|
29198
29593
|
"use strict";
|
|
29199
|
-
|
|
29594
|
+
init_usageSnapshot();
|
|
29595
|
+
newState = /* @__PURE__ */ __name((agentLoop) => ({
|
|
29596
|
+
agentLoop,
|
|
29200
29597
|
messageOpen: false,
|
|
29201
29598
|
pendingAnswer: "",
|
|
29202
29599
|
toolIds: /* @__PURE__ */ new Map()
|
|
@@ -29209,8 +29606,9 @@ var init_eventBridge = __esm({
|
|
|
29209
29606
|
}, "ensureMessageOpen");
|
|
29210
29607
|
closeMessage = /* @__PURE__ */ __name((state, bus, sid, text) => {
|
|
29211
29608
|
if (state.messageOpen || text) {
|
|
29609
|
+
const usage2 = safeUsageSnapshot(state.agentLoop);
|
|
29212
29610
|
bus.emitEvent({
|
|
29213
|
-
payload: { text: text ?? state.pendingAnswer },
|
|
29611
|
+
payload: { text: text ?? state.pendingAnswer, ...usage2 ? { usage: usage2 } : {} },
|
|
29214
29612
|
session_id: sid,
|
|
29215
29613
|
type: "message.complete"
|
|
29216
29614
|
});
|
|
@@ -29218,6 +29616,13 @@ var init_eventBridge = __esm({
|
|
|
29218
29616
|
state.pendingAnswer = "";
|
|
29219
29617
|
}
|
|
29220
29618
|
}, "closeMessage");
|
|
29619
|
+
safeUsageSnapshot = /* @__PURE__ */ __name((agentLoop) => {
|
|
29620
|
+
try {
|
|
29621
|
+
return usageSnapshot(agentLoop);
|
|
29622
|
+
} catch {
|
|
29623
|
+
return void 0;
|
|
29624
|
+
}
|
|
29625
|
+
}, "safeUsageSnapshot");
|
|
29221
29626
|
__name(streamAgentRun, "streamAgentRun");
|
|
29222
29627
|
__name(translateChunk, "translateChunk");
|
|
29223
29628
|
}
|
|
@@ -29297,15 +29702,6 @@ var init_env = __esm({
|
|
|
29297
29702
|
}
|
|
29298
29703
|
});
|
|
29299
29704
|
|
|
29300
|
-
// src/domain/usage.ts
|
|
29301
|
-
var ZERO;
|
|
29302
|
-
var init_usage = __esm({
|
|
29303
|
-
"src/domain/usage.ts"() {
|
|
29304
|
-
"use strict";
|
|
29305
|
-
ZERO = { calls: 0, input: 0, output: 0, total: 0 };
|
|
29306
|
-
}
|
|
29307
|
-
});
|
|
29308
|
-
|
|
29309
29705
|
// src/theme.ts
|
|
29310
29706
|
function parseHex(h) {
|
|
29311
29707
|
const m = /^#?([0-9a-f]{6})$/i.exec(h);
|
|
@@ -29475,6 +29871,14 @@ function normalizeThemeForAnsiLightTerminal(theme, env2 = process.env, isLight =
|
|
|
29475
29871
|
}
|
|
29476
29872
|
return { ...theme, color };
|
|
29477
29873
|
}
|
|
29874
|
+
function isBuiltinSkinName(value) {
|
|
29875
|
+
return BUILTIN_SKINS.some((skin) => skin.name === value);
|
|
29876
|
+
}
|
|
29877
|
+
function themeForBuiltinSkin(name) {
|
|
29878
|
+
if (name === "dark") return DARK_THEME;
|
|
29879
|
+
if (name === "light") return LIGHT_THEME;
|
|
29880
|
+
return DEFAULT_THEME;
|
|
29881
|
+
}
|
|
29478
29882
|
function fromSkin(colors, branding, bannerLogo = "", bannerHero = "", toolPrefix = "", helpHeader = "") {
|
|
29479
29883
|
const d = DEFAULT_THEME;
|
|
29480
29884
|
const c = /* @__PURE__ */ __name((k) => colors[k], "c");
|
|
@@ -29532,7 +29936,7 @@ function fromSkin(colors, branding, bannerLogo = "", bannerHero = "", toolPrefix
|
|
|
29532
29936
|
bannerHero
|
|
29533
29937
|
}, process.env, DEFAULT_LIGHT_MODE);
|
|
29534
29938
|
}
|
|
29535
|
-
var XTERM_6_LEVELS, ANSI_LIGHT_MAX_LUMINANCE, ANSI_LIGHT_TARGET_LUMINANCE, ANSI_LIGHT_MIN_SATURATION, ANSI_MUTED_BUCKET, ANSI_NORMALIZED_FOREGROUNDS, ANSI_MUTED_FOREGROUNDS, BRAND, cleanPromptSymbol, DARK_THEME, LIGHT_THEME, TRUE_RE2, FALSE_RE2, LIGHT_DEFAULT_TERM_PROGRAMS, LUMA_LIGHT_THRESHOLD, HEX_3_RE, HEX_6_RE, DEFAULT_LIGHT_MODE, DEFAULT_THEME;
|
|
29939
|
+
var XTERM_6_LEVELS, ANSI_LIGHT_MAX_LUMINANCE, ANSI_LIGHT_TARGET_LUMINANCE, ANSI_LIGHT_MIN_SATURATION, ANSI_MUTED_BUCKET, ANSI_NORMALIZED_FOREGROUNDS, ANSI_MUTED_FOREGROUNDS, BRAND, cleanPromptSymbol, DARK_THEME, LIGHT_THEME, TRUE_RE2, FALSE_RE2, LIGHT_DEFAULT_TERM_PROGRAMS, LUMA_LIGHT_THRESHOLD, HEX_3_RE, HEX_6_RE, DEFAULT_LIGHT_MODE, DEFAULT_THEME, BUILTIN_SKINS;
|
|
29536
29940
|
var init_theme = __esm({
|
|
29537
29941
|
"src/theme.ts"() {
|
|
29538
29942
|
"use strict";
|
|
@@ -29684,6 +30088,13 @@ var init_theme = __esm({
|
|
|
29684
30088
|
process.env,
|
|
29685
30089
|
DEFAULT_LIGHT_MODE
|
|
29686
30090
|
);
|
|
30091
|
+
BUILTIN_SKINS = [
|
|
30092
|
+
{ name: "default", description: "Auto-detect terminal light/dark preference" },
|
|
30093
|
+
{ name: "dark", description: "OpenJaw dark coral theme" },
|
|
30094
|
+
{ name: "light", description: "Light terminal theme" }
|
|
30095
|
+
];
|
|
30096
|
+
__name(isBuiltinSkinName, "isBuiltinSkinName");
|
|
30097
|
+
__name(themeForBuiltinSkin, "themeForBuiltinSkin");
|
|
29687
30098
|
__name(fromSkin, "fromSkin");
|
|
29688
30099
|
}
|
|
29689
30100
|
});
|
|
@@ -31452,11 +31863,11 @@ function sliceAnsi(str, start, end) {
|
|
|
31452
31863
|
}
|
|
31453
31864
|
if (end !== void 0) {
|
|
31454
31865
|
const key = `${start}|${end}|${str}`;
|
|
31455
|
-
const
|
|
31456
|
-
if (
|
|
31866
|
+
const cached7 = sliceCache.get(key);
|
|
31867
|
+
if (cached7 !== void 0) {
|
|
31457
31868
|
sliceCache.delete(key);
|
|
31458
|
-
sliceCache.set(key,
|
|
31459
|
-
return
|
|
31869
|
+
sliceCache.set(key, cached7);
|
|
31870
|
+
return cached7;
|
|
31460
31871
|
}
|
|
31461
31872
|
const result = computeSlice(str, start, end);
|
|
31462
31873
|
if (sliceCache.size >= SLICE_CACHE_LIMIT) {
|
|
@@ -31511,11 +31922,11 @@ function computeSlice(str, start, end) {
|
|
|
31511
31922
|
return result;
|
|
31512
31923
|
}
|
|
31513
31924
|
function lineWidth(line) {
|
|
31514
|
-
const
|
|
31515
|
-
if (
|
|
31925
|
+
const cached7 = cache.get(line);
|
|
31926
|
+
if (cached7 !== void 0) {
|
|
31516
31927
|
cache.delete(line);
|
|
31517
|
-
cache.set(line,
|
|
31518
|
-
return
|
|
31928
|
+
cache.set(line, cached7);
|
|
31929
|
+
return cached7;
|
|
31519
31930
|
}
|
|
31520
31931
|
const width = stringWidth(line);
|
|
31521
31932
|
if (cache.size >= MAX_CACHE_SIZE) {
|
|
@@ -31532,11 +31943,11 @@ function evictLineWidthCache(keepRatio = 0) {
|
|
|
31532
31943
|
}
|
|
31533
31944
|
function memoizedWrap(text, maxWidth, wrapType) {
|
|
31534
31945
|
const key = `${maxWidth}|${wrapType}|${text}`;
|
|
31535
|
-
const
|
|
31536
|
-
if (
|
|
31946
|
+
const cached7 = wrapCache.get(key);
|
|
31947
|
+
if (cached7 !== void 0) {
|
|
31537
31948
|
wrapCache.delete(key);
|
|
31538
|
-
wrapCache.set(key,
|
|
31539
|
-
return
|
|
31949
|
+
wrapCache.set(key, cached7);
|
|
31950
|
+
return cached7;
|
|
31540
31951
|
}
|
|
31541
31952
|
const result = computeWrap(text, maxWidth, wrapType);
|
|
31542
31953
|
if (wrapCache.size >= WRAP_CACHE_LIMIT) {
|
|
@@ -33496,9 +33907,9 @@ function collectRemovedRects(parent, removed, underAbsolute = false) {
|
|
|
33496
33907
|
}
|
|
33497
33908
|
const elem = removed;
|
|
33498
33909
|
const isAbsolute2 = underAbsolute || elem.style.position === "absolute";
|
|
33499
|
-
const
|
|
33500
|
-
if (
|
|
33501
|
-
addPendingClear(parent,
|
|
33910
|
+
const cached7 = nodeCache.get(elem);
|
|
33911
|
+
if (cached7) {
|
|
33912
|
+
addPendingClear(parent, cached7, isAbsolute2);
|
|
33502
33913
|
nodeCache.delete(elem);
|
|
33503
33914
|
}
|
|
33504
33915
|
for (const child of elem.childNodes) {
|
|
@@ -35618,31 +36029,31 @@ function renderNodeToOutput(node, output, {
|
|
|
35618
36029
|
if (y < 0 && node.style.position === "absolute") {
|
|
35619
36030
|
y = 0;
|
|
35620
36031
|
}
|
|
35621
|
-
const
|
|
35622
|
-
if (!node.dirty && !skipSelfBlit && node.pendingScrollDelta === void 0 &&
|
|
36032
|
+
const cached7 = nodeCache.get(node);
|
|
36033
|
+
if (!node.dirty && !skipSelfBlit && node.pendingScrollDelta === void 0 && cached7 && cached7.x === x && cached7.y === y && cached7.width === width && cached7.height === height && prevScreen) {
|
|
35623
36034
|
const fx = Math.floor(x);
|
|
35624
36035
|
const fy = Math.floor(y);
|
|
35625
36036
|
const fw = Math.floor(width);
|
|
35626
36037
|
const fh = Math.floor(height);
|
|
35627
36038
|
output.blit(prevScreen, fx, fy, fw, fh);
|
|
35628
36039
|
if (node.style.position === "absolute") {
|
|
35629
|
-
absoluteRectsCur.push(
|
|
36040
|
+
absoluteRectsCur.push(cached7);
|
|
35630
36041
|
}
|
|
35631
36042
|
blitEscapingAbsoluteDescendants(node, output, prevScreen, fx, fy, fw, fh);
|
|
35632
36043
|
return;
|
|
35633
36044
|
}
|
|
35634
|
-
const positionChanged =
|
|
36045
|
+
const positionChanged = cached7 !== void 0 && (cached7.x !== x || cached7.y !== y || cached7.width !== width || cached7.height !== height);
|
|
35635
36046
|
if (positionChanged) {
|
|
35636
36047
|
layoutShifted = true;
|
|
35637
36048
|
absoluteOverlayMoved ||= node.style.position === "absolute";
|
|
35638
36049
|
}
|
|
35639
|
-
if (
|
|
36050
|
+
if (cached7 && (node.dirty || positionChanged)) {
|
|
35640
36051
|
output.clear(
|
|
35641
36052
|
{
|
|
35642
|
-
x: Math.floor(
|
|
35643
|
-
y: Math.floor(
|
|
35644
|
-
width: Math.floor(
|
|
35645
|
-
height: Math.floor(
|
|
36053
|
+
x: Math.floor(cached7.x),
|
|
36054
|
+
y: Math.floor(cached7.y),
|
|
36055
|
+
width: Math.floor(cached7.width),
|
|
36056
|
+
height: Math.floor(cached7.height)
|
|
35646
36057
|
},
|
|
35647
36058
|
node.style.position === "absolute"
|
|
35648
36059
|
);
|
|
@@ -35817,7 +36228,7 @@ function renderNodeToOutput(node, output, {
|
|
|
35817
36228
|
const delta = contentCached.y - contentY;
|
|
35818
36229
|
const regionTop = Math.floor(y + contentYoga.getComputedTop());
|
|
35819
36230
|
const regionBottom = regionTop + innerHeight - 1;
|
|
35820
|
-
if (
|
|
36231
|
+
if (cached7?.y === y && cached7.height === height && innerHeight > 0 && Math.abs(delta) < innerHeight) {
|
|
35821
36232
|
hint = { top: regionTop, bottom: regionBottom, delta };
|
|
35822
36233
|
scrollHint = hint;
|
|
35823
36234
|
} else {
|
|
@@ -36117,13 +36528,13 @@ function blitEscapingAbsoluteDescendants(node, output, prevScreen, px, py, pw, p
|
|
|
36117
36528
|
}
|
|
36118
36529
|
const elem = child;
|
|
36119
36530
|
if (elem.style.position === "absolute") {
|
|
36120
|
-
const
|
|
36121
|
-
if (
|
|
36122
|
-
absoluteRectsCur.push(
|
|
36123
|
-
const cx = Math.floor(
|
|
36124
|
-
const cy = Math.floor(
|
|
36125
|
-
const cw = Math.floor(
|
|
36126
|
-
const ch = Math.floor(
|
|
36531
|
+
const cached7 = nodeCache.get(elem);
|
|
36532
|
+
if (cached7) {
|
|
36533
|
+
absoluteRectsCur.push(cached7);
|
|
36534
|
+
const cx = Math.floor(cached7.x);
|
|
36535
|
+
const cy = Math.floor(cached7.y);
|
|
36536
|
+
const cw = Math.floor(cached7.width);
|
|
36537
|
+
const ch = Math.floor(cached7.height);
|
|
36127
36538
|
if (cx < px || cy < py || cx + cw > pr || cy + ch > pb) {
|
|
36128
36539
|
output.blit(prevScreen, cx, cy, cw, ch);
|
|
36129
36540
|
}
|
|
@@ -36139,20 +36550,20 @@ function renderScrolledChildren(node, output, offsetX, offsetY, hasRemovedChild,
|
|
|
36139
36550
|
const childElem = childNode;
|
|
36140
36551
|
const cy = childElem.yogaNode;
|
|
36141
36552
|
if (cy) {
|
|
36142
|
-
const
|
|
36553
|
+
const cached7 = nodeCache.get(childElem);
|
|
36143
36554
|
let top;
|
|
36144
36555
|
let height;
|
|
36145
|
-
if (
|
|
36146
|
-
top =
|
|
36147
|
-
height =
|
|
36556
|
+
if (cached7?.top !== void 0 && !childElem.dirty && cumHeightShift === 0) {
|
|
36557
|
+
top = cached7.top;
|
|
36558
|
+
height = cached7.height;
|
|
36148
36559
|
} else {
|
|
36149
36560
|
top = cy.getComputedTop();
|
|
36150
36561
|
height = cy.getComputedHeight();
|
|
36151
36562
|
if (childElem.dirty) {
|
|
36152
|
-
cumHeightShift += height - (
|
|
36563
|
+
cumHeightShift += height - (cached7 ? cached7.height : 0);
|
|
36153
36564
|
}
|
|
36154
|
-
if (
|
|
36155
|
-
|
|
36565
|
+
if (cached7) {
|
|
36566
|
+
cached7.top = top;
|
|
36156
36567
|
}
|
|
36157
36568
|
}
|
|
36158
36569
|
const bottom = top + height;
|
|
@@ -38562,11 +38973,11 @@ var init_entry_exports = __esm({
|
|
|
38562
38973
|
return rawStringWidth(str);
|
|
38563
38974
|
}
|
|
38564
38975
|
}
|
|
38565
|
-
const
|
|
38566
|
-
if (
|
|
38976
|
+
const cached7 = widthCache.get(str);
|
|
38977
|
+
if (cached7 !== void 0) {
|
|
38567
38978
|
widthCache.delete(str);
|
|
38568
|
-
widthCache.set(str,
|
|
38569
|
-
return
|
|
38979
|
+
widthCache.set(str, cached7);
|
|
38980
|
+
return cached7;
|
|
38570
38981
|
}
|
|
38571
38982
|
const w = rawStringWidth(str);
|
|
38572
38983
|
if (widthCache.size >= WIDTH_CACHE_LIMIT) {
|
|
@@ -40671,9 +41082,9 @@ $ npm install --save-dev react-devtools-core
|
|
|
40671
41082
|
if (char.length === 1) {
|
|
40672
41083
|
const code = char.charCodeAt(0);
|
|
40673
41084
|
if (code < 128) {
|
|
40674
|
-
const
|
|
40675
|
-
if (
|
|
40676
|
-
return
|
|
41085
|
+
const cached7 = this.ascii[code];
|
|
41086
|
+
if (cached7 !== -1) {
|
|
41087
|
+
return cached7;
|
|
40677
41088
|
}
|
|
40678
41089
|
const index2 = this.strings.length;
|
|
40679
41090
|
this.strings.push(char);
|
|
@@ -45690,6 +46101,7 @@ var fmt, money, stub, eventLine, parseScheduleInput, showUsage, openjawCommands;
|
|
|
45690
46101
|
var init_openjaw = __esm({
|
|
45691
46102
|
"src/app/slash/commands/openjaw.ts"() {
|
|
45692
46103
|
"use strict";
|
|
46104
|
+
init_usage();
|
|
45693
46105
|
init_overlayStore();
|
|
45694
46106
|
fmt = /* @__PURE__ */ __name((n) => (n ?? 0).toLocaleString(), "fmt");
|
|
45695
46107
|
money = /* @__PURE__ */ __name((n) => `$${(n ?? 0).toFixed(4)}`, "money");
|
|
@@ -45937,7 +46349,7 @@ var init_openjaw = __esm({
|
|
|
45937
46349
|
if (!r.context_max) {
|
|
45938
46350
|
return ctx.transcript.sys("context usage unavailable");
|
|
45939
46351
|
}
|
|
45940
|
-
ctx.transcript.sys(`context: ${fmt(r.context_used)} / ${fmt(r.context_max)} (${r.context_percent
|
|
46352
|
+
ctx.transcript.sys(`context: ${fmt(r.context_used)} / ${fmt(r.context_max)} (${formatContextPercent(r.context_percent)})`);
|
|
45941
46353
|
}), "run")
|
|
45942
46354
|
},
|
|
45943
46355
|
{
|
|
@@ -46840,6 +47252,8 @@ var init_session2 = __esm({
|
|
|
46840
47252
|
init_slash();
|
|
46841
47253
|
init_platform();
|
|
46842
47254
|
init_text();
|
|
47255
|
+
init_theme();
|
|
47256
|
+
init_usage();
|
|
46843
47257
|
init_interfaces();
|
|
46844
47258
|
init_overlayStore();
|
|
46845
47259
|
init_uiStore();
|
|
@@ -47058,10 +47472,18 @@ var init_session2 = __esm({
|
|
|
47058
47472
|
help: "switch theme skin (fires skin.changed)",
|
|
47059
47473
|
name: "skin",
|
|
47060
47474
|
run: /* @__PURE__ */ __name((arg, ctx) => {
|
|
47061
|
-
|
|
47062
|
-
|
|
47475
|
+
const value = arg.trim().toLowerCase();
|
|
47476
|
+
if (!value || value === "list") {
|
|
47477
|
+
return ctx.transcript.panel("Skins", [
|
|
47478
|
+
{ rows: BUILTIN_SKINS.map((skin) => [skin.name, skin.description]) },
|
|
47479
|
+
{ text: "Use /skin <name> to apply a skin." }
|
|
47480
|
+
]);
|
|
47481
|
+
}
|
|
47482
|
+
if (!isBuiltinSkinName(value)) {
|
|
47483
|
+
return ctx.transcript.sys(`usage: /skin <${BUILTIN_SKINS.map((s) => s.name).join("|")}>`);
|
|
47063
47484
|
}
|
|
47064
|
-
|
|
47485
|
+
patchUiState({ theme: themeForBuiltinSkin(value) });
|
|
47486
|
+
ctx.gateway.rpc("config.set", { key: "skin", value }).then(ctx.guarded(() => ctx.transcript.sys(`skin \u2192 ${value}`)));
|
|
47065
47487
|
}, "run")
|
|
47066
47488
|
},
|
|
47067
47489
|
{
|
|
@@ -47228,7 +47650,7 @@ var init_session2 = __esm({
|
|
|
47228
47650
|
}
|
|
47229
47651
|
const sections = [{ rows }];
|
|
47230
47652
|
if (r.context_max) {
|
|
47231
|
-
sections.push({ text: `Context: ${f(r.context_used)} / ${f(r.context_max)} (${r.context_percent}
|
|
47653
|
+
sections.push({ text: `Context: ${f(r.context_used)} / ${f(r.context_max)} (${formatContextPercent(r.context_percent)})` });
|
|
47232
47654
|
}
|
|
47233
47655
|
if (r.compressions) {
|
|
47234
47656
|
sections.push({ text: `Compressions: ${r.compressions}` });
|
|
@@ -47352,6 +47774,14 @@ function buildSlashCompletions(text) {
|
|
|
47352
47774
|
if (!text.startsWith("/")) {
|
|
47353
47775
|
return { items: [], replace_from: 1 };
|
|
47354
47776
|
}
|
|
47777
|
+
const skinArgMatch = /^\/skin\s+([^\s]*)$/i.exec(text);
|
|
47778
|
+
if (skinArgMatch) {
|
|
47779
|
+
const prefix = skinArgMatch[1]?.toLowerCase() ?? "";
|
|
47780
|
+
return {
|
|
47781
|
+
items: BUILTIN_SKINS.filter((skin) => skin.name.startsWith(prefix)).map((skin) => ({ display: skin.name, meta: skin.description, text: skin.name })),
|
|
47782
|
+
replace_from: text.length - (skinArgMatch[1]?.length ?? 0)
|
|
47783
|
+
};
|
|
47784
|
+
}
|
|
47355
47785
|
const needle = text.slice(1).toLowerCase();
|
|
47356
47786
|
const seen = /* @__PURE__ */ new Set();
|
|
47357
47787
|
const items = [];
|
|
@@ -47370,6 +47800,19 @@ function buildSlashCompletions(text) {
|
|
|
47370
47800
|
});
|
|
47371
47801
|
}
|
|
47372
47802
|
}
|
|
47803
|
+
if (needle.length > 0) {
|
|
47804
|
+
for (const skill of discoverSkills()) {
|
|
47805
|
+
if (!skill.name.toLowerCase().startsWith(needle)) continue;
|
|
47806
|
+
const command = `/${skill.name}`;
|
|
47807
|
+
if (seen.has(command)) continue;
|
|
47808
|
+
seen.add(command);
|
|
47809
|
+
items.push({
|
|
47810
|
+
display: command,
|
|
47811
|
+
meta: `skill \xB7 ${skill.meta.whenToUse || skill.meta.description || ""}`,
|
|
47812
|
+
text: command
|
|
47813
|
+
});
|
|
47814
|
+
}
|
|
47815
|
+
}
|
|
47373
47816
|
items.sort((a, b) => {
|
|
47374
47817
|
const aExact = a.text.slice(1).toLowerCase() === needle ? -1 : 0;
|
|
47375
47818
|
const bExact = b.text.slice(1).toLowerCase() === needle ? -1 : 0;
|
|
@@ -47426,6 +47869,8 @@ var init_catalog = __esm({
|
|
|
47426
47869
|
init_ops();
|
|
47427
47870
|
init_session2();
|
|
47428
47871
|
init_setup();
|
|
47872
|
+
init_registry2();
|
|
47873
|
+
init_theme();
|
|
47429
47874
|
CATEGORIZED = [
|
|
47430
47875
|
{ category: "Core", commands: coreCommands },
|
|
47431
47876
|
{ category: "Session", commands: sessionCommands },
|
|
@@ -47446,7 +47891,7 @@ var init_catalog = __esm({
|
|
|
47446
47891
|
// src/rpcHandlers.ts
|
|
47447
47892
|
import { spawn as spawn7 } from "node:child_process";
|
|
47448
47893
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
47449
|
-
import { existsSync as existsSync31, mkdirSync as mkdirSync17, readFileSync as readFileSync28, rmSync, statSync as
|
|
47894
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync17, readFileSync as readFileSync28, rmSync, statSync as statSync4, writeFileSync as writeFileSync19 } from "node:fs";
|
|
47450
47895
|
import { homedir as homedir28 } from "node:os";
|
|
47451
47896
|
import { basename as basename3, extname as extname4, join as join42 } from "node:path";
|
|
47452
47897
|
function registerRpcHandlers(options) {
|
|
@@ -47628,6 +48073,12 @@ ${helpMessage}` : field.label;
|
|
|
47628
48073
|
if (key === "mtime") {
|
|
47629
48074
|
return { mtime: Date.now() };
|
|
47630
48075
|
}
|
|
48076
|
+
if (key === "reasoning") {
|
|
48077
|
+
return {
|
|
48078
|
+
display: getUiState().showReasoning !== false ? "show" : "hide",
|
|
48079
|
+
value: agentLoop.reasoningEffort ?? "default"
|
|
48080
|
+
};
|
|
48081
|
+
}
|
|
47631
48082
|
const ui = getUiState();
|
|
47632
48083
|
return {
|
|
47633
48084
|
config: {
|
|
@@ -47652,6 +48103,30 @@ ${helpMessage}` : field.label;
|
|
|
47652
48103
|
if (typeof params?.key === "string") {
|
|
47653
48104
|
const key = params.key;
|
|
47654
48105
|
const rawValue = String(params.value ?? "").trim();
|
|
48106
|
+
if (key === "reasoning") {
|
|
48107
|
+
if (!rawValue) {
|
|
48108
|
+
return {
|
|
48109
|
+
display: getUiState().showReasoning !== false ? "show" : "hide",
|
|
48110
|
+
value: agentLoop.reasoningEffort ?? "default"
|
|
48111
|
+
};
|
|
48112
|
+
}
|
|
48113
|
+
if (rawValue === "hide" || rawValue === "show") {
|
|
48114
|
+
return { value: rawValue };
|
|
48115
|
+
}
|
|
48116
|
+
const parsed = parseReasoningEffortInput(rawValue);
|
|
48117
|
+
const modelInfo = agentLoop.getActiveModelMetadata();
|
|
48118
|
+
const nextEffort = parsed.clear ? void 0 : modelInfo ? resolveReasoningEffortForModel(modelInfo, parsed.effort) : parsed.effort;
|
|
48119
|
+
agentLoop.updateReasoningEffort(nextEffort);
|
|
48120
|
+
bus.emitEvent({
|
|
48121
|
+
payload: sessionInfoSnapshot(agentLoop, toolRegistry),
|
|
48122
|
+
session_id: agentLoop.sessionId,
|
|
48123
|
+
type: "session.info"
|
|
48124
|
+
});
|
|
48125
|
+
return {
|
|
48126
|
+
info: sessionInfoSnapshot(agentLoop, toolRegistry),
|
|
48127
|
+
value: nextEffort ?? "default"
|
|
48128
|
+
};
|
|
48129
|
+
}
|
|
47655
48130
|
if (key === "model") {
|
|
47656
48131
|
if (!rawValue) {
|
|
47657
48132
|
return { value: agentLoop.model };
|
|
@@ -47665,6 +48140,15 @@ ${helpMessage}` : field.label;
|
|
|
47665
48140
|
provider = flagsStripped[provIdx + 1];
|
|
47666
48141
|
flagsStripped.splice(provIdx, 2);
|
|
47667
48142
|
}
|
|
48143
|
+
let requestedReasoningEffort;
|
|
48144
|
+
let clearReasoningEffort = false;
|
|
48145
|
+
const effortIdx = flagsStripped.findIndex((t) => t === "--reasoning-effort" || t === "--effort");
|
|
48146
|
+
if (effortIdx >= 0) {
|
|
48147
|
+
const parsed = parseReasoningEffortInput(flagsStripped[effortIdx + 1] ?? "");
|
|
48148
|
+
requestedReasoningEffort = parsed.effort;
|
|
48149
|
+
clearReasoningEffort = parsed.clear;
|
|
48150
|
+
flagsStripped.splice(effortIdx, flagsStripped[effortIdx + 1] ? 2 : 1);
|
|
48151
|
+
}
|
|
47668
48152
|
const model = flagsStripped.join(" ").trim();
|
|
47669
48153
|
if (!model) {
|
|
47670
48154
|
throw new Error("config.set model: missing model id");
|
|
@@ -47673,15 +48157,17 @@ ${helpMessage}` : field.label;
|
|
|
47673
48157
|
throw new Error(`config.set model: unknown provider "${provider}"`);
|
|
47674
48158
|
}
|
|
47675
48159
|
const credential_warning = isProviderAuthenticated(provider) ? void 0 : `${PROVIDER_LABELS[provider]} is not connected \u2014 run /connect to add credentials`;
|
|
48160
|
+
const modelInfo = agentLoop.getModelMetadata(provider, model);
|
|
48161
|
+
const reasoningEffort = clearReasoningEffort ? void 0 : requestedReasoningEffort ? modelInfo ? resolveReasoningEffortForModel(modelInfo, requestedReasoningEffort) : requestedReasoningEffort : modelInfo ? resolveReasoningEffortForModel(modelInfo, agentLoop.reasoningEffort) : agentLoop.reasoningEffort;
|
|
47676
48162
|
try {
|
|
47677
|
-
agentLoop.switchModel(provider, model);
|
|
48163
|
+
agentLoop.switchModel(provider, model, reasoningEffort);
|
|
47678
48164
|
} catch (err) {
|
|
47679
48165
|
throw new Error(err instanceof Error ? err.message : String(err));
|
|
47680
48166
|
}
|
|
47681
48167
|
if (persistGlobal) {
|
|
47682
48168
|
const next = {
|
|
47683
48169
|
...agentConfig,
|
|
47684
|
-
llm: { ...agentConfig.llm, model, provider }
|
|
48170
|
+
llm: { ...agentConfig.llm, model, provider, model_reasoning_effort: reasoningEffort }
|
|
47685
48171
|
};
|
|
47686
48172
|
try {
|
|
47687
48173
|
saveAgentConfig(next);
|
|
@@ -47698,6 +48184,7 @@ ${helpMessage}` : field.label;
|
|
|
47698
48184
|
return {
|
|
47699
48185
|
credential_warning,
|
|
47700
48186
|
info: sessionInfoSnapshot(agentLoop, toolRegistry),
|
|
48187
|
+
reasoning_effort: reasoningEffort,
|
|
47701
48188
|
value: model
|
|
47702
48189
|
};
|
|
47703
48190
|
}
|
|
@@ -47952,7 +48439,11 @@ ${helpMessage}` : field.label;
|
|
|
47952
48439
|
bus.registerRpc("model.switch", (params) => {
|
|
47953
48440
|
const provider = String(params.provider ?? agentLoop.providerName);
|
|
47954
48441
|
const model = String(params.model ?? agentLoop.model);
|
|
47955
|
-
|
|
48442
|
+
const rawEffort = typeof params.reasoning_effort === "string" ? params.reasoning_effort : typeof params.effort === "string" ? params.effort : "";
|
|
48443
|
+
const parsedEffort = rawEffort ? parseReasoningEffortInput(rawEffort) : void 0;
|
|
48444
|
+
const modelInfo = agentLoop.getModelMetadata(provider, model);
|
|
48445
|
+
const reasoningEffort = parsedEffort?.clear ? void 0 : parsedEffort?.effort ? modelInfo ? resolveReasoningEffortForModel(modelInfo, parsedEffort.effort) : parsedEffort.effort : modelInfo ? resolveReasoningEffortForModel(modelInfo, agentLoop.reasoningEffort) : agentLoop.reasoningEffort;
|
|
48446
|
+
agentLoop.switchModel(provider, model, reasoningEffort);
|
|
47956
48447
|
return {
|
|
47957
48448
|
info: sessionInfoSnapshot(agentLoop, toolRegistry),
|
|
47958
48449
|
ok: true
|
|
@@ -47964,12 +48455,20 @@ ${helpMessage}` : field.label;
|
|
|
47964
48455
|
const liveResults = await Promise.all(
|
|
47965
48456
|
PROVIDERS2.map((slug) => fetchLiveModels(slug, agentConfig, currentModel))
|
|
47966
48457
|
);
|
|
48458
|
+
for (let i = 0; i < PROVIDERS2.length; i++) {
|
|
48459
|
+
const provider = PROVIDERS2[i];
|
|
48460
|
+
const models = liveResults[i]?.models;
|
|
48461
|
+
if (provider && models) {
|
|
48462
|
+
agentLoop.setProviderModelMetadata(provider, models);
|
|
48463
|
+
}
|
|
48464
|
+
}
|
|
47967
48465
|
const providers = PROVIDERS2.map(
|
|
47968
48466
|
(slug, i) => buildProviderOption(slug, currentProvider, currentModel, liveResults[i]?.models, liveResults[i]?.error)
|
|
47969
48467
|
);
|
|
47970
48468
|
return {
|
|
47971
48469
|
model: currentModel,
|
|
47972
48470
|
provider: currentProvider,
|
|
48471
|
+
reasoning_effort: agentLoop.reasoningEffort,
|
|
47973
48472
|
providers
|
|
47974
48473
|
};
|
|
47975
48474
|
});
|
|
@@ -48085,8 +48584,7 @@ ${helpMessage}` : field.label;
|
|
|
48085
48584
|
return { cancelled: true, slug: entry.slug };
|
|
48086
48585
|
});
|
|
48087
48586
|
bus.registerRpc("commands.catalog", () => {
|
|
48088
|
-
|
|
48089
|
-
return buildCommandsCatalog({ skillCount });
|
|
48587
|
+
return buildCommandsCatalog({ skillCount: discoverSkills().length });
|
|
48090
48588
|
});
|
|
48091
48589
|
bus.registerRpc("completion.query", () => ({
|
|
48092
48590
|
items: []
|
|
@@ -48094,14 +48592,9 @@ ${helpMessage}` : field.label;
|
|
|
48094
48592
|
bus.registerRpc("complete.slash", (params) => buildSlashCompletions(String(params.text ?? "")));
|
|
48095
48593
|
bus.registerRpc("complete.path", (params) => buildPathCompletions(String(params.word ?? "")));
|
|
48096
48594
|
bus.registerRpc("skills.catalog", () => {
|
|
48097
|
-
const tools = toolRegistry.listTools();
|
|
48098
|
-
const skillTools = tools.filter((t) => /^skill[:_-]/i.test(t.name));
|
|
48099
48595
|
return {
|
|
48100
|
-
categories:
|
|
48101
|
-
skills:
|
|
48102
|
-
description: t.description,
|
|
48103
|
-
name: t.name.replace(/^skill[:_-]/i, "")
|
|
48104
|
-
}))
|
|
48596
|
+
categories: Object.keys(registrySkillsByCategory()).sort(),
|
|
48597
|
+
skills: listRegistrySkills()
|
|
48105
48598
|
};
|
|
48106
48599
|
});
|
|
48107
48600
|
bus.registerRpc("tools.list", () => ({
|
|
@@ -48133,11 +48626,11 @@ ${helpMessage}` : field.label;
|
|
|
48133
48626
|
return { output: lines.join("\n") };
|
|
48134
48627
|
}
|
|
48135
48628
|
if (head === "skills") {
|
|
48136
|
-
const skills =
|
|
48629
|
+
const skills = listRegistrySkills();
|
|
48137
48630
|
if (!skills.length) {
|
|
48138
|
-
return { output: "no skills
|
|
48631
|
+
return { output: "no skills available" };
|
|
48139
48632
|
}
|
|
48140
|
-
const lines = [`${skills.length} skills
|
|
48633
|
+
const lines = [`${skills.length} skills available`, ""];
|
|
48141
48634
|
for (const s of skills.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
48142
48635
|
const desc = s.description ? ` \u2014 ${s.description}` : "";
|
|
48143
48636
|
lines.push(` ${s.name}${desc}`);
|
|
@@ -48413,7 +48906,7 @@ ${helpMessage}` : field.label;
|
|
|
48413
48906
|
const meta = agentLoop.getSessionMeta();
|
|
48414
48907
|
const tools = toolRegistry.listTools();
|
|
48415
48908
|
const cost = `$${usage2.cost_usd.toFixed(4)}`;
|
|
48416
|
-
const ctx = usage2.context_max > 0 ? `${usage2.context_percent}
|
|
48909
|
+
const ctx = usage2.context_max > 0 ? `${formatContextPercent(usage2.context_percent)} (${usage2.context_used}/${usage2.context_max})` : "?";
|
|
48417
48910
|
const lines = [
|
|
48418
48911
|
`Session: ${meta.id}`,
|
|
48419
48912
|
`Title: ${meta.summary || "(untitled)"}`,
|
|
@@ -48543,7 +49036,7 @@ ${helpMessage}` : field.label;
|
|
|
48543
49036
|
let fileSize = 0;
|
|
48544
49037
|
try {
|
|
48545
49038
|
buffer = readFileSync28(path3);
|
|
48546
|
-
fileSize =
|
|
49039
|
+
fileSize = statSync4(path3).size;
|
|
48547
49040
|
} catch (err) {
|
|
48548
49041
|
throw new Error(`image.attach: ${err instanceof Error ? err.message : String(err)}`);
|
|
48549
49042
|
}
|
|
@@ -48638,9 +49131,9 @@ ${helpMessage}` : field.label;
|
|
|
48638
49131
|
bus.registerRpc("spawn_tree.load", () => ({ subagents: [] }));
|
|
48639
49132
|
bus.registerRpc("skills.reload", async () => {
|
|
48640
49133
|
try {
|
|
48641
|
-
|
|
48642
|
-
const skillCount =
|
|
48643
|
-
return { output: `Skills reloaded \xB7 ${skillCount} skills
|
|
49134
|
+
clearSkillsCache();
|
|
49135
|
+
const skillCount = discoverSkills().length;
|
|
49136
|
+
return { output: `Skills reloaded \xB7 ${skillCount} skills available` };
|
|
48644
49137
|
} catch (err) {
|
|
48645
49138
|
return { output: `skills reload failed: ${err instanceof Error ? err.message : String(err)}` };
|
|
48646
49139
|
}
|
|
@@ -48648,18 +49141,28 @@ ${helpMessage}` : field.label;
|
|
|
48648
49141
|
bus.registerRpc("skills.manage", (params) => {
|
|
48649
49142
|
const action2 = String(params.action ?? "").toLowerCase();
|
|
48650
49143
|
const query = String(params.query ?? "").trim().toLowerCase();
|
|
48651
|
-
const
|
|
49144
|
+
const skills = listRegistrySkills();
|
|
48652
49145
|
if (action2 === "list") {
|
|
48653
|
-
return { skills:
|
|
49146
|
+
return { skills: registrySkillsByCategory() };
|
|
48654
49147
|
}
|
|
48655
49148
|
if (action2 === "inspect") {
|
|
48656
|
-
const hit =
|
|
49149
|
+
const hit = query ? findSkill(query) : null;
|
|
48657
49150
|
if (!hit) return { info: null };
|
|
48658
|
-
return {
|
|
49151
|
+
return {
|
|
49152
|
+
info: {
|
|
49153
|
+
category: hit.source,
|
|
49154
|
+
description: skillDescription(hit),
|
|
49155
|
+
entrypoint: hit.entrypoint,
|
|
49156
|
+
name: hit.name,
|
|
49157
|
+
path: hit.filePath,
|
|
49158
|
+
root_dir: hit.rootDir,
|
|
49159
|
+
source: hit.source
|
|
49160
|
+
}
|
|
49161
|
+
};
|
|
48659
49162
|
}
|
|
48660
49163
|
if (action2 === "search") {
|
|
48661
49164
|
if (!query) return { results: [] };
|
|
48662
|
-
const results =
|
|
49165
|
+
const results = skills.filter((s) => s.name.toLowerCase().includes(query) || (s.description ?? "").toLowerCase().includes(query)).map((s) => ({ description: s.description, name: s.name }));
|
|
48663
49166
|
return { results };
|
|
48664
49167
|
}
|
|
48665
49168
|
if (action2 === "install") {
|
|
@@ -48683,8 +49186,30 @@ ${helpMessage}` : field.label;
|
|
|
48683
49186
|
unknown: names.length ? names : [`/tools ${action2 || "?"} is not yet wired in the new TUI \u2014 use the legacy --legacy-ui flag for full toolset toggles`]
|
|
48684
49187
|
};
|
|
48685
49188
|
});
|
|
48686
|
-
bus.registerRpc("command.dispatch", (params) => {
|
|
49189
|
+
bus.registerRpc("command.dispatch", async (params) => {
|
|
48687
49190
|
const name = String(params.name ?? "").trim();
|
|
49191
|
+
const arg = String(params.arg ?? "").trim();
|
|
49192
|
+
if (name) {
|
|
49193
|
+
const skill = findSkill(name);
|
|
49194
|
+
if (skill) {
|
|
49195
|
+
if (!toolRegistry.getTool("invoke_skill")) {
|
|
49196
|
+
return { output: "skill invocation is unavailable: invoke_skill tool is not registered", type: "exec" };
|
|
49197
|
+
}
|
|
49198
|
+
try {
|
|
49199
|
+
const result = await toolRegistry.execute("invoke_skill", { skill: skill.name, args: arg });
|
|
49200
|
+
return { output: formatSkillExecutionResult(result), type: "exec" };
|
|
49201
|
+
} catch (err) {
|
|
49202
|
+
return { output: `skill failed (${skill.name}): ${err instanceof Error ? err.message : String(err)}`, type: "exec" };
|
|
49203
|
+
}
|
|
49204
|
+
}
|
|
49205
|
+
const matches = findSkillMatches(name);
|
|
49206
|
+
if (matches.length > 1) {
|
|
49207
|
+
return {
|
|
49208
|
+
output: `ambiguous skill command /${name}: ${matches.slice(0, 8).map((s) => s.name).join(", ")}${matches.length > 8 ? ", \u2026" : ""}`,
|
|
49209
|
+
type: "exec"
|
|
49210
|
+
};
|
|
49211
|
+
}
|
|
49212
|
+
}
|
|
48688
49213
|
return { output: name ? `unknown command: /${name}` : "(no command)", type: "exec" };
|
|
48689
49214
|
});
|
|
48690
49215
|
bus.registerRpc("delegation.status", () => ({ delegated: [], paused: false }));
|
|
@@ -48714,14 +49239,13 @@ ${helpMessage}` : field.label;
|
|
|
48714
49239
|
}
|
|
48715
49240
|
};
|
|
48716
49241
|
}
|
|
48717
|
-
var PROVIDERS2, PROVIDER_LABELS, PROVIDER_AUTH, isProviderAuthenticated, buildProviderOption, fetchLiveModels, BRIDGE_SOURCES, isBridgeSource, inferBridgeSource, bridgeLabels, bridgeEventLabels, stripBridgeGlyph, firstLogLine, bridgeUser, formatBridgeText, runProcess, contentToText, sessionMessageToMarkdown,
|
|
49242
|
+
var PROVIDERS2, PROVIDER_LABELS, PROVIDER_AUTH, isProviderAuthenticated, buildProviderOption, fetchLiveModels, parseReasoningEffortInput, skillDescription, listRegistrySkills, registrySkillsByCategory, formatSkillExecutionResult, reasoningEffortsForModel, resolveReasoningEffortForModel, BRIDGE_SOURCES, isBridgeSource, inferBridgeSource, bridgeLabels, bridgeEventLabels, stripBridgeGlyph, firstLogLine, bridgeUser, formatBridgeText, runProcess, contentToText, sessionMessageToMarkdown, sessionInfoSnapshot, MCP_TOOL_PREFIX, MAX_TOTAL_TOOLS, syncMcpTools;
|
|
48718
49243
|
var init_rpcHandlers = __esm({
|
|
48719
49244
|
"src/rpcHandlers.ts"() {
|
|
48720
49245
|
"use strict";
|
|
48721
49246
|
init_connect();
|
|
48722
49247
|
init_config();
|
|
48723
49248
|
init_copilot_auth();
|
|
48724
|
-
init_context_manager();
|
|
48725
49249
|
init_eventBridge();
|
|
48726
49250
|
init_fork();
|
|
48727
49251
|
init_provider_auth();
|
|
@@ -48733,6 +49257,11 @@ var init_rpcHandlers = __esm({
|
|
|
48733
49257
|
init_clipboard();
|
|
48734
49258
|
init_models_static();
|
|
48735
49259
|
init_providers();
|
|
49260
|
+
init_types();
|
|
49261
|
+
init_skills();
|
|
49262
|
+
init_registry2();
|
|
49263
|
+
init_usage();
|
|
49264
|
+
init_usageSnapshot();
|
|
48736
49265
|
init_registry3();
|
|
48737
49266
|
PROVIDERS2 = ["anthropic", "openai", "github-copilot"];
|
|
48738
49267
|
PROVIDER_LABELS = {
|
|
@@ -48757,6 +49286,7 @@ var init_rpcHandlers = __esm({
|
|
|
48757
49286
|
const auth = PROVIDER_AUTH[slug];
|
|
48758
49287
|
const authenticated = isProviderAuthenticated(slug);
|
|
48759
49288
|
let models = [];
|
|
49289
|
+
let modelOptions = [];
|
|
48760
49290
|
let source = "static";
|
|
48761
49291
|
if (authenticated) {
|
|
48762
49292
|
if (liveModels && liveModels.length > 0) {
|
|
@@ -48765,10 +49295,12 @@ var init_rpcHandlers = __esm({
|
|
|
48765
49295
|
if (seen.has(m.id)) continue;
|
|
48766
49296
|
seen.add(m.id);
|
|
48767
49297
|
models.push(m.id);
|
|
49298
|
+
modelOptions.push(m);
|
|
48768
49299
|
}
|
|
48769
49300
|
source = "live";
|
|
48770
49301
|
} else {
|
|
48771
49302
|
models = STATIC_MODELS[slug].map((m) => m.id);
|
|
49303
|
+
modelOptions = STATIC_MODELS[slug].map((m) => ({ id: m.id, name: m.name }));
|
|
48772
49304
|
source = "static";
|
|
48773
49305
|
}
|
|
48774
49306
|
}
|
|
@@ -48784,6 +49316,7 @@ var init_rpcHandlers = __esm({
|
|
|
48784
49316
|
is_current: slug === currentProvider,
|
|
48785
49317
|
key_env: auth.key_env,
|
|
48786
49318
|
models,
|
|
49319
|
+
model_options: modelOptions,
|
|
48787
49320
|
name: PROVIDER_LABELS[slug],
|
|
48788
49321
|
slug,
|
|
48789
49322
|
source,
|
|
@@ -48819,6 +49352,54 @@ var init_rpcHandlers = __esm({
|
|
|
48819
49352
|
return { error: err instanceof Error ? err.message : String(err), models: null };
|
|
48820
49353
|
}
|
|
48821
49354
|
}, "fetchLiveModels");
|
|
49355
|
+
parseReasoningEffortInput = /* @__PURE__ */ __name((value) => {
|
|
49356
|
+
const normalized = value.trim().toLowerCase();
|
|
49357
|
+
if (!normalized || normalized === "default" || normalized === "clear" || normalized === "auto") {
|
|
49358
|
+
return { clear: true };
|
|
49359
|
+
}
|
|
49360
|
+
if (!isReasoningEffort(normalized)) {
|
|
49361
|
+
throw new Error(`unknown reasoning effort: ${value}`);
|
|
49362
|
+
}
|
|
49363
|
+
return { clear: false, effort: normalized };
|
|
49364
|
+
}, "parseReasoningEffortInput");
|
|
49365
|
+
skillDescription = /* @__PURE__ */ __name((skill) => skill.meta.whenToUse || skill.meta.description || "", "skillDescription");
|
|
49366
|
+
listRegistrySkills = /* @__PURE__ */ __name(() => discoverSkills().map((skill) => ({
|
|
49367
|
+
category: skill.source,
|
|
49368
|
+
description: skillDescription(skill),
|
|
49369
|
+
entrypoint: skill.entrypoint,
|
|
49370
|
+
name: skill.name,
|
|
49371
|
+
path: skill.filePath,
|
|
49372
|
+
root_dir: skill.rootDir,
|
|
49373
|
+
source: skill.source
|
|
49374
|
+
})), "listRegistrySkills");
|
|
49375
|
+
registrySkillsByCategory = /* @__PURE__ */ __name(() => {
|
|
49376
|
+
const grouped = {};
|
|
49377
|
+
for (const skill of discoverSkills()) {
|
|
49378
|
+
const category = skill.source;
|
|
49379
|
+
grouped[category] ??= [];
|
|
49380
|
+
grouped[category].push(skill.name);
|
|
49381
|
+
}
|
|
49382
|
+
for (const skills of Object.values(grouped)) {
|
|
49383
|
+
skills.sort((a, b) => a.localeCompare(b));
|
|
49384
|
+
}
|
|
49385
|
+
return grouped;
|
|
49386
|
+
}, "registrySkillsByCategory");
|
|
49387
|
+
formatSkillExecutionResult = /* @__PURE__ */ __name((value) => {
|
|
49388
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
49389
|
+
return typeof value === "string" ? value : JSON.stringify(value ?? null);
|
|
49390
|
+
}
|
|
49391
|
+
const result = value;
|
|
49392
|
+
if (result.success === false) {
|
|
49393
|
+
return `skill failed${result.skill ? ` (${String(result.skill)})` : ""}: ${String(result.error ?? "unknown error")}`;
|
|
49394
|
+
}
|
|
49395
|
+
return typeof result.result === "string" ? result.result : JSON.stringify(result);
|
|
49396
|
+
}, "formatSkillExecutionResult");
|
|
49397
|
+
reasoningEffortsForModel = /* @__PURE__ */ __name((model) => model?.supportedReasoningEfforts?.map((option) => option.effort) ?? [], "reasoningEffortsForModel");
|
|
49398
|
+
resolveReasoningEffortForModel = /* @__PURE__ */ __name((model, requested) => {
|
|
49399
|
+
const supported = reasoningEffortsForModel(model);
|
|
49400
|
+
const selected = requested && supported.includes(requested) ? requested : void 0;
|
|
49401
|
+
return selected ?? model?.defaultReasoningEffort ?? defaultReasoningEffort(supported);
|
|
49402
|
+
}, "resolveReasoningEffortForModel");
|
|
48822
49403
|
BRIDGE_SOURCES = ["telegram", "teams", "feishu", "wechat"];
|
|
48823
49404
|
isBridgeSource = /* @__PURE__ */ __name((value) => typeof value === "string" && BRIDGE_SOURCES.includes(value), "isBridgeSource");
|
|
48824
49405
|
inferBridgeSource = /* @__PURE__ */ __name((event) => {
|
|
@@ -48916,28 +49497,10 @@ ${raw}`;
|
|
|
48916
49497
|
}
|
|
48917
49498
|
return [];
|
|
48918
49499
|
}, "sessionMessageToMarkdown");
|
|
48919
|
-
usageSnapshot = /* @__PURE__ */ __name((agentLoop) => {
|
|
48920
|
-
const cost = agentLoop.costTracker.getSessionCost();
|
|
48921
|
-
const contextMax = getContextWindow(agentLoop.model);
|
|
48922
|
-
const contextUsed = agentLoop.contextManager.lastPromptTokens;
|
|
48923
|
-
return {
|
|
48924
|
-
cache_read: cost.totalCacheReadTokens,
|
|
48925
|
-
cache_write: cost.totalCacheCreationTokens,
|
|
48926
|
-
calls: cost.turns,
|
|
48927
|
-
context_max: contextMax,
|
|
48928
|
-
context_percent: contextMax > 0 ? Math.round(contextUsed / contextMax * 100) : 0,
|
|
48929
|
-
context_used: contextUsed,
|
|
48930
|
-
cost_status: "estimated",
|
|
48931
|
-
cost_usd: cost.totalCostUSD,
|
|
48932
|
-
input: cost.totalInputTokens,
|
|
48933
|
-
model: agentLoop.model,
|
|
48934
|
-
output: cost.totalOutputTokens,
|
|
48935
|
-
total: cost.totalInputTokens + cost.totalOutputTokens + cost.totalCacheReadTokens + cost.totalCacheCreationTokens
|
|
48936
|
-
};
|
|
48937
|
-
}, "usageSnapshot");
|
|
48938
49500
|
sessionInfoSnapshot = /* @__PURE__ */ __name((agentLoop, toolRegistry) => ({
|
|
48939
49501
|
cwd: process.cwd(),
|
|
48940
49502
|
model: agentLoop.model,
|
|
49503
|
+
reasoning_effort: agentLoop.reasoningEffort,
|
|
48941
49504
|
skills: {},
|
|
48942
49505
|
system_prompt: "",
|
|
48943
49506
|
tools: { [agentLoop.providerName]: toolRegistry.listTools().map((t) => t.name) },
|
|
@@ -49191,7 +49754,7 @@ var init_gatewayContext = __esm({
|
|
|
49191
49754
|
});
|
|
49192
49755
|
|
|
49193
49756
|
// src/domain/paths.ts
|
|
49194
|
-
var shortCwd,
|
|
49757
|
+
var shortCwd, fullCwdBranch;
|
|
49195
49758
|
var init_paths = __esm({
|
|
49196
49759
|
"src/domain/paths.ts"() {
|
|
49197
49760
|
"use strict";
|
|
@@ -49200,13 +49763,7 @@ var init_paths = __esm({
|
|
|
49200
49763
|
const p = h && cwd.startsWith(h) ? `~${cwd.slice(h.length)}` : cwd;
|
|
49201
49764
|
return p.length <= max ? p : `\u2026${p.slice(-(max - 1))}`;
|
|
49202
49765
|
}, "shortCwd");
|
|
49203
|
-
|
|
49204
|
-
if (!branch) {
|
|
49205
|
-
return shortCwd(cwd, max);
|
|
49206
|
-
}
|
|
49207
|
-
const tag = ` (${branch.length > 16 ? `\u2026${branch.slice(-15)}` : branch})`;
|
|
49208
|
-
return `${shortCwd(cwd, Math.max(8, max - tag.length))}${tag}`;
|
|
49209
|
-
}, "fmtCwdBranch");
|
|
49766
|
+
fullCwdBranch = /* @__PURE__ */ __name((cwd, branch) => branch ? `${cwd} (${branch})` : cwd, "fullCwdBranch");
|
|
49210
49767
|
}
|
|
49211
49768
|
});
|
|
49212
49769
|
|
|
@@ -49574,9 +50131,9 @@ var init_useVirtualHistory = __esm({
|
|
|
49574
50131
|
viewportHeight
|
|
49575
50132
|
}) => itemCount > 0 && viewportHeight > 0 && !sticky && !liveTailActive, "shouldSetVirtualClamp");
|
|
49576
50133
|
ensureVirtualItemHeight = /* @__PURE__ */ __name((heights, key, index, estimate, estimateHeight) => {
|
|
49577
|
-
const
|
|
49578
|
-
if (
|
|
49579
|
-
return Math.max(1, Math.floor(
|
|
50134
|
+
const cached7 = heights.get(key);
|
|
50135
|
+
if (cached7 !== void 0) {
|
|
50136
|
+
return Math.max(1, Math.floor(cached7));
|
|
49580
50137
|
}
|
|
49581
50138
|
const seeded = Math.max(1, Math.floor(estimateHeight?.(index, key) ?? estimate));
|
|
49582
50139
|
heights.set(key, seeded);
|
|
@@ -51508,7 +52065,7 @@ function createSlashHandler(ctx) {
|
|
|
51508
52065
|
}
|
|
51509
52066
|
}
|
|
51510
52067
|
}
|
|
51511
|
-
|
|
52068
|
+
const renderSlashExec = /* @__PURE__ */ __name((r) => {
|
|
51512
52069
|
if (stale()) {
|
|
51513
52070
|
return;
|
|
51514
52071
|
}
|
|
@@ -51517,33 +52074,41 @@ function createSlashHandler(ctx) {
|
|
|
51517
52074
|
${body}` : body;
|
|
51518
52075
|
const long = text.length > 180 || text.split("\n").filter(Boolean).length > 2;
|
|
51519
52076
|
long ? page(text, parsed.name[0].toUpperCase() + parsed.name.slice(1)) : sys(text);
|
|
51520
|
-
})
|
|
51521
|
-
|
|
51522
|
-
|
|
51523
|
-
|
|
51524
|
-
|
|
51525
|
-
|
|
51526
|
-
|
|
51527
|
-
|
|
51528
|
-
|
|
51529
|
-
|
|
51530
|
-
|
|
51531
|
-
|
|
51532
|
-
|
|
51533
|
-
|
|
51534
|
-
|
|
51535
|
-
|
|
52077
|
+
}, "renderSlashExec");
|
|
52078
|
+
const runSlashExec = /* @__PURE__ */ __name(() => {
|
|
52079
|
+
gw.request("slash.exec", { command: cmd.slice(1), session_id: sid }).then(renderSlashExec).catch(guardedErr);
|
|
52080
|
+
}, "runSlashExec");
|
|
52081
|
+
const skillHint = findSkill(parsed.name);
|
|
52082
|
+
if (skillHint) {
|
|
52083
|
+
sys(`\u26A1 loading skill: ${skillHint.name}`);
|
|
52084
|
+
}
|
|
52085
|
+
gw.request("command.dispatch", { arg: parsed.arg, name: parsed.name, session_id: sid }).then((raw) => {
|
|
52086
|
+
if (stale()) {
|
|
52087
|
+
return;
|
|
52088
|
+
}
|
|
52089
|
+
const d = asCommandDispatch(raw);
|
|
52090
|
+
if (!d) {
|
|
52091
|
+
return runSlashExec();
|
|
52092
|
+
}
|
|
52093
|
+
if (d.type === "exec" || d.type === "plugin") {
|
|
52094
|
+
return sys(d.output || "(no output)");
|
|
52095
|
+
}
|
|
52096
|
+
if (d.type === "alias") {
|
|
52097
|
+
return handler(`/${d.target}${argTail}`);
|
|
52098
|
+
}
|
|
52099
|
+
if (d.type === "skill") {
|
|
52100
|
+
if (!skillHint || skillHint.name !== d.name) {
|
|
51536
52101
|
sys(`\u26A1 loading skill: ${d.name}`);
|
|
51537
|
-
return d.message?.trim() ? send(d.message) : sys(`/${parsed.name}: skill payload missing message`);
|
|
51538
52102
|
}
|
|
51539
|
-
|
|
51540
|
-
|
|
51541
|
-
|
|
51542
|
-
|
|
51543
|
-
|
|
52103
|
+
return d.message?.trim() ? send(d.message) : sys(`/${parsed.name}: skill payload missing message`);
|
|
52104
|
+
}
|
|
52105
|
+
if (d.type === "send") {
|
|
52106
|
+
if (d.notice?.trim()) {
|
|
52107
|
+
sys(d.notice);
|
|
51544
52108
|
}
|
|
51545
|
-
|
|
51546
|
-
|
|
52109
|
+
return d.message?.trim() ? send(d.message) : sys(`/${parsed.name}: empty message`);
|
|
52110
|
+
}
|
|
52111
|
+
}).catch(runSlashExec);
|
|
51547
52112
|
return true;
|
|
51548
52113
|
}, "handler");
|
|
51549
52114
|
return handler;
|
|
@@ -51553,6 +52118,7 @@ var init_createSlashHandler = __esm({
|
|
|
51553
52118
|
"use strict";
|
|
51554
52119
|
init_slash();
|
|
51555
52120
|
init_rpc();
|
|
52121
|
+
init_registry2();
|
|
51556
52122
|
init_registry4();
|
|
51557
52123
|
init_uiStore();
|
|
51558
52124
|
__name(createSlashHandler, "createSlashHandler");
|
|
@@ -53170,6 +53736,13 @@ var init_paste = __esm({
|
|
|
53170
53736
|
|
|
53171
53737
|
// src/app/useSubmission.ts
|
|
53172
53738
|
import { useCallback as useCallback9, useEffect as useEffect11, useRef as useRef12 } from "react";
|
|
53739
|
+
function resolveCompletionSubmit(value, row, replaceFrom) {
|
|
53740
|
+
if (!row?.text) return null;
|
|
53741
|
+
const text = value.startsWith("/") && row.text.startsWith("/") ? row.text.slice(1) : row.text;
|
|
53742
|
+
const next = value.slice(0, replaceFrom) + text;
|
|
53743
|
+
if (next === value) return null;
|
|
53744
|
+
return { next, submit: value.startsWith("/") && row.text.startsWith("/") && row.meta?.startsWith("skill \xB7") === true };
|
|
53745
|
+
}
|
|
53173
53746
|
function useSubmission(opts) {
|
|
53174
53747
|
const {
|
|
53175
53748
|
appendMessage,
|
|
@@ -53394,12 +53967,9 @@ function useSubmission(opts) {
|
|
|
53394
53967
|
(value) => {
|
|
53395
53968
|
if (composerState.completions.length) {
|
|
53396
53969
|
const row = composerState.completions[composerState.compIdx];
|
|
53397
|
-
|
|
53398
|
-
|
|
53399
|
-
|
|
53400
|
-
if (next !== value) {
|
|
53401
|
-
return composerActions.setInput(next);
|
|
53402
|
-
}
|
|
53970
|
+
const completion = resolveCompletionSubmit(value, row, composerState.compReplace);
|
|
53971
|
+
if (completion) {
|
|
53972
|
+
return completion.submit ? dispatchSubmission(completion.next) : composerActions.setInput(completion.next);
|
|
53403
53973
|
}
|
|
53404
53974
|
}
|
|
53405
53975
|
if (!value.trim() && !composerState.inputBuf.length) {
|
|
@@ -53456,6 +54026,7 @@ var init_useSubmission = __esm({
|
|
|
53456
54026
|
return (value) => value.replace(PASTE_SNIPPET_RE, (tok) => byLabel.get(tok)?.shift() ?? tok);
|
|
53457
54027
|
}, "expandSnips");
|
|
53458
54028
|
spliceMatches = /* @__PURE__ */ __name((text, matches, results) => matches.reduceRight((acc, m, i) => acc.slice(0, m.index) + results[i] + acc.slice(m.index + m[0].length), text), "spliceMatches");
|
|
54029
|
+
__name(resolveCompletionSubmit, "resolveCompletionSubmit");
|
|
53459
54030
|
__name(useSubmission, "useSubmission");
|
|
53460
54031
|
}
|
|
53461
54032
|
});
|
|
@@ -54040,7 +54611,7 @@ function useMainApp(gw) {
|
|
|
54040
54611
|
const gitBranch = useGitBranch(cwd);
|
|
54041
54612
|
const appStatus = useMemo7(
|
|
54042
54613
|
() => ({
|
|
54043
|
-
cwdLabel:
|
|
54614
|
+
cwdLabel: fullCwdBranch(cwd, gitBranch),
|
|
54044
54615
|
goodVibesTick,
|
|
54045
54616
|
sessionStartedAt: ui.sid ? sessionStartedAt : null,
|
|
54046
54617
|
showStickyPrompt: !!stickyPrompt,
|
|
@@ -55110,7 +55681,7 @@ import { useStore as useStore5 } from "@nanostores/react";
|
|
|
55110
55681
|
import { useEffect as useEffect14, useMemo as useMemo10, useRef as useRef15, useState as useState15 } from "react";
|
|
55111
55682
|
import unicodeSpinners from "unicode-animations";
|
|
55112
55683
|
import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
55113
|
-
function
|
|
55684
|
+
function useTickerText(startedAt) {
|
|
55114
55685
|
const ui = useStore5($uiState);
|
|
55115
55686
|
const style = ui.indicatorStyle;
|
|
55116
55687
|
const [tick, setTick] = useState15(() => Math.floor(Math.random() * 1e3));
|
|
@@ -55133,11 +55704,7 @@ function FaceTicker({ color, startedAt }) {
|
|
|
55133
55704
|
const verb = VERBS[verbTick % VERBS.length] ?? "";
|
|
55134
55705
|
const verbSegment = showVerb ? ` ${padVerb(verb)}` : "";
|
|
55135
55706
|
const durationSegment = startedAt ? ` \xB7 ${fmtDuration(now2 - startedAt)}` : "";
|
|
55136
|
-
return
|
|
55137
|
-
frame,
|
|
55138
|
-
verbSegment,
|
|
55139
|
-
durationSegment
|
|
55140
|
-
] });
|
|
55707
|
+
return `${frame}${verbSegment}${durationSegment}`;
|
|
55141
55708
|
}
|
|
55142
55709
|
function ctxBarColor(pct, t) {
|
|
55143
55710
|
if (pct == null) {
|
|
@@ -55159,6 +55726,27 @@ function ctxBar(pct, w = 10) {
|
|
|
55159
55726
|
const filled = Math.round(p / 100 * w);
|
|
55160
55727
|
return "\u2588".repeat(filled) + "\u2591".repeat(w - filled);
|
|
55161
55728
|
}
|
|
55729
|
+
function fitVisible(text, width) {
|
|
55730
|
+
if (width <= 0) return "";
|
|
55731
|
+
if (stringWidth(text) <= width) return text + " ".repeat(width - stringWidth(text));
|
|
55732
|
+
let out = "";
|
|
55733
|
+
for (const ch of Array.from(text)) {
|
|
55734
|
+
if (stringWidth(out + ch + "\u2026") > width) break;
|
|
55735
|
+
out += ch;
|
|
55736
|
+
}
|
|
55737
|
+
return out + "\u2026" + " ".repeat(Math.max(0, width - stringWidth(out + "\u2026")));
|
|
55738
|
+
}
|
|
55739
|
+
function truncateTailVisible(text, width) {
|
|
55740
|
+
return fitVisible(text, width);
|
|
55741
|
+
}
|
|
55742
|
+
function cwdBranchWidth(cols) {
|
|
55743
|
+
const desired = Math.max(18, Math.floor(cols * 0.38));
|
|
55744
|
+
const maxByCols = Math.max(6, cols - 24);
|
|
55745
|
+
return Math.max(6, Math.min(64, desired, maxByCols));
|
|
55746
|
+
}
|
|
55747
|
+
function buildActivityText(status, width) {
|
|
55748
|
+
return fitVisible(` ${status}`, width);
|
|
55749
|
+
}
|
|
55162
55750
|
function SpawnHud({ t }) {
|
|
55163
55751
|
const delegation = useStore5($delegationState);
|
|
55164
55752
|
const subagents = useTurnSelector((state) => state.subagents);
|
|
@@ -55223,12 +55811,14 @@ function GoodVibesHeart({ tick, t }) {
|
|
|
55223
55811
|
}
|
|
55224
55812
|
return /* @__PURE__ */ jsx19(Text9, { color, children: "\u2665" });
|
|
55225
55813
|
}
|
|
55814
|
+
function ActivityStatusLine({ busy, cols, status, statusColor: statusColor2, turnStartedAt }) {
|
|
55815
|
+
const tickerStatus = useTickerText(busy ? turnStartedAt : null);
|
|
55816
|
+
const text = buildActivityText(busy ? tickerStatus : status, cols);
|
|
55817
|
+
return /* @__PURE__ */ jsx19(Box_default, { height: 1, width: cols, children: /* @__PURE__ */ jsx19(Text9, { color: statusColor2, children: text }) });
|
|
55818
|
+
}
|
|
55226
55819
|
function StatusRule({
|
|
55227
55820
|
cwdLabel,
|
|
55228
55821
|
cols,
|
|
55229
|
-
busy,
|
|
55230
|
-
status,
|
|
55231
|
-
statusColor: statusColor2,
|
|
55232
55822
|
model,
|
|
55233
55823
|
modelFast,
|
|
55234
55824
|
modelReasoningEffort,
|
|
@@ -55236,7 +55826,6 @@ function StatusRule({
|
|
|
55236
55826
|
bgCount,
|
|
55237
55827
|
sessionStartedAt,
|
|
55238
55828
|
showCost,
|
|
55239
|
-
turnStartedAt,
|
|
55240
55829
|
voiceLabel,
|
|
55241
55830
|
t
|
|
55242
55831
|
}) {
|
|
@@ -55244,29 +55833,15 @@ function StatusRule({
|
|
|
55244
55833
|
const barColor = ctxBarColor(pct, t);
|
|
55245
55834
|
const ctxLabel = usage2.context_max ? `${fmtK(usage2.context_used ?? 0)}/${fmtK(usage2.context_max)}` : usage2.total > 0 ? `${fmtK(usage2.total)} tok` : "";
|
|
55246
55835
|
const bar = usage2.context_max ? ctxBar(pct) : "";
|
|
55247
|
-
const
|
|
55248
|
-
|
|
55249
|
-
|
|
55250
|
-
|
|
55251
|
-
|
|
55252
|
-
|
|
55253
|
-
|
|
55254
|
-
|
|
55255
|
-
|
|
55256
|
-
ctxLabel ? /* @__PURE__ */ jsxs10(Text9, { color: t.color.systemNote, children: [
|
|
55257
|
-
" \u2502 ",
|
|
55258
|
-
ctxLabel
|
|
55259
|
-
] }) : null,
|
|
55260
|
-
bar ? /* @__PURE__ */ jsxs10(Text9, { color: t.color.systemNote, children: [
|
|
55261
|
-
" \u2502 ",
|
|
55262
|
-
/* @__PURE__ */ jsxs10(Text9, { color: barColor, children: [
|
|
55263
|
-
"[",
|
|
55264
|
-
bar,
|
|
55265
|
-
"]"
|
|
55266
|
-
] }),
|
|
55267
|
-
" ",
|
|
55268
|
-
/* @__PURE__ */ jsx19(Text9, { color: barColor, children: pct != null ? `${pct}%` : "" })
|
|
55269
|
-
] }) : null,
|
|
55836
|
+
const cwdWidth = cwdBranchWidth(cols);
|
|
55837
|
+
const modelText = modelLabel(model, modelReasoningEffort, modelFast);
|
|
55838
|
+
return /* @__PURE__ */ jsxs10(Box_default, { height: 1, width: cols, children: [
|
|
55839
|
+
/* @__PURE__ */ jsx19(Text9, { color: t.color.border, children: "\u2500 " }),
|
|
55840
|
+
/* @__PURE__ */ jsx19(Box_default, { flexShrink: 0, width: cwdWidth, children: /* @__PURE__ */ jsx19(Text9, { color: t.color.systemNote, children: truncateTailVisible(cwdLabel, cwdWidth) }) }),
|
|
55841
|
+
/* @__PURE__ */ jsx19(Box_default, { flexShrink: 1, children: /* @__PURE__ */ jsxs10(Text9, { color: t.color.systemNote, wrap: "truncate-end", children: [
|
|
55842
|
+
modelText ? ` \u2502 ${modelText}` : "",
|
|
55843
|
+
ctxLabel ? ` \u2502 ${ctxLabel}` : "",
|
|
55844
|
+
bar ? /* @__PURE__ */ jsx19(Text9, { color: barColor, children: statusContextMeter(bar, pct) }) : null,
|
|
55270
55845
|
sessionStartedAt ? /* @__PURE__ */ jsxs10(Text9, { color: t.color.systemNote, children: [
|
|
55271
55846
|
" \u2502 ",
|
|
55272
55847
|
/* @__PURE__ */ jsx19(SessionDuration, { startedAt: sessionStartedAt })
|
|
@@ -55298,9 +55873,7 @@ function StatusRule({
|
|
|
55298
55873
|
" \u2502 $",
|
|
55299
55874
|
usage2.cost_usd.toFixed(4)
|
|
55300
55875
|
] }) : null
|
|
55301
|
-
] }) })
|
|
55302
|
-
/* @__PURE__ */ jsx19(Text9, { color: t.color.border, children: " \u2500 " }),
|
|
55303
|
-
/* @__PURE__ */ jsx19(Text9, { color: t.color.systemNote, children: cwdLabel })
|
|
55876
|
+
] }) })
|
|
55304
55877
|
] });
|
|
55305
55878
|
}
|
|
55306
55879
|
function FloatBox({ children, color }) {
|
|
@@ -55375,7 +55948,7 @@ function TranscriptScrollbar({ focused = false, scrollRef, t }) {
|
|
|
55375
55948
|
}
|
|
55376
55949
|
);
|
|
55377
55950
|
}
|
|
55378
|
-
var FACE_TICK_MS, VERB_PAD_LEN, padVerb, EMOJI_FRAMES, ASCII_FRAMES, SPINNER_TICK_MS, renderIndicator, effortLabel, shortModelLabel, modelLabel;
|
|
55951
|
+
var FACE_TICK_MS, VERB_PAD_LEN, padVerb, EMOJI_FRAMES, ASCII_FRAMES, SPINNER_TICK_MS, renderIndicator, statusContextPercent, statusContextMeter, effortLabel, shortModelLabel, modelLabel;
|
|
55379
55952
|
var init_appChrome = __esm({
|
|
55380
55953
|
"src/components/appChrome.tsx"() {
|
|
55381
55954
|
"use strict";
|
|
@@ -55386,6 +55959,7 @@ var init_appChrome = __esm({
|
|
|
55386
55959
|
init_faces();
|
|
55387
55960
|
init_verbs();
|
|
55388
55961
|
init_messages();
|
|
55962
|
+
init_usage();
|
|
55389
55963
|
init_viewport();
|
|
55390
55964
|
init_subagentTree();
|
|
55391
55965
|
init_text();
|
|
@@ -55418,9 +55992,15 @@ var init_appChrome = __esm({
|
|
|
55418
55992
|
const frame = spinner.frames[tick % spinner.frames.length] ?? "\u280B";
|
|
55419
55993
|
return { frame, intervalMs: Math.max(SPINNER_TICK_MS, spinner.interval), showVerb: false };
|
|
55420
55994
|
}, "renderIndicator");
|
|
55421
|
-
__name(
|
|
55995
|
+
__name(useTickerText, "useTickerText");
|
|
55422
55996
|
__name(ctxBarColor, "ctxBarColor");
|
|
55423
55997
|
__name(ctxBar, "ctxBar");
|
|
55998
|
+
statusContextPercent = /* @__PURE__ */ __name((pct) => formatContextPercent(pct).padStart(5), "statusContextPercent");
|
|
55999
|
+
statusContextMeter = /* @__PURE__ */ __name((bar, pct) => ` \u2502 [${bar}] ${statusContextPercent(pct)}`, "statusContextMeter");
|
|
56000
|
+
__name(fitVisible, "fitVisible");
|
|
56001
|
+
__name(truncateTailVisible, "truncateTailVisible");
|
|
56002
|
+
__name(cwdBranchWidth, "cwdBranchWidth");
|
|
56003
|
+
__name(buildActivityText, "buildActivityText");
|
|
55424
56004
|
__name(SpawnHud, "SpawnHud");
|
|
55425
56005
|
__name(SessionDuration, "SessionDuration");
|
|
55426
56006
|
effortLabel = /* @__PURE__ */ __name((effort) => {
|
|
@@ -55430,6 +56010,7 @@ var init_appChrome = __esm({
|
|
|
55430
56010
|
shortModelLabel = /* @__PURE__ */ __name((model) => model.split("/").pop().replace(/^claude[-_]/, "").replace(/^anthropic[-_]/, "").replace(/[-_]/g, " ").replace(/\b(\d+)\s+(\d+)\b/g, "$1.$2").trim(), "shortModelLabel");
|
|
55431
56011
|
modelLabel = /* @__PURE__ */ __name((model, effort, fast) => [shortModelLabel(model), effortLabel(effort), fast ? "fast" : ""].filter(Boolean).join(" "), "modelLabel");
|
|
55432
56012
|
__name(GoodVibesHeart, "GoodVibesHeart");
|
|
56013
|
+
__name(ActivityStatusLine, "ActivityStatusLine");
|
|
55433
56014
|
__name(StatusRule, "StatusRule");
|
|
55434
56015
|
__name(FloatBox, "FloatBox");
|
|
55435
56016
|
__name(StickyPromptTracker, "StickyPromptTracker");
|
|
@@ -56602,12 +57183,15 @@ import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs13 } from "react/jsx-r
|
|
|
56602
57183
|
function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t }) {
|
|
56603
57184
|
const [providers, setProviders] = useState19([]);
|
|
56604
57185
|
const [currentModel, setCurrentModel] = useState19("");
|
|
57186
|
+
const [currentReasoningEffort, setCurrentReasoningEffort] = useState19();
|
|
56605
57187
|
const [err, setErr] = useState19("");
|
|
56606
57188
|
const [loading, setLoading] = useState19(true);
|
|
56607
57189
|
const [persistGlobal, setPersistGlobal] = useState19(false);
|
|
56608
57190
|
const [providerIdx, setProviderIdx] = useState19(0);
|
|
56609
57191
|
const [modelIdx, setModelIdx] = useState19(0);
|
|
57192
|
+
const [effortIdx, setEffortIdx] = useState19(0);
|
|
56610
57193
|
const [stage, setStage] = useState19("provider");
|
|
57194
|
+
const [selectedModelForEffort, setSelectedModelForEffort] = useState19(null);
|
|
56611
57195
|
const [keyInput, setKeyInput] = useState19("");
|
|
56612
57196
|
const [keySaving, setKeySaving] = useState19(false);
|
|
56613
57197
|
const [keyError, setKeyError] = useState19("");
|
|
@@ -56633,6 +57217,7 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
56633
57217
|
const next = r.providers ?? [];
|
|
56634
57218
|
setProviders(next);
|
|
56635
57219
|
setCurrentModel(String(r.model ?? ""));
|
|
57220
|
+
setCurrentReasoningEffort(r.reasoning_effort);
|
|
56636
57221
|
setProviderIdx(
|
|
56637
57222
|
Math.max(
|
|
56638
57223
|
0,
|
|
@@ -56640,6 +57225,8 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
56640
57225
|
)
|
|
56641
57226
|
);
|
|
56642
57227
|
setModelIdx(0);
|
|
57228
|
+
setEffortIdx(0);
|
|
57229
|
+
setSelectedModelForEffort(null);
|
|
56643
57230
|
setStage("provider");
|
|
56644
57231
|
setErr("");
|
|
56645
57232
|
setLoading(false);
|
|
@@ -56650,8 +57237,34 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
56650
57237
|
});
|
|
56651
57238
|
}, [gw, sessionId]);
|
|
56652
57239
|
const provider = providers[providerIdx];
|
|
56653
|
-
const
|
|
57240
|
+
const modelOptions = useMemo12(() => {
|
|
57241
|
+
if (!provider) return [];
|
|
57242
|
+
if (provider.model_options?.length) return provider.model_options;
|
|
57243
|
+
return (provider.models ?? []).map((id) => ({ id }));
|
|
57244
|
+
}, [provider]);
|
|
57245
|
+
const models = useMemo12(() => modelOptions.map((model) => model.id), [modelOptions]);
|
|
57246
|
+
const effortChoices = useMemo12(() => modelReasoningEfforts(selectedModelForEffort), [selectedModelForEffort]);
|
|
57247
|
+
const providerHasReasoningStage = modelOptions.some((model) => modelReasoningEfforts(model).length > 1);
|
|
56654
57248
|
const names = useMemo12(() => providerDisplayNames(providers), [providers]);
|
|
57249
|
+
const selectionScopeFlag = /* @__PURE__ */ __name(() => persistGlobal ? " --global" : ` ${TUI_SESSION_MODEL_FLAG}`, "selectionScopeFlag");
|
|
57250
|
+
const selectModel = /* @__PURE__ */ __name((model, effort) => {
|
|
57251
|
+
if (!provider) return;
|
|
57252
|
+
onSelect(`${model.id} --provider ${provider.slug} --reasoning-effort ${effort}${selectionScopeFlag()}`);
|
|
57253
|
+
}, "selectModel");
|
|
57254
|
+
const chooseModel = /* @__PURE__ */ __name((model) => {
|
|
57255
|
+
if (!model) {
|
|
57256
|
+
setStage("provider");
|
|
57257
|
+
return;
|
|
57258
|
+
}
|
|
57259
|
+
const efforts = modelReasoningEfforts(model);
|
|
57260
|
+
if (efforts.length > 1) {
|
|
57261
|
+
setSelectedModelForEffort(model);
|
|
57262
|
+
setEffortIdx(initialEffortIndex(efforts, currentReasoningEffort, defaultReasoningForModel(model, efforts)));
|
|
57263
|
+
setStage("effort");
|
|
57264
|
+
return;
|
|
57265
|
+
}
|
|
57266
|
+
selectModel(model, efforts[0] ?? "default");
|
|
57267
|
+
}, "chooseModel");
|
|
56655
57268
|
useEffect17(() => {
|
|
56656
57269
|
mountedRef.current = true;
|
|
56657
57270
|
return () => {
|
|
@@ -56672,6 +57285,7 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
56672
57285
|
}
|
|
56673
57286
|
setProviders(r.providers ?? []);
|
|
56674
57287
|
setCurrentModel(String(r.model ?? ""));
|
|
57288
|
+
setCurrentReasoningEffort(r.reasoning_effort);
|
|
56675
57289
|
}).catch(() => {
|
|
56676
57290
|
}), "refreshProviders");
|
|
56677
57291
|
const cancelActiveOAuth = /* @__PURE__ */ __name(() => {
|
|
@@ -56767,9 +57381,17 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
56767
57381
|
setOauthError("");
|
|
56768
57382
|
return;
|
|
56769
57383
|
}
|
|
57384
|
+
if (stage === "effort") {
|
|
57385
|
+
setStage("model");
|
|
57386
|
+
setEffortIdx(0);
|
|
57387
|
+
setSelectedModelForEffort(null);
|
|
57388
|
+
return;
|
|
57389
|
+
}
|
|
56770
57390
|
if (stage === "model" || stage === "key" || stage === "disconnect") {
|
|
56771
57391
|
setStage("provider");
|
|
56772
57392
|
setModelIdx(0);
|
|
57393
|
+
setEffortIdx(0);
|
|
57394
|
+
setSelectedModelForEffort(null);
|
|
56773
57395
|
setKeyInput("");
|
|
56774
57396
|
setKeyError("");
|
|
56775
57397
|
setKeySaving(false);
|
|
@@ -56867,7 +57489,7 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
56867
57489
|
if (r?.disconnected) {
|
|
56868
57490
|
setProviders(
|
|
56869
57491
|
(prev) => prev.map(
|
|
56870
|
-
(p) => p.slug === provider.slug ? { ...p, authenticated: false, models: [], total_models: 0, warning: p.key_env ? `paste ${p.key_env} to activate` : "run `hermes model` to configure" } : p
|
|
57492
|
+
(p) => p.slug === provider.slug ? { ...p, authenticated: false, models: [], model_options: [], total_models: 0, warning: p.key_env ? `paste ${p.key_env} to activate` : "run `hermes model` to configure" } : p
|
|
56871
57493
|
)
|
|
56872
57494
|
);
|
|
56873
57495
|
}
|
|
@@ -56885,9 +57507,9 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
56885
57507
|
}
|
|
56886
57508
|
return;
|
|
56887
57509
|
}
|
|
56888
|
-
const count = stage === "provider" ? providers.length : models.length;
|
|
56889
|
-
const sel = stage === "provider" ? providerIdx : modelIdx;
|
|
56890
|
-
const setSel = stage === "provider" ? setProviderIdx : setModelIdx;
|
|
57510
|
+
const count = stage === "provider" ? providers.length : stage === "effort" ? effortChoices.length : models.length;
|
|
57511
|
+
const sel = stage === "provider" ? providerIdx : stage === "effort" ? effortIdx : modelIdx;
|
|
57512
|
+
const setSel = stage === "provider" ? setProviderIdx : stage === "effort" ? setEffortIdx : setModelIdx;
|
|
56891
57513
|
if (key.upArrow && sel > 0) {
|
|
56892
57514
|
setSel((v) => v - 1);
|
|
56893
57515
|
return;
|
|
@@ -56922,12 +57544,16 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
56922
57544
|
setModelIdx(0);
|
|
56923
57545
|
return;
|
|
56924
57546
|
}
|
|
56925
|
-
|
|
56926
|
-
|
|
56927
|
-
|
|
56928
|
-
|
|
56929
|
-
|
|
57547
|
+
if (stage === "effort") {
|
|
57548
|
+
const effort = effortChoices[effortIdx];
|
|
57549
|
+
if (selectedModelForEffort && effort) {
|
|
57550
|
+
selectModel(selectedModelForEffort, effort);
|
|
57551
|
+
} else {
|
|
57552
|
+
setStage("model");
|
|
57553
|
+
}
|
|
57554
|
+
return;
|
|
56930
57555
|
}
|
|
57556
|
+
chooseModel(modelOptions[modelIdx]);
|
|
56931
57557
|
return;
|
|
56932
57558
|
}
|
|
56933
57559
|
if (ch.toLowerCase() === "g") {
|
|
@@ -57090,7 +57716,11 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
57090
57716
|
);
|
|
57091
57717
|
const { items: items2, offset: offset2 } = windowItems(rows, providerIdx, VISIBLE2);
|
|
57092
57718
|
return /* @__PURE__ */ jsxs13(Box_default, { flexDirection: "column", width, children: [
|
|
57093
|
-
/* @__PURE__ */
|
|
57719
|
+
/* @__PURE__ */ jsxs13(Text9, { bold: true, color: t.color.accent, wrap: "truncate-end", children: [
|
|
57720
|
+
"Select provider (step 1/",
|
|
57721
|
+
providerHasReasoningStage ? "3" : "2",
|
|
57722
|
+
")"
|
|
57723
|
+
] }),
|
|
57094
57724
|
/* @__PURE__ */ jsx25(Text9, { color: t.color.muted, wrap: "truncate-end", children: "Full model IDs on the next step \xB7 Enter to continue" }),
|
|
57095
57725
|
/* @__PURE__ */ jsxs13(Text9, { color: t.color.muted, wrap: "truncate-end", children: [
|
|
57096
57726
|
"Current: ",
|
|
@@ -57129,9 +57759,61 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
57129
57759
|
/* @__PURE__ */ jsx25(OverlayHint, { t, children: "\u2191/\u2193 select \xB7 Enter choose \xB7 d disconnect \xB7 Esc/q cancel" })
|
|
57130
57760
|
] });
|
|
57131
57761
|
}
|
|
57762
|
+
if (stage === "effort") {
|
|
57763
|
+
const defaultEffort = defaultReasoningForModel(selectedModelForEffort, effortChoices);
|
|
57764
|
+
const warningEffort = effortChoices.includes("xhigh") ? "xhigh" : effortChoices.includes("high") ? "high" : void 0;
|
|
57765
|
+
const warningText = warningEffort ? `\u26A0 ${reasoningEffortLabel(warningEffort)} reasoning can quickly consume rate limits.` : " ";
|
|
57766
|
+
const { items: items2, offset: offset2 } = windowItems(effortChoices, effortIdx, VISIBLE2);
|
|
57767
|
+
return /* @__PURE__ */ jsxs13(Box_default, { flexDirection: "column", width, children: [
|
|
57768
|
+
/* @__PURE__ */ jsx25(Text9, { bold: true, color: t.color.accent, wrap: "truncate-end", children: "Select reasoning level (step 3/3)" }),
|
|
57769
|
+
/* @__PURE__ */ jsxs13(Text9, { color: t.color.muted, wrap: "truncate-end", children: [
|
|
57770
|
+
modelOptionID(selectedModelForEffort ?? void 0) || "(unknown model)",
|
|
57771
|
+
" \xB7 Esc back"
|
|
57772
|
+
] }),
|
|
57773
|
+
/* @__PURE__ */ jsx25(Text9, { color: t.color.label, wrap: "truncate-end", children: warningText }),
|
|
57774
|
+
/* @__PURE__ */ jsx25(Text9, { color: t.color.muted, wrap: "truncate-end", children: offset2 > 0 ? ` \u2191 ${offset2} more` : " " }),
|
|
57775
|
+
Array.from({ length: VISIBLE2 }, (_, i) => {
|
|
57776
|
+
const effort = items2[i];
|
|
57777
|
+
const idx = offset2 + i;
|
|
57778
|
+
if (!effort) {
|
|
57779
|
+
return !effortChoices.length && i === 0 ? /* @__PURE__ */ jsx25(Text9, { color: t.color.muted, wrap: "truncate-end", children: "no reasoning levels listed for this model" }, "empty-effort") : /* @__PURE__ */ jsx25(Text9, { color: t.color.muted, wrap: "truncate-end", children: " " }, `pad-effort-${i}`);
|
|
57780
|
+
}
|
|
57781
|
+
const option = selectedModelForEffort?.supportedReasoningEfforts?.find((o) => o.effort === effort);
|
|
57782
|
+
const description = option?.description && option.description !== effort ? ` \xB7 ${option.description}` : "";
|
|
57783
|
+
const label = `${reasoningEffortLabel(effort)}${effort === defaultEffort ? " (default)" : ""}${description}`;
|
|
57784
|
+
return /* @__PURE__ */ jsxs13(
|
|
57785
|
+
Text9,
|
|
57786
|
+
{
|
|
57787
|
+
bold: effortIdx === idx,
|
|
57788
|
+
color: effortIdx === idx ? t.color.accent : t.color.muted,
|
|
57789
|
+
inverse: effortIdx === idx,
|
|
57790
|
+
wrap: "truncate-end",
|
|
57791
|
+
children: [
|
|
57792
|
+
effortIdx === idx ? "\u25B8 " : currentReasoningEffort === effort ? "* " : " ",
|
|
57793
|
+
idx + 1,
|
|
57794
|
+
". ",
|
|
57795
|
+
label
|
|
57796
|
+
]
|
|
57797
|
+
},
|
|
57798
|
+
`${modelOptionID(selectedModelForEffort ?? void 0)}:${effort}`
|
|
57799
|
+
);
|
|
57800
|
+
}),
|
|
57801
|
+
/* @__PURE__ */ jsx25(Text9, { color: t.color.muted, wrap: "truncate-end", children: offset2 + VISIBLE2 < effortChoices.length ? ` \u2193 ${effortChoices.length - offset2 - VISIBLE2} more` : " " }),
|
|
57802
|
+
/* @__PURE__ */ jsxs13(Text9, { color: t.color.muted, wrap: "truncate-end", children: [
|
|
57803
|
+
"persist: ",
|
|
57804
|
+
persistGlobal ? "global" : "session",
|
|
57805
|
+
" \xB7 g toggle"
|
|
57806
|
+
] }),
|
|
57807
|
+
/* @__PURE__ */ jsx25(OverlayHint, { t, children: "\u2191/\u2193 select \xB7 Enter switch \xB7 Esc back \xB7 q close" })
|
|
57808
|
+
] });
|
|
57809
|
+
}
|
|
57132
57810
|
const { items, offset } = windowItems(models, modelIdx, VISIBLE2);
|
|
57133
57811
|
return /* @__PURE__ */ jsxs13(Box_default, { flexDirection: "column", width, children: [
|
|
57134
|
-
/* @__PURE__ */
|
|
57812
|
+
/* @__PURE__ */ jsxs13(Text9, { bold: true, color: t.color.accent, wrap: "truncate-end", children: [
|
|
57813
|
+
"Select model (step 2/",
|
|
57814
|
+
providerHasReasoningStage ? "3" : "2",
|
|
57815
|
+
")"
|
|
57816
|
+
] }),
|
|
57135
57817
|
/* @__PURE__ */ jsxs13(Text9, { color: t.color.muted, wrap: "truncate-end", children: [
|
|
57136
57818
|
names[providerIdx] || "(unknown provider)",
|
|
57137
57819
|
" \xB7 Esc back"
|
|
@@ -57171,7 +57853,7 @@ function ModelPicker2({ gw, mode = "switch", onCancel, onSelect, sessionId, t })
|
|
|
57171
57853
|
/* @__PURE__ */ jsx25(OverlayHint, { t, children: models.length ? "\u2191/\u2193 select \xB7 Enter switch \xB7 Esc back \xB7 q close" : "Enter/Esc back \xB7 q close" })
|
|
57172
57854
|
] });
|
|
57173
57855
|
}
|
|
57174
|
-
var VISIBLE2, MIN_WIDTH2, MAX_WIDTH2;
|
|
57856
|
+
var VISIBLE2, MIN_WIDTH2, MAX_WIDTH2, modelOptionID, modelReasoningEfforts, defaultReasoningForModel, initialEffortIndex;
|
|
57175
57857
|
var init_modelPicker = __esm({
|
|
57176
57858
|
"src/components/modelPicker.tsx"() {
|
|
57177
57859
|
"use strict";
|
|
@@ -57179,10 +57861,28 @@ var init_modelPicker = __esm({
|
|
|
57179
57861
|
init_providers2();
|
|
57180
57862
|
init_slash();
|
|
57181
57863
|
init_rpc();
|
|
57864
|
+
init_types();
|
|
57182
57865
|
init_overlayControls();
|
|
57183
57866
|
VISIBLE2 = 12;
|
|
57184
57867
|
MIN_WIDTH2 = 40;
|
|
57185
57868
|
MAX_WIDTH2 = 90;
|
|
57869
|
+
modelOptionID = /* @__PURE__ */ __name((model) => model?.id ?? "", "modelOptionID");
|
|
57870
|
+
modelReasoningEfforts = /* @__PURE__ */ __name((model) => {
|
|
57871
|
+
const efforts = model?.supportedReasoningEfforts?.map((option) => option.effort) ?? [];
|
|
57872
|
+
return orderedReasoningEfforts(efforts);
|
|
57873
|
+
}, "modelReasoningEfforts");
|
|
57874
|
+
defaultReasoningForModel = /* @__PURE__ */ __name((model, efforts = modelReasoningEfforts(model)) => {
|
|
57875
|
+
const configured = model?.defaultReasoningEffort;
|
|
57876
|
+
if (configured && efforts.includes(configured)) {
|
|
57877
|
+
return configured;
|
|
57878
|
+
}
|
|
57879
|
+
return efforts[0];
|
|
57880
|
+
}, "defaultReasoningForModel");
|
|
57881
|
+
initialEffortIndex = /* @__PURE__ */ __name((efforts, current, fallback) => {
|
|
57882
|
+
const selected = current && efforts.includes(current) ? current : fallback;
|
|
57883
|
+
const idx = selected ? efforts.indexOf(selected) : -1;
|
|
57884
|
+
return idx >= 0 ? idx : 0;
|
|
57885
|
+
}, "initialEffortIndex");
|
|
57186
57886
|
__name(ModelPicker2, "ModelPicker");
|
|
57187
57887
|
}
|
|
57188
57888
|
});
|
|
@@ -59479,9 +60179,9 @@ function MdImpl({ compact, t, text }) {
|
|
|
59479
60179
|
const nodes = useMemo14(() => {
|
|
59480
60180
|
const bucket = cacheBucket(t);
|
|
59481
60181
|
const cacheKey = `${compact ? "1" : "0"}|${text}`;
|
|
59482
|
-
const
|
|
59483
|
-
if (
|
|
59484
|
-
return
|
|
60182
|
+
const cached7 = cacheGet(bucket, cacheKey);
|
|
60183
|
+
if (cached7) {
|
|
60184
|
+
return cached7;
|
|
59485
60185
|
}
|
|
59486
60186
|
const lines = ensureEmojiPresentation(text).split("\n");
|
|
59487
60187
|
const nodes2 = [];
|
|
@@ -61517,26 +62217,34 @@ var init_appLayout = __esm({
|
|
|
61517
62217
|
if (ui.statusBar !== at) {
|
|
61518
62218
|
return null;
|
|
61519
62219
|
}
|
|
61520
|
-
return /* @__PURE__ */
|
|
61521
|
-
|
|
61522
|
-
|
|
61523
|
-
|
|
61524
|
-
|
|
61525
|
-
|
|
61526
|
-
|
|
61527
|
-
|
|
61528
|
-
|
|
61529
|
-
|
|
61530
|
-
|
|
61531
|
-
|
|
61532
|
-
|
|
61533
|
-
|
|
61534
|
-
|
|
61535
|
-
|
|
61536
|
-
|
|
61537
|
-
|
|
61538
|
-
|
|
61539
|
-
|
|
62220
|
+
return /* @__PURE__ */ jsxs28(Box_default, { flexDirection: "column", marginTop: at === "top" ? 1 : 0, children: [
|
|
62221
|
+
/* @__PURE__ */ jsx41(
|
|
62222
|
+
ActivityStatusLine,
|
|
62223
|
+
{
|
|
62224
|
+
busy: ui.busy,
|
|
62225
|
+
cols: composer.cols,
|
|
62226
|
+
status: ui.status,
|
|
62227
|
+
statusColor: status.statusColor,
|
|
62228
|
+
turnStartedAt: status.turnStartedAt
|
|
62229
|
+
}
|
|
62230
|
+
),
|
|
62231
|
+
/* @__PURE__ */ jsx41(
|
|
62232
|
+
StatusRule,
|
|
62233
|
+
{
|
|
62234
|
+
bgCount: ui.bgTasks.size,
|
|
62235
|
+
cols: composer.cols,
|
|
62236
|
+
cwdLabel: status.cwdLabel,
|
|
62237
|
+
model: ui.info?.model ?? "",
|
|
62238
|
+
modelFast: ui.info?.fast || ui.info?.service_tier === "priority",
|
|
62239
|
+
modelReasoningEffort: ui.info?.reasoning_effort,
|
|
62240
|
+
sessionStartedAt: status.sessionStartedAt,
|
|
62241
|
+
showCost: ui.showCost,
|
|
62242
|
+
t: ui.theme,
|
|
62243
|
+
usage: ui.usage,
|
|
62244
|
+
voiceLabel: status.voiceLabel
|
|
62245
|
+
}
|
|
62246
|
+
)
|
|
62247
|
+
] });
|
|
61540
62248
|
}, "StatusRulePane"));
|
|
61541
62249
|
AppLayout = memo7(/* @__PURE__ */ __name(function AppLayout2({
|
|
61542
62250
|
actions,
|