Skip to content
This repository was archived by the owner on Mar 5, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -325,16 +325,11 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
temp
build*.json
*widget*.json
test_*
test_json/
logs/json/
logs/temp/
logs/
logs/
logs/usage/
*.ignore.*
a.json
a.py
share/
components-check-list.md
jprq
jprq_/
jprq
smarty_ui/
2 changes: 2 additions & 0 deletions functions_to_format/functions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from .functions import functions_mapper, sdui_functions_map
from .base_strategy import FunctionStrategy


__all__ = [
"functions_mapper",
"sdui_functions_map",
"FunctionStrategy",
]
222 changes: 130 additions & 92 deletions functions_to_format/functions/activity_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,30 @@
from pydantic import BaseModel
from typing import Any, Dict, List
from pydivkit.core import Expr
import structlog

from functions_to_format.functions.balance import (
build_balance_ui,
build_home_balances_ui,
)
from .general import Widget, add_ui_to_widget, WidgetInput
from .general.utils import save_builder_output
from models.build import BuildOutput
from functions_to_format.functions.general.const_values import LanguageOptions
from conf import logger
from models.context import Context, LoggerContext
import structlog

# Import smarty_ui components
from smarty_ui import (
VStack,
HStack,
text_1,
text_2,
caption_1,
caption_2,
default_theme,
)

logger = structlog.get_logger(__name__)


