Commit graph

55 commits

Author SHA1 Message Date
patriceckhart
b325477870 Update zot welcome tagline
Some checks failed
ci / test (windows-latest) (push) Has been cancelled
ci / test (macos-latest) (push) Has been cancelled
ci / test (ubuntu-latest) (push) Has been cancelled
2026-06-24 07:33:11 +02:00
patriceckhart
cf7ddf5322 Add quick model switch shortcuts (Ctrl+1..9) with /settings model shortcuts sub-view
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-23 06:56:24 +02:00
patriceckhart
4bec50ae9c fix(swarm): inherit host model provider for auto-spawn
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-22 17:39:21 +02:00
patriceckhart
6899695320 Merge pull request #43 from mi-skam/clipboard-paste-support
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-22 07:54:35 +02:00
patriceckhart
c56e04afd5 fix(tui): correct btw cursor offset
Only count the dialog frame padding row when padDialogFrame actually inserts it, so the btw editor cursor stays on the input row after a turn.

Co-authored-by: mi-skam <40042054+mi-skam@users.noreply.github.com>
2026-06-22 07:47:19 +02:00
patriceckhart
ab3d4c5ced fix: harden clipboard image paste
Preserve prompt whitespace when stripping clipboard image markers, accept osascript warning noise, support clipboard image file paths, and keep the existing user bubble rendering.

Co-authored-by: mi-skam <40042054+mi-skam@users.noreply.github.com>
2026-06-22 07:47:19 +02:00
mi-skam
1f663cb867
fix: use osascript for macos clipboard image paste 2026-06-21 22:31:34 +02:00
mi-skam
2a4b07839d
fix(swarm): ignore tool-loop turn_end for completion 2026-06-21 15:25:47 +02:00
mi-skam
4a6d6915ca
Add clipboard paste support 2026-06-21 14:47:06 +02:00
patriceckhart
1a24a204b4 fix: correct image MIME by content and re-encode for kitty
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
read tool and Anthropic builder derived an image's media type from its
file extension, so a .png file containing JPEG bytes was declared
image/png. Anthropic sniffs the real bytes and 400s the whole request
on a mismatch, breaking the session and making it impossible to resume.

- read tool now sniffs the real format from magic bytes (sniffImageMIME)
- Anthropic request builder reconciles declared MIME against the actual
  bytes on every outbound image, repairing already-persisted sessions on
  continue/resume
- kitty renderer re-encodes non-PNG images to PNG (f=100 is PNG-only),
  fixing empty image boxes for JPEG/GIF screenshots
2026-06-20 18:18:52 +02:00
patriceckhart
0250ce1c48 fix(tui): keep scroll position stable in resumed sessions
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-19 18:09:33 +02:00
patriceckhart
31437ddf2b fix(tui): reserve live tool overlay height to stop band jump 2026-06-19 17:41:41 +02:00
patriceckhart
8cd6818405 feat(tui): show live bash command body
Some checks failed
ci / test (macos-latest) (push) Has been cancelled
ci / test (ubuntu-latest) (push) Has been cancelled
ci / test (windows-latest) (push) Has been cancelled
2026-06-18 07:34:23 +02:00
patriceckhart
6d28881e78 fix(extensions): isolate subprocess process groups 2026-06-18 07:27:38 +02:00
patriceckhart
4615780369 fix(jail): block POSIX-absolute cd targets on Windows
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
filepath.IsAbs("/etc") is false on Windows, so the cd-escape check
folded "/etc" back inside root via filepath.Join and let it through,
failing CI. Treat a leading forward slash that is not OS-absolute as an
escape attempt.
2026-06-17 17:24:02 +02:00
patriceckhart
bfd8c07cfa fix(jail,tui): emit OSC 7 cwd and stop false-positive cd jail errors
#38: emit OSC 7 (ESC ]7;file://host/path) on TUI setup and /cd so
terminals like kitty open new tabs/splits in the launch cwd instead of
inheriting a stale extension-subprocess directory. Verified end-to-end
against kitty 0.46.2.

#39: stop blanket-rejecting cd into subdirectories of the sandbox root.
CheckCommand now resolves the cd target and rejects only real escapes.
Add Sandbox.DisplayPath to present jailed tool-result/error paths
relative to root, reducing the absolute-path bias that pushed the model
toward unjailing.
2026-06-17 17:15:37 +02:00
patriceckhart
5a4e4923f2 test(swarm): wait for inbox listener before send
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-17 16:38:56 +02:00
patriceckhart
ac7da16dd5 Harden custom provider support
Keep built-in models visible when merging models.json, accept custom provider API keys through the login flow, preserve model-level base URLs, and route custom clients through the scoped HTTP wrapper.

Also register providers from model-level baseUrl metadata, warn on unknown api values, dedupe login picker entries, and cover the custom-provider behavior with regression tests.

