| 163 | } |
| 164 | |
| 165 | private buildOutput( |
| 166 | result: PiRunResult, |
| 167 | model: string, |
| 168 | isBYOK: boolean, |
| 169 | startTime: number, |
| 170 | startTimeISO: string |
| 171 | ): NormalizedBlockOutput { |
| 172 | const { totals } = result |
| 173 | const endTime = Date.now() |
| 174 | return { |
| 175 | content: totals.finalText, |
| 176 | model, |
| 177 | changedFiles: result.changedFiles ?? [], |
| 178 | diff: result.diff ?? '', |
| 179 | ...(result.prUrl ? { prUrl: result.prUrl } : {}), |
| 180 | ...(result.branch ? { branch: result.branch } : {}), |
| 181 | tokens: { |
| 182 | input: totals.inputTokens, |
| 183 | output: totals.outputTokens, |
| 184 | total: totals.inputTokens + totals.outputTokens, |
| 185 | }, |
| 186 | cost: computePiCost(model, totals.inputTokens, totals.outputTokens, isBYOK), |
| 187 | providerTiming: { |
| 188 | startTime: startTimeISO, |
| 189 | endTime: new Date(endTime).toISOString(), |
| 190 | duration: endTime - startTime, |
| 191 | }, |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | private async runPi<P extends PiRunParams>( |
| 196 | ctx: ExecutionContext, |