-
Notifications
You must be signed in to change notification settings - Fork 240
Non-graph API #560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non-graph API #560
Conversation
Qodana for JVM852 new problems were found
@@ Code coverage @@
+ 67% total lines covered
11264 lines analyzed, 7548 lines covered
# Calculated according to the filters of your coverage tool☁️ View the detailed Qodana report Detected 205 dependenciesThird-party software listThis page lists the third-party software dependencies used in koog-agents
Contact Qodana teamContact us at qodana-support@jetbrains.com
|
33882ba to
26cc791
Compare
|
@sdubov @Ololoshechkin @EugeneTheDev This PR still in progress and I would like to finish it when I'll back. But it's mostly ready implementation-wise, so it's already up to top-level review (GraphAgent/Non-Graph agent separation, pipeline separation, environment separation, etc). |
26cc791 to
e036de0
Compare
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/ActAIAgent.kt
Show resolved
Hide resolved
e036de0 to
2dd6fab
Compare
e07f8df to
23e21a5
Compare
| * @see [AIAgent] class | ||
| */ | ||
| @OptIn(ExperimentalUuidApi::class) | ||
| public inline fun <reified Input, reified Output> AIAgent( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, as it's an external function it would be even harder to instantiate from Java.
Maybe let's keep everything inside AIAgent and make them separate constructors (and in Java they would be factory methods) ?
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/ActAIAgent.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentLoopStrategy.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/ActAIAgent.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Rizzen, I like the API in general. Looks really cool!
I have some general concerns about the changes in features. Currently, all features need to implement both interfaces and register handlers twice. Even more, each feature should have a duplicated set of handlers if you what to use it in both graph and non-graph agents. This might be a bit overcomplicated.
I would propose to use a bit different approach if you like it. In scope of events, the difference between graph and non-graph agents are in the events that agent execution triggers. For graph agents we have all these before/after node, etc. For non-graph API you have the same, but no node-related events. So, I would expect that if you install the same feature in a non-graph agent you will receive all events registered inside a feature, except nodes-related (as they are not fired on agent execution).
Taking this, you can leave current implementation for all feature as it is right now without any change. The same is true for Agent pipeline. You keep it the same with ability to register all events (graph and non-graph). So, feature can also register them all. On a AIAgentPipeline side you can add some logic (it can be a flag in constructor or use some other checks for context type for each handler) that will define what type of agent is that - graph or non-graph. Based on flag you can ignore some handlers that are not needed. This approach make Feature development as simple as it is right now (without duplicate handlers registration), but delegate this graph/non-graph responsibility to the pipeline class (which I think much easier to control).
Please let me know what do you think about proposed solution.
...s/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/entity/AIAgentGraphStrategy.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/entity/AIAgentStrategy.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/ActAIAgent.kt
Outdated
Show resolved
Hide resolved
agents/agents-ext/src/commonMain/kotlin/ai/koog/agents/ext/agent/AIAgentSubgraphExt.kt
Outdated
Show resolved
Hide resolved
agents/agents-ext/src/commonMain/kotlin/ai/koog/agents/ext/agent/SubgraphWithRetry.kt
Outdated
Show resolved
Hide resolved
...t-handler/src/commonMain/kotlin/ai/koog/agents/features/eventHandler/feature/EventHandler.kt
Show resolved
Hide resolved
prompt/prompt-llm/src/commonMain/kotlin/ai/koog/prompt/llm/LLModel.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/feature/AIAgentGraphPipeline.kt
Show resolved
Hide resolved
|
@sdubov I don't really like the idea of "universal registration" you suggest. The idea behind the current design is clear separation of concerns. When you develop a feature for either a graph or non-graph agent, you only deal with the relevant handlers. This keeps the mental model simple — you know exactly which events your feature can react to. With a universal interface, you end up in situations like: “Okay, I have something called This also opens the door to other confusing scenarios. For example, it would technically allow installing something like the From an implementation perspective, this would also require the non-graph agent to maintain a graph-like pipeline to satisfy all those extra handlers, even if they’re never actually used. That adds unnecessary complexity and coupling in places where it doesn’t belong. The current design avoids these problems by using clear, explicit interfaces: If you’re writing a The type system enforces compatibility — you simply cannot install a non-graph feature into a graph agent or vice versa. This makes incorrect usage impossible at compile time, rather than a silent runtime no-op. This makes the system much more predictable and maintainable. A developer always knows exactly what events are available, what will trigger, and what won’t. It also keeps the boundaries between graph and non-graph agents crisp, without forcing one to emulate the internals of the other just to support a universal abstraction. Yes, it requires to impement two |
|
@Rizzen, I fully agree with your points and concerns. I think there are pros and cons in both approaches. It's up to you, for sure, to estimate which one would be better for an end-user perspective. Let me clarify some points from my suggestion (as I found that I miss-format the original message) and I have a feeling that the idea might be not clear from the initial description:
I would not expect the feature is fully ignored. My suggestion was to ignore a graph-specific events only, e.g. if you have If you install the same feature inside a non-graph-agent, you should get everything except graph-specific events (which are not fired in a non-graph mode) as expected: I think it might be quite clear for a user that everything graph-specific will not work in non-graph-agent scenarios (it is actually already works the same way with your approach, but you explicitly need to write extra code in the feature for that). In the approach that you use, you make every feature development more complicated. You need to be familiar with non-graph option in koog. Otherwise, it also might be a surprise, when you cannot install an existing feature when you run non-graph agent. A user need to be aware that they should implement both interfaces to make sure feature works for both of them, and it is not obvious from my vision. |
|
I think the type system should indicate whether a feature was developed with an awareness of non-graph and/or graph scenarios. If there is a lot of overlap between them, then the overlap could be another candidate for indicating an awareness of via type system. I reckon it probably makes sense to have them separate before identifying that overlap, unless it's very clear already |
|
@sdubov Thank you for clarification, I believe I got your suggestion right. and examples are exactly what I meant by "silently ignoring" events. In case of tracing feature it might be still look pretty logical, because it still traces most events for both agents. But with Persistency, for example, it would be just working feature in the case of graph agent and completely no-op feature in the case of non-graph, while still allowing to install it to non-graph agent. So when we were designing that feature - we were aiming to clearly separate Graph and Non-Graph agents - we have different contexts, different pipelines and different features, preventing to install wrong features to wrong agents on compilation level to avoid strange behaviour and confusion from users. From the feature developer perspective - if you're one, you are aware of concepts like graph agent, non-graph agent and even graph elements like nodes etc. We can do that with additional documentation on feature development. |
|
Just a note to say that the current persistency feature stores not only the current graph node but also the history and the agent state. I would hope that the persistency feature would allow for explicit checkpoint creation/recall from a programatic agent. If it's necessary to decouple the addition of the current graph node to the checkpoint, through an extension point, then it's the way to go IMO. |
00751b5 to
7a84501
Compare
b30384d to
9585e69
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some outdated naming left in a codebase. Other than that, I think it can go to the branch from my vision. Thank you!
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentFunctionalStrategy.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/AIAgentFunctionalStrategy.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/FunctionalAIAgent.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/GraphAIAgent.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonTest/kotlin/ai/koog/agents/core/agent/ActAgentTests.kt
Outdated
Show resolved
Hide resolved
agents/agents-ext/src/commonMain/kotlin/ai/koog/agents/ext/agent/AIAgentSubgraphExt.kt
Outdated
Show resolved
Hide resolved
agents/agents-ext/src/commonMain/kotlin/ai/koog/agents/ext/agent/SubgraphWithRetry.kt
Outdated
Show resolved
Hide resolved
agents/agents-ext/src/commonTest/kotlin/ai/koog/agents/ext/agent/SubgraphWithRetryTest.kt
Outdated
Show resolved
Hide resolved
|
Let's make follow-up cosmetic changes in the future PRs :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All major comments are fixed. There are some other places with outdated comments and KDoc that needs to be updated as well. I've added several places that need to be fixed. @Rizzen you can just search for "loop" or "actAgent" text and fix it here or later. Other that that, LGTM!
examples/src/main/kotlin/ai/koog/agents/example/funApi/FunAgentExample.kt
Outdated
Show resolved
Hide resolved
examples/src/main/kotlin/ai/koog/agents/example/funApi/FunAgentWithTools.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/FunctionalAIAgent.kt
Outdated
Show resolved
Hide resolved
examples/src/main/kotlin/ai/koog/agents/example/chat/FunctionalAgentChat.kt
Outdated
Show resolved
Hide resolved
agents/agents-core/src/commonMain/kotlin/ai/koog/agents/core/agent/FunctionalAIAgent.kt
Outdated
Show resolved
Hide resolved
Qodana for JVM853 new problems were found
@@ Code coverage @@
+ 66% total lines covered
11276 lines analyzed, 7544 lines covered
# Calculated according to the filters of your coverage tool☁️ View the detailed Qodana report Detected 205 dependenciesThird-party software listThis page lists the third-party software dependencies used in koog-agents
Contact Qodana teamContact us at qodana-support@jetbrains.com
|
This PR introduces new kind of agents API - ActAgent, allowing users to create simpler agents without working with graphs. --- #### Type of the change - [x] New feature - [ ] Bug fix - [ ] Documentation fix - [ ] Tests improvement - [ ] Refactoring #### Checklist for all pull requests - [ ] The pull request has a description of the proposed change - [ ] I read the [Contributing Guidelines](https://github.com/JetBrains/koog/blob/main/CONTRIBUTING.md) before opening the pull request - [ ] The pull request uses **`develop`** as the base branch - [ ] Tests for the changes have been added - [ ] All new and existing tests passed ##### Additional steps for pull requests adding a new feature - [ ] An issue describing the proposed change exists - [ ] The pull request includes a link to the issue - [ ] The change was discussed and approved in the issue - [ ] Docs have been added / updated
This PR introduces new kind of agents API - ActAgent, allowing users to create simpler agents without working with graphs. --- #### Type of the change - [x] New feature - [ ] Bug fix - [ ] Documentation fix - [ ] Tests improvement - [ ] Refactoring #### Checklist for all pull requests - [ ] The pull request has a description of the proposed change - [ ] I read the [Contributing Guidelines](https://github.com/JetBrains/koog/blob/main/CONTRIBUTING.md) before opening the pull request - [ ] The pull request uses **`develop`** as the base branch - [ ] Tests for the changes have been added - [ ] All new and existing tests passed ##### Additional steps for pull requests adding a new feature - [ ] An issue describing the proposed change exists - [ ] The pull request includes a link to the issue - [ ] The change was discussed and approved in the issue - [ ] Docs have been added / updated
This PR introduces new kind of agents API - ActAgent, allowing users to create simpler agents without working with graphs.
Type of the change
Checklist for all pull requests
developas the base branchAdditional steps for pull requests adding a new feature