# Backend output schemas for activity reports
Expand Down Expand Up @@ -82,38 +99,48 @@ def _trigger_row(
target_state: str,
log_id: str,
) -> dv.DivContainer:
"""Trigger row: message + chevron (like ReasoningTrigger). Tapping toggles state."""
"""Trigger row: message + chevron (like ReasoningTrigger). Tapping toggles state.

Uses smarty_ui HStack for horizontal layout.
"""
set_state_url = f"div-action://set_state?state_id=0/{state_id}/{target_state}"
return dv.DivContainer(
orientation=dv.DivContainerOrientation.HORIZONTAL,
background=[dv.DivSolidBackground(color=MESSAGE_BLOCK_BG)],
paddings=dv.DivEdgeInsets(
left=TRIGGER_PADDING_H,
right=TRIGGER_PADDING_H,
top=TRIGGER_PADDING_V,
bottom=TRIGGER_PADDING_V,
),
border=dv.DivBorder(
corner_radius=TRIGGER_RADIUS,
stroke=dv.DivStroke(color="#4B5563", width=1),
),
alignment_vertical=dv.DivAlignmentVertical.CENTER,
items=[
dv.DivContainer(
orientation=dv.DivContainerOrientation.VERTICAL,
width=dv.DivMatchParentSize(weight=1),
margins=dv.DivEdgeInsets(right=GAP_MESSAGE_CHEVRON),
items=[_message_glow_text(message)],
),
dv.DivText(
text=chevron,
font_size=16,
text_color=CHEVRON_COLOR,
),
],
action=dv.DivAction(log_id=log_id, url=set_state_url),

# Message container with flex weight
message_container = dv.DivContainer(
orientation=dv.DivContainerOrientation.VERTICAL,
width=dv.DivMatchParentSize(weight=1),
items=[_message_glow_text(message)],
)

# Chevron text
chevron_text = dv.DivText(
text=chevron,
font_size=16,
text_color=CHEVRON_COLOR,
)

# Use HStack for horizontal layout
trigger = HStack(
[message_container, chevron_text],
gap=GAP_MESSAGE_CHEVRON,
align_v="center",
padding_left=TRIGGER_PADDING_H,
padding_right=TRIGGER_PADDING_H,
padding_top=TRIGGER_PADDING_V,
padding_bottom=TRIGGER_PADDING_V,
background=MESSAGE_BLOCK_BG,
corner_radius=TRIGGER_RADIUS,
)

# Add border stroke and action manually (not supported by HStack helper)
trigger.border = dv.DivBorder(
corner_radius=TRIGGER_RADIUS,
stroke=dv.DivStroke(color="#4B5563", width=1),
)
trigger.action = dv.DivAction(log_id=log_id, url=set_state_url)

return trigger


def _build_activity_message_holder(
message: str,
Expand All @@ -122,7 +149,10 @@ def _build_activity_message_holder(
log_id: str,
action_url: str = "div-action://activity-report",
):
"""Reasoning-like collapsible: trigger row (message + chevron) + expandable content (title + detail)."""
"""Reasoning-like collapsible: trigger row (message + chevron) + expandable content (title + detail).

Uses smarty_ui VStack for vertical layouts.
"""
state_id = f"activity_{log_id}"

# Collapsed: only trigger row with ▼ (expand)
Expand All @@ -134,56 +164,40 @@ def _build_activity_message_holder(
log_id=log_id,
)

# Expanded: trigger row with ▲ (collapse) + content below in a card
content_inner = dv.DivContainer(
orientation=dv.DivContainerOrientation.VERTICAL,
items=[
dv.DivText(
text=title,
font_size=13,
text_color=CONTENT_TITLE_COLOR,
font_weight=dv.DivFontWeight.MEDIUM,
margins=dv.DivEdgeInsets(bottom=8),
),
dv.DivText(
text=detail_json,
font_size=11,
text_color=CONTENT_DETAIL_COLOR,
line_height=18,
),
],
# Content inner using VStack
title_text = caption_1(title, color=CONTENT_TITLE_COLOR)
detail_text = caption_2(detail_json, color=CONTENT_DETAIL_COLOR)

content_inner = VStack(
[title_text, detail_text],
gap=8,
)
content_block = dv.DivContainer(
orientation=dv.DivContainerOrientation.VERTICAL,
margins=dv.DivEdgeInsets(top=SPACING_ABOVE_CONTENT),
paddings=dv.DivEdgeInsets(
left=CONTENT_PADDING,
right=CONTENT_PADDING,
top=CONTENT_PADDING,
bottom=CONTENT_PADDING,
),
background=[dv.DivSolidBackground(color=CONTENT_BLOCK_BG)],
border=dv.DivBorder(
corner_radius=CONTENT_RADIUS,
stroke=dv.DivStroke(color=CONTENT_BLOCK_BORDER, width=1),
),
transition_in=dv.DivFadeTransition(duration=200, alpha=0.5),
items=[content_inner],

# Content block with styling
content_block = VStack(
[content_inner],
padding=CONTENT_PADDING,
background=CONTENT_BLOCK_BG,
corner_radius=CONTENT_RADIUS,
)
content_block.margins = dv.DivEdgeInsets(top=SPACING_ABOVE_CONTENT)
content_block.border = dv.DivBorder(
corner_radius=CONTENT_RADIUS,
stroke=dv.DivStroke(color=CONTENT_BLOCK_BORDER, width=1),
)
content_block.transition_in = dv.DivFadeTransition(duration=200, alpha=0.5)

# Expanded trigger
expanded_trigger = _trigger_row(
message=message,
chevron="▲",
state_id=state_id,
target_state="collapsed",
log_id=log_id,
)
expanded_div = dv.DivContainer(
orientation=dv.DivContainerOrientation.VERTICAL,
items=[
expanded_trigger,
content_block,
],
)

# Expanded div using VStack
expanded_div = VStack([expanded_trigger, content_block])

state = dv.DivState(
id=state_id,
Expand All @@ -193,20 +207,33 @@ def _build_activity_message_holder(
dv.DivStateState(state_id="expanded", div=expanded_div),
],
)
wrapper = dv.DivContainer(
orientation=dv.DivContainerOrientation.VERTICAL,
margins=dv.DivEdgeInsets(left=12, right=12, top=8, bottom=8),
items=[state],

widgets = [state]

# Wrapper using VStack
wrapper = VStack(
widgets,
padding_left=12,
padding_right=12,
padding_top=8,
padding_bottom=8,
)

return dv.make_div(wrapper)


def build_function_call_activity_widget(
message: str,
function_name: str,
arguments: Dict[str, Any],
language: LanguageOptions = LanguageOptions.RUSSIAN,
):
"""Builder for function_call activity: shows message and call details (function_name, arguments)."""
logger.debug(
"building_function_call_activity_widget",
function_name=function_name,
message=message,
)
title = f"Calling: {function_name}"
detail_json = json.dumps(arguments, ensure_ascii=False, default=str)[:500]
if len(detail_json) >= 500:
Expand All @@ -224,12 +251,19 @@ def build_function_response_activity_widget(
message: str,
function_name: str,
response: Dict[str, Any],
language: LanguageOptions = LanguageOptions.RUSSIAN,
):
"""Builder for function_response activity: shows message and response (function_name, response)."""
logger.debug(
"building_function_response_activity_widget",
function_name=function_name,
message=message,
)
title = f"Response from: {function_name}"
detail_json = json.dumps(response, ensure_ascii=False, default=str)[:500]
if len(detail_json) >= 500:
detail_json += "..."

return _build_activity_message_holder(
message=message,
title=title,
Expand All @@ -240,20 +274,21 @@ def build_function_response_activity_widget(


def build_activity_indicator_widget(message: str) -> ActivityIndicatorWidget:
container = dv.DivContainer(
id="activity_report",
orientation=dv.DivContainerOrientation.VERTICAL,
items=[
dv.DivText(text=message, font_size=14, text_color="#F1F5F9"),
],
action=dv.DivAction(
log_id="activity_report",
url="div-action://activity-report",
payload={
"message": message,
"link": "http://10.212.134.3:8003/new_messages?idx=12341234",
},
),
"""Build activity indicator widget using smarty_ui components."""
logger.debug("building_activity_indicator_widget", message=message)
# Use text_1 for the message text
message_text = text_1(message, color="#F1F5F9")

# Use VStack for vertical layout
container = VStack([message_text])
container.id = "activity_report"
container.action = dv.DivAction(
log_id="activity_report",
url="div-action://activity-report",
payload={
"message": message,
"link": "http://10.212.134.3:8003/new_messages?idx=12341234",
},
)

return dv.make_div(container)
Expand All @@ -267,7 +302,9 @@ def activity_indicator(context: Context) -> BuildOutput:
language = context.language
chat_id = context.logger_context.chat_id
api_key = context.api_key
logger = context.logger_context.logger
ctx_logger = context.logger_context.logger

ctx_logger.info("activity_indicator_started", llm_output=llm_output)

inp = {}

Expand All @@ -291,5 +328,6 @@ def activity_indicator(context: Context) -> BuildOutput:
widgets=[widget.model_dump(exclude_none=True) for widget in widgets],
)

ctx_logger.info("activity_indicator_completed", widgets_count=len(widgets))
save_builder_output(context, output)
return output
Loading
Loading