taskflow-agent 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/PKG-INFO +1 -1
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/pyproject.toml +1 -1
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/src/web.py +65 -3
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/static/index.html +125 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/.gitignore +0 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/LICENSE +0 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/Makefile +0 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/README.md +0 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/src/__init__.py +0 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/src/db.py +0 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/src/importer.py +0 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/src/models.py +0 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/src/repos.py +0 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/src/server.py +0 -0
- {taskflow_agent-0.3.0 → taskflow_agent-0.4.0}/src/workflows.py +0 -0
|
@@ -1241,7 +1241,6 @@ MUTATING_TOOL_NAMES = {
|
|
|
1241
1241
|
_SUB_AGENT_EXCLUDED_TOOLS: set[str] = {
|
|
1242
1242
|
"run_agent",
|
|
1243
1243
|
"run_shell",
|
|
1244
|
-
"load_tools",
|
|
1245
1244
|
"tf_memory_read",
|
|
1246
1245
|
"tf_memory_update",
|
|
1247
1246
|
} | MUTATING_TOOL_NAMES
|
|
@@ -1261,7 +1260,7 @@ _SUB_AGENT_MAX_TURNS = 15
|
|
|
1261
1260
|
_SUB_AGENT_TIMEOUT = int(os.getenv("SUB_AGENT_TIMEOUT", "300"))
|
|
1262
1261
|
_SUB_AGENT_CLIENT_TIMEOUT = 90
|
|
1263
1262
|
_SUB_AGENT_MAX_TOKENS = 32_000
|
|
1264
|
-
_SUB_AGENT_DEFAULT_MODEL = "claude-
|
|
1263
|
+
_SUB_AGENT_DEFAULT_MODEL = "claude-haiku-4-5-20251001"
|
|
1265
1264
|
|
|
1266
1265
|
mcp_manager = McpClientManager(
|
|
1267
1266
|
allowed_servers=None,
|
|
@@ -1819,6 +1818,7 @@ def make_run_agent_handler(
|
|
|
1819
1818
|
runner_ref: list[Any],
|
|
1820
1819
|
local_tool_handlers: dict[str, Any],
|
|
1821
1820
|
mcp_manager: McpClientManager,
|
|
1821
|
+
event_log: EventLog,
|
|
1822
1822
|
):
|
|
1823
1823
|
async def _handle_run_agent(
|
|
1824
1824
|
tool_input: dict,
|
|
@@ -1834,7 +1834,7 @@ def make_run_agent_handler(
|
|
|
1834
1834
|
return None, {"code": "invalid_input", "message": "task is required"}
|
|
1835
1835
|
|
|
1836
1836
|
raw_model = tool_input.get("model")
|
|
1837
|
-
allowed = {"claude-sonnet-4-6", "claude-opus-4-6"}
|
|
1837
|
+
allowed = {"claude-haiku-4-5-20251001", "claude-sonnet-4-6", "claude-opus-4-6"}
|
|
1838
1838
|
if raw_model is not None and raw_model not in allowed:
|
|
1839
1839
|
return None, {"code": "invalid_input", "message": f"Invalid model: {raw_model}"}
|
|
1840
1840
|
|
|
@@ -1855,6 +1855,43 @@ def make_run_agent_handler(
|
|
|
1855
1855
|
needs_approval=lambda _: False,
|
|
1856
1856
|
)
|
|
1857
1857
|
|
|
1858
|
+
def on_sub_event(event: dict[str, Any], session_id: str) -> None:
|
|
1859
|
+
del session_id
|
|
1860
|
+
event_type = event.get("type")
|
|
1861
|
+
if event_type == "tool_call_start":
|
|
1862
|
+
event_log.append(
|
|
1863
|
+
{
|
|
1864
|
+
"type": "sub_agent_progress",
|
|
1865
|
+
"call_index": call_index,
|
|
1866
|
+
"sub_event": "tool_start",
|
|
1867
|
+
"tool_name": event.get("tool_name", ""),
|
|
1868
|
+
"sub_tool_call_id": event.get("tool_call_id", ""),
|
|
1869
|
+
}
|
|
1870
|
+
)
|
|
1871
|
+
return
|
|
1872
|
+
if event_type == "tool_call_complete":
|
|
1873
|
+
event_log.append(
|
|
1874
|
+
{
|
|
1875
|
+
"type": "sub_agent_progress",
|
|
1876
|
+
"call_index": call_index,
|
|
1877
|
+
"sub_event": "tool_done",
|
|
1878
|
+
"tool_name": event.get("tool_name", ""),
|
|
1879
|
+
"sub_tool_call_id": event.get("tool_call_id", ""),
|
|
1880
|
+
"duration_ms": event.get("duration_ms"),
|
|
1881
|
+
"error": bool(event.get("error")),
|
|
1882
|
+
}
|
|
1883
|
+
)
|
|
1884
|
+
return
|
|
1885
|
+
if event_type == "error":
|
|
1886
|
+
event_log.append(
|
|
1887
|
+
{
|
|
1888
|
+
"type": "sub_agent_progress",
|
|
1889
|
+
"call_index": call_index,
|
|
1890
|
+
"sub_event": "error",
|
|
1891
|
+
"error_message": str(event.get("error", "Sub-agent error")),
|
|
1892
|
+
}
|
|
1893
|
+
)
|
|
1894
|
+
|
|
1858
1895
|
result, error = await runner.spawn_sub_agent(
|
|
1859
1896
|
task,
|
|
1860
1897
|
model=effective_model,
|
|
@@ -1866,6 +1903,7 @@ def make_run_agent_handler(
|
|
|
1866
1903
|
client_timeout=_SUB_AGENT_CLIENT_TIMEOUT,
|
|
1867
1904
|
max_tokens=_SUB_AGENT_MAX_TOKENS,
|
|
1868
1905
|
call_index=call_index,
|
|
1906
|
+
on_sub_event=on_sub_event,
|
|
1869
1907
|
)
|
|
1870
1908
|
return result, error
|
|
1871
1909
|
|
|
@@ -2248,6 +2286,7 @@ async def sse_generator(
|
|
|
2248
2286
|
runner_task: asyncio.Task[None],
|
|
2249
2287
|
request_id: str,
|
|
2250
2288
|
):
|
|
2289
|
+
run_agent_map: dict[int, str] = {}
|
|
2251
2290
|
tool_inputs: dict[str, dict[str, Any]] = {}
|
|
2252
2291
|
tool_calls: dict[str, dict[str, Any]] = {}
|
|
2253
2292
|
turn_tools: list[dict[str, Any]] = []
|
|
@@ -2292,6 +2331,10 @@ async def sse_generator(
|
|
|
2292
2331
|
}
|
|
2293
2332
|
tool_calls[tool_call_id] = tool_entry
|
|
2294
2333
|
turn_tools.append(tool_entry)
|
|
2334
|
+
if tool_name == "run_agent":
|
|
2335
|
+
call_index = event.get("call_index")
|
|
2336
|
+
if call_index is not None:
|
|
2337
|
+
run_agent_map[call_index] = tool_call_id
|
|
2295
2338
|
yield _sse(
|
|
2296
2339
|
{
|
|
2297
2340
|
"type": "tool_call_start",
|
|
@@ -2334,6 +2377,24 @@ async def sse_generator(
|
|
|
2334
2377
|
pending_mutations.append(mutation)
|
|
2335
2378
|
continue
|
|
2336
2379
|
|
|
2380
|
+
if event_type == "sub_agent_progress":
|
|
2381
|
+
call_index = event.get("call_index")
|
|
2382
|
+
parent_tool_call_id = run_agent_map.get(call_index) if call_index is not None else None
|
|
2383
|
+
if parent_tool_call_id:
|
|
2384
|
+
yield _sse(
|
|
2385
|
+
{
|
|
2386
|
+
"type": "sub_agent_progress",
|
|
2387
|
+
"parent_tool_call_id": parent_tool_call_id,
|
|
2388
|
+
"sub_event": event.get("sub_event"),
|
|
2389
|
+
"tool_name": event.get("tool_name", ""),
|
|
2390
|
+
"sub_tool_call_id": event.get("sub_tool_call_id", ""),
|
|
2391
|
+
"duration_ms": event.get("duration_ms"),
|
|
2392
|
+
"error": event.get("error"),
|
|
2393
|
+
"error_message": event.get("error_message"),
|
|
2394
|
+
}
|
|
2395
|
+
)
|
|
2396
|
+
continue
|
|
2397
|
+
|
|
2337
2398
|
if event_type == "stream_complete":
|
|
2338
2399
|
assistant_text = "".join(assistant_chunks).strip()
|
|
2339
2400
|
full_content = assistant_text + _build_tool_summary(turn_tools)
|
|
@@ -2938,6 +2999,7 @@ async def chat(body: ChatRequest, request: Request):
|
|
|
2938
2999
|
runner_ref,
|
|
2939
3000
|
request_handlers,
|
|
2940
3001
|
mcp_manager,
|
|
3002
|
+
event_log,
|
|
2941
3003
|
)
|
|
2942
3004
|
dispatcher = ToolDispatcher(
|
|
2943
3005
|
mcp_client=mcp_manager,
|
|
@@ -1218,6 +1218,22 @@ button { cursor: pointer; }
|
|
|
1218
1218
|
white-space: pre-wrap;
|
|
1219
1219
|
word-break: break-word;
|
|
1220
1220
|
}
|
|
1221
|
+
.chat-sub-progress {
|
|
1222
|
+
padding: 4px 12px 8px;
|
|
1223
|
+
font-family: var(--font-mono);
|
|
1224
|
+
font-size: 10px;
|
|
1225
|
+
line-height: 1.8;
|
|
1226
|
+
color: var(--text-muted);
|
|
1227
|
+
}
|
|
1228
|
+
.chat-sub-progress-line {
|
|
1229
|
+
display: flex;
|
|
1230
|
+
align-items: center;
|
|
1231
|
+
gap: 4px;
|
|
1232
|
+
}
|
|
1233
|
+
.chat-sub-progress-line .marker { color: var(--accent); }
|
|
1234
|
+
.chat-sub-progress-line .marker.done { color: var(--green); }
|
|
1235
|
+
.chat-sub-progress-line .marker.err { color: var(--red); }
|
|
1236
|
+
.chat-sub-progress-line .dur { opacity: 0.6; }
|
|
1221
1237
|
|
|
1222
1238
|
.chat-compose {
|
|
1223
1239
|
border-top: 1px solid var(--border-subtle);
|
|
@@ -2744,6 +2760,102 @@ function completeToolCard(toolCallId, toolName, result, error) {
|
|
|
2744
2760
|
scrollChatToBottom()
|
|
2745
2761
|
}
|
|
2746
2762
|
|
|
2763
|
+
function _ensureSubProgressContainer(card) {
|
|
2764
|
+
let container = card.querySelector('.chat-sub-progress')
|
|
2765
|
+
if (container) return container
|
|
2766
|
+
container = document.createElement('div')
|
|
2767
|
+
container.className = 'chat-sub-progress'
|
|
2768
|
+
const bodyEl = card.querySelector('.chat-tool-body')
|
|
2769
|
+
if (bodyEl) {
|
|
2770
|
+
card.insertBefore(container, bodyEl)
|
|
2771
|
+
} else {
|
|
2772
|
+
card.appendChild(container)
|
|
2773
|
+
}
|
|
2774
|
+
return container
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
function _findSubProgressLine(container, subToolCallId) {
|
|
2778
|
+
if (!subToolCallId) return null
|
|
2779
|
+
return Array.from(container.querySelectorAll('.chat-sub-progress-line'))
|
|
2780
|
+
.find(line => line.dataset.subCallId === subToolCallId) || null
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2783
|
+
function _formatSubProgressDuration(durationMs) {
|
|
2784
|
+
const ms = Number(durationMs)
|
|
2785
|
+
if (!Number.isFinite(ms) || ms < 0) return ''
|
|
2786
|
+
return `${(ms / 1000).toFixed(1)}s`
|
|
2787
|
+
}
|
|
2788
|
+
|
|
2789
|
+
function _renderSubProgressLine(line, markerText, markerClass, text, durationText = '') {
|
|
2790
|
+
line.textContent = ''
|
|
2791
|
+
|
|
2792
|
+
const markerEl = document.createElement('span')
|
|
2793
|
+
markerEl.className = markerClass
|
|
2794
|
+
markerEl.textContent = markerText
|
|
2795
|
+
line.appendChild(markerEl)
|
|
2796
|
+
|
|
2797
|
+
const textEl = document.createElement('span')
|
|
2798
|
+
textEl.textContent = text || 'tool'
|
|
2799
|
+
line.appendChild(textEl)
|
|
2800
|
+
|
|
2801
|
+
if (durationText) {
|
|
2802
|
+
const durationEl = document.createElement('span')
|
|
2803
|
+
durationEl.className = 'dur'
|
|
2804
|
+
durationEl.textContent = durationText
|
|
2805
|
+
line.appendChild(durationEl)
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
function updateSubAgentProgress(parentToolCallId, subEvent, toolName, subToolCallId, durationMs, error, errorMessage) {
|
|
2810
|
+
const card = S.chat.toolCards.get(parentToolCallId)
|
|
2811
|
+
if (!card) return
|
|
2812
|
+
|
|
2813
|
+
const container = _ensureSubProgressContainer(card)
|
|
2814
|
+
const label = toolName || 'tool'
|
|
2815
|
+
|
|
2816
|
+
if (subEvent === 'tool_start') {
|
|
2817
|
+
if (!subToolCallId) return
|
|
2818
|
+
let line = _findSubProgressLine(container, subToolCallId)
|
|
2819
|
+
if (!line) {
|
|
2820
|
+
line = document.createElement('div')
|
|
2821
|
+
line.className = 'chat-sub-progress-line'
|
|
2822
|
+
line.dataset.subCallId = subToolCallId
|
|
2823
|
+
container.appendChild(line)
|
|
2824
|
+
}
|
|
2825
|
+
_renderSubProgressLine(line, '▸', 'marker', label)
|
|
2826
|
+
scrollChatToBottom()
|
|
2827
|
+
return
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
if (subEvent === 'tool_done') {
|
|
2831
|
+
if (!subToolCallId) return
|
|
2832
|
+
let line = _findSubProgressLine(container, subToolCallId)
|
|
2833
|
+
if (!line) {
|
|
2834
|
+
line = document.createElement('div')
|
|
2835
|
+
line.className = 'chat-sub-progress-line'
|
|
2836
|
+
line.dataset.subCallId = subToolCallId
|
|
2837
|
+
container.appendChild(line)
|
|
2838
|
+
}
|
|
2839
|
+
_renderSubProgressLine(
|
|
2840
|
+
line,
|
|
2841
|
+
error ? '✗' : '✓',
|
|
2842
|
+
error ? 'marker err' : 'marker done',
|
|
2843
|
+
label,
|
|
2844
|
+
_formatSubProgressDuration(durationMs),
|
|
2845
|
+
)
|
|
2846
|
+
scrollChatToBottom()
|
|
2847
|
+
return
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2850
|
+
if (subEvent === 'error') {
|
|
2851
|
+
const line = document.createElement('div')
|
|
2852
|
+
line.className = 'chat-sub-progress-line'
|
|
2853
|
+
_renderSubProgressLine(line, '✗', 'marker err', errorMessage || 'Sub-agent error')
|
|
2854
|
+
container.appendChild(line)
|
|
2855
|
+
scrollChatToBottom()
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
|
|
2747
2859
|
function formatToolPayload(value) {
|
|
2748
2860
|
if (value == null) return '{}'
|
|
2749
2861
|
let text = typeof value === 'string' ? value : JSON.stringify(value, null, 2)
|
|
@@ -3040,6 +3152,19 @@ async function handleChatEvent(event) {
|
|
|
3040
3152
|
return false
|
|
3041
3153
|
}
|
|
3042
3154
|
|
|
3155
|
+
if (event.type === 'sub_agent_progress') {
|
|
3156
|
+
updateSubAgentProgress(
|
|
3157
|
+
event.parent_tool_call_id,
|
|
3158
|
+
event.sub_event,
|
|
3159
|
+
event.tool_name,
|
|
3160
|
+
event.sub_tool_call_id,
|
|
3161
|
+
event.duration_ms,
|
|
3162
|
+
event.error,
|
|
3163
|
+
event.error_message,
|
|
3164
|
+
)
|
|
3165
|
+
return false
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3043
3168
|
if (event.type === 'taskflow_mutation') {
|
|
3044
3169
|
await handleChatMutation(event)
|
|
3045
3170
|
return false
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|