Co-authored-by: pulyankote <4314305+pulyankote@users.noreply.github.com>
2026-06-16 20:17:25 +02:00
Patric Eckhart
4570db2a3f
Merge branch 'main' into feat/custom-llm-providers 2026-06-16 19:43:15 +02:00
Gopinath
dc2d337239 feat(provider): support custom providers defined in models.json
Custom provider metadata now lives entirely in $ZOT_HOME/models.json
instead of a separate provider-config.json or auth.json base_url entry.

- Extend UserProvider to carry baseUrl and api format (openai/anthropic).
- Recognize custom providers in Resolve, the login picker, and the model
  list when credentials exist.
- Persist only API keys in auth.json; base URLs are read from models.json.
- Normalize custom provider env vars so my-company uses MY_COMPANY_API_KEY.
- Reuse NewOpenAICompat/NewAnthropicCompat for user-defined endpoints.
- Drop the checked-in provider-config.json example and modelListEndpoint.
2026-06-16 09:53:25 -07:00
patriceckhart
ab7fb37046 Scope --insecure TLS to explicit base URL, drop global transport override
Builds on s3rj1k's --insecure flag (#35) but limits insecure TLS to the
resolved inference client for an explicit --base-url, instead of mutating
http.DefaultTransport process-wide. Built-in providers, auth, and model
discovery keep normal certificate verification. Documents the flag in
the CLI reference.

Co-authored-by: s3rj1k <evasive.gyron@gmail.com>
2026-06-16 07:41:38 +02:00
s3rj1k
5859d66f1a
Add --insecure flag to skip TLS verification 2026-06-16 00:38:22 +02:00
patriceckhart
94ece7d00e Support Shift-Enter in terminal input
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-15 18:54:26 +02:00
patriceckhart
85a3c3b73e Add temperature option
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-14 11:42:31 +02:00
patriceckhart
798174c22c Fix telegram bot process checks on Windows
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-13 17:39:14 +02:00
Raymond Gasper
4a8d2ed68e fix(tui): clear @-picker filter when browsing into/out of a directory
In flat (non-recursive) mode, typing a filter to locate a directory and
then opening it with Right re-applied that same filter inside the
directory. Typing "@eda" then Right to open eda/ showed nothing,
because no child of eda/ matches "eda". The filter the user typed
selected the directory at the current level; it has no meaning one
level deeper.

Clear the text after the last "@" (keeping the bare "@" so the picker
stays open) whenever Right or Left successfully changes the browse
level. The filter was scoped to the level just left, so dropping it
shows the new directory's full contents.

Adds a regression test that opens eda/ after an "@eda" filter and
asserts the directory's contents are listed while the stale filter
would have matched nothing.
2026-06-10 09:41:35 -04:00
Raymond Gasper
1a3e0a572e fix(tui): honor nested .gitignore in recursive @-picker + raise entry cap
The recursive @-picker only read the repo's root .gitignore, so a
nested .gitignore (e.g. .opencode/.gitignore ignoring its own
node_modules) was invisible. WalkDir visits lexically, so a
dot-prefixed vendored tree got walked first and its node_modules
flooded the 5000-entry budget before the walk ever reached deeply
nested source files. The picker then fuzzy-matched against junk and
never surfaced the real target.

- Add ignore.Stack: a per-directory .gitignore chain pushed/popped as
  the recursive walk descends, with git-style nearest-file-wins
  semantics including nested negations. scanRecursive now prunes
  nested-ignored trees like node_modules.
- Raise maxRecursiveEntries 5000 -> 50000 and maxRecursiveDepth
  12 -> 24. The bottleneck is per-keystroke fuzzy.Find, not memory:
  a fileEntry is ~120 bytes (~6 MB at 50k), and benchmarked
  fuzzy.Find latency is ~2ms @ 5k, ~13ms @ 50k, ~21ms @ 100k, so 50k
  keeps ranking under one 60Hz frame while holding a large monorepo
  once nested-gitignore pruning has done its job.

Verified against the reporting monorepo: the fully-pruned tree is
4397 entries (node_modules=0), scan ~360ms once (cached after),
match ~2.5ms per keystroke, and @pipeline.py now finds
eda/rjg/enk-1150/pipeline.py.

Adds regression tests at both the ignore.Stack layer and the
file_suggest layer, including a repro of the nested-node_modules +
deep-file scenario.
2026-06-10 09:13:18 -04:00
Raymond Gasper
fb08ad382b feat(tui): apply .gitignore in both @-picker modes + add respect_gitignore toggle
Previously gitignore filtering ran only in recursive mode; the default
flat directory browse showed .git/, node_modules/, etc. Apply it in
both modes and make it user-controllable.

