Repository navigation
Releases: Pal-AI-Lab/Cortico
Release list
v0.1.16
Extension contract versions are unchanged: world 5, provider 5, bot 6.
Breaking
src/worlds/index.tsno longer exportsBUILTIN_WORLDS. It exportsBUILTIN_WORLD_IDSand
loadBuiltinWorlds(ids?), which imports the chosen built-in Worlds by id; without ids it loads all five, so the
launcher and existing deployments behave as before. A downstream assembly picks its Worlds without replacing
Cortico's files, and a World it leaves out is never imported; an unknown id fails before any import (#237).
Providers
openai-responses-compatgainsoptions.sendSyntheticReasoning, on by default and set in the reasoning replay
panel. Off, plaintext replay sends no synthetic reasoning before a function call without an origin. A 400 whose
body namesreasoning_textwhile it is off says so in the error message (#236).- The provider probe tells apart a 403 for an unsupported country, region or territory (with OpenAI's
supported-countries link), a response that arrived but could not be read, an authentication failure and an
unreachable service (#238).
Console
- Prompts page: a failed save no longer drops the templates after it from the unsaved set; reloading the prefix
saves first, then refreshes unchanged templates from the server and keeps unsaved edits and their undo history.
The editor gains CodeMirror undo and redo, per-segment folding, and variables that can be looked up, chosen with
the keyboard, inserted, dragged in and previewed per segment. Indev:console, consecutive saves no longer
conflict (#235). - Extensions page: the npm registry can be set from the marketplace. It is written to
extensions/.npmrcand
used at once for search, details, update checks and installs (internal routeGET/POST /api/extensions/registry).
A failure while reading a registry response now names the host and the cause too (#239).
v0.1.15
Extension contract versions are unchanged: world 5, provider 5, bot 6.
Console
GET /api/prompts/prefix,POST /api/prompts/resetandPOST /api/session/reload-prefixjoin the public
console HTTP routes indocs/console.md, so a downstream frontend can offer the full prompts page: the prefix
preview, removing a fixed prompt's deployment override, and reloading the current session's prefix (#233).
Packaging
- The published packages name an author:
corticoand the four built-in World packages now carry
"author": "Pal AI Lab", which the extension page shows (#232).
v0.1.14
Extension contract versions are unchanged: world 5, provider 5, bot 6.
Console
docs/console.mdlists the console HTTP routes that are public to downstream products: status, capabilities,
config and its options, blob, worlds and activation, storage clear, theme, avatar, usage, run pause / resume /
shutdown, prompts, sign-in, the model endpoint routes and the panel contract. A breaking change to a listed
route takes a!and a migration note like a config key does. The console web UI itself (pages, DOM, class
names,src/web/client/modules) is a developer tool and makes no promise to downstream products; AGENTS.md
states this as a boundary (#228, #229).- The appearance page's palette moves into a fold at the bottom of the scheme card, with the component specimen
beside the colors. The scheme name next to the light/dark switch is gone, and so is the sentence saying the
choice is saved in this browser: the theme is saved to the deployment throughPOST /api/theme(#224). - The shutdown receipt shows each step's duration again; it read
mswhile the endpoint returnselapsedMs, so
every step showedNaNs(#230).
v0.1.13
Extension contract versions are unchanged: world 5, provider 5, bot 6.
Breaking
Core.cognitionInFlight()andCore.mainSessionSpec()are removed; they had no callers. A Persona reads
ctx.running, andCore.activeSpec()returns the main session's spec (#217).SessionTrackerno longer swallows exceptions thrown by its observers.chargesthat a World passes to
reportUsageand that cannot be copied now throw back to the World (#217).
Core
- The instance lock records the executable path. When the PID in an existing lock is alive but now belongs to a
different executable (taskliston Windows,/proc/<pid>/exeon Linux,ps -o comm=on macOS), the lock is
treated as stale and taken over, so a PID reused after a force-kill no longer blocks every later start. Locks
written by older versions skip this check. A refused start throwsInstanceLockedErrorwith the PID and the
lock file (#220). - Writes rely on the startup instance lock alone: the event store no longer compares file sizes before each
append, and the lock is no longer rechecked every 60 seconds. Stores no longer create their directory before
each write; the data and run directories are created once at startup.usage-logstill recreates its
directory for queued writes (#217).
Extensions
- When the registry answers a
keywords:search with an empty list (npmmirror does), the market searches the
keyword as plain text and keeps only packages tagged with it./api/extensions/searchreturns the registry it
used, and the empty-market text names it and says to setregistry=in.npmrcat the installation location
and restart (#221).
Development
- TypeScript
noUnusedLocalsis on; unused imports, variables and private fields failtypecheck. 252 existing
ones are removed, with no change to the modules loaded at runtime (#218).
v0.1.12
Extension contract versions are unchanged: world 5, provider 5, bot 6.
Breaking
- The built-in Worlds' display-text exports are functions of the console language:
minecraftConfigGroup(language)(and its rhythm, client and player siblings),minecraftPanelDecls,
minecraftStorageDecls,levelTypeLabels,flatPresets,qqConfigGroup,bilibiliConfigGroup,
bilibiliPanelDeclsandwebSearchConfigGroupreplace theMINECRAFT_CONFIG_GROUP-style constants. A bot
package that listed those constants calls the functions instead (#215).
Console
- World names follow the request language everywhere they appear: the Extensions page (built-in and installed
Worlds), sidebar entries, World page titles, Tools page owners, and activation, restart and visibility
receipts. A definition whoselabelis a getter is read on each request (#211). - Text written outside the string tables now follows the request language in all 11 languages: provider
configuration errors, Extensions page load reasons, manifest problems and install, uninstall, check and update
receipts, Persona panel errors, and the shutdown receipt's external checks. The package-detail route answers
400 or 502 from the error's status. A World's own model shows its World id in the session list when it reports
no label. The login page uses the language picked in the console (#215). - The built-in Minecraft, QQ, Bilibili and WebSearch Worlds show their console, config groups, panels and storage
items in Chinese or English; other languages fall back to one of the two. The Bilibili overlay editor follows
the console language too (#215). - The sidebar narrows continuously with the window between 210 px and 280 px. The rail foot shows Running or
Paused under the bot name. Line icons share one 1.6 px stroke; checkboxes use the theme accent (#212). - The terminal timeline shows image attachments as thumbnails and opens them in a lightbox.
GET /api/blob
serves a blob by handle, andui.lightboxjoins the panel UI kit (#213). - On narrow windows, dialogs, drawers and the lightbox sit above the top bar; toasts and tooltips stay above
dialogs (#214).
Contracts
World.shutdownVerification(language)receives the request language for its labels and details.
ProviderModule.localizemay returntitle(#215).
v0.1.11
Extension contract versions are unchanged: world 5, provider 5, bot 6.
Breaking
- A deployment that does not set
timezonenow uses the machine's time zone for timestamps, rendered times and
schedules; before, it usedAsia/Shanghai. To keep the old behavior, set"timezone": "Asia/Shanghai"in the
deployment'sconfig.json. Timestamps already written carry their offset and are compared by instant, so old
data needs no migration (#205).
Core
nowIsocomputes the offset from the target time zone alone, independent of the process time zone; around a
daylight-saving change the offset was off by 60 minutes before. Event-store shards sort by first cursor,fromTs
andtoTscompare by instant, and sessions,previousRunand usage buckets order by instant (#205).- The usage report converts into a currency the calls were not priced in.
usage.rates.<code>in the Core config
says how much of that currency 1 USD is worth, for CNY, EUR, JPY, KRW, TWD, BRL and RUB, initially the
mid-market rates of 2026-10-10; 0 keeps a currency out of conversion. A call priced in the shown currency keeps
its own price (#206, #203).
Console
- Usage & cost lists every currency it can show, and next to a converted one the toolbar shows
1 USD = [rate]; editing it saves to the Core config and converts again (#206). shirtjoins the console icon set (#204).- The console and
logqlist runs in boot order fromindex.jsonl(#205).
Worlds
- Minecraft:
worlds.minecraft.serverMode(auto,local,external; defaultauto, which keeps the old rule:
a filled-inlocal.serverDirmeans local hosting). In external mode the mount panel connects, disconnects and
reconnects the bot only, never touches a server process and needs no server directory. It shows the target, whether
the port accepts a connection and the bot's own state; the bot counts as in the world only after it spawns, and a
failed login reports the server's reason (whitelist, authentication, version, ban, name in use). After a manual
disconnect the bot stays disconnected until connected again. A changed address applies on the next connection; a
reconnect ends the tasks of the old connection first.host,port,usernameandversionare hot-editable
(#199). - QQ history tools read time arguments in the deployment's time zone and answer
[bad input]for one they cannot
read (#205).
v0.1.10
Extension contract versions are unchanged: world 5, provider 5, bot 6.
Core
- A batch that ends over
hardTokensright after the previous batch was force-handed-off at the same limit no
longer hands off again. Core logs one error (hardTokens,estTokens, model) and stops count-based round-end
finishes and forced handoffs at that limit until a check sees the count back under it or the limit changes.
Before, an endpoint whose limit came out as 0 handed off after every batch and the handoff note woke the next
batch, so the bot looped without end. Handoffs on an upstream "input too long" error and manual handoffs are
unchanged (#201, Pal-AI-Lab/Coopanion#100).
Providers and console
- An endpoint spec that sets both
contextWindowandmaxTokensmust havecontextWindow > maxTokens. Saving
such an endpoint or making it current is refused, and the endpoint editor marks the field, also when an already
saved endpoint is opened (#201). - A listed model without a context window takes the window the provider instance reports
(ProviderInstance.contextWindow), so the editor fills it in instead of asking for it by hand. llamacpp
listings are kept as listed, so fetching the list does not probe each model (#201). - The diagnostics bundle has an
endpointsection: the endpoint name, its provider module and the spec'smodel,
thinking,reasoningEffort,temperature,maxTokensandcontextWindow; no address, key or options
(#201).
v0.1.9
Extension contract versions are unchanged: world 5, provider 5, bot 6.
Languages
- The web console is available in 11 languages: 简体中文, 繁體中文, English, 日本語, 한국어, Français, Deutsch,
Español (Latinoamérica), Português (Brasil), Italiano and Русский. Settings → General lists them;config.json
languageandCORTICO_LANGUAGEtake the exact codeszh,zh-Hant,en,ja,ko,fr,de,es-419,
pt-BR,it,ru, and the system locale maps onto them (#197, #198). pick(language, table)requireszhanden; any other language is optional and may translate part of a
table. A missing language or key falls back tozhforzh-Hantand toenfor the rest. Translations live in
strings.<lang>.tsbeside eachstrings.ts(#197, #198).- The console language still does not change model input. Core text that can reach model context (abort reasons,
deadline and cognition errors, host-lifecycle errors) is now English; markers are exported frommarkers.ts
(ABORT_*,HOST_LIFECYCLE_ENDED) (#197). - Extensions receive the wider
LanguageinWorld.console,Persona.console,configOptionsand
ProviderModule.localize. Code that branches onlanguage === 'en'now sends the nine new languages down the
other branch; usepickorbaseLanguageinstead (#197). - Console responses, receipts and errors from
server.ts, the path picker, the reasoning probe and the Cormini
workspace and history panels are translated; the shutdown report states a step timeout in the console language
(#198).
Core
withDeadlinerejects with an exportedDeadlineError(what,ms). CortiV detects a cognition timeout by
that error instead of comparing wall-clock time (#197).
Extensions and console
- Extension cards and details show total, 30-day and 7-day downloads from npm's download statistics
(api.npmjs.org), whichever registry installs use (#195). - A rejected
asyncconsole route now returns 500 and logsAPI错误, instead of leaving the request open and
surfacing as an unhandled rejection (#194).
Worlds
- Each release publishes
minecraft,qq,bilibiliandwebsearchto npm ascortico-world-<id>at the
framework's version, for apps that do not bundle them. A package whose id matches a built-in World is not
loaded (#196).
Translations in this release were machine-translated and have not been reviewed by native speakers. Corrections are
welcome as pull requests to the strings.<lang>.ts files.
v0.1.8
Extension contract versions are unchanged: world 5, provider 5, bot 6.
Extensions and console
- A failed registry request now reports the host and the underlying error code, e.g.
registry.npmjs.org: fetch failed (ERR_TLS_CERT_ALTNAME_INVALID: …), instead of undici's bare
fetch failed(#190, Pal-AI-Lab/Coopanion#78). - Search, package details and update checks use the registry that installs use: the result of
pnpm config get registry --ignore-workspaceinextensions/(extensions/.npmrc, the user's.npmrc,
pnpm_config_registry). It is read once per process; when pnpm cannot report one, the query fails with
pnpm's output (#190). - The extension page shows a package's author from
package.jsonauthor(the name only, for both the
string and the object form) instead of the npm publisher, which Trusted Publishing reports as
GitHub Actions. A market card shows the author once the package document has arrived (#187, #186). - The package detail drawer lists every version still in the registry and can install any of them through the
existing check and install flow (pnpm add name@version, effective after a restart). Clicking a card opens its
details; removing takes two clicks, and the second-click state says that other bots using the same extensions
directory are affected (#178).
Worlds
- QQ: shared cards keep their source name, content title and target link in the message body
([分享 来源:… 标题:… 链接:…]). Only a single http(s) URL is taken as the link; source name and title are
written as the card declares them and are not verified (#174, #170).
Thanks
v0.1.7
Extension contract versions are unchanged: world 5, provider 5, bot 6.
Core
- New
interrupttrigger. When such an event arrives, the in-flight model call is cancelled whether
or not it has produced output; what was already externalized is kept. Running tools that declare
ToolDef.interruptiblereceivectx.signaland report how far they got; other tools run to the
end, and calls in the round that have not started are skipped. The new event is delivered after
the round's receipts, in the same batch (#180, #179). - A cancelled
preemptround no longer ends the wake-up: the batch continues with the new event and
onTurnEndedis not called, so QQ drafts and cua permissions survive a preemption. Apreemptor
interruptthat arrives while tools run or between rounds goes into the next model request (#180). - The default externalization rule is exported as
defaultExternalizes. Cormini's merged output tap
falls back to it per tap instead of treating a tap withoutexternalizesas false (#180). - The main loop reports a
RunPhase(idle,delivering,model,tools,backoff,handoff,
with the round, running tool names, retry time andenteredAt). Visible Worlds receive it through
onRunPhase;getStatus().phasereturns it (#181).
Extension authors
- Worlds can act on their own queued events:
withdrawPending(cursor)removes one before delivery
(recorded ascore.withdrawal, so a restart does not requeue it),promotePending(cursor, trigger)
delivers it now asflush,preemptorinterrupt, andonEventsSettled(events, outcome)reports
when events reach the main session or are discarded. The two host methods are optional; the
Minecraft engine child does not implement them (#180). - The console's
ConsolePromptInputgainsrestore(text, images?), and the icon set gains
message(#182). docs/world-compatibility.mdgrades what a host provides to Worlds in four levels, for bots built
on other architectures.
Console
- The Terminal page's status line follows the core's run phase (delivering, waiting for the model,
running a named tool, retry time, handoff) instead of inferring it from the timeline. The phase
travels in its own/ws/debugframe (#181, #157).
Worlds
- Minecraft: in
automode, a bow shot that cannot be fired at a target more than 8 blocks away
(blocked line of sight, too close, no trajectory) now ends the step as blocked, with the reason,
distance and arrows fired. Previously it switched to melee, chose the bow again on the next round
and kept the event loop busy until the server timed the bot out (#183, #175).