@royalcat/opencode-dcp-rc 4.0.1 → 4.0.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/lib/v2/usage.ts CHANGED
@@ -21,6 +21,12 @@ import {
21
21
  normalizeProviderUsage,
22
22
  type CompressionUsage,
23
23
  } from "../compress/usage"
24
+ import {
25
+ AisdkPartScrubber,
26
+ outputScrubEnabled,
27
+ stripAisdkResultContent,
28
+ type OutputScrubConfig,
29
+ } from "./scrub"
24
30
 
25
31
  interface PendingUsage {
26
32
  provider?: CompressionUsage
@@ -115,14 +121,20 @@ function collectTexts(value: unknown, out: string[], depth = 0): void {
115
121
  }
116
122
  }
117
123
 
118
- function wrapLanguageModel(model: any, tracker: CompressionUsageTracker, logger: Logger): any {
124
+ function wrapLanguageModel(
125
+ model: any,
126
+ tracker: CompressionUsageTracker,
127
+ logger: Logger,
128
+ scrub?: OutputScrubConfig,
129
+ ): any {
119
130
  return new Proxy(model, {
120
131
  get(target, property, receiver) {
121
132
  if (property === "doStream") {
122
- return (options: unknown) => trackedStream(target, options, tracker, logger)
133
+ return (options: unknown) => trackedStream(target, options, tracker, logger, scrub)
123
134
  }
124
135
  if (property === "doGenerate") {
125
- return (options: unknown) => trackedGenerate(target, options, tracker, logger)
136
+ return (options: unknown) =>
137
+ trackedGenerate(target, options, tracker, logger, scrub)
126
138
  }
127
139
  return Reflect.get(target, property, receiver)
128
140
  },
@@ -134,23 +146,26 @@ async function trackedStream(
134
146
  options: unknown,
135
147
  tracker: CompressionUsageTracker,
136
148
  logger: Logger,
149
+ scrub?: OutputScrubConfig,
137
150
  ): Promise<any> {
138
151
  const result = await target.doStream(options)
139
152
  const callId = findSummaryCallId(options)
153
+ const scrubEnabled = !!scrub && outputScrubEnabled(scrub)
140
154
  logger.debug("Compression usage stream call", { callId: callId ?? null })
141
155
  const TransformStreamImpl = (globalThis as any).TransformStream
142
- if (!callId || typeof result?.stream?.pipeThrough !== "function") {
156
+ if ((!callId && !scrubEnabled) || typeof result?.stream?.pipeThrough !== "function") {
143
157
  return result
144
158
  }
145
159
  if (typeof TransformStreamImpl !== "function") {
146
160
  return result
147
161
  }
148
162
 
163
+ const partScrubber = scrubEnabled ? new AisdkPartScrubber(scrub!) : undefined
149
164
  let recorded = false
150
165
  const transform = new TransformStreamImpl({
151
166
  transform(part: any, controller: any) {
152
167
  try {
153
- if (!recorded && part?.type === "finish" && part.usage) {
168
+ if (callId && !recorded && part?.type === "finish" && part.usage) {
154
169
  const usage = normalizeProviderUsage(part.usage)
155
170
  if (usage) {
156
171
  recorded = true
@@ -160,7 +175,10 @@ async function trackedStream(
160
175
  } catch {
161
176
  // Never disturb the model stream because of usage accounting.
162
177
  }
163
- controller.enqueue(part)
178
+ const parts = partScrubber ? partScrubber.process(part) : [part]
179
+ for (const next of parts) {
180
+ controller.enqueue(next)
181
+ }
164
182
  },
165
183
  })
166
184
  return { ...result, stream: result.stream.pipeThrough(transform) }
@@ -171,10 +189,18 @@ async function trackedGenerate(
171
189
  options: unknown,
172
190
  tracker: CompressionUsageTracker,
173
191
  logger: Logger,
192
+ scrub?: OutputScrubConfig,
174
193
  ): Promise<any> {
175
194
  const result = await target.doGenerate(options)
176
195
  const callId = findSummaryCallId(options)
177
196
  logger.debug("Compression usage generate call", { callId: callId ?? null })
197
+ if (scrub && outputScrubEnabled(scrub)) {
198
+ try {
199
+ stripAisdkResultContent(result, scrub)
200
+ } catch {
201
+ // Never disturb the model result because of output scrubbing.
202
+ }
203
+ }
178
204
  if (!callId) {
179
205
  return result
180
206
  }
@@ -193,6 +219,7 @@ export async function installCompressionUsageHook(
193
219
  ctx: Plugin.Context,
194
220
  tracker: CompressionUsageTracker,
195
221
  logger: Logger,
222
+ scrub?: OutputScrubConfig,
196
223
  ): Promise<void> {
197
224
  const aisdk = (ctx as any)?.aisdk
198
225
  if (!aisdk || typeof aisdk.hook !== "function") {
@@ -221,7 +248,7 @@ export async function installCompressionUsageHook(
221
248
  if (!isModel(model)) {
222
249
  return
223
250
  }
224
- event.language = wrapLanguageModel(model, tracker, logger)
251
+ event.language = wrapLanguageModel(model, tracker, logger, scrub)
225
252
  } catch (error: any) {
226
253
  logger.debug("Compression usage hook could not wrap language model", {
227
254
  error: error?.message,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@royalcat/opencode-dcp-rc",
4
- "version": "4.0.1",
4
+ "version": "4.0.3",
5
5
  "type": "module",
6
6
  "workspaces": [
7
7
  "tests/logger"