mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-14 12:16:20 +00:00
Mark fixed values in the chat instead of showing them, and keep them on reload
A value the owner fixed may be a secret, and tool-call events reach whoever runs the agent, so query and body values the owner fixed now show as (fixed); a value the connection sets, like Telegram's default chat, still shows. sent_arguments is saved with the conversation, so a reopened chat shows the same arguments as the live one.
This commit is contained in:
1 parent
01caae80ad
commit
39063d5e41
3 files changed
+56
-25
No files matched your search
@@ -14,7 +14,7 @@ from docsgpt.agents.default_tools import (
|
||||
synthesized_default_tools,
|
||||
)
|
||||
from docsgpt import tracing
|
||||
from docsgpt.agents.tool_pins import iter_parameters, llm_fills, resolve_arguments, sent_arguments, shown_arguments
|
||||
from docsgpt.agents.tool_pins import iter_parameters, llm_fills, resolve_arguments, sent_arguments
|
||||
from docsgpt.agents.tools.tool_action_parser import ToolActionParser
|
||||
from docsgpt.agents.tools.tool_manager import ToolManager
|
||||
from docsgpt.guardrails.types import Stage as GuardrailStage, resolve_tool_result
|
||||
@@ -1513,7 +1513,7 @@ class ToolExecutor:
|
||||
body, parameters = sections["body"], sections["parameters"]
|
||||
# The chat shows what was sent; ``arguments`` keeps what the model
|
||||
# asked for, which is what a later turn replays to it.
|
||||
sent = shown_arguments(sections)
|
||||
sent = sent_arguments(action_data, call_args, self._connection_parameters(tool_data))
|
||||
if sent != (call_args if isinstance(call_args, dict) else {}):
|
||||
tool_call_data["sent_arguments"] = sent
|
||||
|
||||
@@ -1843,7 +1843,9 @@ class ToolExecutor:
|
||||
# Keys the client needs that are not part of the fixed shape below. They are
|
||||
# small and optional, and are copied only when present so an ordinary tool
|
||||
# call does not grow null columns in every persisted row.
|
||||
_PRESERVED_TOOL_CALL_KEYS = ("artifacts", "device_id", "connector_key", "connector_name", "access")
|
||||
_PRESERVED_TOOL_CALL_KEYS = (
|
||||
"artifacts", "device_id", "connector_key", "connector_name", "access", "sent_arguments",
|
||||
)
|
||||
|
||||
def get_truncated_tool_calls(self) -> List[Dict]:
|
||||
"""Project tool calls into the shape that is streamed and persisted.
|
||||
|
||||
+23
-15
@@ -104,17 +104,8 @@ def resolve_arguments(
|
||||
return resolved
|
||||
|
||||
|
||||
def shown_arguments(sections: Mapping[str, Mapping[str, Any]]) -> dict:
|
||||
"""One flat ``{parameter: value}`` view of resolved sections, for the chat.
|
||||
|
||||
Headers are left out: they may carry a pinned secret (an API key the
|
||||
owner fixed), and the chat is shown to whoever runs the agent.
|
||||
"""
|
||||
shown: dict = {}
|
||||
for section in PARAM_SECTIONS:
|
||||
if section != "headers":
|
||||
shown.update(sections.get(section) or {})
|
||||
return shown
|
||||
#: What the chat shows in place of a value the owner fixed.
|
||||
FIXED_MASK = "(fixed)"
|
||||
|
||||
|
||||
def sent_arguments(
|
||||
@@ -122,12 +113,29 @@ def sent_arguments(
|
||||
llm_arguments: Mapping[str, Any],
|
||||
connection_pins: Optional[Mapping[str, Any]] = None,
|
||||
) -> dict:
|
||||
"""What a call sends, flattened for display (see :func:`shown_arguments`).
|
||||
"""What a call sends, flattened for the chat (the approval card, a finished call).
|
||||
|
||||
The approval card and the finished call show this rather than what the
|
||||
model asked for, which fixed values may have replaced.
|
||||
It follows :func:`resolve_arguments`, but a value the owner fixed shows
|
||||
as :data:`FIXED_MASK`: it may be a secret (an API key in a query), and
|
||||
the chat is shown to whoever runs the agent, over the API or a widget
|
||||
too. A value the connection sets (Telegram's default chat) is the
|
||||
account's own setting and shows as it is. Headers are left out.
|
||||
"""
|
||||
return shown_arguments(resolve_arguments(action, llm_arguments, connection_pins))
|
||||
connection_pins = connection_pins or {}
|
||||
shown: dict = {}
|
||||
for section, name, details in iter_parameters(action):
|
||||
if section == "headers":
|
||||
continue
|
||||
if name in connection_pins:
|
||||
shown[name] = connection_pins[name]
|
||||
elif not llm_fills(details):
|
||||
if has_value(details):
|
||||
shown[name] = FIXED_MASK
|
||||
elif name in llm_arguments:
|
||||
shown[name] = llm_arguments[name]
|
||||
elif has_value(details):
|
||||
shown[name] = details["value"]
|
||||
return shown
|
||||
|
||||
|
||||
def coerce_value(details: Mapping, value: Any) -> Any:
|
||||
|
||||
Reference in new issue
Block a user