Repository navigation
Releases: expilu/smart-decisions
Release list
v0.6.0
0.6.0
Minor Changes
-
#26
3c80dd7- Addedmode: 'auto': the question runs System 1 first and escalates exactly once to System 2 when the answer's confidence falls belowautoModeThreshold(default 0.7; fornoul()the confidence equivalent ismax(noul, 1 − noul)). The escalated answer is returned as-is even at low confidence — one deliberate pass, never a loop. Confident System 1 answers complete without touching System 2, so the fast path stays in the milliseconds. -
#26
3c80dd7- Added global debug logging:debug: trueon any question (both modes) logs the internals to stderr — the prompt, the wire request body, the endpoint, raw responses with their HTTP status, every retry with its reason and backoff, and in System 2 the model's reasoning text and each structured-rejection reason. -
#26
3c80dd7- Implement System 2 mode (mode: 'system2') forchoice(),score()andnoul(): the model deliberates and answers a minimal structured object — one integer 0..10 rating per candidate — and the same answer shapes as System 1 come out of it (winner = argmax, distribution = normalized ratings, same entropy confidence). Requests useresponse_formatwith a strict ratings schema,temperature: 0, no default token budget, and a parse-validate-retry fallback that feeds rejection reasons back to the model so engines with broken or missing structured-output support still work. Adds thethinkingquestion option (valid in 'system2'/'auto' mode;falsesendsreasoning_effort: 'none') and the mode-partitioned question types:Question,ScoreQuestionandNoulQuestionswitch from interfaces to unions overmode, sothinkingset withmode: 'system1'no longer compiles — breaking for consumers extending those types withinterface X extends ...(allowed by semver at 0.x).
v0.5.0
v0.4.0
0.4.0
Minor Changes
-
#15
d88ce52Thanks @expilu! - feat:score()— rate a position on a spectrumNew
score()primitive for decisions that are a position on a scale of ordered,
described levels: its answer is ascore(the probability-weighted mean of the
level numbers, so it can fall between two levels), the per-levelprobabilities
andlegendkeyed by level number as string, and the usual 0..1confidence.
Accepts 2..10 level descriptions incriteria(an ordered array, low end of the
scale first); one dimension per question is recommended. Not implemented yet in System 2 mode. -
#15
d88ce52Thanks @expilu! - feat: shared System 1 core, shared mode router and theModetypechoice()System 1 answers are now produced throughsrc/system1/system1.ts(the
one-token logprobs engine any System 1 question type reuses) andsrc/utils/mode/route-mode.ts
(the mode router: default to System 1, System 2 answers "Not implemented yet" from a single
stub). New exported types:Mode(the shared'system1' | 'system2'union) andBaseQuestion
(the fields every question type carries —Questionextends it). No behavior change:
same prompts, same responses, same errors.
v0.3.0
0.3.0
Minor Changes
-
#12
87127d5Thanks @expilu! - Breaking (pre-1.0): the provider settings onQuestionmoved into a newModeltype.apiBaseUrl,apiKeyandmodelno longer sit flat onQuestion; they are now
question.model.{apiBaseUrl, apiKey, model}. This groups everything about how the
model is reached and served into one reusable object to pass to everychoice().ModelgainsextraBody: extra fields forwarded verbatim into the chat completions
request body for engine- or model-specific settings (i.e.chat_template_kwargs
thinking toggles on llama.cpp/vLLM/SGLang,reasoning_efforton OpenAI/OpenRouter/
Ollama, Ollama's nativethink). Reserved request keys the library's single-token
trick depends on (model,messages,stream,logprobs,top_logprobs,
max_tokens,temperature) cannot be overridden through it;chat_template_kwargs
merges one level deep with user keys winning per key.- System 1's request now asks for
top_logprobs: 20instead of 50: 20 is the highest
portable window (OpenAI and OpenRouter cap it at 20, vLLM's server default
--max-logprobsis 20). On llama.cpp (accepts up to 50) the smaller window is
enough for realistic option counts. - New
Modeltype exported from the package root;generateTextaccepts extra
top-level body fields viaChatCompletionRequest's index signature.
Hardening
- The transport no longer follows redirects (
redirect: 'error'): the Bearer token
stays off unexpected paths, and a misconfigured base URL fails loudly. - Response bodies are read under a 10 MB safety cap instead of being buffered
unconditionally; an over-cap body fails fast and is not retried. A declared
Content-Lengthover the cap is refused before reading anything. - Non-finite
maxRetries(i.e.NaN) no longer causes an infinite retry loop: it
falls back to the default, negatives clamp to 0 and fractions to whole attempts. extraBodyignores__proto__andconstructorkeys, so prototype-smuggled
config can never re-parent the request object.- Malformed entries inside
top_logprobs(missing/null token) are skipped instead
of crashing mid-read. - Error messages strip query strings from the request URL, so providers that take
credentials as query parameters cannot leak them into logs. - The endpoint path is joined through the URL API, preserving a query string in
apiBaseUrlinstead of swallowing it, and an invalid base URL throws a clear
Invalid model.apiBaseUrlerror. - CI actions are pinned by commit SHA; the release script spawns every subprocess
as an argv array (no shell), so interpolated values can never be re-parsed as
shell syntax.