(
aiService: AIService & EventEmitter,
workspaceId: string,
messageId: string,
parts: unknown[],
options?: { finishReason?: string }
)
| 454 | // or cooldown gates intervene. |
| 455 | |
| 456 | function emitStreamEnd( |
| 457 | aiService: AIService & EventEmitter, |
| 458 | workspaceId: string, |
| 459 | messageId: string, |
| 460 | parts: unknown[], |
| 461 | options?: { finishReason?: string } |
| 462 | ): void { |
| 463 | aiService.emit("stream-end", { |
| 464 | type: "stream-end", |
| 465 | workspaceId, |
| 466 | messageId, |
| 467 | parts, |
| 468 | metadata: { |
| 469 | model: "openai:gpt-4o", |
| 470 | contextUsage: { inputTokens: 5, outputTokens: 5, totalTokens: 10 }, |
| 471 | providerMetadata: {}, |
| 472 | // Default to a clean natural stop so the silent-continuation |
| 473 | // auto-complete gate matches; individual tests override to |
| 474 | // exercise truncated / non-stop paths. |
| 475 | finishReason: options?.finishReason ?? "stop", |
| 476 | }, |
| 477 | }); |
| 478 | } |
| 479 | |
| 480 | test("text-only stream-end during a goal_continuation turn auto-completes the goal", async () => { |
| 481 | const workspaceId = "silent-continuation-completes"; |
no test coverage detected