koneck 2.25.53 → 2.25.55
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/engine.d.ts +14 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +107 -9
- package/dist/engine.js.map +1 -1
- package/dist/ink-chat.d.ts.map +1 -1
- package/dist/ink-chat.js +9 -0
- package/dist/ink-chat.js.map +1 -1
- package/dist/trajectory.d.ts +99 -0
- package/dist/trajectory.d.ts.map +1 -0
- package/dist/trajectory.js +125 -0
- package/dist/trajectory.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What happened, in order, with timings — the record a session needs to be inspectable.
|
|
3
|
+
*
|
|
4
|
+
* KONECK kept only the message list. That is enough to resume a conversation and useless for
|
|
5
|
+
* answering the questions people actually ask afterwards: where did twenty-five minutes go, which
|
|
6
|
+
* tool was slow, how long was it waiting for the first token rather than generating, what was it
|
|
7
|
+
* thinking before that edit. Every one of those was visible while it scrolled past and gone
|
|
8
|
+
* afterwards.
|
|
9
|
+
*
|
|
10
|
+
* The DeepSeek Harness records this properly and its trajectory view is the reason you can answer
|
|
11
|
+
* those questions there. This is the same idea at the scale a terminal can show: an append-only
|
|
12
|
+
* list of typed events with durations, written alongside the messages in the session file.
|
|
13
|
+
*/
|
|
14
|
+
export type TrajectoryEvent =
|
|
15
|
+
/** A turn began. */
|
|
16
|
+
{
|
|
17
|
+
t: 'turn';
|
|
18
|
+
at: number;
|
|
19
|
+
turn: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* One request to the model.
|
|
23
|
+
*
|
|
24
|
+
* `ttftMs` is time to first token — the wait before anything came back — kept apart from the
|
|
25
|
+
* total because they have completely different causes. A slow first token is the provider
|
|
26
|
+
* queueing or the prompt being large; slow generation after that is the model itself.
|
|
27
|
+
*/
|
|
28
|
+
| {
|
|
29
|
+
t: 'request';
|
|
30
|
+
at: number;
|
|
31
|
+
ms: number;
|
|
32
|
+
ttftMs: number;
|
|
33
|
+
promptTokens: number;
|
|
34
|
+
completionTokens: number;
|
|
35
|
+
}
|
|
36
|
+
/** Reasoning arrived, and how much of it. */
|
|
37
|
+
| {
|
|
38
|
+
t: 'thinking';
|
|
39
|
+
at: number;
|
|
40
|
+
chars: number;
|
|
41
|
+
}
|
|
42
|
+
/** One tool call, with how long it took and whether it worked. */
|
|
43
|
+
| {
|
|
44
|
+
t: 'tool';
|
|
45
|
+
at: number;
|
|
46
|
+
name: string;
|
|
47
|
+
ms: number;
|
|
48
|
+
ok: boolean;
|
|
49
|
+
detail: string;
|
|
50
|
+
resultChars: number;
|
|
51
|
+
}
|
|
52
|
+
/** The conversation was summarised to fit. */
|
|
53
|
+
| {
|
|
54
|
+
t: 'compact';
|
|
55
|
+
at: number;
|
|
56
|
+
before: number;
|
|
57
|
+
after: number;
|
|
58
|
+
}
|
|
59
|
+
/** The run stopped for a stated reason rather than finishing. */
|
|
60
|
+
| {
|
|
61
|
+
t: 'stop';
|
|
62
|
+
at: number;
|
|
63
|
+
reason: string;
|
|
64
|
+
};
|
|
65
|
+
/** Bounded, because a long session should not be able to fill the disk with its own diary. */
|
|
66
|
+
export declare const MAX_EVENTS = 5000;
|
|
67
|
+
export declare class Trajectory {
|
|
68
|
+
private readonly events;
|
|
69
|
+
add(event: TrajectoryEvent): void;
|
|
70
|
+
all(): readonly TrajectoryEvent[];
|
|
71
|
+
get length(): number;
|
|
72
|
+
}
|
|
73
|
+
/** Totals worth knowing about a whole session, derived rather than tracked separately. */
|
|
74
|
+
export interface TrajectorySummary {
|
|
75
|
+
turns: number;
|
|
76
|
+
requests: number;
|
|
77
|
+
modelMs: number;
|
|
78
|
+
toolMs: number;
|
|
79
|
+
waitingMs: number;
|
|
80
|
+
promptTokens: number;
|
|
81
|
+
completionTokens: number;
|
|
82
|
+
slowestTool?: {
|
|
83
|
+
name: string;
|
|
84
|
+
ms: number;
|
|
85
|
+
};
|
|
86
|
+
failedTools: number;
|
|
87
|
+
compactions: number;
|
|
88
|
+
thinkingChars: number;
|
|
89
|
+
}
|
|
90
|
+
export declare function summarise(events: readonly TrajectoryEvent[]): TrajectorySummary;
|
|
91
|
+
/**
|
|
92
|
+
* The trajectory as a person reads it: where the time went, then the events themselves.
|
|
93
|
+
*
|
|
94
|
+
* The totals come first because they answer the question that prompted the look. "Twenty-five
|
|
95
|
+
* minutes, of which nineteen were waiting for first tokens" is the answer; the event list is the
|
|
96
|
+
* evidence for it.
|
|
97
|
+
*/
|
|
98
|
+
export declare function renderTrajectory(events: readonly TrajectoryEvent[], limit?: number): string;
|
|
99
|
+
//# sourceMappingURL=trajectory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trajectory.d.ts","sourceRoot":"","sources":["../src/trajectory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,eAAe;AACzB,oBAAoB;AAClB;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACzC;;;;;;GAMG;GACD;IAAE,CAAC,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE;AAC1G,6CAA6C;GAC3C;IAAE,CAAC,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAC9C,kEAAkE;GAChE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE;AACvG,8CAA8C;GAC5C;IAAE,CAAC,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAC7D,iEAAiE;GAC/D;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9C,8FAA8F;AAC9F,eAAO,MAAM,UAAU,OAAQ,CAAC;AAEhC,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAEhD,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAOjC,GAAG,IAAI,SAAS,eAAe,EAAE;IAIjC,IAAI,MAAM,IAAI,MAAM,CAEnB;CACF;AAOD,0FAA0F;AAC1F,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,GAAG,iBAAiB,CA4B/E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,KAAK,SAAK,GACT,MAAM,CAgDR"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What happened, in order, with timings — the record a session needs to be inspectable.
|
|
3
|
+
*
|
|
4
|
+
* KONECK kept only the message list. That is enough to resume a conversation and useless for
|
|
5
|
+
* answering the questions people actually ask afterwards: where did twenty-five minutes go, which
|
|
6
|
+
* tool was slow, how long was it waiting for the first token rather than generating, what was it
|
|
7
|
+
* thinking before that edit. Every one of those was visible while it scrolled past and gone
|
|
8
|
+
* afterwards.
|
|
9
|
+
*
|
|
10
|
+
* The DeepSeek Harness records this properly and its trajectory view is the reason you can answer
|
|
11
|
+
* those questions there. This is the same idea at the scale a terminal can show: an append-only
|
|
12
|
+
* list of typed events with durations, written alongside the messages in the session file.
|
|
13
|
+
*/
|
|
14
|
+
/** Bounded, because a long session should not be able to fill the disk with its own diary. */
|
|
15
|
+
export const MAX_EVENTS = 5_000;
|
|
16
|
+
export class Trajectory {
|
|
17
|
+
events = [];
|
|
18
|
+
add(event) {
|
|
19
|
+
// Dropping the oldest keeps the recent past, which is what anybody inspecting a session is
|
|
20
|
+
// asking about. Silently dropping the newest would be the wrong half.
|
|
21
|
+
if (this.events.length >= MAX_EVENTS)
|
|
22
|
+
this.events.shift();
|
|
23
|
+
this.events.push(event);
|
|
24
|
+
}
|
|
25
|
+
all() {
|
|
26
|
+
return this.events;
|
|
27
|
+
}
|
|
28
|
+
get length() {
|
|
29
|
+
return this.events.length;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const ms = (value) => value >= 10_000 ? `${(value / 1000).toFixed(0)}s`
|
|
33
|
+
: value >= 1_000 ? `${(value / 1000).toFixed(1)}s`
|
|
34
|
+
: `${Math.round(value)}ms`;
|
|
35
|
+
export function summarise(events) {
|
|
36
|
+
const summary = {
|
|
37
|
+
turns: 0, requests: 0, modelMs: 0, toolMs: 0, waitingMs: 0,
|
|
38
|
+
promptTokens: 0, completionTokens: 0, failedTools: 0, compactions: 0, thinkingChars: 0,
|
|
39
|
+
};
|
|
40
|
+
for (const event of events) {
|
|
41
|
+
switch (event.t) {
|
|
42
|
+
case 'turn':
|
|
43
|
+
summary.turns++;
|
|
44
|
+
break;
|
|
45
|
+
case 'request':
|
|
46
|
+
summary.requests++;
|
|
47
|
+
summary.modelMs += event.ms;
|
|
48
|
+
summary.waitingMs += event.ttftMs;
|
|
49
|
+
summary.promptTokens += event.promptTokens;
|
|
50
|
+
summary.completionTokens += event.completionTokens;
|
|
51
|
+
break;
|
|
52
|
+
case 'tool':
|
|
53
|
+
summary.toolMs += event.ms;
|
|
54
|
+
if (!event.ok)
|
|
55
|
+
summary.failedTools++;
|
|
56
|
+
if (!summary.slowestTool || event.ms > summary.slowestTool.ms) {
|
|
57
|
+
summary.slowestTool = { name: event.name, ms: event.ms };
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
case 'compact':
|
|
61
|
+
summary.compactions++;
|
|
62
|
+
break;
|
|
63
|
+
case 'thinking':
|
|
64
|
+
summary.thinkingChars += event.chars;
|
|
65
|
+
break;
|
|
66
|
+
default: break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return summary;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The trajectory as a person reads it: where the time went, then the events themselves.
|
|
73
|
+
*
|
|
74
|
+
* The totals come first because they answer the question that prompted the look. "Twenty-five
|
|
75
|
+
* minutes, of which nineteen were waiting for first tokens" is the answer; the event list is the
|
|
76
|
+
* evidence for it.
|
|
77
|
+
*/
|
|
78
|
+
export function renderTrajectory(events, limit = 60) {
|
|
79
|
+
if (events.length === 0)
|
|
80
|
+
return 'Nothing recorded yet this session.';
|
|
81
|
+
const s = summarise(events);
|
|
82
|
+
const lines = [];
|
|
83
|
+
lines.push(`**${s.turns} turns**, ${s.requests} requests, ` +
|
|
84
|
+
`${(s.promptTokens + s.completionTokens).toLocaleString()} tokens`);
|
|
85
|
+
lines.push(`**Model** ${ms(s.modelMs)} of which ${ms(s.waitingMs)} waiting for a first token`);
|
|
86
|
+
lines.push(`**Tools** ${ms(s.toolMs)}` +
|
|
87
|
+
(s.failedTools > 0 ? ` ${s.failedTools} failed` : '') +
|
|
88
|
+
(s.slowestTool ? ` slowest: ${s.slowestTool.name} ${ms(s.slowestTool.ms)}` : ''));
|
|
89
|
+
if (s.compactions > 0)
|
|
90
|
+
lines.push(`**Compacted** ${s.compactions} times`);
|
|
91
|
+
if (s.thinkingChars > 0) {
|
|
92
|
+
lines.push(`**Reasoning** about ${Math.round(s.thinkingChars / 4).toLocaleString()} tokens`);
|
|
93
|
+
}
|
|
94
|
+
lines.push('');
|
|
95
|
+
const shown = events.slice(-limit);
|
|
96
|
+
if (shown.length < events.length) {
|
|
97
|
+
lines.push(`*(the last ${shown.length} of ${events.length} events)*`);
|
|
98
|
+
}
|
|
99
|
+
for (const event of shown) {
|
|
100
|
+
switch (event.t) {
|
|
101
|
+
case 'turn':
|
|
102
|
+
lines.push(`**turn ${event.turn}**`);
|
|
103
|
+
break;
|
|
104
|
+
case 'request':
|
|
105
|
+
lines.push(` model ${ms(event.ms).padEnd(7)} first token ${ms(event.ttftMs).padEnd(7)}` +
|
|
106
|
+
` ${event.promptTokens.toLocaleString()} in / ${event.completionTokens.toLocaleString()} out`);
|
|
107
|
+
break;
|
|
108
|
+
case 'thinking':
|
|
109
|
+
lines.push(` thinking ${Math.round(event.chars / 4).toLocaleString()} tokens`);
|
|
110
|
+
break;
|
|
111
|
+
case 'tool':
|
|
112
|
+
lines.push(` ${event.ok ? 'tool' : 'FAIL'} ${ms(event.ms).padEnd(7)} ${event.name}` +
|
|
113
|
+
(event.detail ? ` ${event.detail.slice(0, 54)}` : ''));
|
|
114
|
+
break;
|
|
115
|
+
case 'compact':
|
|
116
|
+
lines.push(` compact ${event.before} messages to ${event.after}`);
|
|
117
|
+
break;
|
|
118
|
+
case 'stop':
|
|
119
|
+
lines.push(` stopped ${event.reason.slice(0, 88)}`);
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return lines.join('\n');
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=trajectory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trajectory.js","sourceRoot":"","sources":["../src/trajectory.ts"],"names":[],"mappings":"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"}
|