File size: 2,179 Bytes
2bf281f
 
a9561a2
2bf281f
37f9abc
 
 
9bcb18b
e9b9bfd
37f9abc
a9561a2
e9b9bfd
e9e55ec
a9561a2
37f9abc
a9561a2
9bcb18b
 
 
 
 
e9b9bfd
9bcb18b
e9b9bfd
 
 
 
 
 
 
9bcb18b
 
 
e9b9bfd
 
 
 
 
 
 
 
 
b40eaae
 
 
37f9abc
a9561a2
b40eaae
 
 
 
e9b9bfd
9bcb18b
e9b9bfd
b40eaae
 
 
a9561a2
37f9abc
 
e9e55ec
 
 
 
 
0450a06
e9e55ec
a9561a2
 
e9e55ec
9bcb18b
a9561a2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
from langchain_core.messages import AIMessage, HumanMessage

from multi_agent_sdlc.agents.coder.model import coder_llm
from multi_agent_sdlc.models import CoderStatus, CoderSummary
from multi_agent_sdlc.state import DevState


def coder_node(state: DevState) -> dict[str, object]:
    coder_messages = state["coder_messages"]

    if not coder_messages:
        raise ValueError("Coder conversation has not been initialized.")

    response = coder_llm.invoke(coder_messages)

    if response.tool_calls:
        submit_calls = [
            tool_call
            for tool_call in response.tool_calls
            if tool_call["name"] == "submit_coder_summary"
        ]

        if submit_calls:
            if len(response.tool_calls) != 1:
                return {
                    "coder_messages": [
                        response,
                        HumanMessage(
                            content=(
                                "`submit_coder_summary` must be called alone. "
                                "Complete any operational tool calls first, "
                                "then submit the Coder summary in a separate "
                                "response."
                            )
                        ),
                    ],
                }

            return _process_coder_summary_call(
                response,
            )

        return {
            "coder_messages": [response],
        }

    return {
        "coder_messages": [
            response,
            HumanMessage(
                content=(
                    "Invalid response. Return no explanatory text. "
                    "Call one or more approved Coder operational tools, "
                    "or call `submit_coder_summary` alone."
                )
            ),
        ],
    }


def _process_coder_summary_call(
    response: AIMessage,
) -> dict[str, object]:
    tool_call = response.tool_calls[0]

    coder_summary = CoderSummary.model_validate(tool_call["args"]["summary"])

    return {
        "coder_messages": [response],
        "current_coder_summary": coder_summary,
        "coder_status": CoderStatus.COMPLETED,
    }