18 Commits

Author SHA1 Message Date
Ettore Di Giacinto 42271c7e1a re-inforce to not use tools if maxIterations is reached
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-03-13 17:02:02 +00:00
LocalAI [bot] 37b69f1aec feat: add automatic conversation compaction based on token threshold (#41)
* feat: add automatic conversation compaction based on token threshold

This commit adds automatic conversation compaction to prevent context overflow
during long-running tool execution sessions.

Key changes:
- Added LLMUsage struct to track token usage from LLM responses
- Modified LLM interface to return token usage alongside Fragment
- Added WithCompactionThreshold option to set token count threshold
- Added WithCompactionKeepMessages option to configure recent messages to keep
- Added compaction logic in ExecuteTools after LLM calls
- Added helper functions: compactFragment, checkAndCompact, estimateTokens
- Added PromptConversationCompaction for generating conversation summaries
- Updated OpenAI and LocalAI clients to return token usage
- Updated mock client for testing

When compactionThreshold is set (> 0), the conversation will be automatically
compacted when estimated token count exceeds the threshold. The compaction
generates a summary of the conversation history using an LLM call while
preserving recent messages.

Signed-off-by: Autonomous Coding Agent <agent@autonomous>

* fix: use actual usage tokens from LLM response for compaction

- Store LastUsage in Status struct from LLM responses
- checkAndCompact now uses actual TotalTokens from LLM response
- Removed estimateTokens function (no longer needed)
- Fallback estimate only used on first iteration when no usage data available

* fix: capture usage tokens after sink state LLM call for compaction

The sink state handling was not capturing usage tokens from the LLM response,
which meant the compaction check would use the rough estimate instead of
actual usage tokens. This change ensures LastUsage is stored after the
llm.Ask call in the hasSinkState block, allowing proper token-based compaction.

* fix: move compaction check to beginning of tool loop

- Removed compaction check after max iterations (not needed)
- Removed compaction check after sink state (not needed)
- Added compaction check at beginning of tool loop (after totalIterations++)
- Uses actual usage tokens from LLM response

* fix: update Ask to return usage tokens from LocalAIClient

* fix: set LastUsage in Ask function return fragment

This addresses reviewer feedback that Ask() should automatically update
the Fragment's LastUsage, not have callers do it. The OpenAIClient and
LocalAIClient Ask functions now set Status.LastUsage before returning.

* refactor: Ask() updates Fragment.Status.LastUsage directly

Instead of returning LLMUsage from Ask(), the LLM clients now update
the Fragment's Status.LastUsage directly. This simplifies the interface
and ensures usage is always tracked in the fragment.

Changes:
- LLM.Ask() now returns (Fragment, error) instead of (Fragment, LLMUsage, error)
- Clients (openai_client.go, localai_client.go) set LastUsage on the returned fragment
- Mock client also updated to set usage in Status
- All callers updated to use new 2-value return signature

This addresses reviewer feedback on PR #41.

* Apply suggestion from @mudler

* Apply suggestion from @mudler

* Apply suggestion from @mudler

* Apply suggestion from @mudler

* Apply suggestions from code review

* Apply suggestion from @mudler

* test: add mocked tests for compaction functionality

- Add DefaultPrompts() function to prompt package for tests
- Export CompactFragment and CheckAndCompact functions for testing
- Add comprehensive unit tests for compaction logic using mocks
- Remove duplicate Ginkgo compaction tests that have import issues

* test: add compaction tests to tools_test.go suite

Add Ginkgo tests for compaction functionality within the existing
tools_test.go suite. Tests cover:
- No compaction when threshold is disabled (0)
- No compaction when tokens below threshold
- Compaction when token threshold is exceeded
- Parent fragment preservation after compaction
- Status preservation after compaction
- Rough token estimate usage when LastUsage is not set

This addresses the reviewer's request to keep tests consistent with
other ginkgo tests in tools_test.go.

* chore: run go fmt and add compaction docs to README

* Make CompactFragment and CheckAndCompact private

Per reviewer request:
- Changed CompactFragment to compactFragment (private)
- Changed CheckAndCompact to checkAndCompact (private)
- Removed tools_compaction_test.go (tests should be in tools_test.go)

The compaction functionality is still available internally via
ExecuteTools with WithCompactionThreshold option.

* chore: remove exported functions from README, keep them private

* chore: verify all changes applied - build passes

* chore: verify build and vet pass

---------

Signed-off-by: Autonomous Coding Agent <agent@autonomous>
Co-authored-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
2026-02-26 00:02:29 +01:00
Ettore Di Giacinto 07b624cc77 chore: put reasoning tool behind a flag
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-16 17:31:19 +01:00
Ettore Di Giacinto c96e8ddc11 chore: use tool for extract reasoning (#36)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-16 15:44:43 +01:00
Ettore Di Giacinto d1c0dc9bd9 feat: improve control loop (#35)
* feat: improve control loop

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Drop last message from subtasks in plan execution

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fixup tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-16 00:07:40 +01:00
Ettore Di Giacinto af34921ff5 chore: consume reasoning (#34)
* chore: consume reasoning

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* break instead

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Refactor

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Adapt tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-15 22:34:13 +01:00
Ettore Di Giacinto da0d4ceb2b Return last message when no tools are selected (#33)
* Return last message when no tools are selected

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Improve logging

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Allow agent to disengage also without sink state

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* ask when needed

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Allow to keep old behavior

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* tests fixups

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-14 21:17:34 +01:00
Ettore Di Giacinto 1321987e12 feat(tools): add parallel tool support (#30)
* feat(tools): add parallel tool support

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Add tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* linting

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-01-19 23:12:45 +01:00
Ettore Di Giacinto 2324131eaa feat: add state and feedback (#18)
* feat: allow to adjust tool call with user feedback

Expand the callback signature such as we accept a string for adjusting
the toolcall. If an adjustment is provided and we should continue, then
cogito prompts again the selection process with the user feedback to
improve the tool call.

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat: return a state such as the execution can be resumed

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* chore: style changes

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* chore: add tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-12-07 23:42:24 +01:00
Ettore Di Giacinto 8859641f81 feat: declare tool args via struct (#14)
* feat: declare tool args via struct

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* simplify even more the API

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-10-29 19:20:17 +01:00
Ettore Di Giacinto 23c7064141 feat: enhance tool selection (#13)
* feat: enhance tool selection

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* try to adapt tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Make tests more stable

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Add autoplan test

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Don't load MCP prompts if we don't have any

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Reorder things

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* TEST

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Revert "TEST"

This reverts commit b08bbc56d5.

* TEST

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* TEST2

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Try to fix tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Add back guidelines

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fixups

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Improve next action logic

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* tests

* tests2

* forcereasoning

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* maxiterations

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Fix tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Better error handling

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* test

* error handling

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Force text reply

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Two-step param generation approach

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Code cleanup

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Add a small note/comment

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Improve tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Small refinements

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-10-26 21:37:24 +01:00
Ettore Di Giacinto 5f46a5b9e3 fix: make fragment status a pointer (#12)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-10-22 17:19:54 +02:00
Ettore Di Giacinto 6da5735ef0 fix: better error propagation
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-10-21 18:46:33 +02:00
Ettore Di Giacinto 9dba7e36fd fix(tests): adapt to plan behavioral changes
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-10-20 22:57:48 +02:00
Ettore Di Giacinto 2f0f800d95 feat(tools): allow to automatically plan (#9)
* feat(tools): allow to automatically plan

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feat(mcp): display MCPs prompts during tool selection

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* feature gate mcp prompts

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Add test

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* fix plans, strict tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-10-13 09:11:13 +02:00
Ettore Di Giacinto 6bb97feb18 feat: add guidelines to steer tool selection (#6)
* feat: add guidelines to steer tool selection

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Display suggested tools

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Add tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-10-03 00:07:19 +02:00
Ettore Di Giacinto 2f20fcce01 Change LLM to interface, split tests, improve content review loop (#3)
* Split e2e and unit tests

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Abstract away LLM to an interface

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Update README

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Fixups

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Enhance content improve generation

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Add unit test for reviewer

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Better handling of result status of tool calls

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Fixups

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

* Add tools test file

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-09-29 22:55:43 +02:00
Ettore Di Giacinto af41faaa19 Initial import
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-09-23 23:24:00 +02:00