koneck 2.101.0 → 2.103.0
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/context-limit.d.ts +0 -17
- package/dist/context-limit.d.ts.map +1 -1
- package/dist/context-limit.js +72 -13
- package/dist/context-limit.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +88 -14
- package/dist/engine.js.map +1 -1
- package/dist/prompt-cache.d.ts +48 -0
- package/dist/prompt-cache.d.ts.map +1 -0
- package/dist/prompt-cache.js +91 -0
- package/dist/prompt-cache.js.map +1 -0
- package/dist/run-progress.d.ts +69 -0
- package/dist/run-progress.d.ts.map +1 -0
- package/dist/run-progress.js +156 -0
- package/dist/run-progress.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/web/ui-client.d.ts.map +1 -1
- package/dist/web/ui-client.js +18 -2
- package/dist/web/ui-client.js.map +1 -1
- package/dist/web/ui-css.d.ts.map +1 -1
- package/dist/web/ui-css.js +54 -2
- package/dist/web/ui-css.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asking the provider to cache the part of the prompt that never changes.
|
|
3
|
+
*
|
|
4
|
+
* A long run re-sends the whole conversation on every request. Measured on a real session: 152
|
|
5
|
+
* requests, 10,028,873 tokens, about 66k a request — and one or two per cent of that total is text
|
|
6
|
+
* that had not been sent before. Everything else is the same prefix, read again, and charged again.
|
|
7
|
+
*
|
|
8
|
+
* Some providers cache prefixes on their own and report how much they served that way; nothing has
|
|
9
|
+
* to be asked of them, and KONECK reads the figure back so the saving is visible. Others cache only
|
|
10
|
+
* what you mark, in Anthropic's style: a `cache_control` note on a content block says "this and
|
|
11
|
+
* everything before it is worth keeping".
|
|
12
|
+
*
|
|
13
|
+
* ## Only where it is documented to work, and dropped the moment it is refused
|
|
14
|
+
*
|
|
15
|
+
* An unknown field can be ignored, or it can fail the request. So the marks go only to providers
|
|
16
|
+
* that document accepting them in an OpenAI-shaped body, and if one rejects the request anyway the
|
|
17
|
+
* marks are dropped for the rest of the run and the turn is taken again. There is no live provider
|
|
18
|
+
* to test this against on the machine it was written on, which is exactly why it is arranged to
|
|
19
|
+
* fail into the old behaviour rather than out of it.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Providers documented to accept cache_control in an OpenAI-compatible request.
|
|
23
|
+
*
|
|
24
|
+
* Deliberately short. A provider that quietly ignores the field costs nothing; one that rejects it
|
|
25
|
+
* costs a round trip, and one that is not on this list is not asked.
|
|
26
|
+
*/
|
|
27
|
+
const CACHE_AWARE = new Set(['anthropic', 'openrouter']);
|
|
28
|
+
export function supportsCacheHints(provider) {
|
|
29
|
+
return CACHE_AWARE.has(provider.trim().toLowerCase());
|
|
30
|
+
}
|
|
31
|
+
/** Below this there is nothing worth caching and the marks are pure overhead. */
|
|
32
|
+
export const MIN_CACHEABLE_CHARS = 8_000;
|
|
33
|
+
/**
|
|
34
|
+
* The same messages, with up to two cache marks.
|
|
35
|
+
*
|
|
36
|
+
* The system message, because it holds the instructions and never changes; and the last message
|
|
37
|
+
* before the newest, because everything up to it is settled while the newest is what this turn is
|
|
38
|
+
* about. Two marks rather than one because a conversation has two stable regions, and rather than
|
|
39
|
+
* four because each is a separate thing for the provider to keep.
|
|
40
|
+
*
|
|
41
|
+
* Nothing is mutated: a copy is returned. The marks describe this request only, and a mark left on
|
|
42
|
+
* a message in the session's own history would travel into every later request and into the saved
|
|
43
|
+
* transcript.
|
|
44
|
+
*/
|
|
45
|
+
export function withCacheHints(messages) {
|
|
46
|
+
const chars = JSON.stringify(messages).length;
|
|
47
|
+
if (chars < MIN_CACHEABLE_CHARS)
|
|
48
|
+
return messages;
|
|
49
|
+
const out = messages.map(m => ({ ...m }));
|
|
50
|
+
const mark = (index) => {
|
|
51
|
+
const m = out[index];
|
|
52
|
+
if (!m || typeof m.content !== 'string' || m.content === '')
|
|
53
|
+
return;
|
|
54
|
+
// A string becomes one text part carrying the note, which is the shape the field is defined
|
|
55
|
+
// on. Only done for a plain string: a message already holding parts may carry an image, and
|
|
56
|
+
// rebuilding that here would be guessing at its shape.
|
|
57
|
+
m.content = [
|
|
58
|
+
{ type: 'text', text: m.content, cache_control: { type: 'ephemeral' } },
|
|
59
|
+
];
|
|
60
|
+
};
|
|
61
|
+
const system = out.findIndex(m => m.role === 'system');
|
|
62
|
+
if (system >= 0)
|
|
63
|
+
mark(system);
|
|
64
|
+
// The newest message is what this turn is about, so the boundary goes before it.
|
|
65
|
+
if (out.length >= 3)
|
|
66
|
+
mark(out.length - 2);
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Whether a failure is the provider objecting to the marks themselves.
|
|
71
|
+
*
|
|
72
|
+
* Matched on the field name, not on the status: a 400 that says nothing about caching is a
|
|
73
|
+
* different problem and must not be answered by turning caching off and retrying, which would
|
|
74
|
+
* hide it behind an unrelated change.
|
|
75
|
+
*/
|
|
76
|
+
export function looksLikeCacheRejection(err) {
|
|
77
|
+
const text = err instanceof Error ? err.message : String(err ?? '');
|
|
78
|
+
if (!/cache[_ -]?control|prompt[_ -]?cach/i.test(text))
|
|
79
|
+
return false;
|
|
80
|
+
return /invalid|unsupported|unexpected|unrecognis|unrecogniz|not (?:be )?(?:allowed|permitted|supported)|extra fields|400/i
|
|
81
|
+
.test(text);
|
|
82
|
+
}
|
|
83
|
+
/** What the reader is told once, when it is working. */
|
|
84
|
+
export function cacheSavingNotice(cached, prompt) {
|
|
85
|
+
const share = Math.round(cached / Math.max(1, prompt) * 100);
|
|
86
|
+
return `${share}% of the input on this run has been served from ${cached >= prompt ? 'the' : "the provider's"} `
|
|
87
|
+
+ `cache (${cached.toLocaleString()} of ${prompt.toLocaleString()} tokens). That is the `
|
|
88
|
+
+ `unchanged part of the conversation not being charged at full price — on a long task it is `
|
|
89
|
+
+ `most of the bill.`;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=prompt-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-cache.js","sourceRoot":"","sources":["../src/prompt-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;;;;GAKG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;AAEzD,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAEzC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,QAA4B;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IAC9C,IAAI,KAAK,GAAG,mBAAmB;QAAE,OAAO,QAAqB,CAAC;IAE9D,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAA2C,CAAC;IACpF,MAAM,IAAI,GAAG,CAAC,KAAa,EAAQ,EAAE;QACnC,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,KAAK,EAAE;YAAE,OAAO;QACpE,4FAA4F;QAC5F,4FAA4F;QAC5F,uDAAuD;QACtD,CAA0B,CAAC,OAAO,GAAG;YACpC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE;SACxE,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACvD,IAAI,MAAM,IAAI,CAAC;QAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,iFAAiF;IACjF,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC;QAAE,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1C,OAAO,GAAgB,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAY;IAClD,MAAM,IAAI,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IACpE,IAAI,CAAC,sCAAsC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACrE,OAAO,oHAAoH;SACxH,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,MAAc;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;IAC7D,OAAO,GAAG,KAAK,mDAAmD,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,GAAG;UAC5G,UAAU,MAAM,CAAC,cAAc,EAAE,OAAO,MAAM,CAAC,cAAc,EAAE,wBAAwB;UACvF,4FAA4F;UAC5F,mBAAmB,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a long run has actually achieved, said alongside what it has spent.
|
|
3
|
+
*
|
|
4
|
+
* The warning about a long run was a pure token threshold: at a million tokens, five million, ten
|
|
5
|
+
* million, it said how many requests and how many tokens and "It is still going. Stop it if that is
|
|
6
|
+
* not what you meant." It looked at nothing else, so it could not tell a run doing the work from a
|
|
7
|
+
* run going round in circles, and said the same alarming thing to both.
|
|
8
|
+
*
|
|
9
|
+
* Reported by somebody whose run had made 152 requests across two or three tasks and done them:
|
|
10
|
+
* "is it healthy or?" — a fair question to have to ask, and one the message should have answered.
|
|
11
|
+
* Worse, the thresholds meant that single run raised it three times.
|
|
12
|
+
*
|
|
13
|
+
* The arithmetic is worth keeping in view. 10,028,873 tokens over 152 requests is 66k a request,
|
|
14
|
+
* which is simply what a 66k conversation costs to re-read 152 times; the part actually produced is
|
|
15
|
+
* one or two per cent of it. So a token total is a measure of conversation size multiplied by
|
|
16
|
+
* turns, not a measure of waste, and presenting it alone invites exactly the wrong conclusion.
|
|
17
|
+
*
|
|
18
|
+
* What distinguishes the two cases is whether anything is changing. Files written, commands run,
|
|
19
|
+
* plan steps closed: a run with those is working, however much it has spent, and a run with none of
|
|
20
|
+
* them after a million tokens is the one worth interrupting.
|
|
21
|
+
*/
|
|
22
|
+
import type { TrajectoryEvent } from './trajectory.js';
|
|
23
|
+
export interface RunProgress {
|
|
24
|
+
/** Successful calls to a tool that changes the workspace. */
|
|
25
|
+
edits: number;
|
|
26
|
+
/** Distinct paths those calls touched, which is closer to what a person counts. */
|
|
27
|
+
files: number;
|
|
28
|
+
commands: number;
|
|
29
|
+
reads: number;
|
|
30
|
+
stepsDone: number;
|
|
31
|
+
stepsTotal: number;
|
|
32
|
+
/** Sub-agents started, since delegated work is work. */
|
|
33
|
+
agents: number;
|
|
34
|
+
}
|
|
35
|
+
export declare function summariseProgress(events: readonly TrajectoryEvent[], plan?: {
|
|
36
|
+
steps: readonly {
|
|
37
|
+
state: string;
|
|
38
|
+
}[];
|
|
39
|
+
}, agents?: number): RunProgress;
|
|
40
|
+
/** Whether anything has actually moved. Reading is not progress; it is looking for some. */
|
|
41
|
+
export declare function isGettingSomewhere(p: RunProgress): boolean;
|
|
42
|
+
/** What was achieved, in the order a person would ask about it. Empty when nothing was. */
|
|
43
|
+
export declare function describeProgress(p: RunProgress): string;
|
|
44
|
+
export interface RunSpend {
|
|
45
|
+
requests: number;
|
|
46
|
+
tokens: number;
|
|
47
|
+
promptTokens: number;
|
|
48
|
+
completionTokens: number;
|
|
49
|
+
cachedTokens: number;
|
|
50
|
+
delegatedTokens: number;
|
|
51
|
+
model: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The whole message.
|
|
55
|
+
*
|
|
56
|
+
* Two different messages, really, and which one you get is the point. A run that is getting
|
|
57
|
+
* somewhere is told what it has done and what it has spent, with no suggestion that anything is
|
|
58
|
+
* wrong — because nothing is. A run that has spent a million tokens and changed nothing is told
|
|
59
|
+
* exactly that, because that is the one worth stopping.
|
|
60
|
+
*
|
|
61
|
+
* Neither version recommends setting a turn limit any more. A turn limit stops a run at a number
|
|
62
|
+
* that has nothing to do with whether the work is finished, and the same person who is told to set
|
|
63
|
+
* one is later told "Stopped after 40 turns — the work may be unfinished".
|
|
64
|
+
*/
|
|
65
|
+
export declare function longRunNotice(spend: RunSpend, progress: RunProgress, opts?: {
|
|
66
|
+
local: boolean;
|
|
67
|
+
priced?: boolean;
|
|
68
|
+
}): string;
|
|
69
|
+
//# sourceMappingURL=run-progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-progress.d.ts","sourceRoot":"","sources":["../src/run-progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAQvD,MAAM,WAAW,WAAW;IAC1B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,IAAI,CAAC,EAAE;IAAE,KAAK,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,EAC9C,MAAM,SAAI,GACT,WAAW,CAkBb;AAED,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAE1D;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAiBvD;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAuBD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,WAAW,EACrB,IAAI,GAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAqB,GAC5D,MAAM,CAgDR"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a long run has actually achieved, said alongside what it has spent.
|
|
3
|
+
*
|
|
4
|
+
* The warning about a long run was a pure token threshold: at a million tokens, five million, ten
|
|
5
|
+
* million, it said how many requests and how many tokens and "It is still going. Stop it if that is
|
|
6
|
+
* not what you meant." It looked at nothing else, so it could not tell a run doing the work from a
|
|
7
|
+
* run going round in circles, and said the same alarming thing to both.
|
|
8
|
+
*
|
|
9
|
+
* Reported by somebody whose run had made 152 requests across two or three tasks and done them:
|
|
10
|
+
* "is it healthy or?" — a fair question to have to ask, and one the message should have answered.
|
|
11
|
+
* Worse, the thresholds meant that single run raised it three times.
|
|
12
|
+
*
|
|
13
|
+
* The arithmetic is worth keeping in view. 10,028,873 tokens over 152 requests is 66k a request,
|
|
14
|
+
* which is simply what a 66k conversation costs to re-read 152 times; the part actually produced is
|
|
15
|
+
* one or two per cent of it. So a token total is a measure of conversation size multiplied by
|
|
16
|
+
* turns, not a measure of waste, and presenting it alone invites exactly the wrong conclusion.
|
|
17
|
+
*
|
|
18
|
+
* What distinguishes the two cases is whether anything is changing. Files written, commands run,
|
|
19
|
+
* plan steps closed: a run with those is working, however much it has spent, and a run with none of
|
|
20
|
+
* them after a million tokens is the one worth interrupting.
|
|
21
|
+
*/
|
|
22
|
+
import { estimateCost, formatCost } from './pricing.js';
|
|
23
|
+
/** Tools whose success means the workspace changed. */
|
|
24
|
+
const MUTATING = new Set([
|
|
25
|
+
'write_file', 'apply_diff', 'search_replace', 'move_file', 'delete_file',
|
|
26
|
+
]);
|
|
27
|
+
export function summariseProgress(events, plan, agents = 0) {
|
|
28
|
+
const touched = new Set();
|
|
29
|
+
let edits = 0, commands = 0, reads = 0;
|
|
30
|
+
for (const e of events) {
|
|
31
|
+
if (e.t !== 'tool' || !e.ok)
|
|
32
|
+
continue;
|
|
33
|
+
if (MUTATING.has(e.name)) {
|
|
34
|
+
edits++;
|
|
35
|
+
// The detail is the path for every mutating tool, which is what makes this countable at all.
|
|
36
|
+
if (e.detail)
|
|
37
|
+
touched.add(e.detail);
|
|
38
|
+
}
|
|
39
|
+
else if (e.name === 'execute_command')
|
|
40
|
+
commands++;
|
|
41
|
+
else
|
|
42
|
+
reads++;
|
|
43
|
+
}
|
|
44
|
+
const steps = plan?.steps ?? [];
|
|
45
|
+
return {
|
|
46
|
+
edits, files: touched.size, commands, reads, agents,
|
|
47
|
+
stepsDone: steps.filter(s => s.state === 'done').length,
|
|
48
|
+
stepsTotal: steps.length,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** Whether anything has actually moved. Reading is not progress; it is looking for some. */
|
|
52
|
+
export function isGettingSomewhere(p) {
|
|
53
|
+
return p.edits > 0 || p.commands > 0 || p.stepsDone > 0 || p.agents > 0;
|
|
54
|
+
}
|
|
55
|
+
/** What was achieved, in the order a person would ask about it. Empty when nothing was. */
|
|
56
|
+
export function describeProgress(p) {
|
|
57
|
+
const parts = [];
|
|
58
|
+
if (p.files > 0) {
|
|
59
|
+
parts.push(`${p.files} ${p.files === 1 ? 'file' : 'files'} changed`
|
|
60
|
+
+ (p.edits > p.files ? ` in ${p.edits} edits` : ''));
|
|
61
|
+
}
|
|
62
|
+
else if (p.edits > 0) {
|
|
63
|
+
parts.push(`${p.edits} ${p.edits === 1 ? 'edit' : 'edits'}`);
|
|
64
|
+
}
|
|
65
|
+
if (p.commands > 0)
|
|
66
|
+
parts.push(`${p.commands} ${p.commands === 1 ? 'command' : 'commands'} run`);
|
|
67
|
+
if (p.stepsTotal > 0)
|
|
68
|
+
parts.push(`${p.stepsDone} of ${p.stepsTotal} plan steps done`);
|
|
69
|
+
if (p.agents > 0) {
|
|
70
|
+
parts.push(`${p.agents} sub-${p.agents === 1 ? 'agent' : 'agents'} it started`);
|
|
71
|
+
}
|
|
72
|
+
if (p.reads > 0 && parts.length === 0) {
|
|
73
|
+
parts.push(`${p.reads} ${p.reads === 1 ? 'read' : 'reads'} and nothing else`);
|
|
74
|
+
}
|
|
75
|
+
return parts.join(', ');
|
|
76
|
+
}
|
|
77
|
+
/*
|
|
78
|
+
* A token total means nothing until it is money, and it is only money when the rate is known.
|
|
79
|
+
*
|
|
80
|
+
* KONECK ships rates for the models it knows. For anything else — a declared provider, a gateway,
|
|
81
|
+
* a local runtime — there is no honest figure, so none is given rather than a wrong one. A local
|
|
82
|
+
* model is free, which is worth saying out loud when the number looks alarming.
|
|
83
|
+
*/
|
|
84
|
+
function spendLine(spend, local) {
|
|
85
|
+
if (local)
|
|
86
|
+
return ' Nothing is being charged for it: the model is running on your own hardware.';
|
|
87
|
+
const cost = estimateCost(spend.model, spend.promptTokens, spend.completionTokens);
|
|
88
|
+
if (!cost.known) {
|
|
89
|
+
return ` KONECK has no price list for ${spend.model}, so it cannot tell you what that cost — `
|
|
90
|
+
+ `check with your provider if the figure matters.`;
|
|
91
|
+
}
|
|
92
|
+
const cached = spend.cachedTokens > 0
|
|
93
|
+
? ` ${Math.round(spend.cachedTokens / Math.max(1, spend.promptTokens) * 100)}% of the input was `
|
|
94
|
+
+ `served from the provider's cache, so the real bill is lower than that.`
|
|
95
|
+
: '';
|
|
96
|
+
return ` At ${spend.model}'s list price that is about ${formatCost(cost.total)}.${cached}`;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The whole message.
|
|
100
|
+
*
|
|
101
|
+
* Two different messages, really, and which one you get is the point. A run that is getting
|
|
102
|
+
* somewhere is told what it has done and what it has spent, with no suggestion that anything is
|
|
103
|
+
* wrong — because nothing is. A run that has spent a million tokens and changed nothing is told
|
|
104
|
+
* exactly that, because that is the one worth stopping.
|
|
105
|
+
*
|
|
106
|
+
* Neither version recommends setting a turn limit any more. A turn limit stops a run at a number
|
|
107
|
+
* that has nothing to do with whether the work is finished, and the same person who is told to set
|
|
108
|
+
* one is later told "Stopped after 40 turns — the work may be unfinished".
|
|
109
|
+
*/
|
|
110
|
+
export function longRunNotice(spend, progress, opts = { local: false }) {
|
|
111
|
+
const per = Math.round(spend.tokens / Math.max(1, spend.requests));
|
|
112
|
+
const req = (n) => `${n} model ${n === 1 ? 'request' : 'requests'}`;
|
|
113
|
+
/*
|
|
114
|
+
* Who did the spending, when it was not this run.
|
|
115
|
+
*
|
|
116
|
+
* A fan-out's tokens arrive in the session total beside a request count that only counts the
|
|
117
|
+
* parent's turns, which once produced "1 model requests and used 2,340,303 tokens on one
|
|
118
|
+
* message" — a sentence that reads as either a serious fault or a nonsense figure and was
|
|
119
|
+
* neither. Kept split, because "most of it went to eight agents" is the answer to the question
|
|
120
|
+
* the number raises.
|
|
121
|
+
*/
|
|
122
|
+
const shape = spend.delegatedTokens > 0
|
|
123
|
+
? `${spend.tokens.toLocaleString()} tokens — ${Math.max(0, spend.tokens - spend.delegatedTokens)
|
|
124
|
+
.toLocaleString()} here across ${req(spend.requests)}, and `
|
|
125
|
+
+ `${spend.delegatedTokens.toLocaleString()} in the sub-agents it started.`
|
|
126
|
+
: `${req(spend.requests)}, ${spend.tokens.toLocaleString()} tokens — about `
|
|
127
|
+
+ `${per.toLocaleString()} a request, which is mostly the conversation being re-read each `
|
|
128
|
+
+ `time rather than anything new.`;
|
|
129
|
+
/*
|
|
130
|
+
* A spend cap rather than a turn cap, when there is a price to cap.
|
|
131
|
+
*
|
|
132
|
+
* The old message ended "or set maxTurns to have KONECK stop on its own", which stops a run at a
|
|
133
|
+
* number that has nothing to do with whether the work is done — and the same person is later
|
|
134
|
+
* told "Stopped after 40 turns, the work may be unfinished". A budget stops it at the thing
|
|
135
|
+
* actually being spent. Claude Code offers the same shape of control and no turn cap at all,
|
|
136
|
+
* which is a fair indication of which of the two is the useful one.
|
|
137
|
+
*
|
|
138
|
+
* Offered only when the model has a known price, because a cap that cannot be measured cannot be
|
|
139
|
+
* enforced, and KONECK already refuses --budget for a model it has no rates for.
|
|
140
|
+
*/
|
|
141
|
+
const cap = !opts.local && opts.priced
|
|
142
|
+
? ` To have it stop on its own, cap the spend rather than the turns: \`--budget 5\` on the `
|
|
143
|
+
+ `command line, or \`/config budget 5\`.`
|
|
144
|
+
: '';
|
|
145
|
+
if (isGettingSomewhere(progress)) {
|
|
146
|
+
return `**This message has taken ${shape}**\n\n`
|
|
147
|
+
+ `It is working: ${describeProgress(progress)}.${spendLine(spend, opts.local)}\n\n`
|
|
148
|
+
+ `Nothing here is wrong — long tasks cost this. Stop it if you have seen enough.${cap}`;
|
|
149
|
+
}
|
|
150
|
+
return `**${spend.tokens.toLocaleString()} tokens on one message, and nothing has changed yet.**\n\n`
|
|
151
|
+
+ `${shape} ${describeProgress(progress) || 'No files changed, no commands run, no plan steps '
|
|
152
|
+
+ 'closed'}.${spendLine(spend, opts.local)}\n\n`
|
|
153
|
+
+ `That is the shape of a run that is stuck rather than slow. Worth stopping and telling it `
|
|
154
|
+
+ `what to do differently — or asking it what it is waiting for.`;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=run-progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-progress.js","sourceRoot":"","sources":["../src/run-progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAExD,uDAAuD;AACvD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC;IACvB,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa;CACzE,CAAC,CAAC;AAeH,MAAM,UAAU,iBAAiB,CAC/B,MAAkC,EAClC,IAA8C,EAC9C,MAAM,GAAG,CAAC;IAEV,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,IAAI,KAAK,GAAG,CAAC,EAAE,QAAQ,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE;YAAE,SAAS;QACtC,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,KAAK,EAAE,CAAC;YACR,6FAA6F;YAC7F,IAAI,CAAC,CAAC,MAAM;gBAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB;YAAE,QAAQ,EAAE,CAAC;;YAC/C,KAAK,EAAE,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;IAChC,OAAO;QACL,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM;QACnD,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,MAAM;QACvD,UAAU,EAAE,KAAK,CAAC,MAAM;KACzB,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,CAAc;IAC/C,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAC1E,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,gBAAgB,CAAC,CAAc;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,UAAU;cAC/D,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzD,CAAC;SAAM,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,CAAC;IACjG,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,UAAU,kBAAkB,CAAC,CAAC;IACtF,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,aAAa,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,mBAAmB,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAYD;;;;;;GAMG;AACH,SAAS,SAAS,CAAC,KAAe,EAAE,KAAc;IAChD,IAAI,KAAK;QAAE,OAAO,8EAA8E,CAAC;IACjG,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACnF,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,iCAAiC,KAAK,CAAC,KAAK,2CAA2C;cAC1F,iDAAiD,CAAC;IACxD,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,GAAG,CAAC;QACnC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,qBAAqB;cAC7F,wEAAwE;QAC5E,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,OAAO,KAAK,CAAC,KAAK,+BAA+B,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;AAC7F,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAe,EACf,QAAqB,EACrB,OAA6C,EAAE,KAAK,EAAE,KAAK,EAAE;IAE7D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnE,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;IACpF;;;;;;;;OAQG;IACH,MAAM,KAAK,GAAG,KAAK,CAAC,eAAe,GAAG,CAAC;QACrC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,aAAa,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,eAAe,CAAC;aAC3F,cAAc,EAAE,gBAAgB,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ;cAC5D,GAAG,KAAK,CAAC,eAAe,CAAC,cAAc,EAAE,gCAAgC;QAC7E,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB;cACxE,GAAG,GAAG,CAAC,cAAc,EAAE,kEAAkE;cACzF,gCAAgC,CAAC;IAEvC;;;;;;;;;;;OAWG;IACH,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM;QACpC,CAAC,CAAC,0FAA0F;cACxF,wCAAwC;QAC5C,CAAC,CAAC,EAAE,CAAC;IAEP,IAAI,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,OAAO,4BAA4B,KAAK,QAAQ;cAC5C,kBAAkB,gBAAgB,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;cAClF,iFAAiF,GAAG,EAAE,CAAC;IAC7F,CAAC;IAED,OAAO,KAAK,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,4DAA4D;UACjG,GAAG,KAAK,IAAI,gBAAgB,CAAC,QAAQ,CAAC,IAAI,mDAAmD;cAC7F,QAAQ,IAAI,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;UAC9C,2FAA2F;UAC3F,+DAA+D,CAAC;AACtE,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -50,6 +50,16 @@ export interface TokenStats {
|
|
|
50
50
|
completionTokens: number;
|
|
51
51
|
totalTokens: number;
|
|
52
52
|
turns: number;
|
|
53
|
+
/**
|
|
54
|
+
* Input tokens the provider served from its own cache, when it says so.
|
|
55
|
+
*
|
|
56
|
+
* A long run re-sends the whole conversation every request — 152 requests at a 66k average is
|
|
57
|
+
* ten million tokens of which one or two per cent is new — so how much of that was charged at
|
|
58
|
+
* the cache rate is the difference between an ordinary bill and a startling one. Providers
|
|
59
|
+
* report it under three different names and most report nothing, in which case this stays 0 and
|
|
60
|
+
* no claim is made about it either way.
|
|
61
|
+
*/
|
|
62
|
+
cachedTokens?: number;
|
|
53
63
|
}
|
|
54
64
|
export interface AgentConfig {
|
|
55
65
|
provider: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEjC,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-client.d.ts","sourceRoot":"","sources":["../../src/web/ui-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"ui-client.d.ts","sourceRoot":"","sources":["../../src/web/ui-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAw0MrC"}
|
package/dist/web/ui-client.js
CHANGED
|
@@ -429,8 +429,22 @@ function setReasoningOpen(open) {
|
|
|
429
429
|
* Folded it keeps a few lines, so it is still evident that the model is thinking and roughly about
|
|
430
430
|
* what, which is the part worth having at a glance. The text itself is never dropped.
|
|
431
431
|
*/
|
|
432
|
+
/*
|
|
433
|
+
* Reasoning has finished when something else starts.
|
|
434
|
+
*
|
|
435
|
+
* Called wherever a reply block or a new reasoning block appears, which is every transition out of
|
|
436
|
+
* "still thinking about this". A pulse that never stops reads as a run that never finished, which
|
|
437
|
+
* is worse than no pulse at all.
|
|
438
|
+
*/
|
|
439
|
+
function settleReasoning() {
|
|
440
|
+
for (const box of document.querySelectorAll('.thinkbox.live')) box.classList.remove('live');
|
|
441
|
+
}
|
|
442
|
+
|
|
432
443
|
function thinkingBlock() {
|
|
433
|
-
|
|
444
|
+
settleReasoning();
|
|
445
|
+
// "live" while text is still arriving, so the accent beside it moves. Cleared when the turn
|
|
446
|
+
// ends — a block that pulses for ever reads as a run that never finished.
|
|
447
|
+
const box = el('div', 'thinkbox live' + (reasoningOpen() ? '' : ' closed'));
|
|
434
448
|
const head = el('div', 'thinkhead');
|
|
435
449
|
head.appendChild(el('span', 'tl', 'reasoning'));
|
|
436
450
|
const toggle = el('button', null, reasoningOpen() ? 'hide' : 'show');
|
|
@@ -524,6 +538,7 @@ function replyBubble() {
|
|
|
524
538
|
const who = el('div', 'who');
|
|
525
539
|
who.appendChild(mark());
|
|
526
540
|
who.appendChild(el('span', null, 'koneck'));
|
|
541
|
+
settleReasoning();
|
|
527
542
|
const body = el('div', 'reply');
|
|
528
543
|
box.appendChild(who); box.appendChild(body);
|
|
529
544
|
add(box);
|
|
@@ -2797,7 +2812,8 @@ function renderPastEntries(entries) {
|
|
|
2797
2812
|
const who = el('div', 'who');
|
|
2798
2813
|
who.appendChild(mark());
|
|
2799
2814
|
who.appendChild(el('span', null, 'koneck'));
|
|
2800
|
-
|
|
2815
|
+
settleReasoning();
|
|
2816
|
+
const body = el('div', 'reply');
|
|
2801
2817
|
body.innerHTML = md(entry.text);
|
|
2802
2818
|
box.appendChild(who); box.appendChild(body);
|
|
2803
2819
|
stream().appendChild(box);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-client.js","sourceRoot":"","sources":["../../src/web/ui-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,MAAM,CAAC,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"ui-client.js","sourceRoot":"","sources":["../../src/web/ui-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAs0MlB,CAAC;AACF,CAAC"}
|
package/dist/web/ui-css.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-css.d.ts","sourceRoot":"","sources":["../../src/web/ui-css.ts"],"names":[],"mappings":"AA8CA,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"ui-css.d.ts","sourceRoot":"","sources":["../../src/web/ui-css.ts"],"names":[],"mappings":"AA8CA,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAu8C3C"}
|
package/dist/web/ui-css.js
CHANGED
|
@@ -228,8 +228,21 @@ header{height:47px;flex:0 0 47px;border-bottom:1px solid var(--line);display:fle
|
|
|
228
228
|
.reply th,.reply td{border:1px solid var(--line);padding:5px 9px;text-align:left}
|
|
229
229
|
.reply th{background:var(--panel-2);color:var(--muted);font-weight:600}
|
|
230
230
|
|
|
231
|
+
/*
|
|
232
|
+
* Long content wraps inside the box rather than being drawn outside it.
|
|
233
|
+
*
|
|
234
|
+
* Measured with a real reply — PowerShell one-liners and a run of
|
|
235
|
+
* 'perm[it_manager][transact]'='1'; assignments, the kind a model writes when it is reporting what
|
|
236
|
+
* it tried: 2,233 pixels of content in a 501-pixel box, painted straight across the border and over
|
|
237
|
+
* whatever was beside it. The reply, you and think classes were fine because they carry
|
|
238
|
+
* word-break; these never had it.
|
|
239
|
+
*
|
|
240
|
+
* overflow-wrap:anywhere rather than break-word, because only anywhere affects the min-content
|
|
241
|
+
* width — which is the measurement a parent uses to decide how wide it has to be. break-word wraps
|
|
242
|
+
* the text and still lets the box grow.
|
|
243
|
+
*/
|
|
231
244
|
.tool{border:1px solid var(--line);border-left:3px solid var(--dim);border-radius:8px;
|
|
232
|
-
background:var(--panel);margin:8px 0;overflow:hidden}
|
|
245
|
+
background:var(--panel);margin:8px 0;overflow:hidden;min-width:0;overflow-wrap:anywhere}
|
|
233
246
|
.tool.ok{border-left-color:var(--green)} .tool.bad{border-left-color:var(--red)}
|
|
234
247
|
.tool.run{border-left-color:var(--amber)}
|
|
235
248
|
.tool .th{display:flex;align-items:center;gap:9px;padding:8px 12px;font-size:calc(var(--ui) * 0.8929);width:100%;
|
|
@@ -292,13 +305,52 @@ header{height:47px;flex:0 0 47px;border-bottom:1px solid var(--line);display:fle
|
|
|
292
305
|
.think pre code{background:none;padding:0}
|
|
293
306
|
.think strong{color:var(--ink);font-weight:600}
|
|
294
307
|
.think a{color:var(--cyan)}
|
|
308
|
+
/*
|
|
309
|
+
* Reasoning, coloured so it can be read at a glance.
|
|
310
|
+
*
|
|
311
|
+
* It was one flat grey — correct, and unreadable at length. A model's reasoning is mostly a
|
|
312
|
+
* sequence of two things: something it noticed, and something it decided. Those are worth telling
|
|
313
|
+
* apart without reading every word, which is the whole point of looking at reasoning at all.
|
|
314
|
+
*
|
|
315
|
+
* Restrained on purpose. This sits under the answer, not over it: a paragraph in four colours
|
|
316
|
+
* competes with the thing you actually asked for. So the accents are the ones already in the
|
|
317
|
+
* interface, and everything unmarked stays muted.
|
|
318
|
+
*/
|
|
319
|
+
/* A path, a symbol, a command — the concrete nouns of a decision. */
|
|
320
|
+
.think code{color:var(--cyan)}
|
|
321
|
+
/* What it settled on. Models bold their conclusions, and those are the skimmable lines. */
|
|
322
|
+
.think strong{color:var(--ink);font-weight:600}
|
|
323
|
+
/* A step it is working through, numbered or bulleted: the marker carries the colour, not the text. */
|
|
324
|
+
.think ol{list-style:none;counter-reset:think-step;padding-left:0}
|
|
325
|
+
.think ol > li{counter-increment:think-step;padding-left:1.9em;position:relative}
|
|
326
|
+
.think ol > li::before{content:counter(think-step);position:absolute;left:0;top:.05em;
|
|
327
|
+
width:1.35em;height:1.35em;border-radius:50%;border:1px solid var(--line-2);
|
|
328
|
+
color:var(--dim);font-size:.78em;display:flex;align-items:center;justify-content:center;
|
|
329
|
+
font-family:var(--mono)}
|
|
330
|
+
.think ul{list-style:none;padding-left:0}
|
|
331
|
+
.think ul > li{padding-left:1.15em;position:relative}
|
|
332
|
+
.think ul > li::before{content:'';position:absolute;left:.28em;top:.62em;width:4px;height:4px;
|
|
333
|
+
border-radius:50%;background:var(--line-2)}
|
|
334
|
+
/* A heading inside reasoning is the model changing subject, so it gets the accent bar. */
|
|
335
|
+
.think h1,.think h2,.think h3,.think h4{border-left:2px solid var(--cyan);padding-left:8px;
|
|
336
|
+
margin-left:-10px}
|
|
337
|
+
/* A quote is nearly always the model reciting evidence — an error, a line of output. */
|
|
338
|
+
.think blockquote{margin:.5em 0;padding:.15em 0 .15em 10px;border-left:2px solid var(--amber);
|
|
339
|
+
color:var(--muted)}
|
|
340
|
+
/* Live reasoning reads as live: the rule beside it breathes while text is arriving. */
|
|
341
|
+
.thinkbox.live{border-left-color:var(--cyan)}
|
|
342
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
343
|
+
.thinkbox.live{animation:thinkpulse 2.4s ease-in-out infinite}
|
|
344
|
+
}
|
|
345
|
+
@keyframes thinkpulse{0%,100%{border-left-color:var(--line-2)}50%{border-left-color:var(--cyan)}}
|
|
346
|
+
|
|
295
347
|
/* Four lines and a fade, so it is plainly cut off rather than mysteriously short. */
|
|
296
348
|
.thinkbox.closed .think{max-height:6.6em;overflow:hidden;
|
|
297
349
|
-webkit-mask-image:linear-gradient(to bottom,#000 60%,transparent);
|
|
298
350
|
mask-image:linear-gradient(to bottom,#000 60%,transparent)}
|
|
299
351
|
.notice{border:1px solid var(--line);border-left:3px solid var(--amber);border-radius:8px;
|
|
300
352
|
padding:10px 13px;margin:9px 0;font-size:calc(var(--ui) * 0.8929);color:var(--muted);white-space:pre-wrap;
|
|
301
|
-
background:var(--panel)}
|
|
353
|
+
background:var(--panel);min-width:0;overflow-wrap:anywhere}
|
|
302
354
|
.notice.info{border-left-color:var(--cyan)}
|
|
303
355
|
.err{border:1px solid var(--red);border-left:3px solid var(--red);border-radius:8px;
|
|
304
356
|
padding:10px 13px;margin:9px 0;font-size:calc(var(--ui) * 0.8929);color:var(--red);white-space:pre-wrap;
|
package/dist/web/ui-css.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-css.js","sourceRoot":"","sources":["../../src/web/ui-css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH;;;;;;;;;;;;GAYG;AACH,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;CAkBZ,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,OAAe;IACjC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;gBAyBO,OAAO;;;oCAGa,IAAI;;2BAEb,IAAI
|
|
1
|
+
{"version":3,"file":"ui-css.js","sourceRoot":"","sources":["../../src/web/ui-css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH;;;;;;;;;;;;GAYG;AACH,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;CAkBZ,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,OAAe;IACjC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;gBAyBO,OAAO;;;oCAGa,IAAI;;2BAEb,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAu6C9B,CAAC;AACF,CAAC"}
|