dsh-smooth-stream 0.3.3 → 0.4.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/README.en.md +23 -18
- package/README.md +23 -18
- package/lib/client.js +2343 -175
- package/lib/client.js.map +1 -1
- package/lib/index.js +123 -6
- package/package.json +15 -10
- package/src/client/DebugPanel.module.css +370 -0
- package/src/client/DebugPanel.tsx +248 -0
- package/src/client/SmoothStreamCard.module.css +8 -0
- package/src/client/SmoothStreamCard.tsx +42 -3
- package/src/client/TypewriterAssistantNodeView.tsx +226 -49
- package/src/client/auto-collapse-controller.ts +977 -0
- package/src/client/debugRuntime.ts +355 -0
- package/src/client/index.ts +121 -30
- package/src/client/locales.ts +122 -0
- package/src/client/smooth-stream-card-controller.ts +97 -14
- package/src/client/smooth-stream-settings-api.ts +53 -3
- package/src/client/teleprompterGlide.ts +160 -31
- package/src/client/useFpsGuard.ts +7 -0
- package/src/client/useProgressiveDomText.ts +99 -17
- package/src/client/useSmoothStreamContent.ts +20 -4
- package/src/plugin.ts +137 -7
- package/src/settings-api.ts +12 -0
- package/src/settings.ts +55 -0
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
|
|
17
|
+
import { DEFAULT_STREAM_DEBUG_TUNING, type StreamDebugTuning } from '../settings.ts'
|
|
18
|
+
import { debugRuntime } from './debugRuntime.ts'
|
|
17
19
|
|
|
18
20
|
export type StreamSmoothingPreset = 'realtime' | 'balanced' | 'silky'
|
|
19
21
|
|
|
@@ -117,13 +119,14 @@ export function computeAdaptiveQueueStep(
|
|
|
117
119
|
dtMs: number,
|
|
118
120
|
debt: number,
|
|
119
121
|
revealScale = 1,
|
|
122
|
+
tuning: StreamDebugTuning = DEFAULT_STREAM_DEBUG_TUNING,
|
|
120
123
|
): AdaptiveQueueStep {
|
|
121
124
|
if (backlog <= 0 || dtMs <= 0) return { revealChars: 0, debt: 0, speedCps: 0 }
|
|
122
125
|
const speedCps = Math.min(
|
|
123
|
-
|
|
124
|
-
QUEUE_BASE_SPEED_CPS + Math.pow(backlog, QUEUE_ACCEL_EXPONENT) *
|
|
126
|
+
tuning.maxRevealCps,
|
|
127
|
+
QUEUE_BASE_SPEED_CPS + Math.pow(backlog, QUEUE_ACCEL_EXPONENT) * tuning.queuePressure,
|
|
125
128
|
)
|
|
126
|
-
const effectiveScale = clamp(revealScale, 0.05,
|
|
129
|
+
const effectiveScale = clamp(revealScale * tuning.revealScale, 0.05, 2)
|
|
127
130
|
const accumulated = Math.max(0, debt) + speedCps * effectiveScale * (dtMs / 1000)
|
|
128
131
|
const revealChars = Math.min(backlog, Math.floor(accumulated))
|
|
129
132
|
return { revealChars, debt: revealChars >= backlog ? 0 : accumulated - revealChars, speedCps }
|
|
@@ -313,6 +316,7 @@ export function useSmoothStreamContent(
|
|
|
313
316
|
revealScaleOutRef.current = revealScaleRef
|
|
314
317
|
const inputCompleteRef = useRef(inputComplete)
|
|
315
318
|
inputCompleteRef.current = inputComplete
|
|
319
|
+
const streamIdRef = useRef(`stream-${Math.random().toString(36).slice(2)}`)
|
|
316
320
|
|
|
317
321
|
useEffect(() => {
|
|
318
322
|
holdBackRef.current = shouldHoldBack
|
|
@@ -374,6 +378,7 @@ export function useSmoothStreamContent(
|
|
|
374
378
|
settleCpsRef.current = null
|
|
375
379
|
const speedOut = speedOutRef.current
|
|
376
380
|
if (speedOut !== undefined) speedOut.current = seedCps
|
|
381
|
+
debugRuntime.reportStream(streamIdRef.current, null)
|
|
377
382
|
stopFrameLoop()
|
|
378
383
|
return
|
|
379
384
|
}
|
|
@@ -390,6 +395,7 @@ export function useSmoothStreamContent(
|
|
|
390
395
|
|
|
391
396
|
const idleMs = now - lastInputTsRef.current
|
|
392
397
|
const producerComplete = inputCompleteRef.current
|
|
398
|
+
const debugTuning = debugRuntime.activeTuning()
|
|
393
399
|
const inputActive = !producerComplete && idleMs <= config.activeInputWindowMs
|
|
394
400
|
const settling = producerComplete || (!inputActive && idleMs >= config.settleAfterMs)
|
|
395
401
|
if (!producerComplete) settleCpsRef.current = null
|
|
@@ -422,7 +428,7 @@ export function useSmoothStreamContent(
|
|
|
422
428
|
},
|
|
423
429
|
dtSeconds,
|
|
424
430
|
)
|
|
425
|
-
revealChars = Math.min(step.revealChars, backlog)
|
|
431
|
+
revealChars = Math.min(Math.round(step.revealChars * debugTuning.revealScale), backlog)
|
|
426
432
|
revealSpeedCps = frameIntervalMs > 0 ? (revealChars * 1000) / frameIntervalMs : 0
|
|
427
433
|
} else {
|
|
428
434
|
const step = computeAdaptiveQueueStep(
|
|
@@ -430,12 +436,21 @@ export function useSmoothStreamContent(
|
|
|
430
436
|
frameIntervalMs,
|
|
431
437
|
queueDebtRef.current,
|
|
432
438
|
revealScaleOutRef.current?.current ?? 1,
|
|
439
|
+
debugTuning,
|
|
433
440
|
)
|
|
434
441
|
revealChars = step.revealChars
|
|
435
442
|
revealSpeedCps = step.speedCps
|
|
436
443
|
nextQueueDebt = step.debt
|
|
437
444
|
}
|
|
438
445
|
|
|
446
|
+
debugRuntime.reportStream(streamIdRef.current, {
|
|
447
|
+
backlog,
|
|
448
|
+
speedCps: revealSpeedCps,
|
|
449
|
+
targetChars: targetCount,
|
|
450
|
+
displayedChars: displayedCount,
|
|
451
|
+
active: !producerComplete,
|
|
452
|
+
})
|
|
453
|
+
|
|
439
454
|
// Performance guard: while degraded and the reply is offscreen, skip
|
|
440
455
|
// the DOM commit — the backlog keeps accumulating and flushes when the
|
|
441
456
|
// guard clears or the reply scrolls into view.
|
|
@@ -527,6 +542,7 @@ export function useSmoothStreamContent(
|
|
|
527
542
|
useEffect(() => {
|
|
528
543
|
return () => {
|
|
529
544
|
stopFrameLoop()
|
|
545
|
+
debugRuntime.reportStream(streamIdRef.current, null)
|
|
530
546
|
}
|
|
531
547
|
}, [stopFrameLoop])
|
|
532
548
|
|
package/src/plugin.ts
CHANGED
|
@@ -7,8 +7,18 @@ import { DEFAULT_STREAM_CONFIG, type StreamConfig } from './config.ts'
|
|
|
7
7
|
import { injectStreamConfig } from './boot-config.ts'
|
|
8
8
|
import { STREAM_PACKAGE_NAME, STREAM_PACKAGE_VERSION } from './package-meta.ts'
|
|
9
9
|
import { inspectProfileInstallation, updateNpmProfilePackage } from './profile-installation.ts'
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import {
|
|
11
|
+
STREAM_SETTINGS_RPC,
|
|
12
|
+
STREAM_SETTINGS_RPC_CHANNEL,
|
|
13
|
+
type StreamDebugSettingsView,
|
|
14
|
+
type StreamSettingsView,
|
|
15
|
+
} from './settings-api.ts'
|
|
16
|
+
import {
|
|
17
|
+
DEFAULT_STREAM_SETTINGS,
|
|
18
|
+
STREAM_SETTINGS_NS,
|
|
19
|
+
type StreamDebugTuning,
|
|
20
|
+
type StreamSettings,
|
|
21
|
+
} from './settings.ts'
|
|
12
22
|
|
|
13
23
|
/** Display name shown by the Host loader while the plugin is mounted. */
|
|
14
24
|
export const name = 'dsh-smooth-stream'
|
|
@@ -42,7 +52,21 @@ export const Config: Schema<Config> = Schema.object({
|
|
|
42
52
|
* settings provider while the browser edits it through the plugin RPC below.
|
|
43
53
|
*/
|
|
44
54
|
export const StreamSettingsSchema: Schema<StreamSettings> = Schema.object({
|
|
55
|
+
enabled: Schema.boolean().default(DEFAULT_STREAM_SETTINGS.enabled),
|
|
45
56
|
thinkAutoExpand: Schema.boolean().default(DEFAULT_STREAM_SETTINGS.thinkAutoExpand),
|
|
57
|
+
autoCollapse: Schema.boolean().default(DEFAULT_STREAM_SETTINGS.autoCollapse),
|
|
58
|
+
debugEnabled: Schema.boolean().default(DEFAULT_STREAM_SETTINGS.debugEnabled),
|
|
59
|
+
debugTuning: Schema.object({
|
|
60
|
+
revealScale: Schema.number().min(0.25).max(2).default(DEFAULT_STREAM_SETTINGS.debugTuning.revealScale),
|
|
61
|
+
queuePressure: Schema.number().min(0).max(2).default(DEFAULT_STREAM_SETTINGS.debugTuning.queuePressure),
|
|
62
|
+
maxRevealCps: Schema.number().min(120).max(1000).default(DEFAULT_STREAM_SETTINGS.debugTuning.maxRevealCps),
|
|
63
|
+
springStiffness: Schema.number().min(40).max(320).default(DEFAULT_STREAM_SETTINGS.debugTuning.springStiffness),
|
|
64
|
+
springDamping: Schema.number().min(8).max(80).default(DEFAULT_STREAM_SETTINGS.debugTuning.springDamping),
|
|
65
|
+
springMass: Schema.number().min(0.5).max(3).default(DEFAULT_STREAM_SETTINGS.debugTuning.springMass),
|
|
66
|
+
runwayPx: Schema.number().min(0).max(120).default(DEFAULT_STREAM_SETTINGS.debugTuning.runwayPx),
|
|
67
|
+
reserveResponseMs: Schema.number().min(60).max(600).default(DEFAULT_STREAM_SETTINGS.debugTuning.reserveResponseMs),
|
|
68
|
+
backpressureMinScale: Schema.number().min(0.25).max(1).default(DEFAULT_STREAM_SETTINGS.debugTuning.backpressureMinScale),
|
|
69
|
+
}),
|
|
46
70
|
})
|
|
47
71
|
|
|
48
72
|
/**
|
|
@@ -79,25 +103,61 @@ export function apply(ctx: Context, config: Config): void {
|
|
|
79
103
|
|
|
80
104
|
const view = (): StreamSettingsView => {
|
|
81
105
|
const installation = inspectProfileInstallation(connectionCtx.baseUrl, STREAM_PACKAGE_NAME)
|
|
106
|
+
const settings = scope.get()
|
|
82
107
|
return {
|
|
83
108
|
version: STREAM_PACKAGE_VERSION,
|
|
84
109
|
installation: installation.kind,
|
|
85
110
|
writable: connectionCtx.settings.writable,
|
|
86
|
-
|
|
111
|
+
enabled: settings.enabled,
|
|
112
|
+
thinkAutoExpand: settings.thinkAutoExpand,
|
|
113
|
+
autoCollapse: settings.autoCollapse,
|
|
87
114
|
canUpgrade: installation.kind === 'npm',
|
|
88
115
|
}
|
|
89
116
|
}
|
|
90
117
|
|
|
118
|
+
const debugView = (): StreamDebugSettingsView => {
|
|
119
|
+
const settings = scope.get()
|
|
120
|
+
return {
|
|
121
|
+
debugEnabled: settings.debugEnabled,
|
|
122
|
+
tuning: { ...settings.debugTuning },
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const validDebugTuning = (value: unknown): value is StreamDebugTuning => {
|
|
127
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) return false
|
|
128
|
+
const tuning = value as Record<string, unknown>
|
|
129
|
+
return typeof tuning.revealScale === 'number'
|
|
130
|
+
&& tuning.revealScale >= 0.25 && tuning.revealScale <= 2
|
|
131
|
+
&& typeof tuning.queuePressure === 'number'
|
|
132
|
+
&& tuning.queuePressure >= 0 && tuning.queuePressure <= 2
|
|
133
|
+
&& typeof tuning.maxRevealCps === 'number'
|
|
134
|
+
&& tuning.maxRevealCps >= 120 && tuning.maxRevealCps <= 1000
|
|
135
|
+
&& typeof tuning.springStiffness === 'number'
|
|
136
|
+
&& tuning.springStiffness >= 40 && tuning.springStiffness <= 320
|
|
137
|
+
&& typeof tuning.springDamping === 'number'
|
|
138
|
+
&& tuning.springDamping >= 8 && tuning.springDamping <= 80
|
|
139
|
+
&& typeof tuning.springMass === 'number'
|
|
140
|
+
&& tuning.springMass >= 0.5 && tuning.springMass <= 3
|
|
141
|
+
&& typeof tuning.runwayPx === 'number'
|
|
142
|
+
&& tuning.runwayPx >= 0 && tuning.runwayPx <= 120
|
|
143
|
+
&& typeof tuning.reserveResponseMs === 'number'
|
|
144
|
+
&& tuning.reserveResponseMs >= 60 && tuning.reserveResponseMs <= 600
|
|
145
|
+
&& typeof tuning.backpressureMinScale === 'number'
|
|
146
|
+
&& tuning.backpressureMinScale >= 0.25 && tuning.backpressureMinScale <= 1
|
|
147
|
+
}
|
|
148
|
+
|
|
91
149
|
const handle: ConnectionRpcHandler = async (endpoint, payload) => {
|
|
92
150
|
if (endpoint === STREAM_SETTINGS_RPC.read) return { ok: true, value: view() }
|
|
93
151
|
if (endpoint === STREAM_SETTINGS_RPC.write) {
|
|
94
|
-
if (typeof payload !== 'object' || payload === null
|
|
95
|
-
|| typeof (payload as {
|
|
152
|
+
if (typeof payload !== 'object' || payload === null || Array.isArray(payload)
|
|
153
|
+
|| typeof (payload as { enabled?: unknown }).enabled !== 'boolean'
|
|
154
|
+
|| typeof (payload as { thinkAutoExpand?: unknown }).thinkAutoExpand !== 'boolean'
|
|
155
|
+
|| typeof (payload as { autoCollapse?: unknown }).autoCollapse !== 'boolean') {
|
|
96
156
|
return {
|
|
97
157
|
ok: false,
|
|
98
158
|
error: {
|
|
99
159
|
code: 'settings-rejected',
|
|
100
|
-
message: 'thinkAutoExpand must be
|
|
160
|
+
message: 'enabled, thinkAutoExpand and autoCollapse must be booleans',
|
|
101
161
|
details: { ns: STREAM_SETTINGS_NS },
|
|
102
162
|
},
|
|
103
163
|
}
|
|
@@ -113,7 +173,30 @@ export function apply(ctx: Context, config: Config): void {
|
|
|
113
173
|
}
|
|
114
174
|
}
|
|
115
175
|
try {
|
|
116
|
-
|
|
176
|
+
const next = payload as {
|
|
177
|
+
enabled: boolean
|
|
178
|
+
thinkAutoExpand: boolean
|
|
179
|
+
autoCollapse: boolean
|
|
180
|
+
debugEnabled?: unknown
|
|
181
|
+
debugTuning?: unknown
|
|
182
|
+
}
|
|
183
|
+
const hasDebug = next.debugEnabled !== undefined || next.debugTuning !== undefined
|
|
184
|
+
if (hasDebug && (typeof next.debugEnabled !== 'boolean' || !validDebugTuning(next.debugTuning))) {
|
|
185
|
+
return {
|
|
186
|
+
ok: false,
|
|
187
|
+
error: {
|
|
188
|
+
code: 'settings-rejected',
|
|
189
|
+
message: 'debugEnabled and debugTuning must be provided together and be valid',
|
|
190
|
+
details: { ns: STREAM_SETTINGS_NS },
|
|
191
|
+
},
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
await scope.update({
|
|
195
|
+
enabled: next.enabled,
|
|
196
|
+
thinkAutoExpand: next.thinkAutoExpand,
|
|
197
|
+
autoCollapse: next.autoCollapse,
|
|
198
|
+
...(hasDebug ? { debugEnabled: next.debugEnabled, debugTuning: next.debugTuning } : {}),
|
|
199
|
+
})
|
|
117
200
|
} catch {
|
|
118
201
|
return {
|
|
119
202
|
ok: false,
|
|
@@ -126,6 +209,53 @@ export function apply(ctx: Context, config: Config): void {
|
|
|
126
209
|
}
|
|
127
210
|
return { ok: true, value: view() }
|
|
128
211
|
}
|
|
212
|
+
if (endpoint === STREAM_SETTINGS_RPC.debugRead) return { ok: true, value: debugView() }
|
|
213
|
+
if (endpoint === STREAM_SETTINGS_RPC.debugWrite) {
|
|
214
|
+
if (typeof payload !== 'object' || payload === null || Array.isArray(payload)) {
|
|
215
|
+
return {
|
|
216
|
+
ok: false,
|
|
217
|
+
error: {
|
|
218
|
+
code: 'settings-rejected',
|
|
219
|
+
message: 'debug settings must be an object',
|
|
220
|
+
details: { ns: STREAM_SETTINGS_NS },
|
|
221
|
+
},
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const next = payload as { debugEnabled?: unknown; tuning?: unknown }
|
|
225
|
+
if (typeof next.debugEnabled !== 'boolean' || !validDebugTuning(next.tuning)) {
|
|
226
|
+
return {
|
|
227
|
+
ok: false,
|
|
228
|
+
error: {
|
|
229
|
+
code: 'settings-rejected',
|
|
230
|
+
message: 'debugEnabled and tuning are malformed',
|
|
231
|
+
details: { ns: STREAM_SETTINGS_NS },
|
|
232
|
+
},
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (!connectionCtx.settings.writable) {
|
|
236
|
+
return {
|
|
237
|
+
ok: false,
|
|
238
|
+
error: {
|
|
239
|
+
code: 'settings-rejected',
|
|
240
|
+
message: 'smooth-stream debug settings are read-only',
|
|
241
|
+
details: { ns: STREAM_SETTINGS_NS },
|
|
242
|
+
},
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
await scope.update({ debugEnabled: next.debugEnabled, debugTuning: next.tuning })
|
|
247
|
+
} catch {
|
|
248
|
+
return {
|
|
249
|
+
ok: false,
|
|
250
|
+
error: {
|
|
251
|
+
code: 'settings-rejected',
|
|
252
|
+
message: 'smooth-stream debug settings update failed',
|
|
253
|
+
details: { ns: STREAM_SETTINGS_NS },
|
|
254
|
+
},
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return { ok: true, value: debugView() }
|
|
258
|
+
}
|
|
129
259
|
if (endpoint === STREAM_SETTINGS_RPC.upgrade) {
|
|
130
260
|
const installation = inspectProfileInstallation(connectionCtx.baseUrl, STREAM_PACKAGE_NAME)
|
|
131
261
|
if (installation.kind !== 'npm') {
|
package/src/settings-api.ts
CHANGED
|
@@ -7,6 +7,8 @@ export const STREAM_SETTINGS_RPC_CHANNEL = '/smooth-stream'
|
|
|
7
7
|
export const STREAM_SETTINGS_RPC = {
|
|
8
8
|
read: 'settings.read',
|
|
9
9
|
write: 'settings.write',
|
|
10
|
+
debugRead: 'debug.read',
|
|
11
|
+
debugWrite: 'debug.write',
|
|
10
12
|
upgrade: 'plugin.upgrade',
|
|
11
13
|
} as const
|
|
12
14
|
|
|
@@ -21,12 +23,22 @@ export interface StreamSettingsView {
|
|
|
21
23
|
installation: StreamInstallationKind
|
|
22
24
|
/** Whether the Host settings provider permits a write. */
|
|
23
25
|
writable: boolean
|
|
26
|
+
/** Whether smooth-stream currently owns conversation rendering. */
|
|
27
|
+
enabled: boolean
|
|
24
28
|
/** Current resolved preference. */
|
|
25
29
|
thinkAutoExpand: boolean
|
|
30
|
+
/** Whether finished turns fold their work process behind a summary row. */
|
|
31
|
+
autoCollapse: boolean
|
|
26
32
|
/** Whether a fixed npm update command is safe to offer. */
|
|
27
33
|
canUpgrade: boolean
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
/** Debug-only settings returned by the diagnostics RPC. */
|
|
37
|
+
export interface StreamDebugSettingsView {
|
|
38
|
+
debugEnabled: boolean
|
|
39
|
+
tuning: import('./settings.ts').StreamDebugTuning
|
|
40
|
+
}
|
|
41
|
+
|
|
30
42
|
/** Successful package update acknowledgement; loading the new code needs a restart. */
|
|
31
43
|
export interface StreamUpgradeView {
|
|
32
44
|
restartRequired: true
|
package/src/settings.ts
CHANGED
|
@@ -10,21 +10,76 @@
|
|
|
10
10
|
/** Settings namespace registered by the Host and served through the plugin RPC. */
|
|
11
11
|
export const STREAM_SETTINGS_NS = 'smooth-stream'
|
|
12
12
|
|
|
13
|
+
/** Runtime knobs exposed only while the diagnostics switch is enabled. */
|
|
14
|
+
export interface StreamDebugTuning {
|
|
15
|
+
/** Multiplier applied to the reveal cadence (1 = preset default). */
|
|
16
|
+
revealScale: number
|
|
17
|
+
/** Multiplier for backlog pressure in the adaptive reveal queue. */
|
|
18
|
+
queuePressure: number
|
|
19
|
+
/** Upper bound for reveal cadence, in characters per second. */
|
|
20
|
+
maxRevealCps: number
|
|
21
|
+
/** Spring stiffness used by the conversation follower. */
|
|
22
|
+
springStiffness: number
|
|
23
|
+
/** Spring damping used by the conversation follower. */
|
|
24
|
+
springDamping: number
|
|
25
|
+
/** Spring mass used by the conversation follower. */
|
|
26
|
+
springMass: number
|
|
27
|
+
/** Predictive runway before the fixed conversation chrome, in pixels. */
|
|
28
|
+
runwayPx: number
|
|
29
|
+
/** Response time for opening/closing the predictive runway, in ms. */
|
|
30
|
+
reserveResponseMs: number
|
|
31
|
+
/** Lowest reveal multiplier when visual lag fills the safe paint room. */
|
|
32
|
+
backpressureMinScale: number
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Defaults preserve the production engine exactly. */
|
|
36
|
+
export const DEFAULT_STREAM_DEBUG_TUNING: StreamDebugTuning = {
|
|
37
|
+
revealScale: 1,
|
|
38
|
+
queuePressure: 0.85,
|
|
39
|
+
maxRevealCps: 600,
|
|
40
|
+
springStiffness: 130,
|
|
41
|
+
springDamping: 24,
|
|
42
|
+
springMass: 1,
|
|
43
|
+
runwayPx: 48,
|
|
44
|
+
reserveResponseMs: 180,
|
|
45
|
+
backpressureMinScale: 0.55,
|
|
46
|
+
}
|
|
47
|
+
|
|
13
48
|
/**
|
|
14
49
|
* Preferences a user may set. Deliberately separate from {@link StreamConfig}
|
|
15
50
|
* because the two change at different times: composition-time values go
|
|
16
51
|
* through the boot global, a live UI edit goes through the protected plugin RPC.
|
|
17
52
|
*/
|
|
18
53
|
export interface StreamSettings {
|
|
54
|
+
/**
|
|
55
|
+
* Whether this plugin replaces and wraps Harness conversation renderers.
|
|
56
|
+
* Off returns all rendering ownership to the built-in UI.
|
|
57
|
+
*/
|
|
58
|
+
enabled: boolean
|
|
19
59
|
/**
|
|
20
60
|
* Whether a reasoning ("Think") block auto-expands while it is the
|
|
21
61
|
* streaming tail. Off keeps the block collapsed — the user can still open
|
|
22
62
|
* it by hand — and stops the running state from re-owning the disclosure.
|
|
23
63
|
*/
|
|
24
64
|
thinkAutoExpand: boolean
|
|
65
|
+
/**
|
|
66
|
+
* Whether a finished turn folds its work process (thinking, tool calls,
|
|
67
|
+
* context injection, intermediate replies) behind one "已处理" summary row,
|
|
68
|
+
* leaving only the final answer visible. The summary row can always be
|
|
69
|
+
* toggled by hand, and turns still expand live while they stream.
|
|
70
|
+
*/
|
|
71
|
+
autoCollapse: boolean
|
|
72
|
+
/** Whether the live renderer diagnostics panel is enabled. */
|
|
73
|
+
debugEnabled: boolean
|
|
74
|
+
/** Values edited by the diagnostics panel. */
|
|
75
|
+
debugTuning: StreamDebugTuning
|
|
25
76
|
}
|
|
26
77
|
|
|
27
78
|
/** Defaults shared by the Host schema and the client-side fallback. */
|
|
28
79
|
export const DEFAULT_STREAM_SETTINGS: StreamSettings = {
|
|
80
|
+
enabled: true,
|
|
29
81
|
thinkAutoExpand: true,
|
|
82
|
+
autoCollapse: true,
|
|
83
|
+
debugEnabled: false,
|
|
84
|
+
debugTuning: DEFAULT_STREAM_DEBUG_TUNING,
|
|
30
85
|
}
|