- Flat scan() now also skips .git and gitignored entries.
- New respectGitignore flag on the suggester (default on), persisted as
  respect_gitignore in config.json, surfaced as a /settings checkbox,
  and plumbed through SettingsStore/InteractiveConfig/cli. Toggling
  flips the picker live.
- .git is always pruned in recursive mode regardless of the toggle, to
  protect the entry budget.
- Tests for flat-mode filtering and the toggle across both modes.
2026-06-09 15:57:50 -04:00
Raymond Gasper
3ce9c2861f refactor: honor .gitignore in recursive @-search instead of a hardcoded denylist
Replace the static recursiveSkipDirs list (which would inevitably drift
as new tools appear) with the project's root .gitignore. Most caches
that bloat a recursive walk \u2014 build outputs, dependency dirs, and IaC
caches like .terraform/.terragrunt-cache \u2014 are already gitignored in
real projects.

- Extract the existing .gitignore matcher from agent/extcmd.go into a
  new leaf package, packages/ignore, so packages/agent/modes can share
  it without an import cycle. extcmd keeps thin aliases for its tests.
- scanRecursive now loads the root .gitignore and prunes ignored
  entries, plus an unconditional .git skip (rarely self-listed).
- Tests: gitignore-driven pruning in the picker, plus unit tests for
  the extracted matcher.

No new dependencies.
2026-06-09 15:54:23 -04:00
Raymond Gasper
e7439baaa6 feat(tui): skip IaC caches (.terraform, .terragrunt-cache, ...) in recursive @-search
Add Terraform/Terragrunt/Pulumi/Serverless/CDK provider and module
caches to the recursive walk skip list. These hold copies of
downloaded providers and generated module trees that would otherwise
dominate the entry budget with non-source files.
2026-06-09 15:48:41 -04:00
Raymond Gasper
7ac6034d1d feat(tui): fuzzy @-file matching with toggleable recursive search
The @-mention file picker previously did a plain case-insensitive
substring match within a single directory, only reachable nesting via
arrow-key drill-down.

