Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
4198174
fix: remove forced branching from bash guidance (#358)
AdhereZ Sep 25, 2026
258adde
feat: sync reviewed 0.5.5 runtime improvements (#367)
hetaoBackend Sep 27, 2026
a30a898
docs: publish feedback and private security contact channels (#360)
hetaoBackend Sep 27, 2026
0f6ad52
fix(tui): distinguish Bash recaps and import models during onboarding…
hetaoBackend Sep 27, 2026
51ac3b2
fix: measure token speed over model generation time (#373)
hetaoBackend Sep 28, 2026
836580e
chore: bump version to 0.5.6 (#374)
hetaoBackend Sep 28, 2026
0b7403c
feat(config): add M3.1 Flash Preview to the fallback catalog (#375)
hetaoBackend Sep 28, 2026
2aed5ca
chore: bump version to 0.5.7 (#377)
hetaoBackend Sep 28, 2026
3ba8169
fix(tui): display hook system messages without adding model context (…
amszuidas Sep 28, 2026
c7935eb
fix(tui): anchor restored sessions above inherited terminal history (…
hetaoBackend Sep 28, 2026
ec4a611
fix(tui): keep slow terminal output off the input loop (#379)
hetaoBackend Sep 28, 2026
e3d7855
chore: bump version to 0.5.8 (#380)
hetaoBackend Sep 28, 2026
c593d3d
feat: cascade explicit session stops to owned background work (#381)
hetaoBackend Sep 28, 2026
68284bb
fix: query structured Windows source volume properties (#383)
hetaoBackend Sep 28, 2026
4fdf523
feat(examples): add Pocket Pet demo and refresh README onboarding (#385)
hetaoBackend Sep 29, 2026
67a5c2a
fix(tui): dismiss stale terminal errors when a new turn starts (#388)
hetaoBackend Sep 29, 2026
9b9c07b
fix(tui): preserve native scrollback during automatic updates (#389)
hetaoBackend Sep 29, 2026
1e136bf
fix(tui): stabilize native history and diff overlay frames (#390)
hetaoBackend Sep 29, 2026
5f3240b
test: pin the srt-macos probe PATH and scale the BYOK serial timeout …
hetaoBackend Sep 29, 2026
d8a32b6
feat: sync MiniMax Code 0.5.9 runtime and TUI changes (#398)
hetaoBackend Sep 29, 2026
c8a39a5
chore: release MiniMax Code 0.5.9 (#399)
hetaoBackend Sep 30, 2026
3d369f5
Revert #390 and #389 to restore TUI scrollback baseline (#396)
hetaoBackend Sep 30, 2026
5683465
fix(tui): sync 0.5.10 prompt and run recovery fixes (#410)
hetaoBackend Sep 30, 2026
e77c763
chore: release MiniMax Code 0.5.10 (#411)
hetaoBackend Sep 30, 2026
8f114d9
fix: include hidden thinking in TPS timing (#413)
SaladDay Oct 1, 2026
bf3916f
fix: omit empty tools from OpenAI compaction requests (#199)
hetaoBackend Oct 1, 2026
c08148e
fix(tui): keep regular-mode history stable during live runs (#416)
hetaoBackend Oct 1, 2026
9150441
feat: sync and release MiniMax Code 0.6.0 (#421)
hetaoBackend Oct 1, 2026
ef2f43d
feat: sync and release MiniMax Code 0.6.1 (#422)
hetaoBackend Oct 1, 2026
564e916
fix(tui): keep side-session Esc and main run timer consistent (#423)
hetaoBackend Oct 2, 2026
7ea1c8c
chore(deps-dev): bump the tooling-minor-patch group across 1 director…
dependabot[bot] Oct 4, 2026
f07e6ef
fix(agent-core): bound hung model requests with first-event and idle …
hetaoBackend Oct 4, 2026
56221c1
fix(tui): defer rebuild after output-driven layout shrink (#429)
hetaoBackend Oct 4, 2026
1852771
fix(agent-core): cap images per request and recover sessions over the…
hetaoBackend Oct 5, 2026
4401b0e
Add opt-in lightweight context mode (#436)
hetaoBackend Oct 6, 2026
f7483f5
feat: add launch-scoped system prompt overrides and fix Ask/Plan turn…
hetaoBackend Oct 8, 2026
71b18b7
Fix locale-dependent capability tests (#443)
hetaoBackend Oct 8, 2026
56d2369
fix(cron): accept week unit in cron once --after durations (#435)
hetaoBackend Oct 8, 2026
a5b56b7
fix(tui): defer rebuild when scrollback rows change without input (#434)
hetaoBackend Oct 8, 2026
8348311
fix(tui): exclude buffered bursts from the output rate at turn start …
hetaoBackend Oct 8, 2026
553b19e
chore: release MiniMax Code 0.6.4 (#447)
hetaoBackend Oct 9, 2026
b26f634
chore: release MiniMax Code 0.6.5 (#458)
hetaoBackend Oct 9, 2026
f466590
fix(tui): keep npm-prefix updates on the Node pinned by the receipt (…
yujiachen-y Oct 9, 2026
c172cf9
fix: schedule exec timeouts above the Node timer limit in chunks (#448)
yujiachen-y Oct 9, 2026
810b11d
chore: record upstream a5b56b7 as already absorbed
cursoragent Oct 9, 2026
fccc7e6
merge: upstream c172cf9 (#454 output rate, #448 exec timeout chunks)
cursoragent Oct 9, 2026
7682398
fix: keep --effort on the MiniMax API-key request (#461)
hetaoBackend Oct 9, 2026
8e93b19
perf(runtime): trim per-turn reminders (budget thresholds, minute tim…
hetaoBackend Oct 9, 2026
5b4e0a4
fix: stop retrying oversized requests and recover with one forced com…
hetaoBackend Oct 9, 2026
c460f08
fix(runtime): restore session ID after compaction and drop forced ove…
hetaoBackend Oct 9, 2026
ebfdc00
fix(tui): support SOCKS5 proxies and stop ALL_PROXY from crashing sta…
amszuidas Oct 9, 2026
1ae5575
Merge commit 'ebfdc00a09b2209cf2201dc17316a8156285a942' into merge/up…
hermes-agent Oct 9, 2026
dc1315d
fix: update Codex catalog client version to 0.162.0 (#477)
yujiachen-y Oct 11, 2026
ed4ec3d
feat(tui): report program status with OSC 7501 (#471)
yujiachen-y Oct 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions docs/tui-capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,31 @@ observed generation window, not server hardware throughput.

## Terminal titles and notifications

Terminal titles show the current state, session name and MCode, for example
`Needs approval | Fix login | MCode`. Renaming or switching a session updates the
title. Unnamed sessions use the project name and a short session ID. Titles are
cleared when MCode exits or suspends and reapplied when it resumes.

Configure these presentation settings in the MCode data directory's `config.yaml`:
The interactive TUI also reports [OSC 7501 program status](https://www.superlogical.com/rex/docs/build/program-status)
with `app=kcode`: idle, working, done, error, or blocked on permission, a question,
or login. It reuses the current session's runtime status, including queue handoffs,
compaction and retries, and does not depend on status line items. Cancellation and
suspension report idle; resume reapplies the current status. Completed and failed
results remain reported when the TUI exits. Reports contain only `state`, `kind` and
`app`, and are sent on changes, without a heartbeat or capability query, as
permitted by protocol revision 0.4. Supporting terminals decide how to display
them; other terminals should ignore the sequence. The protocol treats each
multiplexer pane as its own terminal, so Kinetick Code does not wrap reports for tmux
passthrough; the multiplexer must implement OSC 7501 for its panes. Redirected
output, headless exec and ACP do not emit these reports. Set
`tui.programStatus: false` to disable them. Terminal title and notification
settings remain independent of program status.

Terminal titles show the session title, or `Kinetick Code` when the session is
untitled. Renaming or switching a session updates the title. Agent status does
not rewrite the title.

Configure these presentation settings in the Kinetick Code data directory's `config.yaml`:

```yaml
tui:
terminalTitle: [status, session-name, app-name]
programStatus: true
notifications:
when: unfocused
method: auto
Expand All @@ -38,7 +53,7 @@ Title items can be ordered or omitted; `project-name` is also available. Set
`terminalTitle` to `null` or `[]` to disable title updates. Unknown items are ignored.
Notification `when` accepts `unfocused`, `always` or `never`; `method` accepts
`auto`, `osc9`, `osc777` or `bel`. Omitting `events` enables all four events; `[]`
disables them. Apply configuration changes by restarting MCode.
disables them. Apply configuration changes by restarting Kinetick Code.

Notifications identify the session and suppress duplicates. Completion waits for
the session's queue to finish; failed turns and requests for input can notify
Expand Down
66 changes: 66 additions & 0 deletions packages/agent-core/test/unit/pi-turn-runner/llm-retry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,36 @@ describe("withLLMRetry", () => {
expect(error?.type === "error" ? error.error.errorMessage : undefined).toBe(message);
});

// A request that is too large (HTTP 413, request_too_large, the local
// pre-send body check, or a context-window overflow) is rejected again on
// every resend; the BYOK retry-all budget used to send it six times.
it.each([
["minimax_api", "413 Request Entity Too Large"],
["minimax_api", '413 {"type":"error","error":{"type":"request_too_large","message":"Request exceeds the maximum allowed number of bytes."}}'],
["custom_provider:work", "413 Payload Too Large"],
["custom_provider:work", "413 status code (no body)"],
["minimax_api", "Request body too large: 70000000 bytes exceeds client limit 67108864 bytes."],
["minimax_api", "400 invalid params, context window exceeds limit (2013)"],
["custom_provider:work", '400 {"error":{"message":"prompt is too long: 600000 tokens > 512000 maximum"}}'],
["minimax", "413 Request Entity Too Large"],
["minimax", "Request body too large: 70000000 bytes exceeds client limit 67108864 bytes."],
])("sends an oversized request from %s only once: %s", async (provider, message) => {
let attempts = 0;
const sleep = vi.fn(async () => {});
const inner = (async () => {
attempts += 1;
return errorStream(message);
}) as StreamFn;
const wrapped = withLLMRetry(inner, retryOptions({ sleep }));

const events = await collectEvents(await wrapped(fakeModel(provider), CONTEXT, {}));

expect(attempts).toBe(1);
expect(sleep).not.toHaveBeenCalled();
const error = events.find((event) => event.type === "error");
expect(error?.type === "error" ? error.error.errorMessage : undefined).toBe(message);
});

it.each([
"[Error] 400 Bad Request",
"503 Service Unavailable: too many images queued, try again",
Expand Down Expand Up @@ -1181,4 +1211,40 @@ describe("deterministic request rejection classification", () => {
expect(rejection("401 invalid api key")).toBe(false);
expect(classifyLLMRequestRejectionMessage("invalid_request_error without a status")).toBeUndefined();
});

it("treats HTTP 413, byte-limit and context-overflow rejections as deterministic", () => {
const oversized = rejection;
expect(oversized("413 Request Entity Too Large")).toBe(true);
expect(oversized("anything", 413)).toBe(true);
expect(oversized('{"type":"error","error":{"type":"request_too_large","message":"too big"}}')).toBe(true);
expect(oversized("Request body too large: 9 bytes exceeds client limit 8 bytes.")).toBe(true);
expect(oversized("400 invalid params, context window exceeds limit (2013)")).toBe(true);
expect(oversized("prompt is too long: 213462 tokens > 200000 maximum")).toBe(true);
expect(rejection("413 Payload Too Large")).toBe(true);
});

it("does not treat transient or unrelated size-like errors as deterministic", () => {
const oversized = rejection;
// The bare MiniMax 2013 code is a generic invalid-params code.
expect(oversized("400 invalid params (2013)")).toBe(false);
expect(oversized("400 Bad Request")).toBe(false);
expect(oversized("prompt is too long", 503)).toBe(false);
expect(oversized("429 rate limited: request too large for TPM")).toBe(false);
expect(oversized("Request body too large: timeout while uploading")).toBe(false);
expect(oversized("401 invalid api key")).toBe(false);
});

it("classifies the BYOK-attributed form of an oversized request", () => {
const byok = (detail: string) =>
`BYOK upstream error: ${JSON.stringify({
errorCode: LLM_ERROR_CODES.LLM_UPSTREAM_ERROR,
message: `BYOK provider custom_provider:fixture upstream error: ${detail}`,
errorSource: "byok_upstream",
errorDetail: detail,
errorProviderId: "custom_provider:fixture",
})}`;
expect(rejection(byok("413 Payload Too Large"))).toBe(true);
expect(rejection(byok("400 invalid params, context window exceeds limit (2013)"))).toBe(true);
expect(rejection(byok("503 Service Unavailable"))).toBe(false);
});
});
4 changes: 3 additions & 1 deletion packages/agent-modules/system-reminder/src/blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ export function buildSlimAgentContextBlock(env: AgentEnv): string {
lines.push(` agentName: ${env.agentName}`);
}
lines.push(` SESSION ROLE: ${sessionRole}`);
lines.push(` YOUR SESSION ID: ${env.sessionId}`);
if (!env.sessionIdInContext) {
lines.push(` YOUR SESSION ID: ${env.sessionId}`);
}
if (env.parentSessionId) {
lines.push(` PARENT SESSION: ${env.parentSessionId}`);
lines.push(buildParentResultDeliveryLine(env, isCloud));
Expand Down
7 changes: 7 additions & 0 deletions packages/agent-modules/system-reminder/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ export interface AgentEnv {
userConfiguredName?: string | undefined;
agentRole: string;
sessionId: string;
/**
* Host-verified fact that the model-visible context already carries
* `YOUR SESSION ID` (e.g. an earlier user message since the latest
* compaction). When true, the slim per-turn block omits the line to save
* tokens. Absent/false keeps the line (cloud and legacy callers).
*/
sessionIdInContext?: boolean | undefined;
/** Session type — 0=Branch, 1=Root (formerly Main). */
sessionType?: number | undefined;
/** Parent session ID — set when this is a child session. */
Expand Down
3 changes: 3 additions & 0 deletions packages/config/src/tui-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export interface TuiConfig {
};
/** Show contextual Tips in the idle composer header. Defaults to true. */
showTips?: boolean;
/** Report OSC 7501 program status to the terminal. Defaults to true. */
programStatus?: boolean;
/**
* Status line items, in display order.
*
Expand Down Expand Up @@ -115,6 +117,7 @@ export function parseTuiConfig(raw: Record<string, unknown>): TuiConfig {
}
: {}),
...(typeof tui.showTips === 'boolean' ? { showTips: tui.showTips } : {}),
...(typeof tui.programStatus === 'boolean' ? { programStatus: tui.programStatus } : {}),
...(notifications ? { notifications } : {}),
...(statusLine ? { statusLine } : {}),
...(customStatusLine ? { customStatusLine } : {}),
Expand Down
16 changes: 16 additions & 0 deletions packages/local-runtime-v2/src/compat/v1/agent-host.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,22 @@ describe("createV1AgentHostProductCapabilities", () => {
turnId: "turn-1",
deferTelemetry: true,
});
await product.inputPreparation.reminders.buildSystem({
session: { sessionId: "session-1" },
agent: { agentName: "mavis", resourceAgentName: "main" },
agentConfig: {},
promptText: "again",
turnId: "turn-2",
sessionIdInContext: true,
} as never);
expect(hosted.reminders.buildSystem).toHaveBeenLastCalledWith({
session: { sessionId: "session-1" },
resourceAgentName: "main",
promptText: "again",
turnId: "turn-2",
deferTelemetry: true,
sessionIdInContext: true,
});
expect(product.executor.fileChanges.begin).toBe(hosted.fileChanges.begin);
expect(product.runner.contextUsage).toBe(hosted.contextUsage);
expect(product.runner.logger).toBe(hosted.runnerLogger);
Expand Down
1 change: 1 addition & 0 deletions packages/local-runtime-v2/src/compat/v1/agent-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export function createV1AgentHostProductCapabilities(
promptText: input.promptText,
turnId: input.turnId,
deferTelemetry: true,
...(input.sessionIdInContext ? { sessionIdInContext: true } : {}),
...(model ? { model } : {}),
});
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Official OpenCode Go HTTPS endpoints under `https://opencode.ai/zen/go` receive

登录完成后,`CodexOAuthManager` 从当前 profile 的 `codex-auth.json` 获取凭据,复用
`AuthStorage` 的刷新机制和宿主 `fetch`,请求
`https://chatgpt.com/backend-api/codex/models?client_version=0.153.0`。
`https://chatgpt.com/backend-api/codex/models?client_version=0.162.0`。
`connectivity/codex-model-discovery.ts` 负责这个独立的 Codex 协议。兼容版本来自已验证的
Codex 客户端协议,与 MiniMax Code 产品版本独立;模型 ID 和思考等级由响应提供。OAuth 解析复用可配置思考协议,将远端等级原样映射到请求;
`ultra` 等新增等级不依赖 Pi 的静态等级枚举。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ describe("Codex OAuth profile credentials", () => {
fetch: fetchImpl,
});
expect(fetchImpl).toHaveBeenCalledWith(
expect.stringContaining("/codex/models?"),
"https://chatgpt.com/backend-api/codex/models?client_version=0.162.0",
expect.objectContaining({
headers: expect.objectContaining({
Authorization: "Bearer fresh",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { LocalCustomProviderConfig, LocalModelConfig } from '../contracts.j

const CODEX_BASE_URL = 'https://chatgpt.com/backend-api';
// Codex model discovery negotiates against the Codex client version, independent of our app version.
const CODEX_CATALOG_CLIENT_VERSION = '0.153.0';
const CODEX_CATALOG_CLIENT_VERSION = '0.162.0';

export interface CodexModelCredentials {
access: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export class NativeLocalTurnExecutionPreparationSource<
...(input.execution.desktopCapabilities
? { desktopCapabilities: input.execution.desktopCapabilities }
: {}),
history: (input.execution.runnerHistory ?? input.execution.history)?.messages ?? [],
});
const browserAssets = [...(prepared.browserAssets ?? [])];
const context = createToolContext(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from '../canonical-user-input.js';
import { createBackgroundTaskHostMetadata } from '../history/background/host-metadata.js';
import { assertAgentHostCapabilityAvailable } from '../empty-dependencies.js';
import { messagesCarrySessionId } from '../compaction/session-identity.js';
import {
prepareLocalInlineMedia,
type LocalInlineMediaCandidate,
Expand Down Expand Up @@ -86,6 +87,12 @@ export interface LocalTurnReminderFacts {
readonly promptText: string;
readonly turnId: string;
readonly desktopCapabilities?: AgentHostTurnCapabilityView;
/**
* True when a user message in the model-visible history since the latest
* compaction already contains this session's ID, so per-turn reminders may
* omit it. False on the first turn and after a compaction dropped it.
*/
readonly sessionIdInContext?: boolean;
}) => Promise<{
readonly content: string;
readonly diagnostic?: unknown;
Expand Down Expand Up @@ -135,6 +142,8 @@ export interface LocalTurnInputPreparationRequest {
readonly immediateSendBatch?: AgentHostExecutionRequest['immediateSendBatch'];
readonly provenance: AgentHostTurnProvenance;
readonly desktopCapabilities?: AgentHostTurnCapabilityView;
/** Provider-facing history before this turn's user message. */
readonly history?: readonly unknown[];
}

export interface PreparedLocalTurnInput {
Expand Down Expand Up @@ -203,6 +212,9 @@ export class LocalTurnInputPreparer {
promptText,
turnId: input.lease.turnId,
...(input.desktopCapabilities ? { desktopCapabilities: input.desktopCapabilities } : {}),
...(input.history && messagesCarrySessionId(input.history, input.session.sessionId)
? { sessionIdInContext: true }
: {}),
});
const system = validateSystemReminder(systemValue);
const systemBlock = optionalReminderBlock('system', system.content);
Expand Down
Loading
Loading