Repository navigation
refactor(api): serve Agent logs through an application service #43688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Open
Changes from all commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
731524c
refactor(api): serve Agent logs through an application service
41tair 87f667b
Merge updated stack base into refactor/api-76-10-4
41tair 8fea94f
test(agent): type log transport and database-backed presentation cont…
41tair d15d6ef
docs(api): regenerate agent log endpoint descriptions
41tair 2e821a2
[autofix.ci] apply automated fixes
autofix-ci[bot] 1bb3c25
Merge updated stack base into refactor/api-76-10-4
41tair 6ac8ae2
Merge updated refactor/api-76-10-3
41tair 566ec92
fix(workflow): address review findings in #43688
41tair e211974
Merge updated refactor/api-76-10-3 into refactor/api-76-10-4
41tair acf23be
Merge updated refactor/api-76-10-3 into refactor/api-76-10-4
41tair fa21392
Merge updated refactor/api-76-10-3 into refactor/api-76-10-4
41tair fd6f613
Merge updated refactor/api-76-10-3 into refactor/api-76-10-4
41tair 566a324
Merge updated refactor/api-76-10-3 into refactor/api-76-10-4
41tair 056775f
Merge workflow migration compatibility from updated parent
41tair a68b947
Merge updated refactor/api-76-10-3 into refactor/api-76-10-4
41tair acfcf2c
Use relocated helpers in Agent logs tests
41tair bf58520
Sync validated refactor/api-76-10-3 fixes
41tair da189eb
Sync validated refactor/api-76-10-3 fixes
41tair 31207a5
Sync validated refactor/api-76-10-3 fixes
41tair 003ad49
Sync validated refactor/api-76-10-3 fixes
41tair 1415021
Sync validated refactor/api-76-10-3 fixes
41tair 47b38d9
Sync validated refactor/api-76-10-3 fixes
41tair 33d3ac1
Sync validated refactor/api-76-10-3 fixes
41tair def75c1
Sync validated refactor/api-76-10-3 fixes
41tair a813844
Sync validated refactor/api-76-10-3 fixes
41tair 1442132
Sync validated refactor/api-76-10-3 fixes
41tair dd390e9
Sync validated refactor/api-76-10-3 fixes
41tair f07667a
Sync validated refactor/api-76-10-3 fixes
41tair b150f60
Sync validated refactor/api-76-10-3 fixes
41tair a1f967e
Sync validated refactor/api-76-10-3 fixes
41tair 553ab2d
[autofix.ci] apply automated fixes
autofix-ci[bot] 71112dd
Merge updated refactor/api-76-10-3 into refactor/api-76-10-4
41tair c1dcbca
Regenerate API error contracts for migrated Agent logs
41tair 1301c06
Sync validated refactor/api-76-10-3 fixes
41tair 3c9a511
Sync validated refactor/api-76-10-3 fixes
41tair d5df4d7
Sync validated refactor/api-76-10-3 fixes
41tair 54abad5
Sync validated refactor/api-76-10-3 fixes
41tair a6d87a3
Sync validated refactor/api-76-10-3 fixes
41tair 9175bee
Sync validated refactor/api-76-10-3 fixes
41tair 9e24420
Sync validated refactor/api-76-10-3 fixes
41tair e8fd395
Sync validated refactor/api-76-10-3 fixes
41tair c33da4d
Sync validated refactor/api-76-10-3 fixes
41tair File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| """Rebuild message attachments with the shared file factory and explicit sessions.""" | ||
|
|
||
| from typing import Any | ||
|
|
||
| from sqlalchemy.orm import Session, sessionmaker | ||
|
|
||
| from core.app.file_access import FileAccessControllerProtocol | ||
| from factories.file_factory import build_from_mapping | ||
| from graphon.file import FileTransferMethod | ||
|
|
||
|
|
||
| class AgentLogFileGateway: | ||
| def __init__(self, *, sessions: sessionmaker[Session], access: FileAccessControllerProtocol) -> None: | ||
| self._sessions = sessions | ||
| self._access = access | ||
|
|
||
| def resolve(self, *, tenant_id: str, files: list[dict[str, Any]]) -> list[dict[str, Any]]: | ||
| result = [] | ||
| for source in files: | ||
| mapping = dict(source) | ||
| if mapping["transfer_method"] == FileTransferMethod.TOOL_FILE: | ||
| reference = mapping["upload_file_id"] | ||
| if reference is None: | ||
| reference = mapping["url"].split("/")[-1].split(".")[0] | ||
| mapping["tool_file_id"] = reference | ||
| mapping["upload_file_id"] = reference | ||
| file = build_from_mapping( | ||
| mapping=mapping, tenant_id=tenant_id, access_controller=self._access, sessions=self._sessions | ||
| ) | ||
| result.append( | ||
| {"belongs_to": source["belongs_to"], "upload_file_id": mapping["upload_file_id"], **file.to_dict()} | ||
| ) | ||
| return result |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| """Present one Agent message log after its read transaction has closed.""" | ||
|
|
||
| from datetime import UTC | ||
| from typing import Any | ||
|
|
||
| import pytz | ||
|
|
||
| from core.app.app_config.easy_ui_based_app.agent.manager import AgentConfigManager | ||
| from core.tools.entities.tool_entities import EmojiIconDict | ||
| from libs.datetime_utils import ensure_naive_utc | ||
| from machinery.context import RequestContext | ||
| from services.agent.log_contracts import AgentLogConfigurationError, AgentLogFiles, AgentLogIcons, AgentLogRecords | ||
|
|
||
|
|
||
| class AgentLogService: | ||
| def __init__(self, *, records: AgentLogRecords, icons: AgentLogIcons, files: AgentLogFiles) -> None: | ||
| self._records = records | ||
| self._icons = icons | ||
| self._files = files | ||
|
|
||
| def get(self, context: RequestContext, *, app_id: str, conversation_id: str, message_id: str) -> dict[str, Any]: | ||
| log = self._records.agent_log( | ||
| tenant_id=context.active_workspace_id, | ||
| account_id=context.account_id, | ||
| app_id=app_id, | ||
| conversation_id=conversation_id, | ||
| message_id=message_id, | ||
| ) | ||
| agent_config = AgentConfigManager.convert(log.model_config) | ||
| if agent_config is None: | ||
| raise AgentLogConfigurationError("Agent config not found") | ||
| configured_tools = {tool.tool_name: tool for tool in agent_config.tools or []} | ||
| iterations = [] | ||
| for thought in log.thoughts: | ||
| tool_calls = [] | ||
| for name in thought.tools: | ||
| metadata = thought.metadata.get(name, {}) | ||
| config = metadata.get("tool_config", {}) | ||
| provider_type = config.get("tool_provider_type", "") | ||
| provider_id = config.get("tool_provider", "") | ||
| configured = configured_tools.get(name) | ||
| if not provider_type and configured is not None: | ||
| provider_type = configured.provider_type | ||
| provider_id = provider_id or configured.provider_id | ||
| icon: str | EmojiIconDict = "" | ||
| if provider_type and provider_type != "dataset-retrieval": | ||
| icon = self._icons( | ||
| tenant_id=context.active_workspace_id, | ||
| provider_type=provider_type, | ||
| provider_id=provider_id, | ||
| ) | ||
| if not icon and configured is not None: | ||
| icon = self._icons( | ||
| tenant_id=context.active_workspace_id, | ||
| provider_type=configured.provider_type, | ||
| provider_id=configured.provider_id, | ||
| ) | ||
| tool_calls.append( | ||
| { | ||
| "status": "success" if not metadata.get("error") else "error", | ||
| "error": metadata.get("error"), | ||
| "time_cost": metadata.get("time_cost", 0), | ||
| "tool_name": name, | ||
| "tool_label": thought.labels.get(name, name), | ||
| "tool_input": thought.inputs.get(name, {}), | ||
| "tool_output": thought.outputs.get(name, {}), | ||
| "tool_parameters": metadata.get("tool_parameters", {}), | ||
| "tool_icon": icon, | ||
| } | ||
| ) | ||
| iterations.append( | ||
| { | ||
| "tokens": thought.tokens or 0, | ||
| "tool_calls": tool_calls, | ||
| "tool_raw": {"inputs": thought.raw_input, "outputs": thought.raw_output}, | ||
| "thought": thought.thought, | ||
| "created_at": thought.created_at.isoformat(), | ||
| "files": thought.files, | ||
| } | ||
| ) | ||
| return { | ||
| "meta": { | ||
| "status": "success", | ||
| "executor": log.executor, | ||
| "start_time": ensure_naive_utc(log.created_at) | ||
| .replace(tzinfo=UTC) | ||
| .astimezone(pytz.timezone(log.timezone)) | ||
| .isoformat(), | ||
| "elapsed_time": log.elapsed_time, | ||
| "total_tokens": log.total_tokens, | ||
| "agent_mode": log.model_config["agent_mode"].get("strategy", "react"), | ||
| "iterations": len(iterations), | ||
| }, | ||
| "iterations": iterations, | ||
| "files": self._files.resolve(tenant_id=context.active_workspace_id, files=log.files), | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.