Commit Graph
48 Commits
Author SHA1 Message Date
haelyra 8a404dbbdc fix: preserve story projections and blank provider defaults 2026-10-11 08:56:29 -04:00
haelyra 5da9a1f4a7 fix: preflight ledger storage and normalize saved model padding 2026-10-11 05:33:44 -04:00
haelyra 644269657c fix: harden ledger publication and mixed Ollama histories 2026-10-11 03:53:41 -04:00
haelyra e9f95e394f fix: reconcile profile projections and selected-model fallback checks 2026-10-11 03:05:59 -04:00
haelyra 353f64fa83 Merge remote-tracking branch 'refs/remotes/pr/3499' into integration/ecc-043-20261011
# Conflicts:
#	src/llm/providers/ollama.py
#	src/llm/providers/openai.py
2026-10-11 02:45:34 -04:00
Yann Roberto effa074f7d fix(llm): normalize model environment values 2026-10-11 14:31:45 +08:00
haelyra f4f8beba01 fix: require explicit reasoning format before stripping content 2026-10-11 02:26:58 -04:00
Yann Roberto e4b9451c68 fix(llm): honor selected models in provider resolution 2026-10-11 14:05:46 +08:00
haelyra 544601912a fix(llm): integrate capability-aware Ollama tools from PR 3275
Preserve contributor head and current main reasoning/errors. Reject malformed capability declarations and retry discovery; actual localhost HTTP ReAct round-trip verified.
2026-10-11 01:57:34 -04:00
haelyra 242abdecb4 fix(llm): integrate revised reasoning filtering from PR 3272 2026-10-11 01:56:43 -04:00
haelyra 95bbd84106 merge: preserve tested tool-choice provider source 2950 2026-10-09 16:07:23 -04:00
FenjuFu 586d4b91cc fix(llm): keep answers too deeply nested to parse whole in prefilled mode
Signed-off-by: FenjuFu <fufenjupku@gmail.com>
2026-10-05 01:19:14 +08:00
FenjuFu d351fc5502 fix(llm): fall back when a prefilled answer is too deeply nested to parse
json.loads raises RecursionError on deeply nested input, which escaped the
complete-JSON check and failed the request. Treat it like any other input
that is not a complete JSON document.

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
2026-10-04 16:31:47 +08:00
FenjuFu af325fbb85 fix(llm): keep complete JSON answers whole in prefilled reasoning mode
With prefilled reasoning enabled, a structured answer such as
{"closing":"</think>"} was cut at the tag inside its string value.
Reasoning followed by a closing tag is never a valid JSON document, so a
reply that parses as one complete object or array is now returned
unchanged. Also annotate the tests and helpers this PR adds.

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
2026-10-03 01:44:22 +08:00
FenjuFu 7556360412 fix(llm): retry Ollama capability lookups that failed
Only an answered /api/show lookup is cached now, and the cache is replaced rather than mutated. A failed lookup sends no tools for that request and is retried on the next one, so a transient outage no longer disables tools for the provider's lifetime. Also annotate the test helpers and tests this PR adds.

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
2026-10-03 01:33:53 +08:00
FenjuFu 558c06c3f8 fix(llm): send Ollama tools only to tool-capable models and keep call identity
Tools are now forwarded only when the selected model declares tool support:
catalogued models answer from ModelInfo.supports_tools (llama3.2 and mistral
are tool models on ollama.com, codellama is not), and any other model is
looked up once through /api/show, whose capabilities list is what the
installed model declares. A failed lookup sends no tools.

Native Ollama tool calls often have no id, so each one gets a unique id, and
tool results are sent with tool_name resolved from the call they answer, so
several results stay attributable.

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-10-02 11:15:58 +08:00
FenjuFu 2861dee176 fix(llm): only strip close-only reasoning when the deployment declares it
Strip a balanced <think>...</think> block that opens the reply by default and
leave every other reply untouched, so answers that mention the tags (a lone
or reversed closing tag, JSON string values) are never truncated.

The close-only form produced by chat templates that prefill <think> is now
handled only when the OpenAI or Ollama provider is configured for it, via
prefilled_reasoning=True or OPENAI_PREFILLED_REASONING /
OLLAMA_PREFILLED_REASONING. Hosted providers keep the default.

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-10-02 11:03:17 +08:00
FenjuFu 74836ce65f fix(llm): forward tool definitions to Ollama
OllamaProvider built the /api/chat payload without the tools from
LLMInput, so Ollama models were never told any tools existed and a
ReActAgent backed by Ollama never ran one. The response side already
parsed message.tool_calls.

Send the tools in the OpenAI function format that /api/chat accepts,
matching the other providers.

Fixes #3274

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
2026-09-30 20:38:19 +08:00
FenjuFu d6f20191de fix(llm): strip leaked reasoning from self-hosted model output
Self-hosted reasoning models served through vLLM or llama.cpp without a
reasoning parser, or through Ollama without a thinking template, return
their chain of thought inside message content. The OpenAI-compatible
providers and the Ollama provider passed it through verbatim, so
LLMOutput.content and ReActAgent final answers began with the reasoning.

Models whose chat template prefills <think> in the generation prompt
(Spark-X2.5, Qwen3 thinking variants) only emit the closing tag, so the
content arrives as "...</think>answer" with no opening tag.

Add strip_reasoning() and apply it in the OpenAI, Astraflow, Atlas and
Ollama providers. A <think> that does not open the output is kept as a
literal, and unterminated reasoning is left unchanged.

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
2026-09-30 18:41:24 +08:00
Affaan MustafaandGitHub fc9273e5e0 Merge pull request #3126 from VarunGore36/fix/reviewer-followups
fix(security): security follow-ups for worker, installer, claw, hooks
2026-09-19 19:58:43 -04:00
Iams4kura 8ab8f40567 Merge remote-tracking branch 'origin/main' into bugfix/serialize-openai-tool-calls-20260903t164126z
# Conflicts:
#	tests/test_provider_tools.py
2026-09-19 13:49:57 +08:00
Aniruddha Adak 6502cf24bf fix(llm): forward max_tokens to Ollama num_predict 2026-09-17 02:33:20 +05:30
Geronimo 15f1ee8a41 fix(claw,executor): restore Windows shim launch, close stray coroutine
- claw askClaude: prefer native .exe, route only .cmd/.bat through cmd.exe
  with a quoted command line (DEP0190-safe, same pattern as
  mcp-health-check); never exec .ps1 directly (not executable without
  powershell); model allowlist retained so the shell line carries no
  attacker metacharacters
- executor sync path: close un-awaited coroutine before returning the
  generic failure, eliminating RuntimeWarning noise
2026-09-14 21:56:32 +05:30
Geronimo a3c24818bb fix(security): provider error taxonomy, tool leak hardening, hook gate, atomic cleanup
- ollama: connection failures -> LLMError(connection_error), unknown -> LLMError(provider_error); auth only on real 401
- executor: generic model-facing tool failure, diagnostics to logs; add execute_async/all_async; ReActAgent returns structured provider_error
- run-with-flags.js: gate require() on concrete run-export syntax, not bare word match
- codex-legacy-sync: remove tmp file on atomicWriteJson failure
- tests: async tool + ReActAgent awaitable regression coverage
2026-09-14 13:49:18 +05:30
Iams4kura 8eedb3d3de fix(llm): reject invalid tool arguments 2026-09-04 11:29:14 +08:00
Iams4kura 4a9bdff518 refactor(llm): isolate OpenAI message mapping 2026-09-04 11:16:14 +08:00
Iams4kura 3f702ed40c fix(llm): serialize OpenAI tool call messages 2026-09-04 10:40:20 +08:00
Aditya DattaandAlex Schmitt 9d233aaa63 Trim provider names in prompt builder 2026-08-24 22:27:42 -03:00
a15c8e8533 ci: add Python CI job (ruff, mypy, pytest) for the llm-abstraction package (#2364)
* ci: add ruff + mypy to the Python CI job and fix pyproject tool config

The python-tests job runs pytest but not lint/type checks, and the ruff
and mypy configuration in pyproject.toml was silently broken, so neither
tool could run at all.

- add ruff and mypy steps to the existing python-tests job
- fix invalid pyproject keys: [tool.ruff] src-path -> src,
  [tool.mypy] src_paths -> mypy_path
- ignore ruff UP042 (the (str, Enum) mixin is intentional)
- resolve ruff findings (unused/unsorted imports) across src and tests
- fix mypy errors in tools/executor.py and prompt/builder.py

* fix(ci): satisfy Python lint after main refresh

---------

Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-08-11 14:15:57 -04:00
Affaan MustafaandGitHub bc774282e6 feat: connect ECC to canonical Ito compute CLI (#2558) 2026-07-23 19:28:55 -07:00
Affaan MustafaandGitHub 96789caaf9 feat: add Itô compute sponsor routing and Phase 2 plan (#2546)
* feat: add Ito compute sponsor routing

* fix: harden Ito integration CI and framing
2026-07-22 03:07:45 -04:00
ThejeshandGitHub fb98726d0a fix(llm/providers/claude): attach cache_control to system block, not top-level (#2515)
* fix(llm/providers/claude): attach cache_control to system block, not top-level

The Anthropic Messages API does not accept `cache_control` as a top-level
request parameter — it is a per-content-block field. Passing it at the top
level raises `TypeError` in the Python SDK (which validates kwargs against
`messages.create()`'s signature) or a `400 unknown_parameter` from the API,
so every ClaudeProvider.generate() call fails.

Move `cache_control: {"type": "ephemeral"}` onto the last system-prompt
block so ephemeral prompt caching still works when a system prompt is
present, and drop it when there isn't one (nothing to cache).

Existing tests didn't catch this because `FakeMessages.create(**_params)`
accepted anything and ignored the kwargs. FakeMessages now records
`last_params`, and two regression tests assert that:
  - `cache_control` never appears as a top-level param, and
  - when a system prompt is set, `cache_control` rides on the last block.

Fixes #2512

* test(claude_provider): split composite isinstance+truthiness assertion (PT018)

Ruff PT018 flagged the combined `isinstance(system, list) and system` check
in `test_generate_does_not_pass_cache_control_as_top_level_param`. Split
it into two focused asserts (`isinstance(system, list)` then `assert system`)
so a failure points at the exact violation instead of a compound condition.

Behavior unchanged; 6/6 tests still pass.

Addresses CodeRabbit review on #2515.
2026-07-17 16:04:32 -04:00
1a747097f2 fix: docs/COMMAND-REGISTRY.json check fails on fresh Windows clone (missing .gitattributes) (#2437)
* fix: add .gitattributes to force LF line endings for text files

npm run command-registry:check (part of npm test) fails on a fresh clone
on Windows with the common core.autocrlf=true setting: git checks out
docs/COMMAND-REGISTRY.json with CRLF, but generate-command-registry.js
always writes LF, so the strict string comparison in checkRegistry()
never matches. Forcing LF via .gitattributes makes checkouts consistent
across platforms regardless of a contributor's local autocrlf setting.

* fix: normalize CRLF line endings to LF per .gitattributes

pyproject.toml, src/llm/__init__.py, src/llm/prompt/builder.py,
src/llm/providers/claude.py, and tests/test_builder.py had CRLF line
endings committed to the repo, inconsistent with the rest of the
codebase. Renormalized via 'git add --renormalize .' now that
.gitattributes enforces eol=lf.

---------

Co-authored-by: Affaan Mustafa <me@affaanmustafa.com>
2026-07-03 20:14:55 -07:00
8973d0f6c5 fix(llm): align Claude provider with current Anthropic API (#2133)
Replace invalid default model IDs (e.g. claude-sonnet-4-7) with current
claude-sonnet-4-6, claude-opus-4-8, and claude-haiku-4-5. Route system
messages to the API system field, enable ephemeral prompt caching, omit
temperature for Opus 4.7/4.8, and surface cache usage metrics. Update the
CLI model picker to match.

Co-authored-by: Vladimir Đuranović <vlada@MacBook-Pro.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:50:52 -07:00
71792fda81 feat: add Atlas Cloud as LLM/AI provider (#2279)
* feat: add Atlas Cloud as OpenAI-compatible LLM provider

- Add Atlas Cloud env vars to .env.example (ATLAS_API_KEY, ATLAS_BASE_URL)
- Add docs/ATLAS-CLOUD-GUIDE.md with configuration, model list, and usage example
- Atlas Cloud provides 59+ LLM models via OpenAI-compatible API at https://api.atlascloud.ai/v1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(atlascloud): add Atlas Cloud provider implementation

Wire Atlas Cloud in as a first-class OpenAI-compatible LLM provider,
complementing the existing .env.example/docs entries.

- src/llm/providers/atlas.py: AtlasProvider adapter (base_url
  https://api.atlascloud.ai/v1, default model deepseek-ai/deepseek-v4-pro);
  floors max_tokens to 512 for reasoning models; reads ATLAS_API_KEY
  (falls back to ATLASCLOUD_API_KEY), ATLAS_BASE_URL, ATLAS_MODEL
- src/llm/core/types.py: add ProviderType.ATLAS
- providers __init__/resolver: export + register AtlasProvider
- tests: test_atlas_provider.py + resolver coverage for "atlas"

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 16:29:11 -04:00
Affaan Mustafa eb0d893948 fix: harden openai-compatible provider responses 2026-05-18 01:04:28 -04:00
Your Name cc62e89152 fix: guard against empty choices in OpenAI and AstraFlow LLM providers
The OpenAI-compatible API can return HTTP 200 with an empty choices list
or choices[0].message = None (content-filtered responses on Gemini,
overwhelmed Ollama instances). Without a guard, both sites raise an
unhandled IndexError or AttributeError crashing the provider.

Added guard in OpenAIProvider.generate() and AstraFlowProvider.generate().
2026-05-17 23:49:00 -05:00
Affaan MustafaandAffaan Mustafa e9c8845833 feat: add Astraflow provider support 2026-05-11 23:21:46 -04:00
Affaan MustafaandAffaan Mustafa b39d2244cf docs: salvage focused stale PR contributions
- add Vite and Redis pattern skills from closed stale PRs

- add frontend-slides support assets

- port skill-comply runner fixes and LLM prompt/provider regressions

- harden agent frontmatter validation and sync catalog counts
2026-05-11 05:31:12 -04:00
Affaan MustafaandAffaan Mustafa 7fa1e5b6db fix: port LLM provider config and tool schemas 2026-05-11 04:12:35 -04:00
Anish 813755b879 Done 2026-04-12 12:56:20 +05:30
Anish 74b91cb3f3 fix: resolve git conflicts in LLM abstraction layer
- Fix gui() function import in __init__.py (use cli.selector)
- Fix prompt builder system message merging logic
- Add default max_tokens for Anthropic API in claude.py
- Fix openai tool_call arguments parsing with json.loads
- Fix test_builder.py PromptConfig import and assertions
2026-04-12 07:10:54 +00:00
Anish d39a8a049a Small changes 2026-04-12 12:34:45 +05:30
Anish AgrawalGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
fd0cde69d8 Update src/llm/__init__.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-04-12 12:31:03 +05:30
Anish AgrawalGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
5736b3b684 Update src/llm/prompt/builder.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-04-12 12:25:36 +05:30
Anish AgrawalGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
6691e7cc9e Update src/llm/providers/openai.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-04-12 12:25:15 +05:30
Anish AgrawalGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
a7f73576a9 Update src/llm/providers/claude.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-04-12 12:24:49 +05:30
Anish f53a89ff88 GUI Created, Dark Mode Created, npm script added, styling changed, Decoupled from Claude made more open source. 2026-04-12 12:16:49 +05:30