snow-flow 10.0.186-dev.682 → 10.0.186-dev.683
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 +1 -1
- package/src/cli/cmd/tui/routes/session/index.tsx +3 -1
- package/src/format/index.ts +3 -1
- package/src/plugin/index.ts +4 -1
- package/src/project/bootstrap.ts +3 -1
- package/src/session/message-v2.ts +15 -1
- package/src/share/share-next.ts +45 -40
- package/src/share/share.ts +22 -17
package/package.json
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
For,
|
|
8
8
|
Match,
|
|
9
9
|
on,
|
|
10
|
+
onCleanup,
|
|
10
11
|
onMount,
|
|
11
12
|
Show,
|
|
12
13
|
Switch,
|
|
@@ -202,7 +203,7 @@ export function Session() {
|
|
|
202
203
|
})
|
|
203
204
|
|
|
204
205
|
let lastSwitch: string | undefined = undefined
|
|
205
|
-
sdk.event.on("message.part.updated", (evt) => {
|
|
206
|
+
const unsubPartUpdated = sdk.event.on("message.part.updated", (evt) => {
|
|
206
207
|
const part = evt.properties.part
|
|
207
208
|
if (part.type !== "tool") return
|
|
208
209
|
if (part.sessionID !== route.sessionID) return
|
|
@@ -217,6 +218,7 @@ export function Session() {
|
|
|
217
218
|
lastSwitch = part.id
|
|
218
219
|
}
|
|
219
220
|
})
|
|
221
|
+
onCleanup(() => unsubPartUpdated())
|
|
220
222
|
|
|
221
223
|
let scroll: ScrollBoxRenderable
|
|
222
224
|
let prompt: PromptRef
|
package/src/format/index.ts
CHANGED
|
@@ -100,9 +100,11 @@ export namespace Format {
|
|
|
100
100
|
return result
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
let formatUnsub: (() => void) | undefined
|
|
103
104
|
export function init() {
|
|
104
105
|
log.info("init")
|
|
105
|
-
|
|
106
|
+
formatUnsub?.()
|
|
107
|
+
formatUnsub = Bus.subscribe(File.Event.Edited, async (payload) => {
|
|
106
108
|
const file = payload.properties.file
|
|
107
109
|
log.info("formatting", { file })
|
|
108
110
|
const ext = path.extname(file)
|
package/src/plugin/index.ts
CHANGED
|
@@ -116,6 +116,7 @@ export namespace Plugin {
|
|
|
116
116
|
return state().then((x) => x.hooks)
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
let busUnsub: (() => void) | undefined
|
|
119
120
|
export async function init() {
|
|
120
121
|
const hooks = await state().then((x) => x.hooks)
|
|
121
122
|
const config = await Config.get()
|
|
@@ -123,7 +124,9 @@ export namespace Plugin {
|
|
|
123
124
|
// @ts-expect-error this is because we haven't moved plugin to sdk v2
|
|
124
125
|
await hook.config?.(config)
|
|
125
126
|
}
|
|
126
|
-
|
|
127
|
+
// Clean up previous subscription to prevent accumulation on re-init
|
|
128
|
+
busUnsub?.()
|
|
129
|
+
busUnsub = Bus.subscribeAll(async (input) => {
|
|
127
130
|
const hooks = await state().then((x) => x.hooks)
|
|
128
131
|
for (const hook of hooks) {
|
|
129
132
|
hook["event"]?.({
|
package/src/project/bootstrap.ts
CHANGED
|
@@ -75,9 +75,11 @@ export async function InstanceBootstrap() {
|
|
|
75
75
|
await ensureAgentsMd()
|
|
76
76
|
await ensureInstanceMd()
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
bootstrapUnsub?.()
|
|
79
|
+
bootstrapUnsub = Bus.subscribe(Command.Event.Executed, async (payload) => {
|
|
79
80
|
if (payload.properties.name === Command.Default.INIT) {
|
|
80
81
|
await Project.setInitialized(Instance.project.id)
|
|
81
82
|
}
|
|
82
83
|
})
|
|
83
84
|
}
|
|
85
|
+
let bootstrapUnsub: (() => void) | undefined
|
|
@@ -447,6 +447,8 @@ export namespace MessageV2 {
|
|
|
447
447
|
|
|
448
448
|
// In-memory message cache: avoids re-reading all messages from disk on every loop iteration.
|
|
449
449
|
// Uses Instance.state for per-instance isolation and Bus events for cache invalidation.
|
|
450
|
+
// LRU eviction: only the most recently accessed sessions are kept in memory.
|
|
451
|
+
const MAX_CACHED_SESSIONS = 3
|
|
450
452
|
const messageCache = Instance.state(
|
|
451
453
|
() => {
|
|
452
454
|
const sessions = new Map<string, MessageV2.WithParts[]>()
|
|
@@ -508,7 +510,12 @@ export namespace MessageV2 {
|
|
|
508
510
|
export async function streamCached(sessionID: string): Promise<WithParts[]> {
|
|
509
511
|
const { sessions } = messageCache()
|
|
510
512
|
const existing = sessions.get(sessionID)
|
|
511
|
-
if (existing)
|
|
513
|
+
if (existing) {
|
|
514
|
+
// LRU: move to end (most recently used)
|
|
515
|
+
sessions.delete(sessionID)
|
|
516
|
+
sessions.set(sessionID, existing)
|
|
517
|
+
return existing
|
|
518
|
+
}
|
|
512
519
|
|
|
513
520
|
// Cold start: load from disk and populate cache
|
|
514
521
|
const result: WithParts[] = []
|
|
@@ -517,6 +524,13 @@ export namespace MessageV2 {
|
|
|
517
524
|
}
|
|
518
525
|
result.reverse() // stream yields newest first, we want chronological order
|
|
519
526
|
sessions.set(sessionID, result)
|
|
527
|
+
|
|
528
|
+
// LRU eviction: remove oldest sessions if over limit
|
|
529
|
+
while (sessions.size > MAX_CACHED_SESSIONS) {
|
|
530
|
+
const oldest = sessions.keys().next().value
|
|
531
|
+
if (oldest) sessions.delete(oldest)
|
|
532
|
+
}
|
|
533
|
+
|
|
520
534
|
return result
|
|
521
535
|
}
|
|
522
536
|
|
package/src/share/share-next.ts
CHANGED
|
@@ -17,52 +17,57 @@ export namespace ShareNext {
|
|
|
17
17
|
|
|
18
18
|
const disabled = process.env["OPENCODE_DISABLE_SHARE"] === "true" || process.env["OPENCODE_DISABLE_SHARE"] === "1"
|
|
19
19
|
|
|
20
|
+
const shareNextUnsubs: (() => void)[] = []
|
|
20
21
|
export async function init() {
|
|
21
22
|
if (disabled) return
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
data: evt.properties.info as any,
|
|
35
|
-
},
|
|
36
|
-
])
|
|
37
|
-
if (evt.properties.info.role === "user") {
|
|
23
|
+
for (const unsub of shareNextUnsubs) unsub()
|
|
24
|
+
shareNextUnsubs.length = 0
|
|
25
|
+
shareNextUnsubs.push(
|
|
26
|
+
Bus.subscribe(Session.Event.Updated, async (evt) => {
|
|
27
|
+
await sync(evt.properties.info.id, [
|
|
28
|
+
{
|
|
29
|
+
type: "session",
|
|
30
|
+
data: evt.properties.info,
|
|
31
|
+
},
|
|
32
|
+
])
|
|
33
|
+
}),
|
|
34
|
+
Bus.subscribe(MessageV2.Event.Updated, async (evt) => {
|
|
38
35
|
await sync(evt.properties.info.sessionID, [
|
|
39
36
|
{
|
|
40
|
-
type: "
|
|
41
|
-
data:
|
|
42
|
-
await Provider.getModel(evt.properties.info.model.providerID, evt.properties.info.model.modelID).then(
|
|
43
|
-
(m) => m,
|
|
44
|
-
),
|
|
45
|
-
],
|
|
37
|
+
type: "message",
|
|
38
|
+
data: evt.properties.info as any,
|
|
46
39
|
},
|
|
47
40
|
])
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
41
|
+
if (evt.properties.info.role === "user") {
|
|
42
|
+
await sync(evt.properties.info.sessionID, [
|
|
43
|
+
{
|
|
44
|
+
type: "model",
|
|
45
|
+
data: [
|
|
46
|
+
await Provider.getModel(evt.properties.info.model.providerID, evt.properties.info.model.modelID).then(
|
|
47
|
+
(m) => m,
|
|
48
|
+
),
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
])
|
|
52
|
+
}
|
|
53
|
+
}),
|
|
54
|
+
Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => {
|
|
55
|
+
await sync(evt.properties.part.sessionID, [
|
|
56
|
+
{
|
|
57
|
+
type: "part",
|
|
58
|
+
data: evt.properties.part,
|
|
59
|
+
},
|
|
60
|
+
])
|
|
61
|
+
}),
|
|
62
|
+
Bus.subscribe(Session.Event.Diff, async (evt) => {
|
|
63
|
+
await sync(evt.properties.sessionID, [
|
|
64
|
+
{
|
|
65
|
+
type: "session_diff",
|
|
66
|
+
data: evt.properties.diff,
|
|
67
|
+
},
|
|
68
|
+
])
|
|
69
|
+
}),
|
|
70
|
+
)
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
export async function create(sessionID: string) {
|
package/src/share/share.ts
CHANGED
|
@@ -46,24 +46,29 @@ export namespace Share {
|
|
|
46
46
|
})
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
const shareUnsubs: (() => void)[] = []
|
|
49
50
|
export function init() {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
51
|
+
for (const unsub of shareUnsubs) unsub()
|
|
52
|
+
shareUnsubs.length = 0
|
|
53
|
+
shareUnsubs.push(
|
|
54
|
+
Bus.subscribe(Session.Event.Updated, async (evt) => {
|
|
55
|
+
await sync("session/info/" + evt.properties.info.id, evt.properties.info)
|
|
56
|
+
}),
|
|
57
|
+
Bus.subscribe(MessageV2.Event.Updated, async (evt) => {
|
|
58
|
+
await sync("session/message/" + evt.properties.info.sessionID + "/" + evt.properties.info.id, evt.properties.info)
|
|
59
|
+
}),
|
|
60
|
+
Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => {
|
|
61
|
+
await sync(
|
|
62
|
+
"session/part/" +
|
|
63
|
+
evt.properties.part.sessionID +
|
|
64
|
+
"/" +
|
|
65
|
+
evt.properties.part.messageID +
|
|
66
|
+
"/" +
|
|
67
|
+
evt.properties.part.id,
|
|
68
|
+
evt.properties.part,
|
|
69
|
+
)
|
|
70
|
+
}),
|
|
71
|
+
)
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
export const URL =
|