MCPcopy
hub / github.com/coder/mux / handleTruncatedStreamCompletion

Method handleTruncatedStreamCompletion

src/node/services/streamManager.ts:2330–2361  ·  view source on GitHub ↗
(
    workspaceId: WorkspaceId,
    streamInfo: WorkspaceStreamInfo
  )

Source from the content-addressed store, hash-verified

2328 }
2329
2330 private async handleTruncatedStreamCompletion(
2331 workspaceId: WorkspaceId,
2332 streamInfo: WorkspaceStreamInfo
2333 ): Promise<void> {
2334 const workspaceLog = this.getWorkspaceLogger(workspaceId, streamInfo);
2335 const streamMeta = await this.getStreamMetadata(streamInfo);
2336 const totalUsage = this.resolveTotalUsageForStreamEnd(streamInfo, streamMeta.totalUsage);
2337 const contextUsage = streamMeta.contextUsage ?? streamInfo.lastStepUsage;
2338 const previousResponseId = this.getOpenAIPreviousResponseId(streamInfo.request.providerOptions);
2339 const providerDisplayName = getStreamProviderDisplayName(streamInfo.model);
2340
2341 // Do not treat iterator EOF as success. Anthropic and OpenAI Responses both
2342 // have semantic terminal events; without the SDK finish part, this may be a
2343 // clean proxy/provider drop after partial text was already streamed.
2344 workspaceLog.error("Stream ended without a terminal finish event", {
2345 messageId: streamInfo.messageId,
2346 model: streamInfo.model,
2347 providerDisplayName,
2348 durationMs: streamMeta.duration,
2349 totalUsage,
2350 contextUsage,
2351 cumulativeUsage: streamInfo.cumulativeUsage,
2352 previousResponseId,
2353 partsCount: streamInfo.parts.length,
2354 });
2355
2356 await this.handleStreamFailure(
2357 workspaceId,
2358 streamInfo,
2359 new StreamTruncatedError(providerDisplayName)
2360 );
2361 }
2362
2363 private async retryEmptyStreamBeforeFailure(
2364 workspaceId: WorkspaceId,

Callers 1

Calls 6

getWorkspaceLoggerMethod · 0.95
getStreamMetadataMethod · 0.95
handleStreamFailureMethod · 0.95

Tested by

no test coverage detected