@omercnet/paseo-omp 0.4.0-next.123.1 → 0.4.0-next.125.1
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/package.json
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Release Please keeps this bundle-safe constant aligned with package.json. */
|
|
2
|
-
export const PASEO_OMP_PACKAGE_VERSION = "0.4.0-next.
|
|
2
|
+
export const PASEO_OMP_PACKAGE_VERSION = "0.4.0-next.125.1"; // x-release-please-version
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { ProviderEvent } from "@getpaseo/plugin/server/provider";
|
|
3
|
+
import type { OmpRpcEvent } from "./omp-rpc-protocol";
|
|
4
|
+
import type { OmpPublicDataSerializer } from "./security";
|
|
5
|
+
import type { ActiveTurn } from "./session-terminal";
|
|
6
|
+
import type { OmpSessionUsage } from "./session-usage";
|
|
7
|
+
import type { OmpTimelineProjector } from "./timeline-projector";
|
|
8
|
+
|
|
9
|
+
type Emit = (event: ProviderEvent) => void;
|
|
10
|
+
|
|
11
|
+
export interface ActiveCompaction {
|
|
12
|
+
id: string;
|
|
13
|
+
trigger: "auto" | "manual";
|
|
14
|
+
turnId: string;
|
|
15
|
+
generation: number;
|
|
16
|
+
retrying: boolean;
|
|
17
|
+
action?: string;
|
|
18
|
+
preTokens?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class OmpSessionCompaction {
|
|
22
|
+
private operation: ActiveCompaction | null = null;
|
|
23
|
+
private discardedEnds = 0;
|
|
24
|
+
|
|
25
|
+
constructor(
|
|
26
|
+
private readonly sessionId: string,
|
|
27
|
+
private readonly emit: Emit,
|
|
28
|
+
private readonly projector: OmpTimelineProjector,
|
|
29
|
+
private readonly dataFilter: OmpPublicDataSerializer,
|
|
30
|
+
private readonly usage: OmpSessionUsage,
|
|
31
|
+
) {}
|
|
32
|
+
|
|
33
|
+
get active(): ActiveCompaction | null {
|
|
34
|
+
return this.operation;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
start(turn: ActiveTurn, trigger: "auto" | "manual", action?: string): void {
|
|
38
|
+
if (this.discardedEnds > 0) {
|
|
39
|
+
this.discardedEnds += 1;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const active = this.operation;
|
|
43
|
+
if (active && active.trigger === trigger && active.action === action) {
|
|
44
|
+
active.retrying = false;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (active) {
|
|
48
|
+
this.retire("OMP emitted overlapping compactions");
|
|
49
|
+
this.discardedEnds = 2;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const operation: ActiveCompaction = {
|
|
53
|
+
id: randomUUID(),
|
|
54
|
+
trigger,
|
|
55
|
+
turnId: turn.turnId,
|
|
56
|
+
generation: turn.generation,
|
|
57
|
+
action,
|
|
58
|
+
retrying: false,
|
|
59
|
+
preTokens: this.usage.latest?.contextWindowUsedTokens,
|
|
60
|
+
};
|
|
61
|
+
this.operation = operation;
|
|
62
|
+
this.projector.flush(true);
|
|
63
|
+
this.emit({
|
|
64
|
+
type: "timeline.item",
|
|
65
|
+
sessionId: this.sessionId,
|
|
66
|
+
item: {
|
|
67
|
+
id: operation.id,
|
|
68
|
+
type: "compaction",
|
|
69
|
+
status: "loading",
|
|
70
|
+
trigger,
|
|
71
|
+
...(operation.preTokens !== undefined ? { preTokens: operation.preTokens } : {}),
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
handleAutoEnd(
|
|
77
|
+
turn: ActiveTurn,
|
|
78
|
+
event: Extract<OmpRpcEvent, { type: "auto_compaction_end" }>,
|
|
79
|
+
): boolean {
|
|
80
|
+
if (this.discardedEnds > 0) {
|
|
81
|
+
this.discardedEnds -= 1;
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
const operation = this.operation;
|
|
85
|
+
if (
|
|
86
|
+
operation?.trigger !== "auto" ||
|
|
87
|
+
operation.turnId !== turn.turnId ||
|
|
88
|
+
operation.generation !== turn.generation
|
|
89
|
+
) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (event.action !== undefined && operation.action !== event.action) {
|
|
93
|
+
this.retire("OMP emitted overlapping compactions");
|
|
94
|
+
this.discardedEnds = 1;
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
if (event.willRetry) {
|
|
98
|
+
operation.retrying = true;
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
if (operation.retrying) {
|
|
102
|
+
operation.retrying = false;
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
const state = event.aborted
|
|
106
|
+
? "canceled"
|
|
107
|
+
: event.errorMessage
|
|
108
|
+
? "failed"
|
|
109
|
+
: event.skipped
|
|
110
|
+
? "skipped"
|
|
111
|
+
: "completed";
|
|
112
|
+
this.finish(state, {
|
|
113
|
+
tokensBefore: event.result?.tokensBefore ?? event.result?.preTokens,
|
|
114
|
+
message: event.errorMessage,
|
|
115
|
+
});
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
finish(
|
|
120
|
+
state: "completed" | "failed" | "canceled" | "skipped",
|
|
121
|
+
options: { tokensBefore?: number | null; message?: string } = {},
|
|
122
|
+
): void {
|
|
123
|
+
const operation = this.operation;
|
|
124
|
+
if (!operation) return;
|
|
125
|
+
this.operation = null;
|
|
126
|
+
this.projector.flush(true);
|
|
127
|
+
if (state === "completed") {
|
|
128
|
+
this.usage.completeCompaction();
|
|
129
|
+
}
|
|
130
|
+
if (state !== "completed") {
|
|
131
|
+
const defaultMessage =
|
|
132
|
+
state === "failed"
|
|
133
|
+
? "OMP compaction failed"
|
|
134
|
+
: state === "canceled"
|
|
135
|
+
? "OMP compaction canceled"
|
|
136
|
+
: "OMP compaction skipped";
|
|
137
|
+
this.emit({
|
|
138
|
+
type: "timeline.item",
|
|
139
|
+
sessionId: this.sessionId,
|
|
140
|
+
item: {
|
|
141
|
+
id: operation.id,
|
|
142
|
+
type: "notification",
|
|
143
|
+
level: state === "failed" ? "error" : "info",
|
|
144
|
+
message: this.dataFilter.text(options.message ?? defaultMessage, 4_096),
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const tokensBefore = options.tokensBefore ?? operation.preTokens;
|
|
150
|
+
this.emit({
|
|
151
|
+
type: "timeline.item",
|
|
152
|
+
sessionId: this.sessionId,
|
|
153
|
+
item: {
|
|
154
|
+
id: operation.id,
|
|
155
|
+
type: "compaction",
|
|
156
|
+
status: "completed",
|
|
157
|
+
trigger: operation.trigger,
|
|
158
|
+
...(tokensBefore !== undefined ? { preTokens: tokensBefore } : {}),
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
retire(message: string): void {
|
|
164
|
+
const operation = this.operation;
|
|
165
|
+
if (!operation) return;
|
|
166
|
+
this.operation = null;
|
|
167
|
+
this.emit({
|
|
168
|
+
type: "timeline.item",
|
|
169
|
+
sessionId: this.sessionId,
|
|
170
|
+
item: {
|
|
171
|
+
id: operation.id,
|
|
172
|
+
type: "compaction",
|
|
173
|
+
status: "completed",
|
|
174
|
+
trigger: operation.trigger,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
this.emit({
|
|
178
|
+
type: "timeline.item",
|
|
179
|
+
sessionId: this.sessionId,
|
|
180
|
+
item: { id: `${operation.id}:error`, type: "error", message },
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
resetDiscardedEnds(): void {
|
|
185
|
+
this.discardedEnds = 0;
|
|
186
|
+
}
|
|
187
|
+
}
|