@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 +7 -2
- package/README.md +9 -4
- package/docs/deep-research-engine.md +172 -0
- package/docs/local-first-agent-runtime.md +4 -1
- package/docs/model-selection.md +4 -3
- package/docs/perception-and-web-research.md +8 -0
- package/package.json +6 -2
- package/scripts/smoke-auth.js +33 -23
- package/scripts/smoke-deep-research.js +516 -0
- package/scripts/smoke-localllm-auto-max.js +22 -31
- package/scripts/smoke-localllm-code-routing.js +589 -0
- package/scripts/smoke-localllm-model-tiers.js +62 -46
- package/scripts/smoke-progressive-tool-selection.js +6 -0
- package/skills/deep-research/SKILL.md +49 -0
- package/src/agent-runner.js +76 -6
- package/src/config.js +15 -1
- package/src/deep-research.js +986 -0
- package/src/guardrails.js +36 -0
- package/src/interactive-cli.js +34 -1
- package/src/local-code-routing.js +146 -0
- package/src/model-client.js +62 -1
- package/src/model-routing.js +276 -1
- package/src/progressive-tool-selection.js +7 -5
- package/src/project.js +2 -0
- package/src/step-budget-controller.js +2 -0
- package/src/task-profiles.js +2 -2
- package/src/tool-contract.js +1 -0
- package/src/web-search.js +525 -39
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
|
-
#
|
|
17
|
-
#
|
|
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`
|
|
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
|
|
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
|
|
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
|
|
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 |
|
package/docs/model-selection.md
CHANGED
|
@@ -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.
|
|
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
|
},
|
package/scripts/smoke-auth.js
CHANGED
|
@@ -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
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
199
|
-
if (
|
|
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
|
}
|