Repository navigation
Releases: nouli-ai/nouli
Release list
v0.5.1
Changed
- Enter on a blank TUI form row advances to the next section without sending. Nonempty Context and Options/Levels rows still add items; send from a nonempty Question or use Ctrl-S from any section, including to reuse a previous question.
v0.5.0
Added
- The TUI model picker:
/modelor Ctrl-L opens a search list in the view with models from your connections, fetched from each provider where it offers a list. Add a connection or enter a missing API key without leaving the view. The model you choose stays selected in later views. nouli-core:provider::models::listfetches the models a provider lists;HttpTransport::get_with_headerssends a GET with the same credentials as a request.- The TUI status line is configurable:
/statuslinechooses built-in fields or the Minimal, Session, Request, and Hidden presets, and the choice is saved intui.tomlbesideconfig.toml. nouli-core:Ledger::decode_settingsdecodes a frozen-settings snapshot and distinguishes missing or unsupported format versions from malformed payloads.nouli-core:ErrorReport::newconstructs non-retryable diagnostic reports;RevisionOrigin::of_turnandRevisionOrigin::of_basepreserve durable and ephemeral context origins;context::validate_updatesvalidates update shapes and rejects duplicate new-record IDs.nouli-core:WorkflowRequest::validatechecks workflow graphs and request intent without a ledger or fingerprint;workflow::RequestErrordistinguishes graph-compilation errors from invalid session selections, request IDs, required records, and context updates.nouli-core: plan-localmedia::PreparedImages/PreparedImagereuse image derivatives and dimensions.TokenCounter::count_preparedand optional ownedTokenCounter::snapshotsupport prepared counting and blocking context construction; existing custom counters keep their synchronous behavior by default.DecisionProvider::attempt_prepareddefaults to the existing attempt method.EngineError::Internalreports failed blocking context tasks as internal errors.nouli-core:provider::evaluatesends a decision through the selected protocol;ProviderProfile::image_encodingreturns the configured or protocol-default image encoding.nouli-core:Criterion::label,Criterion::description,TurnOutcome::outcome_for,outcome::outcome_for,Answer::selected_probability,Answer::probability_of, andoutcome::probability_ofread a criterion's text, the outcome for a question, and a choice's probabilities.nouli-core:context::evidencetypes saved image and saved-answer records:DecisionReference,ImageSnapshot,image_record,rebind_decision_record,ContextRecord::as_image,ContextRecord::as_decision_reference, and theIMAGE_KEY_PREFIX,DECISION_KEY_PREFIX,IMAGE_FIELD, andDECISION_REFERENCE_FIELDconstants.storage::decisions::DecisionSourceis re-exported from there.nouli-core:context::evidence::markerfinds, formats, parses, and strips the inline[image:UUID]and[decision:UUID]markers that bind text to saved images and saved answers.nouli-core:protocol::OUTCOME_UNKNOWN,protocol::NOT_DISPATCHED, andprotocol::OWNER_EXITEDname the error codes that recovery reads from saved attempts and workflow nodes.nouli-core:Engine::planned_settings,Engine::planned_ephemeral_settings, andEngine::planned_workflow_settingsreturn the settings an evaluation will use, so callers can prepare credentials for the providers it will actually call.
Changed
- The TUI status row shows the model before its provider, such as
jev-latest · typesafe, so a model ID likeanthropic/claude-opus-4.8is not mistaken for its provider. - TUI form navigation: Enter in Context adds a row and never sends, so send with Enter in Question or Ctrl-S. Tab moves between Context, Question, and Options/Levels, and Enter adds Options/Levels rows. Backspace on an empty Context row reopens the row above.
- The TUI form shows which box is active: inactive headings dim, the box Tab goes to says so (
Tab to add a question), all answer types show only in Question, and three or more Context rows fold into a count away from Context. nouli-core:Dataequality compares numbers by value, so a whole-number float equals the same integer and a value equals its stored copy.- The TUI has a quieter layout and a larger bee closer to the brand mascot. Answer types sit at the right of the Question rule, the decisions pane takes the full height, and the status row shows the chosen fields and
Shift-Tab question type. Progress, errors, and list hints appear in their own row only when needed. /helpin the TUI opens a shortcuts dialog instead of printing to the transcript; type/to list commands.- Ctrl-P now holds and resumes the TUI view for copying; Esc also resumes.
nouli-core:Ledger::decode_payloadconsistently reports typed decoding failures asStorageError::Payload, including unsupported direct or nested settings snapshots. UseLedger::decode_settingsto distinguish unsupported snapshot versions asStorageError::FrozenSettings. Built-in frozen request and workflow loaders retain theunsupported_frozen_settingsreport.nouli-core: convertingStorageError::ConflictintoTurnErrornow consistently producesTurnError::Conflictand thehead_conflictreport code, including outside turn writes.nouli-core:AcceptedRequest::statenow usesstorage::reservations::ReservationStateinstead ofString; exported JSON retains the samepending,completed, andinterruptedvalues.nouli-core: workflow request and node validation rejects context updates that create the same record ID more than once.nouli-core: workflow report projection moves fromprotocol::projection::workflowand itsProjectionErrortoengine::workflow::reporting::{workflow, ReportError}.- Invalid
nouli connect --protocoland--bindingvalues now show clap usage errors listing the accepted values. REPL session creation and rename use the same session-name validation message. nouli-core:Ledger::decision_referencereports an invalid snapshot value asDecisionError::Evidenceinstead ofDecisionError::Data.- Report each
nouli connectand terminal startup setup failure with its own error code and exit code instead ofconnection_setup_failedwith exit 2. Invalid arguments, such as an unknown service, protocol, binding, connection name, model, environment variable, credential command, or key, are input errors (exit 2) with codes such asunknown_service,invalid_protocol, andconnection_exists. Configuration problems keep their configuration codes and name the configuration file, such asinvalid_configuration_syntax,configuration_unreadable, orauth_store_insecure(exit 2). Failures to write the configuration (configuration_write_failed) or the credential store (auth_store_write_failed, asnouli auth loginreports) exit 6, and canceling setup reportssetup_canceledand exits 130. nouli-core:context::projection::project_with_base,Ledger::record_attempt_progress,Ledger::record_workflow_progress, andLedger::fail_workflow_attempttake their origin or progress argument by reference, so callers no longer clone it.- Save each new attempt's provider error with the same category and code as the final report, such as
provider_capacity,provider_authentication_failed, andprovider_transport_failed, instead of separate attempt-only codes. Timed-out attempts keep theprovider_outcome_unknowncode under thetransportcategory, and each attempt keeps its detailed message, such as the HTTP status. nouli-core: workflow ledger methods returnWorkflowError::Conflictinstead ofWorkflowError::Storage(StorageError::Conflict)when a run, reservation, or node changes concurrently.
Removed
- All TUI function-key bindings: F5 (use Enter or Ctrl-S) and F6 (use Ctrl-P).
- The TUI's Enter-to-send banner, bottom shortcut legend, and Ready and Draft status words.
nouli-core: removemedia::Evidence::assets;provider::wire::bodyprepares image assets using the connection settings. Existing protocol-specific evaluation and request-body functions remain available.nouli-core: remove the unusedhistory::AttemptState,history::AttemptRecord,HistoryEvent::AttemptRecorded, andworkflow::FrozenRuntypes, and theContextPlan::questionsandContextPlan::requiredfields. The ledger never wrote these types, and the context a model receives is unchanged.
Fixed
- Keep the TUI model picker responsive while credential commands run, cancel its background work when it closes, and preserve the highlighted choice as model lists arrive. Long model names now leave room for the provider column in narrow terminals.
- Sending a question that references a saved answer containing a whole-number probability, such as 0 or 1, no longer fails with
head_conflict. - Workflows no longer fail with
workflow_conflictwhen a node input is a whole number, such as a probability of exactly 1. - Keep the terminal responsive to cancellation while native image turns assemble context and prepare request bodies. Reuse each image derivative across budgeting, context reduction, and dispatch within a plan, while retaining original saved images and wire bytes.
- A timed-out file import now stops converter descendants as well as their launcher, so imports cannot leave converter processes running or wait indefinitely for inherited pipes.
- Keep fact text at normal brightness when it contains phrases such as
(from x)or(replaced; ...); dim source and replacement annotations using their saved metadata. - In the terminal view, a saved-answer reference recorded without a display label, such as one a
nouli-corecaller wrote, is usable as@saved answerinstead of being reported unavailable when a draft cites it. A malformed saved-answer reference is reported as an error when the terminal view restores a session, and fails the terminal graph andnouli viewwith a message naming it, instead of being skipped silently. - Run only the credential commands of the providers a turn or
workflow runuses. A `...
v0.4.3
Added
- Select and copy TUI text with the Select text header control or F6. Drag normally and use the terminal's Copy command; Esc or F6 restores the draft and graph controls. The view holds still during selection while active model requests continue.
Changed
- Install with
brew install nouli-ai/tap/nouli; installations fromstanding-desks/tapswitch to the new tap on the nextbrew update. The download installer is now athttps://nouli.ai/install.sh, and the previous URL keeps working. - Keep the TUI's bee greeter at the top of the transcript, so output scrolls it away instead of replacing it; scrolling back reveals it again.
v0.4.2
Added
- Greet interactive sessions with Nouli's honey bee above the form, with
> <eyes at rest and> _while drafting. The greeter gives way to conversation output and stays hidden in short terminals.
v0.4.1
Changed
- Configure any compatible service through
system-oneoropenai-decisions, explicit HTTP bindings, headers, image formats and optional limits. Remove provider/model recognition and the bundled capacity catalog; omitted budgets use 8,192 estimated tokens, clamped to a configured window. This replaces thetypesafeandopenrouter-decisionsprotocol names. Older frozen runs require a fresh store and are preserved untouched. - Resize the graph by dragging its divider at any time, including while editing a field. Ctrl-G remains keyboard navigation; use the terminal’s selection modifier for native text selection. Keep the chosen width through session changes and clamp it when the terminal shrinks.
- Connect referenced answers to the questions that use them in the TUI and
nouli view, including after reopening a destination session. Load the exact saved source history without blending sessions; separate question cards where necessary and mark reference edges with dashed arrows in Mermaid. - Search saved conversation text with
@, including context, structured values, options and answers across local sessions. Show matching excerpts, carry the selected saved state into the next decision, and preview historical input with image filenames and scrolling in Browse history, including narrow terminals and long drafts. - Show the latest saved question included in the next TUI request, including Yes/No follow-ups, and retain its answer and used images alongside new evidence during context reduction.
- Show image filenames in the form, transcript, graph, and session previews. Keep internal image references hidden while preserving native image data; attachment movement and deletion operate on the complete image label.
- Use Shift-Tab as the only answer-type shortcut, cycling left to right from any field, with a short hint beside the selector. Tab navigates fields and options/levels.
- In Options/Levels, Enter adds the next row; a second consecutive Enter sends. Typing, pasting, or navigation continues editing without sending.
- Simplify the terminal view with a
nouliheader, plain question text, hidden generated question IDs, one-line reuse notices, shorter key hints, and one model name. Enter sends from Context/Question when ready; in Options/Levels, Enter adds a row and a second Enter sends. Tab moves between fields and list items. - Use the terminal’s selection modifier for native text selection (Option-drag in iTerm2). Navigate form fields with the keyboard; mouse reporting lets the divider resize without changing focus.
- Use Citrus accents for answer types: lime for Yes/No, cyan for Choose one, and rose for Score, including results and decision cards. Color-free output keeps text emphasis.
- Keep the selected answer type after sending. In the terminal form, leaving a choice's options or a score's levels empty reuses the latest matching question's exact list and rubric, with a visible notice. Leave its question empty too to ask it again with new context. Enter a new list to replace it. Yes/No questions stay fresh, and earlier answers remain in history.
- Ask questions in plain text in the full-screen form, with automatic IDs and literal punctuation. Shift-Tab cycles answer types left to right from any field; Tab navigates fields and moves through options/levels, adding a row after the last filled item. Ctrl-S / F5 submits from any field, including context still being edited.
- Paste several lines into Options to add one option per line. Context and question fields preserve paragraphs and indentation.
- Keep decisions from sessions opened in the same TUI visible when starting another session. New sessions appear as independent roots; shared ancestry is drawn once.
- Prepare upright, resized images for Jev automatically while preserving saved originals. Image estimates count visual input separately from text, including repeated references, so screenshots no longer consume context as base64 text.
- Show the selected provider/model and Ready, Draft, Asking, or Cancelling status before the first answer. After a response, the actual served model replaces its alias. Key hints follow the focused field, failed input stays available for retry, and unnamed graph sessions use short IDs.
Removed
- Remove the interactive
/whatifcommand from completion, help, and input handling.
Added
-
Set up connections with
nouli connect, service shortcuts or a fully custom endpoint, masked API keys, environment sources and credential programs. Edit the generated ordinary TOML directly; setup preserves unrelated comments and serializes concurrent edits. Use/connect,/login,/logoutand/modelwhile idle without losing the draft. -
Call Cloudflare Workers AI directly through the shared System One codec and its explicit HTTP binding, including model-specific routes and response envelopes.
-
Find files from the launch folder with
@beside saved answers. Select without sending, and snapshot contents into the focused field. Import DOCX/PPTX text and tables, CSV/TSV rows, XLS/XLSX/XLSM/XLSB/ODS sheets and native images including rendered SVGs; PDF text uses Poppler and legacy DOC/PPT conversion optionally uses LibreOffice. File drops use the same parsers, and each file occupies one option/level. -
Rename the current session with
/rename NAME, preserving its history, IDs, model settings, references and unsent draft. Header, graph and later@searches use the new name; collisions leave the session unchanged. -
Reference saved answers with
@in any TUI field. Search question text or IDs across all sessions in the selected local store, inspect answer versions in Browse history, and insert an exact source without changing the current question type or answer list. References retain their saved results and image inputs, survive follow-ups and session changes, and remain ordinary selectable terminal text. -
Give new sessions without an explicit name a durable random
scientist-number-nounname, such ascurie-7-diffraction, using short lowercase surnames, numbers 1–20, and original spinner-style noun forms. Names are unique within the ledger, including concurrent launches. Bare/newnow works without a name; explicit names remain available. -
Drop files into the focused terminal field: UTF-8 files insert their contents, PDFs import text through Poppler's
pdftotext, and PNG, JPEG, GIF, WebP, BMP, TIFF, and ICO images become saved image evidence. Quoted paths, shell-escaped paths, file URLs, multiple files, and terminals without bracketed drops are supported. Each file is limited to 16 MiB; unsupported files report an error without submitting. -
Send image evidence using native TypeSafe, OpenAI Decisions, and OpenRouter formats. Images used by the current turn are required evidence, so context reduction cannot silently remove them. Provider model support and context limits still apply.
v0.4.0
Added
- Open interactive sessions full screen. In a terminal, a bare
noulistarts a new session, known by its short ID, andnouli open SESSIONopens one, creating it without asking when it is missing. The transcript sits above a form that holds the queued facts, the question, and its options or levels: Shift-Tab picks yes/no, choice, or score, and Tab, Up, and Down move between the sections. The session's decisions are drawn beside the transcript when the terminal is at least 116 columns wide, and Ctrl-G shows them in narrower ones. Typing/lists the commands,/sessionsresumes an earlier session, and Ctrl-C cancels a running turn.
Changed
- Brighten the teal accent in terminal output.
Removed
- Remove the line-by-line prompt. Nouli no longer writes
repl_history, so you can delete that file from your store. Piped input, and terminals that take no escape codes (TERM=dumb), still read lines from standard input. A barenoulino longer lists sessions before opening one;/sessionslists them in the view.
v0.3.0
Changed
- Ask each question once. A turn asks only the questions given with it,
-qor a?line, in one call, and no later turn, branch, or blend asks them again, so a saved answer is never decided again. Sessions saved by 0.2.0 keep reading, and the questions they saved are no longer asked. - Take one question per command:
-qno longer repeats, so each question is its own call, and a second-qis a usage error. Request files and workflow nodes can still ask several independent questions in one call. - Require a question for every turn:
nouli add,ask, andwhatif, andnewwith facts, fail withquestions_requiredwithout-q. Innouli open, facts wait in the queue until a?line sends them. - Make
/whatifask its own question,/whatif ?id: prompt [a, b], with the queued facts; it still saves nothing. An empty line now sends again only what a failed turn left queued. - Drop
re-asked Nfrom turn headers.
Removed
- Remove standing questions:
--drop,nouli questions, and the/drop,/questions, and/askcommands. A request file that setsstandingfails withinvalid_standing_question, and session exports no longer liststanding_questions.
v0.2.0
Added
- Add Homebrew installation through
standing-desks/tap/nouli. - Add a checksum-verified download installer for Apple silicon macOS and ARM64 or x86_64 GNU/Linux.
- Build Linux x86_64 release archives alongside the existing ARM64 downloads.
- Add a
sessionreport for a session created without a turn. - Add a credential store:
nouli auth login PROVIDERsaves a key once,nouli auth logout PROVIDERremoves it, andnouli auth listshows where each provider's key comes from. A key can be stored directly, read from an environment variable, or printed by a command. The file is created private (auth.toml, mode 0600) and refused if others can read it. Shell variables and.envfiles still win. - Add an interactive session loop:
nouli open SESSION, or a barenouliin a terminal. Type facts, then ask a question with?id: prompt [a, b]to send them with it; questions stay with the session, and return on an empty line asks them again. Slash commands branch, blend, replace facts, drop questions, and run what-ifs. Without a terminal,nouli openreads its lines from standard input. - Add
nouli facts SESSION, which lists numbered facts and marks the ones inherited from a source session or replaced, andnouli questions SESSION, which prints standing questions in the one-line syntax. Both support--json. - Accept questions written as one-line strings in workflow files, mixed freely with full question objects. A mistake names the node and question.
- Add a one-line question syntax:
id: prompt [a, b]for a choice,id: prompt <a, b, c>for an ordered score, andid: promptfor a yes/no question. - Add standing questions to the library: a session remembers the questions it keeps asking, so a turn can send only new facts. A branch inherits its source's questions as they were at the branch point, and a blend starts with none.
- Add facts to the library: caller evidence stored as numbered records. Replacing a fact keeps its number and the model sees only the new text, while the earlier version stays in the session history.
Changed
- Replace evaluating at the root command with verbs:
nouli new NAME,nouli add SESSION,nouli ask SESSION, andnouli whatif SESSION. A session keeps its facts and the questions it keeps asking, so a turn only needs what is new.nouli new NAMEwith no facts or questions creates the session without a turn. - Write questions on the command line as
-q "id: prompt [a, b]"instead of JSON. Questions given withnew,add, oraskbecome standing questions that later turns ask again;--drop IDstops asking one. - Record facts as numbered evidence instead of turn text.
--replace N TEXTcorrects fact N; the model sees only the new text and the earlier version stays in the session history. - Print turns as text with probability bars for every option, with a marker where an answer moved since the last turn.
--json,--jsonl, and TOON output keep their shape. - Select the session by position in
nouli view SESSION, and renamenouli workflowstonouli workflow. - Take a request file as
--input FILEwithout asession; the command supplies the session.
Removed
- Remove
nouli view --sessionandnouli workflows. - Remove
-s/--state,--name,--session,--no-session, and the root--fromand--questionsoptions. Usenouli new NAME --from SOURCE,nouli add SESSION, andnouli whatif SESSION. - Remove JSON and TOON text after
-q. Put complete questions in a request file with--input.
v0.1.0
Added
- Add typed choice, noul, and score decisions through the Nouli CLI and Rust library.
- Add durable session histories, branching, blending, and workflow recovery.
- Add decision graph views in the terminal, and
nouli view --mermaidfor Mermaid flowcharts on GitHub and other Markdown renderers. - Add provider configuration and
.envcredential loading. - License Nouli and its Rust packages under MIT, including the license in native archives.
- Add Linux and macOS ARM64 downloads.