- Rank matches with sahilm/fuzzy (pinned v0.1.1 to avoid the go 1.24.5
  directive in v0.1.2, which would exceed CI's Go 1.23).
- Add a recursive mode that walks the whole project tree below cwd,
  matching cwd-relative paths (e.g. @foobar finds src/foo/bar.go),
  skipping heavy dirs (.git, node_modules, ...) and bounded by entry
  and depth caps. Arrow drill-down is disabled in this mode.
- Persist as recursive_file_suggest in config.json, surfaced as a
  /settings checkbox, plumbed through SettingsStore/InteractiveConfig/
  cli. Toggling live flips the picker without a restart.
- Tests for fuzzy ranking, recursive cross-dir match, heavy-dir
  pruning, and cache reset on toggle.
2026-06-09 15:44:47 -04:00
patriceckhart
a373e82896 style: drop em-dashes from output-token-budget strings/comments
Co-authored-by: Raymond Gasper <raymondgasper@fastmail.com>
2026-06-09 18:38:09 +02:00
Raymond Gasper
3cf22fc32b fix: request model's full output-token budget per turn
Turns omitted MaxTokens on the provider request, so Bedrock applied its
conservative 4096 default and silently truncated long writes/edits with
stopReason=length. In the TUI this read like the interaction timed out.

Thread the resolved model's catalog MaxOutput through to the request:
  catalog Model.MaxOutput -> Resolved.MaxOutput -> Agent.MaxTokens
  -> provider.Request.MaxTokens
Zero still falls back to each provider's own default, so models without a
catalog MaxOutput are unaffected. The SDK path inherits this via NewAgent.

Also surface StopLength explicitly in the TUI ('response hit the output
limit -- ask it to continue') instead of ending silently.

Tests: TestAgentPropagatesMaxTokens (Agent.MaxTokens reaches the wire) and
TestBedrockBuildRequestMaxTokens (non-zero flows through; zero -> 4096).
2026-06-09 12:24:04 -04:00
patriceckhart
f7bf4a9d41 chore: gofmt spontaneous panel files
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
Co-authored-by: Raymond Gasper <raymondgasper@fastmail.com>
2026-06-08 19:41:28 +02:00
Raymond Gasper
2d46ef9b09 feat(panels): spontaneous open_panel frame for human-in-the-loop tool gates (#19)
Allow extensions to emit an open_panel frame at any time, not just as
the action of a command_response. This makes it possible to build
approval gates, secret collection, and freeform user-input prompts
directly inside tool handlers.

Changes:
- extproto: add OpenPanelFromExt wire type
- extensions/manager: route spontaneous open_panel frames to hooks.OpenPanel
- ext/ext.go: add Extension.OpenPanel() SDK method
- tests: TestSpontaneousOpenPanel (manager), TestOpenPanelEmitsCorrectFrame,
  TestBlockingToolWaitsForPanelKey, TestBlockingToolDenied (SDK)
- docs/plans: add spontaneous-panel.md design doc

The blocking tool pattern (open panel → block on channel → key event →
tool_result) requires no additional wire changes; it falls out of
standard Go concurrency on the extension side.

Part 3 (intercept timeout for built-in tool gating) is out of scope
and tracked separately.
2026-06-08 12:13:55 -04:00
patriceckhart
956b0a24e2 Merge remote-tracking branch 'origin/main' into pr-11 2026-06-08 15:23:22 +02:00
patriceckhart
eef2714dea Scan all known providers in credential fallback (adopts #16) 2026-06-08 15:22:40 +02:00
patriceckhart
323df7f6d3 Discover env-only bedrock in credential fallback scan 2026-06-08 15:17:22 +02:00
Patric Eckhart
ab6d543626
Merge branch 'main' into openrouter-live-models 2026-06-08 07:47:42 +02:00
patriceckhart
a7ef8c22a1 Respect ollama model baseUrl before default
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-08 07:41:05 +02:00
patriceckhart
7da9114a05 Gate live tool rendering behind preceding stream text
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-07 16:58:39 +02:00
patriceckhart
63e33d9aa9 Add clear_notes extension frame and clear notes on new prompt
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-07 11:10:02 +02:00
patriceckhart
30cff8843d Respect gitignore when installing extensions 2026-06-07 10:25:50 +02:00
patriceckhart
10fde8fd0e Fix ext install with relative path source 2026-06-07 10:18:41 +02:00
Dawid Piotrkowski
88b93da57f provider: discover OpenRouter models live, drop baked-in catalog 2026-06-05 15:20:54 +02:00
patriceckhart
7a7bf0b52c Fix Bedrock streaming and provider setup docs
Some checks are pending
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
2026-06-05 08:31:54 +02:00
patriceckhart
4bcdf8804b Purge VS Code scrollback on clear, overlay close, and resize
On VS Code's xterm.js the transcript is taller than the viewport, so an
in-place clear (home + erase-to-end) only wipes the visible rows and the
scrolled-away part lingers in retained scrollback, stacking a duplicate
on the next full repaint.

- Clear() (Ctrl+L) now emits \x1b[3J under keepScrollback to actually
  drop that scrollback, then homes and repaints. Accepts VS Code's
  viewport-snap since the user explicitly asked for a clean screen.
- Overlay close (esc on a dialog, slash/file popup dismissal) now runs
  the same Clear() so closing a picker purges the stale overlay rows
  instead of leaving them in scrollback.
- Resize() does the same purge under keepScrollback; previously it
  skipped the wipe and left a half-repainted old-width frame until the
  user pressed Ctrl+L.

Other terminals keep their no-snap clear path.
2026-06-04 19:16:21 +02:00
patriceckhart
cde9298410 Add !command shell escape and fix VS Code terminal repaints
- Shell escape: typing "!cmd" runs it via the bash tool's shell in the
  session cwd, honoring the /jail sandbox. Output is parked below the
  transcript as a styled terminal-log block until the next prompt or
  /clear, so it never enters the model conversation. Shares busy state
  with the agent: esc cancels it and no turn or other escape can start
  while one is in flight.
- VS Code terminal: full repaints used \x1b[2J, which xterm.js scrolls
  into scrollback and duplicates the frame. Clear in place via cursor
  home + erase-to-end under keepScrollback; Clear()/Resize() no longer
  eagerly wipe. Force a viewport-safe Invalidate on slash/file popup
  open and close transitions there.
- Restore the live tool-call overlay behavior (keep in-flight boxes
  visible until the tool_result reaches the transcript) and drop the
  forced repaint at turn start.
- Document the shell escape in the README.
2026-06-04 18:05:17 +02:00
patriceckhart
ec5eb20ce9 feat(provider): alias common provider names and clarify Bedrock 403
Some checks failed
ci / test (macos-latest) (push) Has been cancelled
ci / test (ubuntu-latest) (push) Has been cancelled
ci / test (windows-latest) (push) Has been cancelled
Map short/alternate provider names (bedrock -> amazon-bedrock, vertex,
gemini, azure, copilot, codex, ...) to their canonical ids in Resolve so
an alias is never treated as unknown and silently downgraded to
anthropic. Add a region-aware hint to Bedrock 403 responses on the
bearer route.
2026-06-03 18:13:22 +02:00
patriceckhart
ea58887bfa Fix login dialog cursor alignment
Some checks failed
ci / test (macos-latest) (push) Has been cancelled
ci / test (ubuntu-latest) (push) Has been cancelled
ci / test (windows-latest) (push) Has been cancelled
2026-05-31 13:51:13 +02:00