Custom connections are gone: the CLI talks to the LLeMbas server it is logged in to
LLeMbas CLI 2.0 is LLeMbas-server-specific (CLI rule 2). Removed: the anthropic, gemini, ollama and responses clients, context discovery and llama-swap unloading (discover.ts), the Connection schema with its dialect, auth, key_cmd, discover, unload_url and one_model_at_a_time, the model `fallback` (it only ever moved to another server), effort_map and cache, and the multi-connection refs. Kept: openai-chat, http, sse, think, effort, tokens and all of src/lembas. - connections.yaml holds the login (`type: webui`, as lembas login writes it). A custom entry from 1.x is read past with a warning that says how to log in, so an old file still starts; with several logins left, the latest is used and the others named. - A model's ref is the id the server serves it under; the older forms (`<login>/<id>`, `<login>/<model>`) still resolve and config.yaml is rewritten once. Without a login there is no model, and the error (and the first-run screen, now the sign-in alone) says `lembas login <address>`. - A login to another server signs this machine out of the previous one. - The window is the server's word (no discovery); a capacity group comes from the server's `capacity.group` alone; embeddings use the server's /v1/embeddings. - `lembas models` lists the server's models; install.sh's starter files, the README and the JSON schemas say the same. Tests: every fixture is a login now (the fake server lists models, answers other GETs with 404, and can hand one model to another script, as a server with several backends); the dialect suites and the cross-connection tests are gone with their code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
80 files changed
+587
-2575
No files matched your search
+1
-20
@@ -17,7 +17,6 @@ import { DEFAULT_RULES, toRules } from "./permission/evaluate.ts"
|
||||
import { hardlineRules } from "./permission/hardline.ts"
|
||||
import { defaultEffort } from "./provider/effort.ts"
|
||||
import { clientFor, familyOf, resolveModel } from "./provider/index.ts"
|
||||
import { discoverContext, unload } from "./provider/discover.ts"
|
||||
import { assembleSystem, instructionFiles, knowledgeScope } from "./prompt/assemble.ts"
|
||||
import { describeRepo, repoState } from "./git/repo.ts"
|
||||
import { findProject, persistProjectRule, trustOf, type Project } from "./project/root.ts"
|
||||
@@ -100,7 +99,7 @@ export interface App {
|
||||
/** The subagents the task tool offers (built-in, global, and a trusted project's), as of start. */
|
||||
agents: import("./project/agents.ts").AgentSpec[]
|
||||
store: Store | undefined
|
||||
/** Every configured `connection/model`, in config order. */
|
||||
/** Every model the server serves, by its id there, in its order. */
|
||||
modelRefs(): string[]
|
||||
/** A ref in any form it may be written in (the old `<login>/<model>` too) as the ref the
|
||||
* model has now; the ref itself when it names nothing. */
|
||||
@@ -497,7 +496,6 @@ export function createApp(o: AppOptions): App {
|
||||
...(at ? { root: at.root, cwd: at.cwd, projectDir: undefined } : {}),
|
||||
jobs: { registry, owner: () => ({ sessionId: childSessionId, job }) },
|
||||
},
|
||||
fallback: engine.o.fallback,
|
||||
steerMark: MARKS.to_subagent,
|
||||
system: (mode, current, plan) =>
|
||||
system(
|
||||
@@ -567,16 +565,6 @@ export function createApp(o: AppOptions): App {
|
||||
system: (m, current, plan) => system(m, current, undefined, undefined, plan),
|
||||
persistRule: trusted ? (rule) => persistProjectRule(project, rule) : undefined,
|
||||
spawn,
|
||||
fallback(current, tried) {
|
||||
for (const ref of current.spec.fallback ?? []) {
|
||||
if (tried.has(ref)) continue
|
||||
try {
|
||||
const m = resolveModel(loaded, ref)
|
||||
return { model: m, client: clientFor(m), effort: startEffort(m) }
|
||||
} catch {}
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
})
|
||||
|
||||
// MCP tools join the engine's list as servers connect (the engine reads it at each prompt).
|
||||
@@ -647,18 +635,11 @@ export function createApp(o: AppOptions): App {
|
||||
const snapshots = o.snapshots === false ? undefined : new Snapshots(project.root, project.gitRoot)
|
||||
engine.busyInput = loaded.config.busy_input ?? "steer"
|
||||
const turns = new Turns(engine, snapshots, store)
|
||||
// After a reply, learn the window if nobody configured it (the model is loaded by then).
|
||||
bus.on((e) => {
|
||||
if (e.type === "done" && !engine.model.spec.context) void discoverContext(engine.model, engine.client).then((n) => n && engine.usage && bus.emit({ type: "usage", usage: engine.usage, context: n, used: engine.contextUsed() }))
|
||||
})
|
||||
// By provider for an instance's models (`deepseek/deepseek-flash`), src/provider/refs.ts.
|
||||
const modelRefs = () => loaded.refs.map((r) => r.ref)
|
||||
const switchModel = (ref: string) => {
|
||||
const m = resolveModel(loaded, ref)
|
||||
const prev = engine.model
|
||||
engine.setModel(m, clientFor(m), startEffort(m))
|
||||
// Moving to another connection frees the old one's memory (llama-swap /unload).
|
||||
if (prev.connectionName !== m.connectionName) void unload(prev)
|
||||
}
|
||||
const setIn = (key: string, value: unknown) => {
|
||||
const path = key.split(".")
|
||||
|
||||
Reference in new issue
Block a user