conductor-oss / conductor-oss/python-sdk

Framework-agent failures return `None` instead of the failed task's reason

オープン 初心者向け
#483 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
bug
主要言語
Python
スター
104
フォーク
42
平均マージ
2日 1時間
マージ済み PR(30日)
3

説明

**In short:** when a framework agent fails, the SDK prints `None` instead of the reason — even though the server recorded a perfectly good one. Every such failure costs a manual walk of the server API to diagnose.

**File:** `src/conductor/ai/agents/runtime/runtime.py`

## Symptom

```
$ CONDUCTOR_AGENT_LLM_MODEL=anthropic/claude-sonnet-4-6 python examples/agents/93_openai_runner_hello_world.py
Framework agent 'Assistant' execution FAILED
None
```

No reason, no task name, nothing actionable. Diagnosing it means walking the server API by hand:

```
curl -s localhost:8080/api/agent/executions?size=20
curl -s "localhost:8080/api/workflow/?includeTasks=true" # find FAILED tasks, read reasonForIncompletion
```

## Cause

`_run_framework()` reports:

```python
error=status.reason if raw_status in ("FAILED", "TERMINATED") else None
```

For these failures `status.reason` is empty, so the result is `None`.

The reason was available all along, at both levels of the execution:

- the **workflow's** own `reasonForIncompletion`:
```
Task 41830611-7c25-4d51-a36f-50e324e59239 failed with status: FAILED and reason:
'Task execution failed: OpenAI Responses API call failed: Responses API failed with status 401 ...'
```
- the failed **task's** `reasonForIncompletion` (`Assistant_llm`), carrying the same text.

There is also an existing helper that already does this. `_extract_failed_task_reason(wf)` reads the first FAILED task's `reasonForIncompletion` and returns `Task '' failed: `. It is called by `run()` (line ~2534) and `_run_by_name()` (line ~2623) — which is why **native**-agent failures report properly, e.g. `54_software_bug_assistant` prints:

```
ERROR: Task 'software_assistant_54_list_mcp_0' failed: Failed to list MCP tools ... HTTP 400
```

`_run_framework()` never calls it.

## Fix

When `status.reason` is empty, fall back to the workflow's `reasonForIncompletion`, or call `_extract_failed_task_reason` as `run()` does. Either is sufficient.

## Verify

Start the server without `OPENAI_API_KEY`, run `93` — it should name the failing task and its reason instead of printing `None`.

## Note — possible second gap, unconfirmed

`59_coding_agent` goes through `run()` yet also reported no reason, while its server-side SUB_WORKFLOW task did carry one (`Anthropic Messages API failed with status 404`). `_extract_failed_task_reason` only inspects the top-level workflow's tasks, so failures inside a sub-workflow may need the same treatment. Worth checking while fixing this.

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

Start in src/conductor/ai/agents/runtime/runtime.py at _run_framework(), then compare its failure reporting with _extract_failed_task_reason and the calls from run() and _run_by_name(). Run examples/agents/93_openai_runner_hello_world.py with the server lacking OPENAI_API_KEY; done means the framework-agent failure names the failed task and reports its reason instead of None.

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
backend
issue の種類
バグ
難易度
2/5
見積もり時間
1〜3時間
活発さ
静か
明瞭さ
明確に書かれている
初心者へのやさしさ
78/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。