Repository navigation
fix: propagate workspace runtime in skill_exec #351
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,6 +52,7 @@ | |
| from pydantic import Field | ||
| from trpc_agent_sdk.code_executors import BaseProgramRunner | ||
| from trpc_agent_sdk.code_executors import BaseProgramSession | ||
| from trpc_agent_sdk.code_executors import BaseWorkspaceRuntime | ||
| from trpc_agent_sdk.code_executors import DEFAULT_EXEC_YIELD_MS | ||
| from trpc_agent_sdk.code_executors import DEFAULT_IO_YIELD_MS | ||
| from trpc_agent_sdk.code_executors import DEFAULT_SESSION_KILL_SEC | ||
|
|
@@ -90,6 +91,8 @@ | |
| from ._skill_run import SkillRunInput | ||
| from ._skill_run import SkillRunOutput | ||
| from ._skill_run import SkillRunTool | ||
| from ._skill_run import _WARN_STDERR_TRUNCATED | ||
| from ._skill_run import _WARN_STDOUT_TRUNCATED | ||
| from ._skill_run import _filter_failed_empty_outputs | ||
| from ._skill_run import _select_primary_output | ||
| from ._skill_run import _truncate_output | ||
|
|
@@ -216,6 +219,7 @@ class _ExecSession: | |
|
|
||
| proc: BaseProgramSession | ||
| ws: WorkspaceInfo | ||
| workspace_runtime: BaseWorkspaceRuntime | ||
| in_data: ExecInput | ||
|
|
||
| # Final state | ||
|
|
@@ -458,6 +462,7 @@ async def _run_async_impl( | |
| tool_context=tool_context, | ||
| inputs=inputs, | ||
| ws=ws, | ||
| workspace_runtime=workspace_runtime, | ||
| rel_cwd=rel_cwd, | ||
| env=merged_env, | ||
| ) | ||
|
|
@@ -730,6 +735,7 @@ async def _start_session( | |
| tool_context: InvocationContext, | ||
| inputs: ExecInput, | ||
| ws: WorkspaceInfo, | ||
| workspace_runtime: BaseWorkspaceRuntime, | ||
| rel_cwd: str, | ||
| env: dict[str, str], | ||
| ) -> _ExecSession: | ||
|
|
@@ -744,7 +750,7 @@ async def _start_session( | |
| tty=inputs.tty, | ||
| ) | ||
| proc = await runner.start_program(tool_context, ws, spec) | ||
| return _ExecSession(proc=proc, ws=ws, in_data=inputs) | ||
| return _ExecSession(proc=proc, ws=ws, workspace_runtime=workspace_runtime, in_data=inputs) | ||
|
|
||
|
|
||
| async def _write_stdin(exec_session: _ExecSession, chars: str, submit: bool) -> None: | ||
|
|
@@ -778,35 +784,56 @@ async def _collect_final_result( | |
| inputs=in_data.inputs, | ||
| outputs=in_data.outputs, | ||
| ) | ||
| warnings: list[str] = [] | ||
| try: | ||
| files, manifest = await run_tool._prepare_outputs(ctx, exec_session.ws, fake_run_input) | ||
| files, manifest = await run_tool._prepare_outputs(ctx, exec_session.ws, exec_session.workspace_runtime, | ||
| fake_run_input) | ||
|
Comment on lines
+789
to
+790
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 问题: 本次变更使 触发条件: 实际影响: 超时被杀的命令被报告为普通失败:按 修正方向: 从
Comment on lines
+789
to
+790
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 问题: 本次变更使输出收集( 触发条件: 交互进程已退出而 LLM 未先成功轮询到退出态,直接调用 实际影响: 会话的最终 修正方向: 在 kill 与 TTL 逐出路径中,若
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个问题我认同,但是它涉及
Comment on lines
+789
to
+790
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 问题: 本次变更使 触发条件: 实际影响: 静默降级路径变成向上抛异常(本来旨在优雅返回空结果以结束交互链,反而中断整个工具调用); 修正方向: 给异常分支的
Comment on lines
+789
to
+790
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 问题: 本次变更使收集路径首次真正执行(本变更行补上 触发条件: 交互命令向 stderr 输出内容(例如 20KB 的错误堆栈)且成功收集;或调用方检查 实际影响: 按 修正方向: 从 |
||
| except Exception as ex: # pylint: disable=broad-except | ||
| logger.warning("skill_exec: collect outputs failed: %s", ex) | ||
| files, manifest = [], None | ||
|
Comment on lines
788
to
793
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 问题: 本次变更修复了 触发条件: 进程退出后收集阶段 实际影响: 用户得到 修正方向: 将收集失败显式表达:在该分支向 |
||
| warnings.append(f"output collection failed: {ex}") | ||
|
|
||
| timed_out = False | ||
| duration_ms = 0 | ||
| try: | ||
| run_result = await exec_session.proc.run_result() | ||
| total_out = (run_result.stdout or "") + (run_result.stderr or "") | ||
| stdout_raw = run_result.stdout or "" | ||
| stderr_raw = run_result.stderr or "" | ||
| exit_code = run_result.exit_code | ||
| timed_out = bool(getattr(run_result, "timed_out", False)) | ||
| duration_ms = int((getattr(run_result, "duration", 0) or 0) * 1000) | ||
| except Exception: # pylint: disable=broad-except | ||
| run_log = await exec_session.proc.log(None, None) | ||
| total_out = run_log.output or "" | ||
| exit_code = exec_session.exit_code or 0 | ||
| try: | ||
| run_log = await exec_session.proc.log(None, None) | ||
| stdout_raw = run_log.output or "" | ||
| except Exception: # pylint: disable=broad-except | ||
| stdout_raw = "" | ||
| stderr_raw = "" | ||
| if exec_session.exit_code is not None: | ||
| exit_code = exec_session.exit_code | ||
| else: | ||
| exit_code = 0 | ||
| warnings.append("exit code unavailable after run_result failure; reported as 0") | ||
|
|
||
| # Reuse the same output-quality helpers as skill_run | ||
| warnings: list[str] = [] | ||
| stdout, trunc = _truncate_output(total_out) | ||
| stdout, trunc = _truncate_output(stdout_raw) | ||
| if trunc: | ||
| warnings.append("stdout truncated") | ||
| warnings.append(_WARN_STDOUT_TRUNCATED) | ||
| stderr, trunc = _truncate_output(stderr_raw) | ||
| if trunc: | ||
| warnings.append(_WARN_STDERR_TRUNCATED) | ||
|
|
||
| files, filter_warns = _filter_failed_empty_outputs(exit_code, False, files) | ||
| files, filter_warns = _filter_failed_empty_outputs(exit_code, timed_out, files) | ||
| warnings.extend(filter_warns) | ||
|
|
||
| primary = _select_primary_output(files) | ||
|
|
||
| result = SkillRunOutput( | ||
| stdout=stdout, | ||
| stderr=stderr, | ||
| exit_code=exit_code, | ||
| timed_out=timed_out, | ||
| duration_ms=duration_ms, | ||
| output_files=files, | ||
| primary_output=primary, | ||
| warnings=warnings, | ||
|
|
@@ -820,6 +847,13 @@ async def _collect_final_result( | |
| if manifest: | ||
| run_tool._merge_manifest_artifact_refs(manifest, result) | ||
|
|
||
| # omit_inline_content: keep metadata only, match skill_run contract | ||
| if in_data.omit_inline_content: | ||
| for f in result.output_files: | ||
| f.content = "" | ||
| if result.primary_output: | ||
| result.primary_output.content = "" | ||
|
|
||
| exec_session.final_result = result | ||
| exec_session.finalized = True | ||
| return result | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
问题:
_collect_final_result在此变更行启动的真实收集路径中,将omit_inline_content透传给fake_run_input(第 781 行),但组装SkillRunOutput时从不把output_files/primary_output的content置空。对照_skill_run.py:742-747在skill_run路径会按该标志清空内容。本次变更前_prepare_outputs因缺参必然抛TypeError被吞掉、files恒为空,该标志没有任何可观察效果;本次变更在调用处(即本行)补上workspace_runtime使收集真正生效后,标志被静默忽略成为可观察缺陷。触发条件: 调用
skill_exec(或经skill_poll_session/skill_write_stdin完成最终收集)且ExecInput设置omit_inline_content=True、声明了output_files或outputs产物,_prepare_outputs返回非空files后进入后续组装。实际影响: 调用方按契约(
ExecInput.omit_inline_content字段描述及_skill_processor.py对模型的引导:设置该标志后output_files只返回元数据、用ref按需读取)期望省略内联内容,实际却拿到全部文件全文,与skill_run行为不一致;大文件内容直接膨胀进工具响应,消耗模型上下文预算,本 PR 之前不会发生。修正方向: 在
_collect_final_result组装SkillRunOutput前,参照_skill_run.py:742-747,当in_data.omit_inline_content为真时对files及选出的primary_output置空content,并补充该场景的回归测试。