dsh-ntr 0.3.2 → 0.3.3
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 +2 -0
- package/README.md +2 -0
- package/lib/bridge.js +1819 -54
- package/lib/client/activity-pill.js +156 -0
- package/lib/client/branch-action.js +16 -0
- package/lib/client/index.js +44 -4
- package/lib/client/model-seat.js +8 -2
- package/lib/client/store.js +32 -0
- package/lib/client.js +228 -5
- package/lib/client.js.map +1 -1
- package/lib/impl.js +1175 -7
- package/lib/index.js +27 -0
- package/lib/tps.js +32 -0
- package/lib/types/bridge.d.ts +621 -12
- package/lib/types/client/activity-pill.d.ts +81 -0
- package/lib/types/client/branch-action.d.ts +8 -1
- package/lib/types/client/model-seat.d.ts +21 -0
- package/lib/types/client/store.d.ts +10 -0
- package/lib/types/impl.d.ts +53 -6
- package/lib/types/protocol.d.ts +22 -0
- package/lib/types/tps.d.ts +17 -0
- package/package.json +1 -1
- package/src/bridge.ts +2103 -53
- package/src/client/activity-pill.tsx +201 -0
- package/src/client/branch-action.tsx +19 -1
- package/src/client/index.tsx +36 -4
- package/src/client/model-seat.tsx +28 -3
- package/src/client/store.ts +37 -0
- package/src/impl.ts +1167 -11
- package/src/index.ts +25 -0
- package/src/protocol.ts +24 -0
- package/src/tps.ts +40 -0
package/src/index.ts
CHANGED
|
@@ -277,6 +277,31 @@ export function apply(ctx: Context, config?: unknown): void {
|
|
|
277
277
|
})
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
+
const wireAttachments = (injectedCtx?: Context): void => {
|
|
281
|
+
const c = injectedCtx ?? ctx
|
|
282
|
+
let attachments: unknown
|
|
283
|
+
try {
|
|
284
|
+
if (typeof c.get === 'function') {
|
|
285
|
+
attachments = c.get('attachments') ?? c.get('attachmentService')
|
|
286
|
+
}
|
|
287
|
+
} catch {}
|
|
288
|
+
try {
|
|
289
|
+
if (attachments === undefined) {
|
|
290
|
+
attachments = (c as unknown as Record<string, unknown>).attachments ?? (c as unknown as Record<string, unknown>).attachmentService
|
|
291
|
+
}
|
|
292
|
+
} catch {}
|
|
293
|
+
if (attachments !== undefined) {
|
|
294
|
+
manager.setAttachmentResolver(attachments)
|
|
295
|
+
} else {
|
|
296
|
+
manager.setAttachmentResolver(c)
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
wireAttachments()
|
|
300
|
+
if (typeof ctx.inject === 'function') {
|
|
301
|
+
ctx.inject(['attachments'], injectedCtx => { wireAttachments(injectedCtx) })
|
|
302
|
+
ctx.inject(['attachmentService'], injectedCtx => { wireAttachments(injectedCtx) })
|
|
303
|
+
}
|
|
304
|
+
|
|
280
305
|
/** Registration handle: callable disposer, plus `replace` to re-announce routes. */
|
|
281
306
|
interface LlmAdapterHandle {
|
|
282
307
|
(): void
|
package/src/protocol.ts
CHANGED
|
@@ -458,6 +458,18 @@ export type AcpEvent =
|
|
|
458
458
|
*/
|
|
459
459
|
| { type: 'permission/synced'; requestIds: string[] }
|
|
460
460
|
| { type: 'turn/start'; sessionId: string; turnId: string; text: string }
|
|
461
|
+
| {
|
|
462
|
+
type: 'turn/metrics'
|
|
463
|
+
/** ACP session id (the store keys live burst state by it). */
|
|
464
|
+
sessionId: string
|
|
465
|
+
/** DSH chat session id (routing/context only). */
|
|
466
|
+
dshSessionId: string
|
|
467
|
+
turnId: string
|
|
468
|
+
/** Session aggregate INCLUDING the current turn when measurable. */
|
|
469
|
+
outputTokens: number
|
|
470
|
+
burstMs: number
|
|
471
|
+
final: boolean
|
|
472
|
+
}
|
|
461
473
|
| { type: 'turn/end'; sessionId: string; turnId: string; stopReason?: string; error?: string }
|
|
462
474
|
/**
|
|
463
475
|
* A DSH chat conversation was locked to its agent at the start of its first
|
|
@@ -481,6 +493,14 @@ export interface PermissionOptionView {
|
|
|
481
493
|
|
|
482
494
|
export type PermissionOutcome = { outcome: 'selected'; optionId: string } | { outcome: 'cancelled' }
|
|
483
495
|
|
|
496
|
+
/** Plugin-side measurable burst aggregate for one ACP session (not host turn timings). */
|
|
497
|
+
export interface SessionBurst {
|
|
498
|
+
/** Sum of estimated output tokens over measurable turns. */
|
|
499
|
+
outputTokens: number
|
|
500
|
+
/** Sum of within-burst chunk gaps over those turns; tool/approval/long pauses excluded. */
|
|
501
|
+
burstMs: number
|
|
502
|
+
}
|
|
503
|
+
|
|
484
504
|
/** Derived session snapshot for replay/reconnect (source of truth stays in the transcript). */
|
|
485
505
|
export interface SessionView {
|
|
486
506
|
sessionId: string
|
|
@@ -494,6 +514,8 @@ export interface SessionView {
|
|
|
494
514
|
availableCommands?: Array<{ name: string; description?: string; [key: string]: unknown }>
|
|
495
515
|
plan?: unknown[]
|
|
496
516
|
usage?: { used: number; size: number; cost?: { amount: number; currency: string } }
|
|
517
|
+
/** Measurable burst aggregate over this session's turns; absent until measured. */
|
|
518
|
+
burst?: SessionBurst
|
|
497
519
|
running: boolean
|
|
498
520
|
closed: boolean
|
|
499
521
|
/**
|
|
@@ -569,6 +591,8 @@ export interface ChatSessionView {
|
|
|
569
591
|
* browser live-patches this row from the update frames (see AGENTS/ui.md).
|
|
570
592
|
*/
|
|
571
593
|
usage?: SessionView['usage']
|
|
594
|
+
/** Measurable burst aggregate over this session's turns; absent until measured. */
|
|
595
|
+
burst?: SessionView['burst']
|
|
572
596
|
/** The agent process died; the session awaits a `session/load` resume. */
|
|
573
597
|
released?: boolean
|
|
574
598
|
/** The agent is running a turn on this session right now. */
|
package/src/tps.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** ACP `usage_update` is context occupancy, not request tokens; this is the plugin's 4-chars/token OUTPUT estimate (tool args excluded). */
|
|
2
|
+
export const OUTPUT_CHARS_PER_TOKEN = 4
|
|
3
|
+
export const BURST_GAP_MS = 1000
|
|
4
|
+
|
|
5
|
+
export interface TurnTpsSnapshot {
|
|
6
|
+
outputTokens: number
|
|
7
|
+
burstMs: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class TurnTpsTracker {
|
|
11
|
+
private readonly gapMs: number
|
|
12
|
+
private lastProseAt: number | undefined
|
|
13
|
+
private outputChars = 0
|
|
14
|
+
private burstMs = 0
|
|
15
|
+
|
|
16
|
+
constructor(gapMs = BURST_GAP_MS) {
|
|
17
|
+
this.gapMs = gapMs
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
onProse(text: string, at: number): void {
|
|
21
|
+
if (text === '') return
|
|
22
|
+
if (this.lastProseAt !== undefined) {
|
|
23
|
+
const gap = at - this.lastProseAt
|
|
24
|
+
if (gap <= this.gapMs) this.burstMs += gap
|
|
25
|
+
}
|
|
26
|
+
this.lastProseAt = at
|
|
27
|
+
this.outputChars += text.length
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
onBreak(): void {
|
|
31
|
+
this.lastProseAt = undefined
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
snapshot(): TurnTpsSnapshot {
|
|
35
|
+
return {
|
|
36
|
+
outputTokens: Math.round(this.outputChars / OUTPUT_CHARS_PER_TOKEN),
|
|
37
|
+
burstMs: this.burstMs,
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|