Commit Graph

93 Commits

Author SHA1 Message Date
Ettore Di Giacinto 43a247d6a1 add example
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-03-31 16:18:30 +00:00
Ettore Di Giacinto 33d6c44bf0 feat: add sub-agents support
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-03-28 21:17:21 +00:00
Ettore Di Giacinto 8548e1e1aa feat: add auto-improver
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-03-19 17:35:38 +00:00
Ettore Di Giacinto a09552a3a4 fix: only check content
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-03-16 00:41:54 +00:00
Ettore Di Giacinto 1952b0d9ce fix: recover from models that give invalid output
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-03-16 00:33:55 +00:00
Ettore Di Giacinto 63abdec718 feat: support streaming mode (#44)
* feat: support streaming mode

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

* feat: support streaming mode for tool calls

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

* feat: add decision with streaming

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

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-03-15 23:29:27 +01:00
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
Ettore Di Giacinto 9b8f2eac82 fix: consume message IF in sink mode
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
v0.9.4
2026-03-13 10:06:01 +00:00
Ettore Di Giacinto 3bc79f756d fixups v0.9.3 2026-03-09 14:50:14 +00:00
Ettore Di Giacinto e073d115bd fix: normalize messages and join system messages automatically
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-03-06 20:24:29 +00:00
Richard Palethorpe 070e9f69c0 feat: Add grammar constraint for LocalAI (#43)
Signed-off-by: Richard Palethorpe <io@richiejp.com>
v0.9.2
2026-02-27 13:12:23 +01:00
LocalAI [bot] b766916377 fix: assign to intentionMessages instead of messages (ineffectual assignment) (#42)
The code was assigning to 'messages' but then using 'intentionMessages'
throughout the rest of the function. This caused a golang-ci lint error.

Closes #42
2026-02-26 00:48:59 +01: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 070948df04 chore: add sleeps between re-attempt in case of failure
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-23 11:19:54 +01:00
Ettore Di Giacinto 3e74a9b3ac feat: add Extract for extracting typed structs
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-22 22:46:53 +00:00
Ettore Di Giacinto 7e5c0264aa chore: force sink state when reasoner is enabled (non-thinking models)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-20 22:05:46 +00:00
Ettore Di Giacinto b8aaf55307 fix: correctly unmarshal field
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-20 10:01:38 +01:00
Ettore Di Giacinto d0bb45367d Update LLM initialization to use clients package 2026-02-19 22:25:40 +01:00
Ettore Di Giacinto 66d4f934fc Update LLM client initialization in README 2026-02-19 22:24:02 +01:00
Ettore Di Giacinto 5c89648cf8 feat: split clients and add LocalAI client (#39)
* chore(refactor): split client to a separate package

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

* chore: abstract away LLM reply

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

* add localai client

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

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-19 22:22:36 +01:00
Ettore Di Giacinto 2b5c5de8e2 chore(refactor): pass by reasoning and message separately to avoid ambiguity (#38)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-19 19:26:30 +01:00
Ettore Di Giacinto 46417df69f feat: allow to inject messages during tool loop execution (#37)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-18 22:38:52 +01:00
Ettore Di Giacinto a3f85ec027 chore: drop tool reasoner
This is basically duplicating the logic which is already covered now in
the main loop.

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-18 21:20:52 +00:00
Ettore Di Giacinto bb7f986ed2 chore: improve prompts
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
v0.9.1
2026-02-17 15:38:01 +01:00
Ettore Di Giacinto e9820e6bf7 chore: improvements to sink state handling
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-16 19:28:42 +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>
v0.9.0
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 a5346975d4 chore: return any result from tools in the status (#32)
This allows to put arbitrary data as results of any tool and be later
picked up when inspecting the execution results of the agent.

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-06 16:34:01 +01:00
Ettore Di Giacinto b5fa1ef9ec chore: add message manipulator callback (#31)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-02-05 22:40:59 +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 ef0538f67c feat(planning): support multiple reviewers (#29)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-01-19 22:41:19 +01:00
Ettore Di Giacinto 2ec99d0648 fix(plan): add description in the schema
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
v0.8.1
2026-01-15 20:36:24 +00:00
Ettore Di Giacinto f195b2553f feat(todo): add todo-based goal execution similar to cursor agent mode (#25)
* feat(todo): add todo-based goal execution similar to cursor agent mode

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

* reinforce tests

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

* Bump timeout for tests

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

* feat: guided tools

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

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
v0.8.0
2026-01-15 21:19:15 +01:00
Ettore Di Giacinto 35b0d01edb feat: guided tools (#26)
* feat: guided tools

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

* Update docs

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

---------

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2026-01-15 21:19:01 +01:00
Ettore Di Giacinto 7a0768f167 go fmt v0.7.2 2025-12-19 23:04:26 +01:00
Ettore Di Giacinto 1a6237e2ec chore: move logging to its own package so can be shared across repos (#23)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-12-19 23:02:17 +01:00
Ettore Di Giacinto ab4090ff35 chore(logging): allow to set programmatically log level (#22)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
v0.7.1
2025-12-16 21:45:42 +01:00
Ettore Di Giacinto 19ffb31772 chore: return status if we terminate for other reasons (#19)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-12-16 21:45:32 +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>
v0.7.0
2025-12-07 23:42:24 +01:00
Ettore Di Giacinto ab5e39c511 feat(sink): allow to configure and disable sink state (#17)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
v0.6.0
2025-12-03 22:57:05 +01:00
Grant Foster d7a0254ef1 fix: ensure tool call IDs are properly set and matched between tool calls and results (#15)
* fix: chat id

* fix: format code (gofmt)

* chore: test comment change
v0.5.1
2025-11-07 22:02:37 +01:00
Ettore Di Giacinto d8926243e1 Refactor README for custom tools and annotations
Removed redundant section on creating custom tools and added field annotations for tool arguments.
2025-10-30 18:19:08 +01:00
Ettore Di Giacinto 875c615613 Change iteration expectation to be greater than or equal 2025-10-30 18:16:12 +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>
v0.5.0
2025-10-29 19:20:17 +01:00
Ettore Di Giacinto d94e0bd20e fix: make sure we propagate reasoning
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
v0.4.2
2025-10-28 18:47:21 +01:00
Ettore Di Giacinto 3196b1a2c3 fix: add default reasoning callback
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
v0.4.1
2025-10-28 09:13:53 +01:00
Ettore Di Giacinto 3f982f8fe7 chore: add Reasoning to ToolChoice
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-10-27 13:24:54 +01:00