PoC: CAP aligned API and data model - #50
Draft
BobdenOs wants to merge 2 commits into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
API proposal
LLM
At the core of the
Agentstory is theLLMprovider. The easier it is to interact with theLLMprovider the simpler the rest of the implementation becomes. Therefor I focused on keeping theLLMServiceAPI as straight forward as it really is. We have to send anarrayofMessagesto theLLMprovider in a provider specific structure. Therefor theLLMServiceaccepts anarrayofMessages. Additionally you might not really care about the details and just want to get a prompt answered. For that use case it is also possible to justsendyour prompt to theLLMService. Behind the scenes the prompt will be put into an object and wrapped into thearray.Agent
For the majority of the time people will only interact with
@agentand be satisfied with only doingAGENT.mdandSKILL.mdsetups, but for CAP itself and for more complex agent configurations it will be required to control in more detail what happens around theAgent. Therefor theAgentServicecan be extended and used as the basis of anyCAPservice to provide a fully customizedAgentenvironment. Like defining their own truetoolsas allactionscurrently will be proxied through the defaultactiontool. As it is becoming a standard to grouptools.The fully custom
toolsrequire onlyCAPknowledge as theCAPtypes are automatically translated to the properjson_schemaor whatever theLLMprovider requires fortooldefinitions their input and output types. Additionally the type conversion enforces the same requirements thatcds.assertdoes by default as long as it is possible to express it in theLLMproviders theirtoolschema definition.Data Model
As the
LLMproviders have a hard limitation to what can go to their endpoints we know that everything that we will ever be sending to their endpoints arearrays. So while the exact contents of thearraywill differ between theLLMproviders it comes down to a simple constructMessages.Additionally as all the
Messagesare inherently part of aSessionorConversation. There is no real need to have a secondary persistence to track whatSessions we have available to us. Therefor TheSessionsentity was turned into a view.Harness
Probably the most important API for customization is the actual
harness. As this allows for clever tricks for truly engineering thecontext. This is often calledworkflowswhere the harness takes on certain responsibilities that theLLMwould require extra round trips. Additionally theLLMhas the chance that it will not use thetoolcorrectly and derail in trying to debug how to call thetool.Some examples of what the
harnessmight take over:llmservice)llmservice orRegExp🤷)Additionally it is possible to use the
harnessto createsessionsprogrammatically. Which enables future features like even more sub agents. Handing over specifictools,skillsorsystemprompts.The
sessionis aDuplexstream, because theLLMproviders are limited to having a linear array ofcontext. All implementation on top are effectively justchatsand as everyone knows that has written an single workingchatprogram. They are all simply a by directionalsocketwhich is also just aDuplexstream.As the
sessionis just anotherstream. All theMessageprocessing is done through apipeline. Which allows all the complex logic to be split into their own individual functions. As an example lets implement arate limit. That will prevent theLLMfrom sending more then100messages or call more then10tools.Or if someone wants to disable
reasoningfrom going further through the stream.A2A
It is just a protocol adapter now that all the required functionalities have stable APIs.
Agent Flow
It is important to understand the primary difference between the
LLMServiceand theAgentServiceis that theAgentSessionpersists the session context to theDatabaseService. Therefor it is required for every iteration to send the whole session context to theLLMService. To enable theCAPservice to do this for many sessions in parallel the whole context is never loaded into memory. Instead theDatabaseServiceis queried tostreamtheMessagesdirectly to theLLMService. This means that no matter how many sessions or messages there are in any given session theCAPservice can process them. Additionally all the responses from theLLMServiceare streamed back into theDatabaseServiceto ensure that theLargeStringcontents of the responses never accumelate in the application memory. This also applies to all tool calls who respond withstreamresponses.The following diagram describes the flow of sending a
promptto anAgentSession. Where the first response of theLLMServiceis atool_callwhich will trigger another cycle in theAgentSession. For theLLMServiceto respond with the final result for theprompt.The
Messagesinside theAgentSessionlook as follows. Depending on the type of messages theAgentSessionwill eitherstart/pause/resume. Every time theAgentSessioneitherstartsorresumesthe whole session context is generated and directly streamed into theLLMService. Therefor as moreMessagesare stored into theDatabaseServicethe session context is automatically extended. Keeping theAgentSessionimplementation itself stateless. This also ensures that when anA2Atask request is received by any application instance it is able to directly interact with theDatabaseServiceto eithercheck/cancel/listthe tasks. Where as alangchainorpiimplementation would require theA2Arequest to hit the exact application instance that happens to be processing the target task.