MCPcopy Index your code
hub / github.com/coder/coder / flushActiveState

Function flushActiveState

coderd/x/chatd/chatloop/chatloop.go:1644–1699  ·  view source on GitHub ↗

flushActiveState moves any in-progress text, reasoning, and tool calls from the active tracking maps into result.content and result.toolCalls. This is called on interruption so that partial content from an incomplete stream is available for persistence.

(
	result *stepResult,
	activeText map[string]string,
	activeReasoning map[string]reasoningState,
	activeToolCalls map[string]*fantasy.ToolCallContent,
	toolNames map[string]string,
)

Source from the content-addressed store, hash-verified

1642// partial content from an incomplete stream is available for
1643// persistence.
1644func flushActiveState(
1645 result *stepResult,
1646 activeText map[string]string,
1647 activeReasoning map[string]reasoningState,
1648 activeToolCalls map[string]*fantasy.ToolCallContent,
1649 toolNames map[string]string,
1650) {
1651 // Flush partial text content.
1652 for _, text := range activeText {
1653 if text != "" {
1654 result.content = append(result.content, fantasy.TextContent{Text: text})
1655 }
1656 }
1657
1658 // Flush partial reasoning content. The matching
1659 // completedAt is filled in here with the interruption
1660 // time so partial reasoning shows the time spent before
1661 // the interruption.
1662 flushedAt := dbtime.Now()
1663 for _, rs := range activeReasoning {
1664 if rs.text == "" && !chatsanitize.HasAnthropicSignedReasoningOptions(fantasy.ProviderOptions(rs.options)) {
1665 continue
1666 }
1667 result.content = append(result.content, fantasy.ReasoningContent{
1668 Text: rs.text,
1669 ProviderMetadata: rs.options,
1670 })
1671 result.reasoningStartedAt = append(result.reasoningStartedAt, rs.startedAt)
1672 result.reasoningCompletedAt = append(result.reasoningCompletedAt, flushedAt)
1673 }
1674
1675 // Flush in-progress tool calls. These haven't received a
1676 // StreamPartTypeToolCall yet, so they only exist in
1677 // activeToolCalls. We add them to both content and toolCalls
1678 // so persistInterruptedStep can generate synthetic error
1679 // results for them.
1680 for id, tc := range activeToolCalls {
1681 if tc == nil {
1682 continue
1683 }
1684 // Prefer the tool name from the toolNames map since
1685 // ToolInputStart may provide a cleaner name.
1686 toolName := tc.ToolName
1687 if name, ok := toolNames[id]; ok && strings.TrimSpace(name) != "" {
1688 toolName = name
1689 }
1690 flushed := fantasy.ToolCallContent{
1691 ToolCallID: tc.ToolCallID,
1692 ToolName: toolName,
1693 Input: tc.Input,
1694 ProviderExecuted: tc.ProviderExecuted,
1695 }
1696 result.content = append(result.content, flushed)
1697 result.toolCalls = append(result.toolCalls, flushed)
1698 }
1699}
1700
1701// persistInterruptedStep saves durable content from a partial stream.

Calls 3

NowFunction · 0.92
ProviderOptionsMethod · 0.45