@lazyingart/agintiflow 0.20.200 → 0.20.202

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example CHANGED
@@ -6,6 +6,7 @@ LOCALLLM_BASE_URL=http://127.0.0.1:8008/v1
6
6
  LOCALLLM_API_KEY=local-dev-key
7
7
  AGINTI_LOCALLLM_ROUTE_MODEL=localllm-fast
8
8
  AGINTI_LOCALLLM_MAIN_MODEL=localllm-deep
9
+ AGINTI_LOCALLLM_CODE_MODEL=localllm-code
9
10
  AGINTI_LOCALLLM_MAX_MODEL=localllm-max
10
11
  AGINTI_LOCALLLM_ALLOW_AUTO_MAX=false
11
12
  AGINTI_LOCALLLM_VISION_MODEL=localllm-vision-xl
@@ -13,8 +14,10 @@ AGINTI_LOCALLLM_CONTEXT_TOKENS=32768
13
14
  AGINTI_LOCALLLM_MAX_OUTPUT_TOKENS=8192
14
15
  AGINTI_LOCALLLM_TOOL_SCHEMA_TOKENS=4096
15
16
 
16
- # Auto-Max is off unless explicitly enabled. Enabled runs still require authenticated
17
- # alias discovery plus a fresh RAM/swap/GPU headroom check before selecting Max.
17
+ # Genuine implementation work uses the code alias only after authenticated model
18
+ # discovery confirms that exact configured alias; otherwise it remains on Deep.
19
+ # Auto-Max is off unless explicitly enabled. Enabled non-code runs still require
20
+ # authenticated alias discovery plus a fresh RAM/swap/GPU headroom check.
18
21
  # Hosted provider keys below never act as a LocalLLM failure fallback.
19
22
 
20
23
  # Optional explicit hosted upgrades. They are never automatic fallbacks.
@@ -22,6 +25,8 @@ DEEPSEEK_API_KEY=
22
25
  OPENAI_API_KEY=
23
26
  AGINTI_ALLOW_HOSTED_IMAGE_PERCEPTION=false
24
27
  AGINTI_ALLOW_HOSTED_WEB_RESEARCH=false
28
+ AGINTI_WEB_SEARCH_PROVIDER=auto
29
+ # BRAVE_SEARCH_API_KEY=only_when_AGINTI_WEB_SEARCH_PROVIDER_is_brave
25
30
  AGINTI_ALLOW_HOSTED_JSON_SPECIALIST=false
26
31
  # A cross-provider writer needs both an explicit target and the permission below.
27
32
  AGINTI_WRITING_PROVIDER=
package/README.md CHANGED
@@ -54,7 +54,7 @@ Most agent tools are either a chat box with hidden state or an expensive one-mod
54
54
  | Disciplined by default | `AGINTI.md` starts with a behavior contract: surface ambiguity, keep edits surgical, avoid speculative complexity, verify outcomes, and respect permission blockers. |
55
55
  | Role-based models | Route, main, spare, wrapper, and auxiliary image roles are separate. LocalLLM supplies the default fast/deep lanes; DeepSeek, OpenAI, OpenRouter, Qwen, and Venice are optional explicit routes. |
56
56
  | Writing without agent noise | `writing_specialist` drafts novels, books, scripts, essays, and paper prose in an isolated writing-only context on the active provider. Cross-provider writing requires explicit permission; ambient keys and model arguments cannot silently switch a LocalLLM session to a hosted model. The main agent then handles files, formatting, citations, checks, and artifacts. |
57
- | Visual and web evidence | `read_image` uses the loopback LocalLLM vision model in local sessions and never falls through to a hosted provider. `web_research` saves sourced snippet artifacts for local synthesis. OpenAI perception/research and wrapper second opinions require explicit provider/tool permission. |
57
+ | Visual and web evidence | `read_image` keeps local pixels local. Fast search has provider fallback; exact page reads preserve hashes and metadata; `deep_research` adds resumable planning, parallel retrieval, exact-quote evidence, gap filling, synthesis, and citation auditing on the active provider. |
58
58
  | Scouts before big work | Parallel scouts can cheaply map architecture, tests, risks, symbols, and integration points before the main executor edits anything. |
59
59
  | SCS by default | Student-Committee-Supervisor mode adds a typed gate: committee drafts, student approves/monitors, supervisor executes. Use `/scs off` or `--no-scs` only when speed matters more than validation. |
60
60
  | AAPS for large workflows | AAPS describes top-down agentic pipeline scripts; AgInTiFlow can act as the interactive backend that validates, compiles, and executes those workflows. |
@@ -85,7 +85,7 @@ aginti init --template aaps
85
85
  aginti init --template supervision
86
86
  ```
87
87
 
88
- By default, AgInTiFlow connects to the sibling LocalLLM gateway at `http://127.0.0.1:8008/v1`, using `localllm-fast` for routing and the installed 30B-A3B Q4 `localllm-deep` for substantive coding and agent work. The Q8 `localllm-max` remains resource-gated on every new or resumed run (24 GiB available RAM, no more than 75% swap use, and 40 GiB aggregate free NVIDIA memory). The automatic Vision policy requires both a trusted image-input signal and confirmed model capability; the shipped CLI/web currently use the readiness-checked local `read_image` tool or an explicit `localllm-vision-xl` selection rather than inferring vision from prompt keywords. Routing does not load a model. Startup checks the LocalLLM service, its Ollama runtime, selected aliases, and any required Max headroom before inference. A local failure stops with an actionable error; it never silently sends the task to a hosted provider.
88
+ By default, AgInTiFlow connects to the sibling LocalLLM gateway at `http://127.0.0.1:8008/v1`, using `localllm-fast` for routing and the installed 30B-A3B Q4 `localllm-deep` for substantive general agent work. High-confidence coding and repository implementation requests begin on Deep, then switch to the provider-neutral `localllm-code` capability alias only after bearer-authenticated `/v1/models` discovery confirms that exact configured alias. If it is absent, the run stays on Deep; writing, research, documentation, design, explanation-only code questions, explicit providers, and manual model choices are not silently rerouted. Set `AGINTI_LOCALLLM_CODE_MODEL` to another LocalLLM capability alias without coupling AgInTiFlow to an engine tag. The Q8 `localllm-max` remains resource-gated on every new or resumed run (24 GiB available RAM, no more than 75% swap use, and 40 GiB aggregate free NVIDIA memory). The automatic Vision policy requires both a trusted image-input signal and confirmed model capability; the shipped CLI/web currently use the readiness-checked local `read_image` tool or an explicit `localllm-vision-xl` selection rather than inferring vision from prompt keywords. Routing does not load a model. Startup checks the LocalLLM service, its Ollama runtime, selected aliases, and any required Max headroom before inference. A local failure stops with an actionable error; it never silently sends the task to a hosted provider.
89
89
 
