opencode-extended-sidebar 0.2.90 → 0.2.91
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/.oesignore +17 -17
- package/CHANGELOG.md +96 -95
- package/LICENSE +21 -21
- package/README.md +150 -235
- package/oes.json +13 -11
- package/package.json +100 -100
- package/scripts/install-git-hooks.mjs +29 -29
- package/src/pware.oc.core/constants/index.ts +18 -18
- package/src/pware.oc.core/constants/pware.oc.core.constants.eventKind.ts +29 -29
- package/src/pware.oc.core/constants/pware.oc.core.constants.eventName.ts +15 -13
- package/src/pware.oc.core/constants/pware.oc.core.constants.eventType.ts +241 -241
- package/src/pware.oc.core/constants/pware.oc.core.constants.myWork.ts +55 -55
- package/src/pware.oc.core/constants/pware.oc.core.constants.partType.ts +65 -65
- package/src/pware.oc.core/constants/pware.oc.core.constants.phase.ts +58 -58
- package/src/pware.oc.core/constants/pware.oc.core.constants.pulse.ts +63 -63
- package/src/pware.oc.core/constants/pware.oc.core.constants.rowKind.ts +34 -34
- package/src/pware.oc.core/constants/pware.oc.core.constants.status.ts +74 -74
- package/src/pware.oc.core/constants/pware.oc.core.constants.toolName.ts +69 -69
- package/src/pware.oc.core/git/index.ts +7 -7
- package/src/pware.oc.core/git/pware.oc.core.git.ts +237 -237
- package/src/pware.oc.core/git/pware.oc.core.gitignore.ts +87 -87
- package/src/pware.oc.core/index.ts +19 -18
- package/src/pware.oc.core/pware.oc.core.bus.ts +42 -42
- package/src/pware.oc.core/pware.oc.core.cache.ts +48 -48
- package/src/pware.oc.core/pware.oc.core.clipboard.ts +97 -97
- package/src/pware.oc.core/pware.oc.core.debug.ts +280 -280
- package/src/pware.oc.core/pware.oc.core.events.ts +79 -79
- package/src/pware.oc.core/pware.oc.core.glyph.ts +135 -135
- package/src/pware.oc.core/pware.oc.core.layout.ts +234 -234
- package/src/pware.oc.core/pware.oc.core.oes.ts +99 -89
- package/src/pware.oc.core/pware.oc.core.paths.ts +240 -240
- package/src/pware.oc.core/pware.oc.core.preview.ts +74 -74
- package/src/pware.oc.core/pware.oc.core.pulse.ts +726 -726
- package/src/pware.oc.core/pware.oc.core.runtimeConfig.ts +41 -0
- package/src/pware.oc.core/pware.oc.core.sqlite.ts +164 -175
- package/src/pware.oc.core/pware.oc.core.sqliteGateway.ts +89 -0
- package/src/pware.oc.core/pware.oc.core.status.ts +214 -214
- package/src/pware.oc.core/pware.oc.core.timing.ts +63 -63
- package/src/pware.oc.core/pware.oc.core.width.ts +215 -215
- package/src/pware.oc.omo/constants/index.ts +15 -15
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.backgroundTask.ts +18 -18
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.boulderStatus.ts +49 -49
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.docKind.ts +29 -29
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.eventName.ts +11 -11
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.planStatus.ts +60 -60
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.reviewStatus.ts +49 -49
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.startWork.ts +25 -25
- package/src/pware.oc.omo/constants/pware.oc.omo.constants.verdict.ts +38 -38
- package/src/pware.oc.omo/index.ts +7 -7
- package/src/pware.oc.omo/resolver/index.ts +19 -19
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approval.ts +179 -179
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approvalGroup.ts +116 -116
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.approvalState.ts +34 -34
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.boulder.ts +503 -503
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.config.ts +40 -40
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.doc.ts +269 -269
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.draftFile.ts +18 -18
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.notepadsFile.ts +18 -18
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.plan.ts +155 -155
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.planFile.ts +363 -361
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.proofFile.ts +18 -18
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.rulesFile.ts +11 -11
- package/src/pware.oc.omo/resolver/pware.oc.omo.resolver.runContinuationFile.ts +14 -14
- package/src/pware.oc.opencode/constants/index.ts +10 -10
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.eventName.ts +15 -15
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.fileTouch.ts +18 -18
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.questionKind.ts +45 -45
- package/src/pware.oc.opencode/constants/pware.oc.opencode.constants.sessionStatus.ts +58 -58
- package/src/pware.oc.opencode/index.ts +8 -8
- package/src/pware.oc.opencode/pware.oc.opencode.events.ts +182 -182
- package/src/pware.oc.opencode/pware.oc.opencode.files.ts +399 -399
- package/src/pware.oc.opencode/resolver/index.ts +223 -170
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.file.ts +150 -162
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.question.ts +149 -185
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.session.ts +248 -211
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.todo.ts +22 -26
- package/src/pware.oc.opencode/resolver/pware.oc.opencode.resolver.tool.ts +224 -236
- package/src/pware.oc.perf/index.ts +14 -14
- package/src/pware.oc.perf/pware.oc.perf.asciichart.d.ts +15 -15
- package/src/pware.oc.perf/pware.oc.perf.charts.ts +284 -284
- package/src/pware.oc.perf/pware.oc.perf.reader.ts +962 -927
- package/src/pware.oc.perf/pware.oc.perf.realtime.ts +88 -88
- package/src/pware.oc.perf/pware.oc.perf.realtimeBlock.ts +118 -118
- package/src/pware.oc.perf/pware.oc.perf.realtimeCpuRam.ts +79 -79
- package/src/pware.oc.perf/pware.oc.perf.realtimeSampler.ts +71 -71
- package/src/pware.oc.perf/pware.oc.perf.realtimeTimeline.ts +214 -214
- package/src/pware.oc.perf/pware.oc.perf.self.ts +179 -179
- package/src/pware.oc.perf/pware.oc.perf.view.tsx +463 -462
- package/src/pware.oc.runtime/index.ts +13 -13
- package/src/pware.oc.runtime/pware.oc.runtime.monitor.ts +142 -142
- package/src/pware.oc.runtime/pware.oc.runtime.mywork-enrich.ts +87 -79
- package/src/pware.oc.runtime/pware.oc.runtime.mywork.ts +282 -253
- package/src/pware.oc.runtime/pware.oc.runtime.omoRead.ts +37 -0
- package/src/pware.oc.runtime/pware.oc.runtime.questions.ts +83 -95
- package/src/pware.oc.runtime/pware.oc.runtime.snapshotClient.ts +130 -129
- package/src/pware.oc.runtime/pware.oc.runtime.source.ts +105 -105
- package/src/pware.oc.runtime/pware.oc.runtime.worker.ts +44 -43
- package/src/pware.oc.runtime/resolver/index.ts +268 -224
- package/src/pware.oc.runtime/resolver/pware.oc.runtime.resolver.delegate.ts +146 -146
- package/src/pware.oc.ui/index.ts +12 -12
- package/src/pware.oc.ui/pware.oc.ui.chrome.tsx +381 -339
- package/src/pware.oc.ui/pware.oc.ui.glyphs.tsx +144 -144
- package/src/pware.oc.ui/pware.oc.ui.host.tsx +111 -111
- package/src/pware.oc.ui/pware.oc.ui.live.tsx +82 -82
- package/src/pware.oc.ui/pware.oc.ui.menudialogs.tsx +843 -843
- package/src/pware.oc.ui/pware.oc.ui.sections.tsx +552 -526
- package/src/pware.oc.ui/pware.oc.ui.sidebar.tsx +1718 -1629
- package/src/pware.oc.ui.tsx +98 -98
|
@@ -1,182 +1,182 @@
|
|
|
1
|
-
import {
|
|
2
|
-
deltaKindFromEvent,
|
|
3
|
-
deltaTextFromEvent,
|
|
4
|
-
estimateTokens,
|
|
5
|
-
flowFromEvent,
|
|
6
|
-
sessionBusyFromEvent,
|
|
7
|
-
sessionIdFromEvent,
|
|
8
|
-
toolHitFromEvent,
|
|
9
|
-
type FlowHint,
|
|
10
|
-
type ToolHit,
|
|
11
|
-
} from "../pware.oc.core/pware.oc.core.pulse.js"
|
|
12
|
-
import { eventType } from "../pware.oc.core/pware.oc.core.events.js"
|
|
13
|
-
import {
|
|
14
|
-
fileFilter,
|
|
15
|
-
filesFromEvent,
|
|
16
|
-
type FileView,
|
|
17
|
-
} from "./pware.oc.opencode.files.js"
|
|
18
|
-
import {
|
|
19
|
-
EV_OC_FILES_TOUCHED,
|
|
20
|
-
EV_OC_FLOW,
|
|
21
|
-
EV_OC_SESSION_ACTIVITY,
|
|
22
|
-
EV_OC_TOKENS_DELTA,
|
|
23
|
-
EV_OC_TOOL_HIT,
|
|
24
|
-
} from "./constants/pware.oc.opencode.constants.eventName.js"
|
|
25
|
-
|
|
26
|
-
export type OcSessionActivityEvent = {
|
|
27
|
-
type: typeof EV_OC_SESSION_ACTIVITY
|
|
28
|
-
ts: number
|
|
29
|
-
data: {
|
|
30
|
-
sessionId: string | null
|
|
31
|
-
busy: boolean
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export type OcFlowEvent = {
|
|
36
|
-
type: typeof EV_OC_FLOW
|
|
37
|
-
ts: number
|
|
38
|
-
data: {
|
|
39
|
-
sessionId: string
|
|
40
|
-
dir: FlowHint
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export type OcToolHitEvent = {
|
|
45
|
-
type: typeof EV_OC_TOOL_HIT
|
|
46
|
-
ts: number
|
|
47
|
-
data: {
|
|
48
|
-
hit: ToolHit
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export type OcFilesTouchedEvent = {
|
|
53
|
-
type: typeof EV_OC_FILES_TOUCHED
|
|
54
|
-
ts: number
|
|
55
|
-
data: {
|
|
56
|
-
sessionId: string
|
|
57
|
-
files: FileView[]
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export type OcTokensDeltaEvent = {
|
|
62
|
-
type: typeof EV_OC_TOKENS_DELTA
|
|
63
|
-
ts: number
|
|
64
|
-
data: {
|
|
65
|
-
sessionId: string
|
|
66
|
-
/** Which stream produced the delta — `out` (text) or `reasoning` (thinking). */
|
|
67
|
-
kind: "out" | "reasoning"
|
|
68
|
-
tokens: number
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export type OcEvent =
|
|
73
|
-
| OcSessionActivityEvent
|
|
74
|
-
| OcFlowEvent
|
|
75
|
-
| OcToolHitEvent
|
|
76
|
-
| OcFilesTouchedEvent
|
|
77
|
-
| OcTokensDeltaEvent
|
|
78
|
-
|
|
79
|
-
export function hostEventToOcEvents(
|
|
80
|
-
evt: unknown,
|
|
81
|
-
opts: {
|
|
82
|
-
sessionId: string
|
|
83
|
-
projectRoot: string | null
|
|
84
|
-
},
|
|
85
|
-
): OcEvent[] {
|
|
86
|
-
const ts = Date.now()
|
|
87
|
-
const out: OcEvent[] = []
|
|
88
|
-
const eventSessionId = sessionIdFromEvent(evt) ?? opts.sessionId
|
|
89
|
-
|
|
90
|
-
const busy = sessionBusyFromEvent(evt)
|
|
91
|
-
if (busy.busy != null) {
|
|
92
|
-
out.push({
|
|
93
|
-
type: EV_OC_SESSION_ACTIVITY,
|
|
94
|
-
ts,
|
|
95
|
-
data: {
|
|
96
|
-
sessionId: busy.id ?? eventSessionId,
|
|
97
|
-
busy: busy.busy,
|
|
98
|
-
},
|
|
99
|
-
})
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const flow = flowFromEvent(evt)
|
|
103
|
-
const flowSessionId = flow.id ?? eventSessionId
|
|
104
|
-
if (flow.dir && flowSessionId) {
|
|
105
|
-
out.push({
|
|
106
|
-
type: EV_OC_FLOW,
|
|
107
|
-
ts,
|
|
108
|
-
data: {
|
|
109
|
-
sessionId: flowSessionId,
|
|
110
|
-
dir: flow.dir,
|
|
111
|
-
},
|
|
112
|
-
})
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const hit = toolHitFromEvent(evt)
|
|
116
|
-
if (hit && (!hit.sessionId || hit.sessionId === opts.sessionId)) {
|
|
117
|
-
out.push({
|
|
118
|
-
type: EV_OC_TOOL_HIT,
|
|
119
|
-
ts,
|
|
120
|
-
data: { hit },
|
|
121
|
-
})
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const files = filesFromEvent(evt, opts.sessionId, fileFilter(opts.projectRoot))
|
|
125
|
-
if (files.length > 0) {
|
|
126
|
-
out.push({
|
|
127
|
-
type: EV_OC_FILES_TOUCHED,
|
|
128
|
-
ts,
|
|
129
|
-
data: {
|
|
130
|
-
sessionId: eventSessionId,
|
|
131
|
-
files,
|
|
132
|
-
},
|
|
133
|
-
})
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const delta = deltaTextFromEvent(evt)
|
|
137
|
-
if (delta) {
|
|
138
|
-
const tokens = estimateTokens(delta)
|
|
139
|
-
if (tokens > 0) {
|
|
140
|
-
out.push({
|
|
141
|
-
type: EV_OC_TOKENS_DELTA,
|
|
142
|
-
ts,
|
|
143
|
-
data: {
|
|
144
|
-
sessionId: eventSessionId,
|
|
145
|
-
kind: deltaKindFromEvent(evt),
|
|
146
|
-
tokens,
|
|
147
|
-
},
|
|
148
|
-
})
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return out
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const QUESTION_EVENT_HINTS = ["question.asked", "question.replied", "question.rejected"] as const
|
|
156
|
-
|
|
157
|
-
function isQuestionToolBag(bag: unknown): boolean {
|
|
158
|
-
if (!bag || typeof bag !== "object") return false
|
|
159
|
-
const b = bag as Record<string, unknown>
|
|
160
|
-
const tool = b.tool
|
|
161
|
-
if (typeof tool !== "string" || tool.toLowerCase() !== "question") return false
|
|
162
|
-
const type = b.type
|
|
163
|
-
return type == null || String(type).toLowerCase() === "tool"
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/** Session id when a host event signals a `question` tool part changed state, else `null`. */
|
|
167
|
-
export function questionSessionFromEvent(evt: unknown): string | null {
|
|
168
|
-
const type = eventType(evt)
|
|
169
|
-
if (QUESTION_EVENT_HINTS.some((hint) => type.includes(hint))) {
|
|
170
|
-
return sessionIdFromEvent(evt)
|
|
171
|
-
}
|
|
172
|
-
if (!evt || typeof evt !== "object") return null
|
|
173
|
-
const o = evt as Record<string, unknown>
|
|
174
|
-
const props =
|
|
175
|
-
o.properties && typeof o.properties === "object"
|
|
176
|
-
? (o.properties as Record<string, unknown>)
|
|
177
|
-
: null
|
|
178
|
-
for (const bag of [o.part, props?.part, props]) {
|
|
179
|
-
if (isQuestionToolBag(bag)) return sessionIdFromEvent(evt)
|
|
180
|
-
}
|
|
181
|
-
return null
|
|
182
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
deltaKindFromEvent,
|
|
3
|
+
deltaTextFromEvent,
|
|
4
|
+
estimateTokens,
|
|
5
|
+
flowFromEvent,
|
|
6
|
+
sessionBusyFromEvent,
|
|
7
|
+
sessionIdFromEvent,
|
|
8
|
+
toolHitFromEvent,
|
|
9
|
+
type FlowHint,
|
|
10
|
+
type ToolHit,
|
|
11
|
+
} from "../pware.oc.core/pware.oc.core.pulse.js"
|
|
12
|
+
import { eventType } from "../pware.oc.core/pware.oc.core.events.js"
|
|
13
|
+
import {
|
|
14
|
+
fileFilter,
|
|
15
|
+
filesFromEvent,
|
|
16
|
+
type FileView,
|
|
17
|
+
} from "./pware.oc.opencode.files.js"
|
|
18
|
+
import {
|
|
19
|
+
EV_OC_FILES_TOUCHED,
|
|
20
|
+
EV_OC_FLOW,
|
|
21
|
+
EV_OC_SESSION_ACTIVITY,
|
|
22
|
+
EV_OC_TOKENS_DELTA,
|
|
23
|
+
EV_OC_TOOL_HIT,
|
|
24
|
+
} from "./constants/pware.oc.opencode.constants.eventName.js"
|
|
25
|
+
|
|
26
|
+
export type OcSessionActivityEvent = {
|
|
27
|
+
type: typeof EV_OC_SESSION_ACTIVITY
|
|
28
|
+
ts: number
|
|
29
|
+
data: {
|
|
30
|
+
sessionId: string | null
|
|
31
|
+
busy: boolean
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type OcFlowEvent = {
|
|
36
|
+
type: typeof EV_OC_FLOW
|
|
37
|
+
ts: number
|
|
38
|
+
data: {
|
|
39
|
+
sessionId: string
|
|
40
|
+
dir: FlowHint
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type OcToolHitEvent = {
|
|
45
|
+
type: typeof EV_OC_TOOL_HIT
|
|
46
|
+
ts: number
|
|
47
|
+
data: {
|
|
48
|
+
hit: ToolHit
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type OcFilesTouchedEvent = {
|
|
53
|
+
type: typeof EV_OC_FILES_TOUCHED
|
|
54
|
+
ts: number
|
|
55
|
+
data: {
|
|
56
|
+
sessionId: string
|
|
57
|
+
files: FileView[]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type OcTokensDeltaEvent = {
|
|
62
|
+
type: typeof EV_OC_TOKENS_DELTA
|
|
63
|
+
ts: number
|
|
64
|
+
data: {
|
|
65
|
+
sessionId: string
|
|
66
|
+
/** Which stream produced the delta — `out` (text) or `reasoning` (thinking). */
|
|
67
|
+
kind: "out" | "reasoning"
|
|
68
|
+
tokens: number
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type OcEvent =
|
|
73
|
+
| OcSessionActivityEvent
|
|
74
|
+
| OcFlowEvent
|
|
75
|
+
| OcToolHitEvent
|
|
76
|
+
| OcFilesTouchedEvent
|
|
77
|
+
| OcTokensDeltaEvent
|
|
78
|
+
|
|
79
|
+
export function hostEventToOcEvents(
|
|
80
|
+
evt: unknown,
|
|
81
|
+
opts: {
|
|
82
|
+
sessionId: string
|
|
83
|
+
projectRoot: string | null
|
|
84
|
+
},
|
|
85
|
+
): OcEvent[] {
|
|
86
|
+
const ts = Date.now()
|
|
87
|
+
const out: OcEvent[] = []
|
|
88
|
+
const eventSessionId = sessionIdFromEvent(evt) ?? opts.sessionId
|
|
89
|
+
|
|
90
|
+
const busy = sessionBusyFromEvent(evt)
|
|
91
|
+
if (busy.busy != null) {
|
|
92
|
+
out.push({
|
|
93
|
+
type: EV_OC_SESSION_ACTIVITY,
|
|
94
|
+
ts,
|
|
95
|
+
data: {
|
|
96
|
+
sessionId: busy.id ?? eventSessionId,
|
|
97
|
+
busy: busy.busy,
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const flow = flowFromEvent(evt)
|
|
103
|
+
const flowSessionId = flow.id ?? eventSessionId
|
|
104
|
+
if (flow.dir && flowSessionId) {
|
|
105
|
+
out.push({
|
|
106
|
+
type: EV_OC_FLOW,
|
|
107
|
+
ts,
|
|
108
|
+
data: {
|
|
109
|
+
sessionId: flowSessionId,
|
|
110
|
+
dir: flow.dir,
|
|
111
|
+
},
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const hit = toolHitFromEvent(evt)
|
|
116
|
+
if (hit && (!hit.sessionId || hit.sessionId === opts.sessionId)) {
|
|
117
|
+
out.push({
|
|
118
|
+
type: EV_OC_TOOL_HIT,
|
|
119
|
+
ts,
|
|
120
|
+
data: { hit },
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const files = filesFromEvent(evt, opts.sessionId, fileFilter(opts.projectRoot))
|
|
125
|
+
if (files.length > 0) {
|
|
126
|
+
out.push({
|
|
127
|
+
type: EV_OC_FILES_TOUCHED,
|
|
128
|
+
ts,
|
|
129
|
+
data: {
|
|
130
|
+
sessionId: eventSessionId,
|
|
131
|
+
files,
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const delta = deltaTextFromEvent(evt)
|
|
137
|
+
if (delta) {
|
|
138
|
+
const tokens = estimateTokens(delta)
|
|
139
|
+
if (tokens > 0) {
|
|
140
|
+
out.push({
|
|
141
|
+
type: EV_OC_TOKENS_DELTA,
|
|
142
|
+
ts,
|
|
143
|
+
data: {
|
|
144
|
+
sessionId: eventSessionId,
|
|
145
|
+
kind: deltaKindFromEvent(evt),
|
|
146
|
+
tokens,
|
|
147
|
+
},
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return out
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const QUESTION_EVENT_HINTS = ["question.asked", "question.replied", "question.rejected"] as const
|
|
156
|
+
|
|
157
|
+
function isQuestionToolBag(bag: unknown): boolean {
|
|
158
|
+
if (!bag || typeof bag !== "object") return false
|
|
159
|
+
const b = bag as Record<string, unknown>
|
|
160
|
+
const tool = b.tool
|
|
161
|
+
if (typeof tool !== "string" || tool.toLowerCase() !== "question") return false
|
|
162
|
+
const type = b.type
|
|
163
|
+
return type == null || String(type).toLowerCase() === "tool"
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Session id when a host event signals a `question` tool part changed state, else `null`. */
|
|
167
|
+
export function questionSessionFromEvent(evt: unknown): string | null {
|
|
168
|
+
const type = eventType(evt)
|
|
169
|
+
if (QUESTION_EVENT_HINTS.some((hint) => type.includes(hint))) {
|
|
170
|
+
return sessionIdFromEvent(evt)
|
|
171
|
+
}
|
|
172
|
+
if (!evt || typeof evt !== "object") return null
|
|
173
|
+
const o = evt as Record<string, unknown>
|
|
174
|
+
const props =
|
|
175
|
+
o.properties && typeof o.properties === "object"
|
|
176
|
+
? (o.properties as Record<string, unknown>)
|
|
177
|
+
: null
|
|
178
|
+
for (const bag of [o.part, props?.part, props]) {
|
|
179
|
+
if (isQuestionToolBag(bag)) return sessionIdFromEvent(evt)
|
|
180
|
+
}
|
|
181
|
+
return null
|
|
182
|
+
}
|