Skip to content

TEDI v0.3.92

Choose a tag to compare

@github-actions github-actions released this 20 Jul 03:31

Added

  • Local AI models (Ollama, llama.cpp, vLLM) now work end to end. Bring-your-own-key already covered the hosted providers, but a local endpoint was rejected before it could ever connect: the model builder demanded an API key, so a keyless Ollama or llama.cpp server could not be used at all. A loopback base URL (127.x / localhost / [::1]) now counts as keyless, while a remote gateway still gets the actionable "add a key" message instead of a bare 401, and one-click presets were added for Ollama (:11434), llama.cpp (:8080) and vLLM (:8000). See config.ts, OpenAICompatibleBlock.tsx.
  • Editor autocomplete works with every provider, not just three. Ghost-text completion was hardwired to Cerebras / Groq / LM Studio, so anyone holding only an OpenAI, Anthropic or local key got nothing. It now runs on all ten providers with a fast default model each, and the settings block gained a model-id field so a local model name can be entered directly. See autocomplete/provider.ts, AutocompleteBlock.tsx.
  • A read_browser_console tool so the AI can see what a page logged. A document-start capture script folds console.error/warn, onerror and unhandled rejections into a 200-entry ring buffer (so load-time errors are caught too) that the AI drains on demand, closing the browser-debug loop that nothing in the app previously closed. This brings the AI command count to 103. See preview/embed.rs, browser/lib/native.ts.
  • The AI can read images. read_file now falls back to a binary read and returns real image files (PNG/JPEG/GIF/WebP) as image parts, capped at 4 MB; SVG stays text. See tools/fs.ts.
  • Extension API: ctx.ai, ctx.paths.home and clickable status items. Extensions can now read the live AI state and, behind the new ai:configure / ai:prompt permissions, set the model, toggle sub-agents, or send a prompt (setApprovalMode is deliberately not exposed, since it is the one AI setting that persists across restarts). StatusItem.onClick renders a real button instead of a click-hijacking span, and ctx.paths.home was added. See host.ts, registries.ts.
  • A refreshed model line-up. Added GPT-5.x, Claude Opus 4.8 / Sonnet 5 / Fable 5, Gemini 3.5, Grok 4.5 and newer Groq models; every legacy id is kept so an existing saved selection never breaks. See config.ts.

Changed

  • Forced sub-agent fan-out now keys off breadth, not message length. A study verb paired with a breadth cue ("audit the whole codebase", "analisa arsitektur sistem ini") reliably pins the first step to a sub-agent fan-out, while narrow single-file study ("pahami fungsi ini", "analyze the whole file") still does not. The previous fixed 40-character floor rejected genuinely broad but short requests, so the breadth word - not the sentence length - now makes the call. See orchestrationIntent.ts.
  • Cheaper AI turns on gateways without prompt caching. Per-step history compaction used to rewrite old messages on every provider, which busts the prefix cache on those that have one; it now only does so for cache-less gateways and when the payload is actually large, and Anthropic prompt-cache breakpoints are re-applied per step (capped so they never exceed the four-breakpoint ceiling). See compact.ts, cache.ts.
  • The install review shows what an extension's AI tools actually say. Contributed AI-tool descriptions - the text injected into every AI turn, and the real prompt-injection surface - are now disclosed before you consent, not just the tool names. See InstallReviewDialog.tsx.

Fixed

  • Keyless local models now appear in the model pickers. A provider-level filter dropped the entire OpenAI-Compatible provider whenever the shared key slot was empty, so a working keyless local endpoint's models were hidden from both the chat model dropdown and the default-model picker, and the per-instance readiness check downstream never ran. The provider is now gated per instance, so a loopback endpoint's models show and are selectable. See ModelDropdown.tsx, DefaultModelDropdown.tsx.
  • A floated terminal honors your scrollback setting. The pop-out terminal hardcoded a 10,000-line scrollback, ignoring the preference and doubling the memory a user who lowered it had asked to save; it now reads the setting and follows later changes. See FloatTerminal.tsx.
  • Installing an extension can no longer leave an uninstallable "ghost". The TypeScript manifest schema was stricter than the Rust validator, so an extension Rust accepted but TypeScript rejected installed with a success toast yet never appeared in Settings and could not be removed from the UI. The schemas were relaxed to match the backend and the invariant documented. See manifest.ts.
  • A bad extension manifest and a failed activation clean up after themselves. A malformed manifest now surfaces a toast instead of a silent console warning, and an extension whose activate threw no longer leaves its settings card and commands on screen until restart. See loader.ts.

Security

  • Extension risk tiers no longer under-warn on wildcard permissions. The install badge derived its risk level separately from what a permission actually grants, so broad patterns (*:*, invoke*, s*, shell:*, *fs_*) all granted a high-risk capability while badging only medium. The tier is now derived by probing the real permission check, and mcp_ (which can launch arbitrary binaries) and the new ai: permissions are rated high. See permissions.ts.
  • One extension can no longer silently install or approve another. The extension-management commands (ext_install_from_zip / _from_github / ext_enable / ext_disable / ext_uninstall) were added to the hard-deny invoke list, since reaching them would let an extension mint install-time consent for a second one. See permissions.ts.
  • A cross-provider credential leak in autocomplete is closed. The completion key was held in a bare ref while the provider was read fresh from the store, so switching provider and then typing shipped the previous provider's API key to the new provider's endpoint. The key reference now carries its provider provenance and is re-checked after the async key fetch. See EditorPane.tsx, autocomplete/provider.ts.
  • Unattended sub-agent shells are now scope-checked. An autonomous worker's bash was the one tool with no scope enforcement; its commands now run their path tokens through the same secret deny-list and out-of-scope check the file tools use, blocking obvious reads like cat ~/.ssh/id_rsa or absolute paths outside the workspace. It raises the bar rather than sandboxing (a shell cannot be fully scoped by inspecting a string), and only the auto-approved worker path is affected - the approval-gated main agent is unchanged. See security.ts, tools/shell.ts.

macOS users: if Gatekeeper says TEDI "can't be opened because Apple cannot check it for malicious software" or "is damaged and can't be opened", drag the app to /Applications and run this once in Terminal:

xattr -cr /Applications/TEDI.app