90
90
  Hosted providers are optional, explicit upgrades. When you select DeepSeek, OpenAI, OpenRouter, Qwen, or Venice, the auth wizard can save that provider's key account-wide in `~/.agintiflow/.env` with restricted permissions. Current project `.aginti/.env` files can still override account defaults when needed. You can rerun setup any time:
91
91
 
@@ -174,6 +174,7 @@ aginti --language de
174
174
  | Generate images | `/auxiliary image`, then ask for an image |
175
175
  | Read screenshots/images | `/image-read path/to/screenshot.png "what changed?"` |
176
176
  | Research with sources | `/web-research latest Android Gradle plugin official docs` |
177
+ | Run deep research | `/deep-research standard compare current research-agent citation methods` |
177
178
  | Enable research wrapper | `/research-wrapper gpt-5.4-mini medium` |
178
179
  | Resume current project | `aginti resume` (`1` is newest/latest; Space shows more) |
179
180
  | Browse all sessions | `aginti resume --all-sessions` |
@@ -252,11 +253,11 @@ The website keeps the visual walkthrough in a carousel so this README can stay f
252
253
  | File tools | `inspect_project`, `list_files`, `read_file`, `search_files`, `write_file`, `apply_patch`, `open_workspace_file`, `preview_workspace`, and `read_image`. |
253
254
  | Shell tools | Guarded host or Docker workspace shell execution with package-install policy and command safety checks. |
254
255
  | Browser tools | Playwright browser actions with lazy startup and optional domain allowlists. |
255
- | Model routing | LocalLLM Fast/Deep defaults, explicit and resource-gated Max, image-capability-gated Vision XL, explicit DeepSeek/OpenAI/OpenRouter/Qwen/Venice/mock routes, and optional spare/wrapper/auxiliary models. |
256
+ | Model routing | LocalLLM Fast/Deep defaults, authenticated implementation-only Code capability, explicit and resource-gated Max, image-capability-gated Vision XL, explicit DeepSeek/OpenAI/OpenRouter/Qwen/Venice/mock routes, and optional spare/wrapper/auxiliary models. |
256
257
  | Writing specialist | A dedicated writing-only LLM call for prose, chapters, scripts, books, essays, research-paper sections, and revisions, with formatter handoff notes for Markdown/LaTeX/Final Draft. |
257
258
  | Patch workflow | Codex-style patch envelopes, unified diffs, exact replacements, hashes, compact diffs, and path guardrails. |
258
259
  | Parallel scouts | Optional scout calls for architecture, implementation, review, tests, git flow, research, symbol tracing, and dependency risk. |
259
- | Image reading and web research | LocalLLM sessions send pixels only to the loopback vision endpoint. `web_research` preserves source lists for the active model to synthesize. Hosted OpenAI and wrapper paths are explicit opt-ins, never credential-driven fallbacks. |
260
+ | Image reading and web research | LocalLLM sessions keep pixels on the loopback vision endpoint. `web_search`, `read_web_page`, and `deep_research` provide fast discovery, exact source extraction, resumable evidence gathering, and claim-level citation audits. Hosted paths remain explicit opt-ins. |
260
261
  | SCS mode | Default Student-Committee-Supervisor quality gate with independent planning, execution, and validation roles. |
261
262
  | AAPS adapter | Optional `@lazyingart/aaps` integration for `.aaps` workflow init, validate, parse, compile, dry-run, and run commands. |
262
263
  | AgentLink | Local-first collaboration between AgInTi sessions through boards, typed messages, action contracts, safe summaries, and evidence bundles. |
@@ -274,6 +275,7 @@ AgInTiFlow does not treat "the model" as one global setting. It has roles:
274
275
  | --- | --- | --- |
275
276
  | Route | `localllm/localllm-fast` | Local planner, triage, short tasks, and routing decisions. |
276
277
  | Main | `localllm/localllm-deep` | Local complex executor for coding, debugging, writing, research, and long tasks. |
278
+ | Code capability | `localllm/localllm-code` | Smart implementation-only upgrade after authenticated alias discovery; unavailable aliases fall back to Deep. |
277
279
  | Spare | `localllm/localllm-deep` medium | Local cross-check lane; a hosted spare requires explicit selection. |
278
280
  | Wrapper | `codex/gpt-5.5` medium | Optional external coding-agent advisor; `research_wrapper` defaults to `gpt-5.4-mini` medium for image/web second opinions. |
279
281
  | Auxiliary | `grsai/nano-banana-2` (off) | Explicitly enabled image generation and other non-text helper tools; no credential-driven provider failover. |
@@ -371,6 +373,7 @@ LOCALLLM_BASE_URL=http://127.0.0.1:8008/v1
371
373
  LOCALLLM_API_KEY=local-dev-key
372
374
  AGINTI_LOCALLLM_ROUTE_MODEL=localllm-fast
373
375
  AGINTI_LOCALLLM_MAIN_MODEL=localllm-deep
376
+ AGINTI_LOCALLLM_CODE_MODEL=localllm-code
374
377
 
375
378
  # Optional explicit hosted upgrades; never automatic LocalLLM fallbacks.
376
379
  DEEPSEEK_API_KEY=...
@@ -404,6 +407,7 @@ More detail:
404
407
  - [docs/model-selection.md](docs/model-selection.md)
405
408
  - [docs/auxiliary-image-generation.md](docs/auxiliary-image-generation.md)
406
409
  - [docs/perception-and-web-research.md](docs/perception-and-web-research.md)
410
+ - [docs/deep-research-engine.md](docs/deep-research-engine.md)
407
411
  - [docs/cli-i18n.md](docs/cli-i18n.md)
