Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: architecting-act
description: Designs Act and Cast architectures through dynamic questioning, outputting validated CLAUDE.md with mermaid diagrams. Covers resilience patterns (Saga/compensation, long-running threads with DeltaChannel, graceful drain checkpoints, node timeout boundaries) from langgraph v1.2+. Use when starting new Act project, adding cast, planning architecture, extracting sub-cast (10+ nodes), redesigning existing cast, or ask "design architecture", "plan cast", "redesign cast", "create CLAUDE.md".
version: "2026.05.26"
version: "2026.05.27"
author: Proact0
allowed-tools:
- Bash(uv run act cast *)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: developing-cast
description: Implements LangGraph cast components following systematic workflow (state, deps, nodes, conditions, graph). Use when implementing cast, building nodes/agents/tools, need LangGraph patterns (memory, retry, guardrails, vector stores, node timeouts, error handlers, DeltaChannel, graceful shutdown), or ask "implement cast", "build graph", "add node".
version: "2026.05.26"
version: "2026.05.27"
author: Proact0
allowed-tools:
- Bash(uv sync *)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ from typing_extensions import TypedDict
from langgraph.channels import DeltaChannel


# Bulk reducer: receives state + sequence of all writes from the current step
def list_reducer(state: list[Any], writes: Sequence[list[Any]]) -> list[Any]:
result = list(state)
# Bulk reducer: receives state + sequence of all writes from the current step.
# `state` may be `None` on the very first reconstruction — handle it defensively.
def list_reducer(state: list[Any] | None, writes: Sequence[list[Any]]) -> list[Any]:
result = list(state) if state is not None else []
for write in writes:
result.extend(write)
return result
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: developing-deepagent
description: Implements DeepAgent components using LangChain's deepagents SDK. Use when building deep agents with create_deep_agent, configuring backends/subagents/skills/memory/interpreter, need DeepAgent patterns (sandbox, HITL interrupts, long-term memory, subagent spawning, subagent structured output, QuickJS code interpreter with programmatic tool calling), or ask "implement deep agent", "add subagent", "configure backend", "add interpreter".
version: "2026.05.26"
version: "2026.05.27"
author: Proact0
allowed-tools:
- Bash(uv sync *)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: streaming-cast
description: Implements LangGraph v3 event streaming for graphs with subgraphs and agents. Use when adding streaming to runtime/API endpoint, need token streaming, custom stream projections, subagent streaming, or ask "add streaming", "stream tokens", "stream graph".
version: "2026.05.26"
version: "2026.05.27"
author: Proact0
allowed-tools:
- Read
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ async def event_generator(query: str, config: dict):
"event": "tool_result",
"data": {
"name": call.tool_name,
"content": str(call.output) if call.error is None else None,
# Pass the raw output — the outer json.dumps handles str/dict/list/None
# natively. Stringifying with str() would produce Python repr like
# "{'k': 'v'}" (single quotes = invalid JSON for the client to re-parse).
"content": call.output if call.error is None else None,
"error": str(call.error) if call.error else None,
},
})
Expand Down Expand Up @@ -158,7 +161,10 @@ async def handle_websocket_message(send_json, data: dict) -> None:
await send_json({
"type": "tool_result",
"name": call.tool_name,
"content": str(call.output) if call.error is None else None,
# Pass the raw output — send_json's underlying json.dumps handles
# str/dict/list/None natively. Stringifying with str() would produce
# Python repr like "{'k': 'v'}" (single quotes = invalid JSON).
"content": call.output if call.error is None else None,
"error": str(call.error) if call.error else None,
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ await asyncio.gather(coordinator_task(), subagent_task())

## Dispatch Pattern

Clean handler dispatch for multi-projection streams:
Clean handler dispatch for multi-projection streams. Each projection consumer is a wrapper coroutine that iterates its async source and dispatches per item; `asyncio.gather` runs the three consumers concurrently:

```python
import asyncio
Expand All @@ -144,13 +144,23 @@ async def dispatch_subagent(subagent):
async for token in message.text:
await send({"type": "token", "content": token, "source": subagent.name})

await asyncio.gather(
*(dispatch_message(m) async for m in stream.messages),
*(dispatch_tool_call(c) async for c in stream.tool_calls),
*(dispatch_subagent(s) async for s in stream.subagents),
)
async def consume_messages():
async for message in stream.messages:
await dispatch_message(message)

async def consume_tool_calls():
async for call in stream.tool_calls:
await dispatch_tool_call(call)

async def consume_subagents():
async for subagent in stream.subagents:
await dispatch_subagent(subagent)

await asyncio.gather(consume_messages(), consume_tool_calls(), consume_subagents())
```

> **Why not `*(dispatch_x(x) async for x in stream.x)`?** Async generator expressions cannot be unpacked with `*` (raises `TypeError: 'async_generator' object is not iterable`). Wrapping each projection consumer in its own coroutine preserves streaming semantics: each handler dispatches items as they arrive, instead of buffering the entire stream before `gather` starts.

---

## Performance
Expand Down
Loading