Skip to content

feat: simple react agent structure#103

Merged
blkdmr merged 1 commit into
pyfenn:mainfrom
DagaBhai:agent
May 19, 2026
Merged

feat: simple react agent structure#103
blkdmr merged 1 commit into
pyfenn:mainfrom
DagaBhai:agent

Conversation

@DagaBhai
Copy link
Copy Markdown
Contributor

@DagaBhai DagaBhai commented May 19, 2026

What does this PR do?

contributing to #99

adds a simple autoconfigure agent module

files added:

  • agent.py - Agent class which takes the yaml file and sets the shared dict with the llm
  • llm.py - Client lets the user add any llm they want with a customized function for the llm to call
  • tool.py - Scaffold of some of the basic tools (to be worked on)
  • node.py - based on the Node class which extends ThinkNode, ActNode, ObserveNode all 3 consists of 3 stages - [pre, exec, post]
  • ThinkNode - uses the LLM to decide what to do next
  • ActNode - executes tool calls
  • ObserveNode - records the result and feeds it back into the loop

Test

from fenn.agents.agent import Agent
from fenn.agents.llm import Client
from google import genai
import yaml

# load config to get model name
with open("agent.yaml") as f:
    config = yaml.safe_load(f)

gemini_client = genai.Client(api_key="")
model = config["llm"]["model"]  # ← from yaml

def my_fn(messages, **kwargs):
    system = next((m["content"] for m in messages if m["role"] == "system"), "")

    history = []
    for msg in messages:
        if msg["role"] == "system":
            continue
        history.append({
            "role": "user" if msg["role"] == "user" else "model",
            "parts": [{"text": msg["content"]}]
        })

    if system and history:
        history[0]["parts"][0]["text"] = f"{system}\n\n{history[0]['parts'][0]['text']}"

    response = gemini_client.models.generate_content(
        model=model,
        contents=history
    )
    return response.text

gpt = Client()
gpt.register(my_fn)

agent = Agent(config="agent.yaml", llm=gpt)
print(agent.run("What is 123 * 456?"))

Note

  • some llms need the model in the client init and some while calling so it may not read the model from the yaml file for example
  • openai
from openai import OpenAI

client = OpenAI(
    api_key="your-key"
)

response = client.chat.completions.create(
    model="gpt-4.1",
    messages=[
        {"role": "user", "content": "Hello"}
    ]
)
  • langchain_google_genai
from langchain_google_genai import ChatGoogleGenerativeAI

llm = ChatGoogleGenerativeAI(
    model="gemini-2.5-flash",
    google_api_key="YOUR_API_KEY"
)

response = llm.invoke("Hello")
print(response.content)

Copy link
Copy Markdown
Collaborator

@blkdmr blkdmr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thank you very much for your support!

@blkdmr blkdmr merged commit 31fb2c3 into pyfenn:main May 19, 2026
0 of 2 checks passed
@DagaBhai
Copy link
Copy Markdown
Contributor Author

Great work! Thank you very much for your support!

thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants