Skip to content

Commit 76c264e

Browse files
authored
Merge pull request #93 from altaidevorg/review/pr-90-run-scoped-provider-config
feat!: isolate provider configuration per run
2 parents d4743ea + 605297a commit 76c264e

8 files changed

Lines changed: 673 additions & 189 deletions

File tree

AGENTS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ Sub-agents (`subagent_spawn`, `task_*`, `subagent_plan_execute`, `task_history_l
5555

5656
**Loop hardening:** top-level **`doom_loop_enabled`** in `config.toml` (default true) enables ml-intern-style detection of repeated identical tool calls before each LLM step; a corrective **user** message is persisted when triggered (`src/agent/doom_loop.rs`). Independently, the pure controller in `src/agent/budget.rs` tracks LLM turns, wall time, provider-reported tokens, provider retries, context recoveries, repeated typed tool root causes, and observable progress. It emits run-scoped typed warnings, stops three consecutive failures with the same `(tool, error code)` as `Stuck::RepeatedRootCause`, stops sustained no-progress runs as `Stuck::NoProgress`, and retains `max_iterations` only as the absolute LLM-turn ceiling. Steering and context recovery reset no-progress only; successful new evidence may also clear the repeated-root-cause streak, while consumed time/tokens/retries are never refunded.
5757

58+
**Run-scoped LLM providers:** `AgentLogic` keeps the active provider and its credentials behind one lock and snapshots that pair, plus the filtered failover candidates, when a run is admitted. Active runs and already-admitted FIFO items never read process-global provider state. A `/model` switch atomically changes the pair for subsequent admissions; an inbound accepted after the switch keeps the new pair even when it waits behind an older run. Sub-agents use the same snapshot contract. Embedders that need failover candidates use `AgentLogic::new_with_fallback_providers`; `AgentLogic::new` remains the compatibility path with no candidates.
59+
5860
### Structured LLM Extraction
5961
If you are asking the LLM to yield a structured JSON payload internally (e.g. for reflection or summarization outside of the standard `ToolCall` registry):
6062
**DO NOT** use brittle string matching like `text.find('{')`.

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "isanagent"
3-
version = "0.10.0"
3+
version = "0.11.0"
44
edition = "2021"
55
license = "Apache-2.0"
66
repository = "https://github.com/altaidevorg/isanagent"

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ model_name = "claude-sonnet-4-6"
103103

104104
Use `/model` in the TUI to open the interactive model selector, or `/model gemini-2-5-flash` to switch directly. Your choice is remembered across restarts.
105105

106+
Provider selection is isolated per accepted run. Switching models does not alter an in-flight run; messages accepted after the switch use the new provider and credentials even if they wait in that chat's FIFO. Configured failover candidates are also snapshotted per run, so concurrent chats cannot overwrite one another's fallback policy.
107+
106108
### Skill management
107109

108110
isanagent supports installing specialized **skills** (structured procedures and instructions) from remote GitHub repositories. You can install an entire repository of skills or a specific one using shorthand `owner/repo` or full URLs.
@@ -155,4 +157,4 @@ cargo clippy --release -p isanagent --all-targets
155157
cargo test --release -p isanagent
156158
```
157159

158-
On Windows, prefer **`--release`** for builds and tests if debug linking hits PDB issues.
160+
On Windows, prefer **`--release`** for builds and tests if debug linking hits PDB issues.

docs/public-api-surface.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,36 @@ Constructor: `pub fn new(db_path: &str) -> Result<Self, String>` [src/memory.rs:
279279

280280
## 6. Top-level orchestrator types
281281

282+
### 0.11 migration: run-scoped provider configuration
283+
284+
Version 0.11 intentionally removes the process-global and independently
285+
mutable provider-credential APIs. These removals are breaking changes:
286+
287+
| Removed 0.10 API | 0.11 replacement |
288+
| --- | --- |
289+
| `set_fallback_providers(specs)` | Pass `specs` to `AgentLogic::new_with_fallback_providers(params, specs)`. |
290+
| `agent.provider_credentials_handle()` followed by independent writes | Build the matching provider and call `agent.switch_provider_with_credentials(provider, credentials).await`. |
291+
292+
`switch_provider(provider)` and `set_provider_credentials(credentials)` remain
293+
temporary compatibility shims. The provider-only form clears credential
294+
identity and disables failover for later admissions; the credential-only form
295+
rebuilds a standard provider. Custom provider embedders should migrate directly
296+
to `switch_provider_with_credentials` so the provider and its credentials become
297+
visible atomically.
298+
282299
### 6.1 `AgentLogic` — struct [src/agent/mod.rs:1045](../src/agent/mod.rs#L1045)
283300

284301
The central reasoning actor. All fields private. Constructed via `pub fn new(params: AgentLogicParams) -> Self` [src/agent/mod.rs:1073](../src/agent/mod.rs#L1073). Implements `ActorLogic<BusMessage>` at [src/agent/mod.rs:1270](../src/agent/mod.rs#L1270).
285302

303+
Provider configuration changes must use
304+
`switch_provider_with_credentials(provider, credentials)` so the provider and
305+
the credential identity become visible in one write. The older
306+
`switch_provider(provider)` and `set_provider_credentials(credentials)` methods
307+
remain source-compatible migration shims: the former clears credential identity
308+
and disables fallback for later admissions, while the latter rebuilds a standard
309+
provider from the supplied credentials. Custom provider embedders must migrate
310+
to the paired method. No supported API exposes a mutable credential handle.
311+
286312
> **Overhaul touchpoint.** PR-5 adds a pub method `trigger_compaction(chat_id, options)` to this struct.
287313
288314
### 6.2 `AgentLogicParams` — struct [src/agent/mod.rs:999](../src/agent/mod.rs#L999)
@@ -293,6 +319,7 @@ Constructor params for `AgentLogic::new`. **All fields `pub`** — embedding cra
293319
pub struct AgentLogicParams {
294320
pub name: String,
295321
pub provider: Box<dyn Provider>,
322+
pub provider_credentials: ProviderCredentials,
296323
pub session_manager: SessionManager,
297324
pub tools: ToolRegistry,
298325
pub skills: SkillRegistry,
@@ -315,6 +342,8 @@ pub struct AgentLogicParams {
315342
}
316343
```
317344

345+
`AgentLogic::new(params)` preserves the compatibility path with no failover candidates. Embedding crates that configure failover use `AgentLogic::new_with_fallback_providers(params, candidates)`. The candidate vector is owned by that `AgentLogic`; every admitted main-agent or sub-agent run snapshots its provider, credential identity, and filtered fallbacks. Runtime model switches therefore affect only later admissions.
346+
318347
**This struct is on the critical compatibility path.** Adding fields here is breaking without `#[non_exhaustive]` because constructors enumerate every field. Phase 0.0b must add the marker and document the workaround (use struct-update syntax with a default).
319348

320349
### 6.3 `SubagentHarnessParams` — struct [src/agent/mod.rs:1032](../src/agent/mod.rs#L1032)

0 commit comments

Comments
 (0)