408
412
  - [docs/skillmesh.md](docs/skillmesh.md)
409
413
 
@@ -420,6 +424,7 @@ More detail:
420
424
  | Runtime modes and autonomy | [docs/runtime-modes-and-autonomy.md](docs/runtime-modes-and-autonomy.md) |
421
425
  | Skills and tools | [docs/skills-and-tools.md](docs/skills-and-tools.md) |
422
426
  | Image reading and web research | [docs/perception-and-web-research.md](docs/perception-and-web-research.md) |
427
+ | Deep research engine | [docs/deep-research-engine.md](docs/deep-research-engine.md) |
423
428
  | Server-owned text-only fallback | [docs/safe-chat.md](docs/safe-chat.md) |
424
429
  | Skill Mesh | [docs/skillmesh.md](docs/skillmesh.md) |
425
430
  | Housekeeping logs | [docs/housekeeping.md](docs/housekeeping.md) |
@@ -0,0 +1,172 @@
1
+ # Deep Research Engine
2
+
3
+ AgInTiFlow has two deliberately different research paths:
4
+
5
+ - `web_search` is a fast lookup tool.
6
+ - `deep_research` is a bounded, resumable evidence workflow for questions that
7
+ need multiple sources, disagreement analysis, or a durable report.
8
+
9
+ Simple questions should stay on the fast path. A deep-research run spends more
10
+ queries and model calls only when breadth, verification, and traceability add
11
+ real value.
12
+
13
+ ## Architecture
14
+
15
+ The implementation follows the strongest production patterns without making
16
+ every query an unbounded agent swarm:
17
+
18
+ 1. **Plan**: the active provider decomposes the question into non-overlapping
19
+ subquestions, search queries, preferred source types, and exclusions.
20
+ 2. **Search**: queries run with bounded concurrency. The no-key default falls
21
+ back from DuckDuckGo HTML to Bing RSS. An explicitly configured Brave Search
22
+ route is optional. Multi-domain corpora receive separate bounded `site:`
23
+ queries matched to entity-specific subquestions instead of one fragile OR
24
+ expression.
25
+ 3. **Rank, diversify, and deduplicate**: canonical URLs remove tracking state;
26
+ primary, official, scholarly, and high-relevance results rank ahead of
27
+ summaries, while a bounded diversity penalty prevents one domain from
28
+ crowding every selected source.
29
+ 4. **Read exact sources**: `read_web_page` validates every redirect before the
30
+ next request, rejects private DNS resolutions, streams bounded bytes, strips
31
+ scripts/navigation, extracts article/main text and metadata, records hashes,
32
+ and marks all retrieved text as untrusted evidence.
33
+ 5. **Extract evidence**: isolated structured-output calls identify relevant
34
+ subquestions, claims, exact quotations, confidence, and limitations.
35
+ 6. **Verify**: deterministic code checks that quoted passages occur in the
36
+ exact retrieved source. Unverified quotations do not enter synthesis.
37
+ 7. **Fill gaps**: standard/deep runs may issue one bounded follow-up pass for
38
+ uncovered subquestions when query and source budgets remain.
39
+ 8. **Synthesize**: the active provider receives verified evidence rather than
40
+ arbitrary page text. Every substantive paragraph and finding carries source
41
+ IDs.
42
+ 9. **Audit**: deterministic code removes invented source IDs and unsupported
43
+ synthesis statements whose cited sources produced no verified evidence,
44
+ then reports claim, quotation, citation, question, domain, and
45
+ primary-source coverage.
46
+ 10. **Persist**: every stage checkpoints one JSON state file. The final cited
47
+ Markdown report is saved beside it and sent to the canvas.
48
+
49
+ This combines the orchestrator/worker and separate citation-pass lessons
50
+ described by [Anthropic's production research
51
+ system](https://www.anthropic.com/engineering/multi-agent-research-system)
52
+ with the iterative plan/search/read/gap/synthesize and background-resume model
53
+ documented for [Gemini Deep
54
+ Research](https://ai.google.dev/gemini-api/docs/deep-research). AgInTiFlow keeps
55
+ the fan-out explicitly bounded and stays on the active DeepSeek, LocalLLM, or
56
+ other selected provider.
57
+
58
+ ## Research Budgets
59
+
60
+ | Depth | Queries | Sources | Gap passes | Intended use |
61
+ | --- | ---: | ---: | ---: | --- |
62
+ | `quick` | 3 | 6 | 0 | Small comparison or source check |
63
+ | `standard` | 6 | 12 | 1 | Normal multi-source research |
64
+ | `deep` | 10 | 20 | 1 | Broad review, contested topic, or decision report |
65
+
66
+ The caller may reduce these budgets, but hard caps remain 12 queries and 24
67
+ sources. Search/page concurrency is bounded to six and defaults to three or
68
+ four.
69
+
70
+ ## Usage
71
+
72
+ Interactive:
73
+
74
+ ```text
75
+ /deep-research standard Compare current primary-source approaches to citation verification in research agents
76
+ /deep-research deep Review recent optical biosensing methods, emphasizing original papers and unresolved limitations
77
+ ```
78
+
79
+ An agent can call:
80
+
81
+ ```json
82
+ {
83
+ "query": "What evidence supports the current design choices?",
84
+ "depth": "standard",
85
+ "sourcePolicy": "primary",
86
+ "domains": ["docs.example.org", "arxiv.org"]
87
+ }
88
+ ```
89
+
90
+ To resume a partial or completed same-query run, pass the returned
91
+ `researchId`. A completed same-day run is returned from its checkpoint unless
92
+ `refresh=true` is explicit. A transient run that retrieved zero allowed sources
93
+ is marked failed, preserves its attempts, and retries retrieval on resume
94
+ instead of caching an empty report as success. Checkpoint schema changes
95
+ invalidate old cached runs automatically.
96
+
97
+ ## Artifacts
98
+
99
+ Each session stores:
100
+
101
+ ```text
102
+ artifacts/deep-research-RESEARCH_ID.json
103
+ artifacts/deep-research-RESEARCH_ID.md
104
+ ```
105
+
106
+ The JSON includes:
107
+
108
+ - objective, plan, query/source budgets, and source policy;
109
+ - every search attempt and provider failure/fallback;
110
+ - canonical source URLs, metadata, retrieval timestamps, and SHA-256 hashes;
111
+ - readable source text and ranked passages;
112
+ - extracted claims, exact quotations, limitations, and question mappings;
113
+ - missing questions, source diversity, and quote-verification rates;
114
+ - final synthesis and citation audit;
115
+ - stage/status fields used for crash-safe resume.
116
+
117
+ ## Search Providers
118
+
119
+ The default `auto` policy uses public no-key providers:
120
+
121
+ ```text
122
+ DuckDuckGo HTML -> Bing RSS
123
+ ```
124
+
125
+ For an explicitly configured Brave Search account:
126
+
127
+ ```bash
128
+ export AGINTI_WEB_SEARCH_PROVIDER=brave
129
+ export BRAVE_SEARCH_API_KEY=...
130
+ ```
131
+
132
+ An ambient key does not select Brave. The provider must be selected explicitly
133
+ through configuration or a tool argument.
134
+
135
+ ## Safety And Evidence Rules
136
+
137
+ - Only public HTTP/HTTPS URLs are accepted. Embedded credentials, single-label
138
+ internal hosts, loopback, RFC1918, link-local, multicast, `.local`, private
139
+ DNS resolutions, and redirected private targets are rejected before fetch.
140
+ - Domain allowlists and blocklists apply to search results, direct reads, and
141
+ redirect targets.
142
+ - Tracking parameters and fragments are removed before deduplication.
143
+ - Page bytes are bounded while streaming; extracted characters are bounded too.
144
+ - HTML scripts, forms, navigation, footers, and similar noise are removed.
145
+ - Retrieved text is always labeled untrusted and never treated as tool or agent
146
+ instructions.
147
+ - PDFs are hash-verified but not misrepresented as parsed by the dependency-free
148
+ page reader. A document/PDF tool remains responsible for full PDF extraction.
149
+ - Synthesis sees only verified evidence records. Unknown citation IDs and
150
+ citations to sources without verified evidence are removed and reported.
151
+ - Provider selection remains explicit. Deep research uses the active provider;
152
+ it does not silently escape LocalLLM or DeepSeek because another API key is
153
+ present.
154
+
155
+ ## Quality Signals
156
+
157
+ The report audit exposes evidence quality rather than hiding it behind fluent
158
+ prose:
159
+
160
+ - question coverage;
161
+ - readable source count;
162
+ - primary/scholarly source count;
163
+ - independent-domain count;
164
+ - exact-quote verification rate;
165
+ - statement-level citation coverage;
166
+ - unknown/invented citation IDs;
167
+ - unsupported synthesis statements removed before report rendering;
168
+ - contradictions, uncertainties, and unresolved questions.
169
+
170
+ These metrics are diagnostic gates, not a guarantee that a source is correct.
171
+ High-stakes work still requires domain review and, where appropriate, direct
172
+ inspection of the underlying paper, standard, dataset, or official record.
@@ -30,6 +30,7 @@ health: http://127.0.0.1:8008/healthz
30
30
  models: authenticated GET /v1/models
31
31
  route lane: localllm-fast
32
32
  main lane: localllm-deep
33
+ coding lane: localllm-code (authenticated, implementation-only capability upgrade)
33
34
  maximum lane: localllm-max
34
35
  vision: localllm-vision-xl
35
36
  embedding: localllm-embed (sibling-service alias; not an AgInTi text-routing tier)
@@ -39,7 +40,7 @@ The default bearer value used by the local deployment is an interoperability pla
39
40
 
40
41
  Readiness requires both `health.ok === true` and `health.ollama.ok === true`, followed by an authenticated `/v1/models` check that confirms the requested alias exists. Health alone is not sufficient.
41
42
 
42
- The installed local ladder is capability- and resource-aware. `localllm-fast` handles short routing and bounded work; substantive coding and agent tasks use the 30B-A3B Q4 `localllm-deep` lane. The 30B-A3B Q8 `localllm-max` lane remains explicitly selectable, but every new or resumed Max run performs a fresh pre-inference gate after authenticated alias discovery. It requires at least 24 GiB available host RAM, swap use no higher than 75%, and 40 GiB aggregate free NVIDIA memory (Q8 weights plus working reserve). Missing GPU telemetry fails closed. Automatic Max is off by default and requires `AGINTI_LOCALLLM_ALLOW_AUTO_MAX=true`; an eligible run confirms the configured Max alias and fresh headroom before upgrading the actual model client from Deep. If the optional upgrade cannot be proven safe, it continues on Deep rather than failing. The automatic Vision policy requires both a trusted image-input signal and confirmed model capability. The shipped CLI/web currently reach vision through the local `read_image` tool or explicit `localllm-vision-xl` selection; both paths readiness-check the selected alias, and prompt keywords alone never activate Vision XL.
43
+ The installed local ladder is capability- and resource-aware. `localllm-fast` handles short routing and bounded work; substantive general agent tasks use the 30B-A3B Q4 `localllm-deep` lane. High-confidence implementation work begins on Deep and may upgrade to the independently configured `AGINTI_LOCALLLM_CODE_MODEL` alias only when the same bearer-authenticated `/v1/models` response reports it. Missing or unverified availability stays on Deep, never a hosted provider. The implementation classifier excludes writing, research, paper, book, novel, design, documentation, slides, education, and image profiles, and requires an implementation action rather than a bare code mention or explanation request. The effective selection and a secret-free candidate policy are durable: selected coding sessions resume exactly, while a Deep fallback may re-evaluate authenticated availability on a later resume. Manual models and explicit providers remain exact. The 30B-A3B Q8 `localllm-max` lane remains explicitly selectable, but every new or resumed Max run performs a fresh pre-inference gate after authenticated alias discovery. It requires at least 24 GiB available host RAM, swap use no higher than 75%, and 40 GiB aggregate free NVIDIA memory (Q8 weights plus working reserve). Missing GPU telemetry fails closed. Automatic Max is off by default and requires `AGINTI_LOCALLLM_ALLOW_AUTO_MAX=true`; an eligible non-code run confirms the configured Max alias and fresh headroom before upgrading the actual model client from Deep. If the optional upgrade cannot be proven safe, it continues on Deep rather than failing. The automatic Vision policy requires both a trusted image-input signal and confirmed model capability. The shipped CLI/web currently reach vision through the local `read_image` tool or explicit `localllm-vision-xl` selection; both paths readiness-check the selected alias, and prompt keywords alone never activate Vision XL.
43
44
 
44
45
  ## Provider-neutral capabilities
45
46
 
@@ -171,6 +172,7 @@ Offline deterministic tests run on every change:
171
172
  - timeout before output, cancellation, and no post-cancel dispatch;
172
173
  - context calculation includes tool schemas and output reserve;
173
174
  - no silent hosted fallback;
175
+ - implementation-only coding alias selection requires authenticated exact availability, with Deep fallback and durable resume behavior;
174
176
  - session resume preserves provider, model, capability profile, and executed-tool ledger.
175
177
 
176
178
  Live compatibility tests are opt-in because they load local models:
@@ -180,6 +182,7 @@ Live compatibility tests are opt-in because they load local models:
180
182
  | `localllm-pocket` / 4B (direct sibling-service compatibility alias, not an automatic AgInTi tier) | direct answer, one-tool selection, malformed-output recovery, truthful blocker |
181
183
  | `localllm-fast` / 8B | focused code inspection/edit/test loop, cancellation, resumed turn |
182
184
  | `localllm-deep` / 30B-A3B Q4 | multi-step plan, repair after failed tool evidence, long-context compaction |
185
+ | `localllm-code` / configured coding capability | repository implementation/tool loop, exact-alias readiness, Deep fallback, resumed selection |
183
186
  | `localllm-max` / 30B-A3B Q8 | explicit opt-in, resource preflight, highest-fidelity local code task |
184
187
  | `localllm-vision-xl` / 30B-A3B Q4 | attached-image understanding with no keyword-only activation |
185
188
  | DeepSeek/OpenAI | same fixtures, plus explicit escalation and stronger-model quality comparison |
@@ -20,10 +20,11 @@ The local tier policy uses the workstation's installed aliases without treating
20
20
  | --- | --- | --- |
21
21
  | `localllm-fast` | Qwen3 8B Q4 routing and bounded work | Default for simple work. |
22
22
  | `localllm-deep` | Qwen3 30B-A3B Q4 substantive coding/agent work | Default for complex work. |
23
+ | `localllm-code` | Provider-neutral coding capability (the sibling catalog currently maps it to Qwen3-Coder 30B-A3B Q4) | Smart selection only for high-confidence implementation work and only after authenticated availability; otherwise Deep. |
23
24
  | `localllm-max` | Qwen3 30B-A3B Q8 highest-fidelity local text/code | Explicit selection; automatic use additionally requires opt-in, authenticated availability, fresh resource readiness, and no shared-workstation pressure. |
24
25
  | `localllm-vision-xl` | Qwen3-VL 30B-A3B Q4 image understanding | The automatic policy requires a trusted image-input signal plus confirmed capability. The shipped CLI/web currently use readiness-checked `read_image` or explicit selection; prompt keywords alone do not activate it. |
25
26
 
26
- Installed aliases are not loaded during routing. Automatic Max is off by default; set `AGINTI_LOCALLLM_ALLOW_AUTO_MAX=true` to opt in. An opted-in high-complexity run starts on Deep, confirms the Max alias through authenticated `/v1/models`, and only then samples current resources. Unknown or pressured resource state stays on Deep. Explicit Max also cannot bypass the live gate: immediately before client creation, each new or resumed run rechecks at least 24 GiB available RAM, swap use at or below 75%, and 40 GiB aggregate free NVIDIA memory. A blocked explicit gate creates no model client and performs no inference.
27
+ Installed aliases are not loaded during routing. A genuine coding/implementation request starts on Deep, checks the authenticated model inventory, and selects the exact `AGINTI_LOCALLLM_CODE_MODEL` value only when present. Missing or unverified capability stays on Deep; the decision and effective model are recorded so fallback sessions can re-evaluate and selected sessions resume on the same model. Explanation-only code questions and non-code writing/research/documentation/design keep their existing route. Automatic Max is off by default; set `AGINTI_LOCALLLM_ALLOW_AUTO_MAX=true` to opt in. An opted-in high-complexity non-code run starts on Deep, confirms the Max alias through authenticated `/v1/models`, and only then samples current resources. Unknown or pressured resource state stays on Deep. Explicit Max also cannot bypass the live gate: immediately before client creation, each new or resumed run rechecks at least 24 GiB available RAM, swap use at or below 75%, and 40 GiB aggregate free NVIDIA memory. A blocked explicit gate creates no model client and performs no inference.
27
28
 
28
29
  Long writing tasks use an additional tool boundary: `writing_specialist`. The main model still plans the run, manages files, formats Markdown/LaTeX/Final Draft output, compiles/checks artifacts, and finishes. The specialist gets only the writing brief, canon, style guide, prior draft, target, audience, constraints, and format intent, then returns prose plus a formatter handoff. It follows the active LocalLLM provider by default even when hosted keys exist. Cross-provider writing requires both an explicit target (`AGINTI_WRITING_PROVIDER` or a per-run provider override) and `AGINTI_ALLOW_HOSTED_WRITING_SPECIALIST=true` (or the equivalent per-run permission flag); language detection and ambient credentials never grant that permission.
29
30
 
@@ -75,7 +76,7 @@ Provider families:
75
76
 
76
77
  | Family | Models |
77
78
  | --- | --- |
78
- | LocalLLM | `localllm-fast`, `localllm-deep`, `localllm-max`, `localllm-vision-xl`; Max and Vision retain the gates above |
79
+ | LocalLLM | `localllm-fast`, `localllm-deep`, `localllm-code`, `localllm-max`, `localllm-vision-xl`; Code, Max, and Vision retain the gates above |
79
80
  | DeepSeek | `deepseek-v4-flash`, `deepseek-v4-pro` |
80
81
  | Venice | `venice-uncensored-1-2`, `venice-uncensored`, `gemma-4-uncensored` |
81
82
  | OpenAI | `gpt-5.5`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.3-codex`, `gpt-5.3-codex-spark`, `gpt-5.2`; each has low/medium/high/xhigh reasoning |
@@ -148,7 +149,7 @@ It keeps smart routing enabled. If the Venice key is missing, run `/auth venice`
148
149
 
149
150
  ## Keys
150
151
 
151
- The LocalLLM baseline uses `http://127.0.0.1:8008/v1` and the installation's loopback key (`local-dev-key` in the documented local setup). `AGINTI_LOCALLLM_MODEL` or `LOCALLLM_MODEL` is the shared local text override; role-specific `AGINTI_LOCALLLM_ROUTE_MODEL` and `AGINTI_LOCALLLM_MAIN_MODEL` take precedence. Optional `AGINTI_LOCALLLM_MAX_MODEL` and `AGINTI_LOCALLLM_VISION_MODEL` name the gated heavyweight aliases. LocalLLM overrides must remain loopback URLs. Generic `LLM_*` values do not redefine the local provider.
152
+ The LocalLLM baseline uses `http://127.0.0.1:8008/v1` and the installation's loopback key (`local-dev-key` in the documented local setup). `AGINTI_LOCALLLM_MODEL` or `LOCALLLM_MODEL` is the shared local text override; role-specific `AGINTI_LOCALLLM_ROUTE_MODEL` and `AGINTI_LOCALLLM_MAIN_MODEL` take precedence. `AGINTI_LOCALLLM_CODE_MODEL` names the independently configurable coding capability alias; AgInTiFlow never needs the underlying engine tag. Optional `AGINTI_LOCALLLM_MAX_MODEL` and `AGINTI_LOCALLLM_VISION_MODEL` name the other gated heavyweight aliases. LocalLLM overrides must remain loopback URLs. Generic `LLM_*` values do not redefine the local provider.
152
153
 
153
154
  Keys are saved account-wide in `~/.agintiflow/.env` by default. Use `--project` only when the current project needs an override in ignored `.aginti/.env`:
154
155
 
@@ -8,7 +8,9 @@ AgInTiFlow separates visual understanding, web search, and wrapper advice so eac
8
8
  | --- | --- | --- |
9
9
  | `read_image` | Read workspace screenshots, plots, scanned text, diagrams, or allowed remote image URLs. | Saves JSON and Markdown reports under `artifacts/perception/`, records image hashes, and sends the Markdown report to the canvas when used by an agent run. |
10
10
  | `web_search` | Cheap raw search snippets. | Returns compact titles, URLs, snippets, and fallback search URL. |
11
+ | `read_web_page` | Read one exact public source instead of relying on a snippet. | Returns bounded article text, metadata, canonical URL, relevant passages, retrieval time, and content hash. |
11
12
  | `web_research` | Sourced research unit for current or external information. | Saves `artifacts/research/*-web-research.json` with query, mode, source list, and answer. |
13
+ | `deep_research` | Plan, retrieve, verify, synthesize, and audit a genuinely multi-source question. | Saves resumable JSON state and a cited Markdown report with coverage metrics. |
12
14
  | `research_wrapper` | Read-only strict-JSON second opinion from the selected wrapper. | Saves `artifacts/wrappers/*-research-wrapper.json` with wrapper, model, reasoning, metadata, result, and raw fallback output. |
13
15
 
14
16
  ## Defaults
@@ -18,6 +20,8 @@ AgInTiFlow separates visual understanding, web search, and wrapper advice so eac
18
20
  - Codex image reading requires both `provider=codex` and explicitly enabled wrapper tools. It is not an automatic fallback.
19
21
  - OpenAI image reading defaults to `AGINTI_PERCEPTION_MODEL=gpt-5.4-mini` and `AGINTI_PERCEPTION_REASONING=medium`, with fallback models remaining inside the same explicitly selected OpenAI provider.
20
22
  - `web_research` defaults to lightweight snippet mode. The active LocalLLM can synthesize those returned snippets and sources during the next agent step without a second provider call.
23
+ - `web_search` automatically falls back from DuckDuckGo HTML to Bing RSS. Brave Search is available only when explicitly selected and configured.
24
+ - `deep_research` uses the active provider for planning, evidence extraction, and synthesis. It never treats another provider's ambient credentials as permission.
21
25
  - `web_research mode=openai` is accepted only for an active OpenAI session or when `allowHostedWebResearch=true`. A denied or failed hosted synthesis is returned with `ok=false`; any preserved snippets are labeled fallback evidence rather than hosted success.
22
26
  - `json_specialist` stays on the active provider. A different provider requires `allowHostedJsonSpecialist=true`; ambient hosted keys and model-generated provider arguments cannot escalate a LocalLLM session.
23
27
  - `research_wrapper` defaults to `AGINTI_RESEARCH_WRAPPER_MODEL=gpt-5.4-mini` and `AGINTI_RESEARCH_WRAPPER_REASONING=medium`.
@@ -30,6 +34,7 @@ AgInTiFlow separates visual understanding, web search, and wrapper advice so eac
30
34
  /image-read artifacts/screenshots/app.png what looks wrong?
31
35
  /image-read --codex artifacts/screenshots/app.png what looks wrong?
32
36
  /web-research latest Android Gradle plugin official docs
37
+ /deep-research standard compare current citation-verification methods using primary sources
33
38
  /research-wrapper gpt-5.4-mini medium
34
39
  /research-wrapper off
35
40
  ```
@@ -40,6 +45,8 @@ Use `read_image` when pixels matter. Do not guess from filenames or surrounding
40
45
 
41
46
  Use `web_research` when freshness, sources, package docs, standards, or current external information matter. Use `domains` to restrict research to official or primary sources.
42
47
 
48
+ Use `deep_research` when one lookup is insufficient: literature reviews, disputed claims, broad comparisons, technical decisions, or reports that require explicit coverage and citation auditing. See [Deep Research Engine](deep-research-engine.md).
49
+
43
50
  Use `research_wrapper` when a second model should cross-check image/web/research conclusions. The wrapper receives a strict JSON contract and should preserve uncertainty when it cannot directly inspect a source.
44
51
 
45
52
  ## Safety
@@ -47,6 +54,7 @@ Use `research_wrapper` when a second model should cross-check image/web/research
47
54
  - Local image paths must stay inside the workspace unless the run is explicitly trusted host mode.
48
55
  - `.env`, credential files, private keys, and secret-looking paths are blocked.
49
56
  - Remote images require web access and respect domain allowlists.
57
+ - Web page reads reject private/local network targets and private redirect destinations.
50
58
  - Images are capped at 10 MB and four inputs per call.
51
59
  - Artifacts preserve hashes and metadata but never store API keys.
52
60
  - Provider selection is credential-neutral: an ambient key authenticates only a backend that the run already selected and permitted.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.200",
3
+ "version": "0.20.202",
4
4
  "type": "module",
5
5
  "description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
6
6
  "license": "Apache-2.0",
@@ -77,6 +77,7 @@
77
77
  "scripts/smoke-inbox.js",
78
78
  "scripts/smoke-long-jobs.js",
79
79
  "scripts/smoke-localllm-auto-max.js",
80
+ "scripts/smoke-localllm-code-routing.js",
80
81
  "scripts/smoke-local-resource-policy.js",
81
82
  "scripts/smoke-localllm-model-tiers.js",
82
83
  "scripts/smoke-localllm-provider.js",
@@ -92,6 +93,7 @@
92
93
  "scripts/smoke-model-roles.js",
93
94
  "scripts/smoke-platform.js",
94
95
  "scripts/smoke-perception-research.js",
96
+ "scripts/smoke-deep-research.js",
95
97
  "scripts/smoke-permission-modes.js",
96
98
  "scripts/smoke-public-research-wrapper.js",
97
99
  "scripts/smoke-safe-chat.js",
@@ -143,6 +145,7 @@
143
145
  "smoke:run-stdin": "node scripts/smoke-run-stdin.js",
144
146
  "smoke:runtime-core": "node scripts/smoke-runtime-core.js",
145
147
  "smoke:localllm-auto-max": "node scripts/smoke-localllm-auto-max.js",
148
+ "smoke:localllm-code-routing": "node scripts/smoke-localllm-code-routing.js",
146
149
  "smoke:local-resource-policy": "node scripts/smoke-local-resource-policy.js",
147
150
  "smoke:context-budget-recovery": "node scripts/smoke-context-budget-recovery.js",
148
151
  "smoke:localllm-model-tiers": "node scripts/smoke-localllm-model-tiers.js",
@@ -154,6 +157,7 @@
154
157
  "smoke:model-roles": "node scripts/smoke-model-roles.js",
155
158
  "smoke:platform": "node scripts/smoke-platform.js",
156
159
  "smoke:perception-research": "node scripts/smoke-perception-research.js",
160
+ "smoke:deep-research": "node scripts/smoke-deep-research.js",
157
161
  "smoke:permission-modes": "node scripts/smoke-permission-modes.js",
158
162
  "smoke:public-research": "node scripts/smoke-public-research-wrapper.js",
159
163
  "smoke:safe-chat": "node scripts/smoke-safe-chat.js",
@@ -175,7 +179,7 @@
175
179
  "storage:migrate": "node bin/aginti-cli.js storage migrate",
176
180
  "publish:env": "node scripts/npm-publish-from-env.js publish --access public",
177
181
  "publish:env:whoami": "node scripts/npm-publish-from-env.js whoami",
178
- "test": "npm run check && npm run smoke:localllm-provider && npm run smoke:localllm-model-tiers && npm run smoke:localllm-auto-max && npm run smoke:local-resource-policy && npm run smoke:context-budget-recovery && npm run smoke:session-runtime && npm run smoke:runtime-core && npm run smoke:progressive-tools && npm run smoke:truthful-completion && npm run smoke:writing-specialist-routing && npm run eval:local-first-agent && npm run eval:provider-attribution && npm run smoke:runtime-compat && npm run smoke:autoupdate && npm run smoke:web-api && npm run smoke:math-rendering && npm run smoke:web-ui && npm run smoke:web-autostart && npm run smoke:webapp-command && npm run smoke:web-port-fallback && npm run smoke:docker-command && npm run smoke:coding-tools && npm run smoke:dynamic-step-budget && npm run smoke:execution-policy && npm run smoke:aaps-adapter && npm run smoke:auxiliary-tools && npm run smoke:perception-research && npm run smoke:public-research && npm run smoke:safe-chat && npm run smoke:auth && npm run smoke:agentlink && npm run smoke:canvas-artifacts && npm run smoke:capabilities && npm run smoke:mcp && npm run smoke:model-roles && npm run smoke:platform && npm run smoke:permission-modes && npm run smoke:skills && npm run smoke:skillmesh && npm run smoke:tmux-tools && npm run smoke:long-jobs && npm run smoke:run-stdin && npm run smoke:cli-chat && npm run smoke:inbox",
182
+ "test": "npm run check && npm run smoke:localllm-provider && npm run smoke:localllm-model-tiers && npm run smoke:localllm-code-routing && npm run smoke:localllm-auto-max && npm run smoke:local-resource-policy && npm run smoke:context-budget-recovery && npm run smoke:session-runtime && npm run smoke:runtime-core && npm run smoke:progressive-tools && npm run smoke:truthful-completion && npm run smoke:writing-specialist-routing && npm run eval:local-first-agent && npm run eval:provider-attribution && npm run smoke:runtime-compat && npm run smoke:autoupdate && npm run smoke:web-api && npm run smoke:math-rendering && npm run smoke:web-ui && npm run smoke:web-autostart && npm run smoke:webapp-command && npm run smoke:web-port-fallback && npm run smoke:docker-command && npm run smoke:coding-tools && npm run smoke:dynamic-step-budget && npm run smoke:execution-policy && npm run smoke:aaps-adapter && npm run smoke:auxiliary-tools && npm run smoke:perception-research && npm run smoke:deep-research && npm run smoke:public-research && npm run smoke:safe-chat && npm run smoke:auth && npm run smoke:agentlink && npm run smoke:canvas-artifacts && npm run smoke:capabilities && npm run smoke:mcp && npm run smoke:model-roles && npm run smoke:platform && npm run smoke:permission-modes && npm run smoke:skills && npm run smoke:skillmesh && npm run smoke:tmux-tools && npm run smoke:long-jobs && npm run smoke:run-stdin && npm run smoke:cli-chat && npm run smoke:inbox",
179
183
  "pack:dry-run": "npm pack --dry-run",
180
184
  "smoke:capabilities": "node scripts/smoke-capabilities.js"
181
185
  },
@@ -4,26 +4,22 @@ import fs from "node:fs/promises";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
- import { authProviderKeyHelp, authProviderKeyUrl, normalizeAuthProvider } from "../src/auth-onboarding.js";
8
- import { getProviderDefaults } from "../src/model-routing.js";
9
- import { maskProviderKey, providerKeyPreview, providerKeyStatus, setProviderKey } from "../src/project.js";
10
7
 
11
8
  const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
12
9
  const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "agintiflow-auth-"));
13
- const envKeys = [
14
- "DEEPSEEK_API_KEY",
15
- "OPENAI_API_KEY",
16
- "OPENROUTER_API_KEY",
17
- "LLM_API_KEY",
18
- "QWEN_API_KEY",
19
- "VENICE_API_KEY",
20
- "GRSAI",
21
- "GRSAI_API_KEY",
22
- ];
23
- const originalEnv = Object.fromEntries(envKeys.map((key) => [key, process.env[key]]));
24
- const originalAgintiflowHome = process.env.AGINTIFLOW_HOME;
25
- for (const key of envKeys) delete process.env[key];
10
+ const CONFIG_ENV_PATTERN = /^(?:AGENT|AGINTI|AGINTIFLOW|LOCALLLM|LOCAL_LLM|LLM|DEEPSEEK|OPENAI|OPENROUTER|QWEN|VENICE|GRSAI|BRAVE|ALLOW_|WRAPPER_|MAX_STEPS$|SANDBOX_MODE$|USE_DOCKER_SANDBOX$|PACKAGE_INSTALL_POLICY$|COMMAND_CWD$|PREFERRED_WRAPPER$)/u;
11
+ for (const key of Object.keys(process.env)) {
12
+ if (CONFIG_ENV_PATTERN.test(key)) delete process.env[key];
13
+ }
26
14
  process.env.AGINTIFLOW_HOME = path.join(tempRoot, ".agintiflow-home");
15
+ const [authOnboarding, modelRouting, project] = await Promise.all([
16
+ import("../src/auth-onboarding.js"),
17
+ import("../src/model-routing.js"),
18
+ import("../src/project.js"),
19
+ ]);
20
+ const { authProviderKeyHelp, authProviderKeyUrl, normalizeAuthProvider } = authOnboarding;
21
+ const { getProviderDefaults } = modelRouting;
22
+ const { loadProjectEnv, maskProviderKey, providerKeyPreview, providerKeyStatus, setProviderKey } = project;
27
23
 
28
24
  function assert(condition, message) {
29
25
  if (!condition) throw new Error(message);
@@ -35,7 +31,12 @@ async function runCli(args, stdin = "") {
35
31
  cwd: tempRoot,
36
32
  stdio: ["pipe", "pipe", "pipe"],
37
33
  env: {
38
- ...process.env,
34
+ PATH: process.env.PATH || "/usr/bin:/bin",
35
+ HOME: tempRoot,
36
+ USERPROFILE: tempRoot,
37
+ LANG: "C.UTF-8",
38
+ LC_ALL: "C.UTF-8",
39
+ AGINTIFLOW_HOME: process.env.AGINTIFLOW_HOME,
39
40
  AGINTIFLOW_RUNTIME_DIR: "",
40
41
  },
41
42
  });
@@ -89,7 +90,17 @@ try {
89
90
 
90
91
  const projectOnlyRoot = path.join(tempRoot, "project-only");
91
92
  await fs.mkdir(path.join(projectOnlyRoot, ".aginti"), { recursive: true });
92
- await fs.writeFile(path.join(projectOnlyRoot, ".aginti", ".env"), 'OPENAI_API_KEY="project-only-openai-key"\n', "utf8");
93
+ await fs.writeFile(
94
+ path.join(projectOnlyRoot, ".aginti", ".env"),
95
+ ['OPENAI_API_KEY="project-only-openai-key"', 'AGINTI_LOCALLLM_CODE_MODEL="project-code-alias"', ""].join("\n"),
96
+ "utf8"
97
+ );
98
+ const projectOnlyEnv = loadProjectEnv(projectOnlyRoot);
99
+ assert(projectOnlyEnv.projectEnv, "project-only LocalLLM code model env was not parsed");
100
+ assert(
101
+ process.env.AGINTI_LOCALLLM_CODE_MODEL === "project-code-alias",
102
+ "AGINTI_LOCALLLM_CODE_MODEL was not loaded from the project env"
103
+ );
93
104
  let projectOnlyStatus = providerKeyStatus(projectOnlyRoot);
94
105
  assert(projectOnlyStatus.openai && projectOnlyStatus.projectEnv, "project-only key was not loaded");
95
106
  await fs.access(path.join(tempRoot, ".agintiflow-home", ".env"))
@@ -100,6 +111,7 @@ try {
100
111
  if (error?.code !== "ENOENT") throw error;
101
112
  });
102
113
  delete process.env.OPENAI_API_KEY;
114
+ delete process.env.AGINTI_LOCALLLM_CODE_MODEL;
103
115
 
104
116
  process.env.DEEPSEEK_API_KEY = "ambient-deepseek-key";
105
117
  process.env.OPENROUTER_API_KEY = "ambient-openrouter-key";
@@ -182,6 +194,7 @@ try {
182
194
  "openrouter-defaults",
183
195
  "venice-defaults",
184
196
  "project-key-not-auto-promoted",
197
+ "project-code-model-env",
185
198
  "ambient-key-discovery-is-read-only",
186
199
  "project-key-override",
187
200
  "qwen-key-status",
@@ -195,11 +208,8 @@ try {
195
208
  )
196
209
  );
197
210
  } finally {
198
- for (const key of envKeys) {
199
- if (originalEnv[key] === undefined) delete process.env[key];
200
- else process.env[key] = originalEnv[key];
211
+ for (const key of Object.keys(process.env)) {
212
+ if (CONFIG_ENV_PATTERN.test(key)) delete process.env[key];
201
213
  }
202
- if (originalAgintiflowHome === undefined) delete process.env.AGINTIFLOW_HOME;
203
- else process.env.AGINTIFLOW_HOME = originalAgintiflowHome;
204
214
  await fs.rm(tempRoot, { recursive: true, force: true });
205
215
  }