neko-harness 0.4.8 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/client/assets/index-CP-ffuep.css +2 -0
- package/dist/client/assets/index-LHUxaMG9.js +396 -0
- package/dist/client/index.html +36 -2
- package/dist/gateway.js +23 -11
- package/dist/neko.js +38640 -36842
- package/package.json +1 -1
- package/dist/client/assets/index-vrkP1dHF.js +0 -395
- package/dist/client/assets/index-wmHY1s4T.css +0 -2
package/dist/client/index.html
CHANGED
|
@@ -4,13 +4,47 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<meta name="color-scheme" content="light" />
|
|
7
|
+
<script>
|
|
8
|
+
// 首屏前应用外观偏好(与 src/client/lib/appearance.ts 的键名/属性名对拍,test/appearance.test.ts)
|
|
9
|
+
(() => {
|
|
10
|
+
try {
|
|
11
|
+
const data = JSON.parse(localStorage.getItem("neko.appearance") || "null");
|
|
12
|
+
if (!data || typeof data !== "object") return;
|
|
13
|
+
const attrs = {
|
|
14
|
+
theme: "data-theme",
|
|
15
|
+
font: "data-chat-font",
|
|
16
|
+
size: "data-chat-size",
|
|
17
|
+
weight: "data-chat-weight",
|
|
18
|
+
leading: "data-chat-leading",
|
|
19
|
+
};
|
|
20
|
+
for (const key of Object.keys(attrs)) {
|
|
21
|
+
const value = data[key];
|
|
22
|
+
if (typeof value === "string" && /^[a-z0-9-]{1,16}$/.test(value))
|
|
23
|
+
document.documentElement.setAttribute(attrs[key], value);
|
|
24
|
+
}
|
|
25
|
+
const meta = document.querySelector('meta[name="color-scheme"]');
|
|
26
|
+
if (data.theme === "dark" && meta) meta.setAttribute("content", "dark");
|
|
27
|
+
} catch {}
|
|
28
|
+
})();
|
|
29
|
+
</script>
|
|
30
|
+
<script>
|
|
31
|
+
// 首屏前同步界面语言到 <html lang>(与 src/client/lib/language.ts 的键名对拍,test/language.test.ts)
|
|
32
|
+
(() => {
|
|
33
|
+
try {
|
|
34
|
+
document.documentElement.setAttribute(
|
|
35
|
+
"lang",
|
|
36
|
+
localStorage.getItem("neko.language") === "en" ? "en" : "zh-CN",
|
|
37
|
+
);
|
|
38
|
+
} catch {}
|
|
39
|
+
})();
|
|
40
|
+
</script>
|
|
7
41
|
<link
|
|
8
42
|
rel="icon"
|
|
9
43
|
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='26' fill='%23ffb7c5'/%3E%3Ctext x='50' y='70' font-size='58' text-anchor='middle' fill='%23ffffff' font-family='sans-serif' font-weight='bold'%3En%3C/text%3E%3C/svg%3E"
|
|
10
44
|
/>
|
|
11
45
|
<title>neko harness</title>
|
|
12
|
-
<script type="module" crossorigin src="/assets/index-
|
|
13
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
46
|
+
<script type="module" crossorigin src="/assets/index-LHUxaMG9.js"></script>
|
|
47
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CP-ffuep.css">
|
|
14
48
|
</head>
|
|
15
49
|
<body>
|
|
16
50
|
<div id="root"></div>
|
package/dist/gateway.js
CHANGED
|
@@ -19605,7 +19605,9 @@ class JobManager {
|
|
|
19605
19605
|
#reporter = createReporter();
|
|
19606
19606
|
#runner = this.#createRunner();
|
|
19607
19607
|
extension;
|
|
19608
|
-
|
|
19608
|
+
#startWindowMs;
|
|
19609
|
+
constructor(options = {}) {
|
|
19610
|
+
this.#startWindowMs = options.startWindowMs ?? JOB_LIMITS.startWindowMs;
|
|
19609
19611
|
this.extension = this.#createExtension();
|
|
19610
19612
|
}
|
|
19611
19613
|
#closing = false;
|
|
@@ -19795,7 +19797,7 @@ class JobManager {
|
|
|
19795
19797
|
throw error;
|
|
19796
19798
|
}
|
|
19797
19799
|
const live = entry;
|
|
19798
|
-
await Promise.race([live.exited, delay(
|
|
19800
|
+
await Promise.race([live.exited, delay(this.#startWindowMs, context.abortSignal)]);
|
|
19799
19801
|
live.windowOpen = false;
|
|
19800
19802
|
if (live.suppressReport)
|
|
19801
19803
|
await live.exited;
|
|
@@ -20996,6 +20998,8 @@ var SessionMetadataDoc = defineDoc5({
|
|
|
20996
20998
|
namingUsage: { models: {}, tools: {} }
|
|
20997
20999
|
})
|
|
20998
21000
|
});
|
|
21001
|
+
var NAMING_REQUEST_TIMEOUT_MS = 20000;
|
|
21002
|
+
var NAMING_RETRY_DELAY_MS = 2000;
|
|
20999
21003
|
function shortText(value, limit = 60) {
|
|
21000
21004
|
return [
|
|
21001
21005
|
...stripVTControlCharacters(value).replace(/\p{Cc}/gu, " ").replace(/\s+/g, " ").trim()
|
|
@@ -21033,7 +21037,7 @@ function mergeUsage(base, extra) {
|
|
|
21033
21037
|
}
|
|
21034
21038
|
return result;
|
|
21035
21039
|
}
|
|
21036
|
-
function namingTask(canUse) {
|
|
21040
|
+
function namingTask(canUse, { requestTimeoutMs, retryDelayMs }) {
|
|
21037
21041
|
let active = 0;
|
|
21038
21042
|
const waits = new Set;
|
|
21039
21043
|
return defineTask3({
|
|
@@ -21084,7 +21088,7 @@ function namingTask(canUse) {
|
|
|
21084
21088
|
return { status: "running", checkpoint: { phase: "generate", attempt: d.attempts } };
|
|
21085
21089
|
}, context);
|
|
21086
21090
|
let title = "", usage;
|
|
21087
|
-
const signal = AbortSignal.any([runtime.signal, AbortSignal.timeout(
|
|
21091
|
+
const signal = AbortSignal.any([runtime.signal, AbortSignal.timeout(requestTimeoutMs)]);
|
|
21088
21092
|
try {
|
|
21089
21093
|
const budget = Math.max(32, Math.min(12000, Math.floor((model.contextWindow - 512) / 4)));
|
|
21090
21094
|
const response = await Promise.race([
|
|
@@ -21123,7 +21127,7 @@ function namingTask(canUse) {
|
|
|
21123
21127
|
d.answer = "";
|
|
21124
21128
|
} else
|
|
21125
21129
|
d.naming = d.attempts >= 2 ? "fallback" : "pending";
|
|
21126
|
-
return title || d.attempts >= 2 ? { status: "terminal", outcome: { status: "completed", result: null } } : { status: "running", checkpoint: { phase: "wait", until: runtime.now() +
|
|
21130
|
+
return title || d.attempts >= 2 ? { status: "terminal", outcome: { status: "completed", result: null } } : { status: "running", checkpoint: { phase: "wait", until: runtime.now() + retryDelayMs } };
|
|
21127
21131
|
}, context);
|
|
21128
21132
|
} finally {
|
|
21129
21133
|
active--;
|
|
@@ -21155,8 +21159,11 @@ class SessionMetadataManager {
|
|
|
21155
21159
|
storage;
|
|
21156
21160
|
context;
|
|
21157
21161
|
report;
|
|
21158
|
-
constructor(harness, storage, context, registry, report = console.error, canUseModel = async () => true) {
|
|
21159
|
-
this.task = namingTask(canUseModel
|
|
21162
|
+
constructor(harness, storage, context, registry, report = console.error, canUseModel = async () => true, timings = {}) {
|
|
21163
|
+
this.task = namingTask(canUseModel, {
|
|
21164
|
+
requestTimeoutMs: timings.requestTimeoutMs ?? NAMING_REQUEST_TIMEOUT_MS,
|
|
21165
|
+
retryDelayMs: timings.retryDelayMs ?? NAMING_RETRY_DELAY_MS
|
|
21166
|
+
});
|
|
21160
21167
|
this.harness = harness;
|
|
21161
21168
|
this.storage = storage;
|
|
21162
21169
|
this.context = context;
|
|
@@ -22736,7 +22743,7 @@ async function createNekoRuntime(options = {}) {
|
|
|
22736
22743
|
registry.install(createSubagentExtension(async (id, requestId, cwd) => {
|
|
22737
22744
|
resourceSnapshots.stage(id, requestId, cwd, await loadResources(cwd));
|
|
22738
22745
|
}, resourceSnapshots.discard, (ref) => guardProvider(ref)));
|
|
22739
|
-
const jobs = new JobManager;
|
|
22746
|
+
const jobs = new JobManager(options.timings?.jobStartWindowMs === undefined ? {} : { startWindowMs: options.timings.jobStartWindowMs });
|
|
22740
22747
|
registry.install(jobs.extension);
|
|
22741
22748
|
registry.install(createTodoExtension());
|
|
22742
22749
|
let questions;
|
|
@@ -22754,6 +22761,7 @@ async function createNekoRuntime(options = {}) {
|
|
|
22754
22761
|
models,
|
|
22755
22762
|
registry,
|
|
22756
22763
|
settings: {
|
|
22764
|
+
...options.timings?.retryBaseDelayMs === undefined ? {} : { retry: { baseDelayMs: options.timings.retryBaseDelayMs } },
|
|
22757
22765
|
get compaction() {
|
|
22758
22766
|
return compactionPolicy(contextState, allModels().filter((model) => !isModelProvider(model.provider) || enabled.has(model.provider)).map((model) => model.contextWindow));
|
|
22759
22767
|
}
|
|
@@ -22852,7 +22860,10 @@ async function createNekoRuntime(options = {}) {
|
|
|
22852
22860
|
};
|
|
22853
22861
|
if (existing.length === 0)
|
|
22854
22862
|
await touchConversation(conversation.id);
|
|
22855
|
-
const metadata = new SessionMetadataManager(harness, storage, context, registry, options.onReport, (provider, modelId) => guardProvider({ provider, modelId }).then(() => true, () => false)
|
|
22863
|
+
const metadata = new SessionMetadataManager(harness, storage, context, registry, options.onReport, (provider, modelId) => guardProvider({ provider, modelId }).then(() => true, () => false), {
|
|
22864
|
+
...options.timings?.namingRequestTimeoutMs === undefined ? {} : { requestTimeoutMs: options.timings.namingRequestTimeoutMs },
|
|
22865
|
+
...options.timings?.namingRetryDelayMs === undefined ? {} : { retryDelayMs: options.timings.namingRetryDelayMs }
|
|
22866
|
+
});
|
|
22856
22867
|
if (existing.length === 0)
|
|
22857
22868
|
await metadata.initialize(conversation.id);
|
|
22858
22869
|
for (const record of existing)
|
|
@@ -24969,7 +24980,7 @@ function subagentClient(connect) {
|
|
|
24969
24980
|
import { createHash as createHash2 } from "crypto";
|
|
24970
24981
|
|
|
24971
24982
|
// packages/core/src/application-version.ts
|
|
24972
|
-
var RUNNING_VERSION = "0.4.
|
|
24983
|
+
var RUNNING_VERSION = "0.4.9";
|
|
24973
24984
|
var APPLICATION_PROTOCOL = 8;
|
|
24974
24985
|
function stableVersion(value) {
|
|
24975
24986
|
return typeof value === "string" && /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(value) && value.split(".").every((n) => Number.isSafeInteger(Number(n)));
|
|
@@ -30490,7 +30501,8 @@ async function startGateway(options = {}) {
|
|
|
30490
30501
|
...options.extensions !== undefined ? { extensions: options.extensions } : {},
|
|
30491
30502
|
...options.promptHome !== undefined ? { promptHome: options.promptHome } : {},
|
|
30492
30503
|
...fileConfig.shell?.path !== undefined ? { shellPath: fileConfig.shell.path } : {},
|
|
30493
|
-
...options.shellResolver !== undefined ? { shellResolver: options.shellResolver } : {}
|
|
30504
|
+
...options.shellResolver !== undefined ? { shellResolver: options.shellResolver } : {},
|
|
30505
|
+
...options.timings !== undefined ? { timings: options.timings } : {}
|
|
30494
30506
|
});
|
|
30495
30507
|
try {
|
|
30496
30508
|
return await bindGateway(runtime, {
|