The non-streaming response handler was saving assistant messages without
their usage/token data. While the streaming handler correctly extracted
and saved usage information, the non-streaming path discarded it entirely.
This caused assistant messages from non-streaming completions to have
NULL usage in the chat_message table, making them invisible to the
analytics token aggregation queries and contributing to the '0 tokens'
display in Admin Panel Analytics.
Extract and normalize the usage data from the API response and include
it in the database upsert, matching the pattern already used by the
streaming handler.
* perf(models): batch-fetch function valves to eliminate N+1 queries
get_action_priority() called Functions.get_function_valves_by_id()
individually for every action on every model — an N+1 query pattern
that issued one DB round-trip per (action x model) pair.
Add Functions.get_function_valves_by_ids() that fetches all valves in
a single WHERE IN query, then look up each action's valves from the
pre-fetched dict inside get_action_priority().
No functional change — same priority resolution, same sort order.
* Update models.py
* Update models.py
Backend emits terminal events for write_file, replace_file_content,
and run_command. Frontend showFileNavDir subscriber uses startsWith
path matching to smartly refresh only when the event is relevant:
- write_file/replace_file_content: refresh if path is in current view
- run_command: always refresh (uses root '/' which matches everything)
- Also adds copy-to-clipboard button and code preview full-height fix