Conversation
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
| obs.Progress = append(obs.Progress, types.Progress{ | ||
| ActionResult: res.Result, | ||
| }) | ||
| a.observer.Update(*obs) |
There was a problem hiding this comment.
Have lines like this been recreated in the new version?
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
There was a problem hiding this comment.
Pull Request Overview
This PR integrates the Cogito library to drive agent reasoning and tool execution, and removes the legacy “old” web UI in favor of the new React UI.
- Replace in-house planning/reasoning and MCP tool wrapping with Cogito-based execution and evaluation
- Remove legacy server-side templates and HTMX-based UI; simplify Fiber app initialization for React UI
- Add Cogito integration points (status callbacks, tool callbacks, MCP sessions); update knowledgebase summarization to use Cogito
Reviewed Changes
Copilot reviewed 34 out of 37 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| webui/routes.go | Removes old embedded views/public routes; keeps React UI assets served. |
| webui/old/... (multiple) | Deletes legacy HTML/CSS/JS views and assets. |
| webui/app.go | Drops HTMX/templates engine usage; simplifies Fiber initialization. |
| go.mod | Adds cogito dependency; updates Go version/toolchain; adjusts deps. |
| core/types/job.go | Removes nextAction/pastActions; adds cogito.Fragment field. |
| core/types/actions.go | Adds cogito wrapper to expose Actions as Cogito tools; removes Plannable from interface. |
| core/agent/templates.go | Simplifies templates to align with Cogito-driven flow. |
| core/agent/mcp.go | Stops generating Actions for MCP tools; keeps MCP client sessions for Cogito. |
| core/agent/knowledgebase.go | Uses Cogito LLM to summarize conversation. |
| core/agent/evaluation.go | Removes custom evaluation; Cogito now handles evaluation. |
| core/agent/agent.go | Major refactor to Cogito execution, planning, and callbacks; cleans old codepaths. |
| core/agent/actions.go | Removes custom decision/planning utilities; simplifies available actions. |
| core/action/* (several) | Removes obsolete actions (reply, reasoning, plan, intention, goal). |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| chosenAction := availableActions.Find(tc.Name) | ||
|
|
||
| var obs *types.Observable | ||
| if job.Obs != nil { | ||
| obs = a.observer.NewObservable() | ||
| obs.Name = "action" | ||
| obs.Icon = "bolt" | ||
| obs.ParentID = job.Obs.ID | ||
| obs.Creation = &types.Creation{ | ||
| FunctionDefinition: chosenAction.Definition().ToFunctionDefinition(), | ||
| FunctionParams: types.ActionParams(tc.Arguments), | ||
| } |
There was a problem hiding this comment.
Possible nil pointer dereference if chosenAction is nil (e.g., for MCP tools or tools not in availableActions). Guard chosenAction before accessing Definition() and before later uses (job.Callback, SetResult). If nil, skip FunctionDefinition, and either construct a minimal placeholder for observer/callback or branch handling for non-local tools.
| cont := job.Callback(types.ActionCurrentState{ | ||
| Job: job, | ||
| Action: chosenAction, | ||
| Params: types.ActionParams(tc.Arguments), | ||
| Reasoning: reasoning}) | ||
|
|
||
| if !cont { | ||
| job.Result.SetResult( | ||
| types.ActionState{ | ||
| ActionCurrentState: types.ActionCurrentState{ | ||
| Job: job, | ||
| Action: chosenAction, | ||
| Params: types.ActionParams(tc.Arguments), | ||
| Reasoning: reasoning, | ||
| }, | ||
| ActionResult: types.ActionResult{Result: "stopped by callback"}, | ||
| }) |
There was a problem hiding this comment.
Same nil dereference risk: chosenAction may be nil for MCP/external tools. Add a nil check and handle callback/result construction accordingly to avoid panics.
| toolToCall := fragment.Messages[len(fragment.Messages)-2].ToolCalls[0].Function.Name | ||
| switch toolToCall { | ||
| case action.StopActionName: | ||
| job.Result.Finish(nil) | ||
| return |
There was a problem hiding this comment.
Potential out-of-bounds access if fragment.Messages has fewer than 2 entries or if the assistant message has no ToolCalls. Guard lengths before indexing and verify ToolCalls is non-empty to avoid panics.
| toolToCall := fragment.Messages[len(fragment.Messages)-2].ToolCalls[0].Function.Name | |
| switch toolToCall { | |
| case action.StopActionName: | |
| job.Result.Finish(nil) | |
| return | |
| // Guard against out-of-bounds access | |
| if len(fragment.Messages) >= 2 { | |
| toolCalls := fragment.Messages[len(fragment.Messages)-2].ToolCalls | |
| if len(toolCalls) > 0 { | |
| toolToCall := toolCalls[0].Function.Name | |
| switch toolToCall { | |
| case action.StopActionName: | |
| job.Result.Finish(nil) | |
| return | |
| } | |
| } |
| fragment := cogito.NewEmptyFragment().AddStartMessage("user", "Summarize the conversation below, keep the highlights as a bullet list:\n"+Messages(conv).String()) | ||
| fragment, err := a.llm.Ask(a.context.Context, fragment) | ||
| if err != nil { | ||
| xlog.Error("Error summarizing conversation", "error", err) |
There was a problem hiding this comment.
If Ask returns an error, fragment might be nil or incomplete; calling fragment.LastMessage() can panic. Return early on error (or ensure fragment is valid) before accessing LastMessage.
| xlog.Error("Error summarizing conversation", "error", err) | |
| xlog.Error("Error summarizing conversation", "error", err) | |
| return |
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
| }, | ||
| }, | ||
| }, | ||
| }) |
There was a problem hiding this comment.
This looks quite suspicious. It seems like this is creating and completing an observable for a decision step upon receiving the result of that decision. Really it should be created when the first request is submitted to the LLM as part of the decision process.
There was a problem hiding this comment.
mmm you are right, I think I've did some mistake when porting the logic, can you check again?
There was a problem hiding this comment.
I think you need to create the observable when making the request to the LLM and close it when you get the result. I don't know if you have the callbacks for this in Cogito? It's the kind of thing only needed for observability.
Presently the user will just see the decision appear after completion with the whole of conv as the query to the LLM which may or may not be what is actually passed to the LLM.
There was a problem hiding this comment.
there is WithStatusCallback which is called with the reasoning, and WithToolCallResultCallback with the tool call result. WithToolCallBack instead accepts a func with a boolean, which if false will stop the tool execution and the agent.
I think I've misread a bit things initially, but now I've moved the update and the closing of the observable to use the callbacks above
There was a problem hiding this comment.
Possibly there should be WithReasoningCallback and WithReasoningResultCallback?
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
d0887fd to
38dbaa7
Compare
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
8c2cd2e to
e7ba8b5
Compare
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
|
tests are passing and manual tests looks good - the only issues I have now are with the observables @richiejp - looks like these are stuck in progress, but can't really pinpoint what's wrong |
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
06e4d0d to
cdabab8
Compare
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Blocked by: mudler/cogito#9
Depends on : mudler/cogito#13
some TODO: