chore: sync upstream 2026-09-11 - #71
Merged
Merged
Conversation
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…otAI#3675) * docs(changelog): sync 0.42.0 from apps/kimi-code/CHANGELOG.md * docs(changelog): use absolute URL for the Remote Control guide link * docs(changelog): use absolute URLs for the remaining doc links
…hotAI#3662) - the human agent state machine now assigns turn ids and echoes the drained queue item in turn.started; the facade adopts machine ids instead of reserving its own - the turn machine produces the step ordinal and surfaces it via a first-class step.started fact; the llm requester layer stays step-agnostic - turn.prompt wire records carry an explicit turnId; turnKey and transcript foldFacts read it directly with a counting fallback for legacy records - queued prompts are addressed by promptId: cancel(turnId) is active-turn only, cancelQueued targets queue entries, Turn.id resolves once the turn starts - drop PromptPayload.disabledTools and its klient/node-sdk pass-through (no client consumer)
…ovider-catalog state machine (MoonshotAI#3606) The human/llm provider-catalog state machine becomes the single source of truth for the runtime model/provider directory. IModelCatalog's data plane reads through a new llm-adapter catalog-runtime adapter that mirrors config section diffs into catalog upserts, and CatalogEntry cache invalidation is driven precisely by the machine's changed events instead of a blunt clear. The persistence layer is untouched: config.toml stays the full source of truth and refresh results keep being written to it. Also remove the model resolution trace/inspect stack end to end: ResolutionTraceCollector, the llm-adapter model/contract inspection modules, IModelCatalog.inspect, the capability explainability indirection, and the kimi-inspect model inspector panel.
…t phase at kap-server edge (MoonshotAI#3678)
…MoonshotAI#3681) * feat(agent-core-v2): warn on [models] entries missing the model field * refactor(agent-core-v2): contribute model config diagnostics from the models section Move collectMalformedModelEntries next to ModelRecordSchema and derive the known object-field set from the schema shape instead of hardcoding it, so future object fields cannot drift out of sync. Sections now contribute load-time diagnostics through a collectDiagnostics hook, mirroring the deprecations contribution.
…otAI#3691) * feat(agent-core-v2): add event-sourced store core and rewire human agent/session human/eventStore core (schema-first defineEvent factories, serial fold-first dispatch with snapshotting, late-join slices, journal reset), agent events/slices/historySchema, machine rewrite around a store actor with mirror consumption, session stores with turnIndex-boundary undo, todo slice, v2 migration to the new event types, and the loop engine bridge. * refactor(agent-core-v2): make the agent machine self-consistent and the store actor static Phantom-turn root cause: local patches plus the async store.changed mirror were two consistency models for the same data. The machine now owns its state (every transition is a local assign plus a store.append dual write) and consumes only store.ready/reset/error. - store actor becomes static storeActor logic with the engine passed via invoke input; the session machine registers agentActor and spawns it by name - SessionStores.open/fork return the engine directly - store.reset aborts the old abort scope (cascades to in-flight turn/tools/background) - no-op drain events are no longer journaled - engine bridge seeds the initial turn id into the journal before folding, and resetHistory is awaited before the retry notify - tests pass the store via machine input and wait for the log to catch up before store assertions; drop debug residue * refactor(agent-core-v2): drop journal snapshots for plain full-replay event sourcing Snapshots serialized the whole slice state every 500 events and, on an asynchronous backend, their fire-and-forget append could still be queued when the next dispatch read journal.nextSeq(), making the recorded FoldContext.ref.seq one less than the persisted event's sequence and shifting turnIndex undo boundaries. Removing the mechanism eliminates the race and the full-state rewrite; refold now always seeds from initial state and replays every event record (legacy snapshot entries are ignored).
…onshotAI#3688) * fix(mcp): preserve original attachments omitted from model output * test: register session media storage in agent lifecycle fixture * fix(mcp): retain media originals and bound attachment details * fix(mcp): resolve session attachments and honor cancellation * test: check concrete media references in provider requests * fix(media): read session attachments from their owning storage * fix(media): preserve attachment access across runtime and history changes * fix(mime): recognize structured application text attachments
* fix(agent-core-v2): tower resume, wake, teardown, and mission-resolution reliability - Require run_in_background=true in every roster-agent resume guidance and veto foreground roster resumes, abstaining when the profile has no background task tools; resume ids are trimmed before the roster lookup. - Wake the tower when workers send inbox messages to it or broadcast, coalesced into a single notification per batch. - Make teardown idempotent: worktrees git no longer knows are reported as already removed instead of failing. - Resolve branch-to-mission unambiguously (closed missions skipped, latest open wins, merges of closed-only branches refused), reject plan-time branch collisions against existing missions and unowned git refs, and reserve the protocol names tower/all. * fix(agent-core-v2): validate reserved tower names before spawn side effects and stamp reviews with their mission - TowerSpawn rejects the reserved protocol names tower/all up front; the roster backstop no longer fires after the worktree, subagent, and detached task already exist. - Reviews now record the mission they were written for; TowerMerge refuses when the latest clean review was stamped for a different mission, or carries no stamp while the branch is shared with other mission records. * fix(agent-core-v2): pin tower reviews to the mission assigned at reviewer spawn The reviewer's roster entry now records the mission resolved when it was spawned, and submitReview stamps that assignment instead of recomputing at submit time, so a review stays pinned to the mission the reviewer was briefed on even if the branch's resolution moved on; roster-less submissions fall back to the current resolution. * chore: drop the enable hint from the tower changeset * refactor(agent-core-v2): omit undefined fields in tower frontmatter rendering renderFrontmatter now accepts and skips undefined values, so callers pass optional properties (review mission, inbox scope/action/consent_ref) directly instead of using conditional spreads, per the repository rule for optional object properties. * fix(agent-core-v2): leave reviews by unpinned tower reviewers unstamped A roster reviewer without a recorded mission assignment (entries persisted before reviewMissionId existed) no longer gets a stamp inferred from the submission-time branch resolution, which could name a different mission than the one it was briefed on; unstamped reviews on shared branches are refused by the sibling-mission gate until a pinned re-review, while unshared branches merge as before. Tower-submitted reviews keep the resolution fallback. * fix(agent-core-v2): probe tower worktree registration per path instead of parsing porcelain output git worktree list --porcelain emits paths containing newlines literally, so the line-based parser truncated them and teardown misreported those worktrees as already removed; the -z flag suggested for this is unavailable on the git versions the project supports (2.34). teardown now checks each mission worktree directly: git -C <path> rev-parse --git-dir resolving under <repo>/.git/worktrees means registered, which round-trips any filesystem path on any git version. * fix(agent-core-v2): resolve the common git dir when probing tower worktree registration In a linked checkout repoRoot/.git is a file and worktree admin directories live under the repository's common git directory, so every mission worktree failed the containment check and teardown left them on disk; the probe now resolves git rev-parse --git-common-dir first. * docs(agent-core-v2): permit foreground roster resumes when background task tools are inactive * fix(agent-core-v2): reject blank or whitespace-padded tower agent names Recipients are trimmed at send time, so a name carrying surrounding whitespace would register an unreachable agent or alias a reserved protocol name; spawn and roster registration now reject such names up front. * fix(agent-core-v2): drop queued tower inbox wakes on tower exit The wake notify handle is now retained and dropped by exit(), so a queued wake can no longer inject a stale TowerInbox prompt after the user leaves tower mode. * fix(agent-core-v2): drop queued tower inbox wakes when availability changes reconcileTowerProjection now drops a pending wake and resets the wake state whenever the effective projection turns inactive, covering live flag-disable and feature-disassembly paths that never call exit(). * fix(agent-core-v2): truncate the subject preview in tower inbox wakes The full subject stays in the inbox file, but the synthetic wake message now caps it at 120 characters so a body-sized subject cannot flood the tower's context. * fix(agent-core-v2): recheck branch ownership at tower spawn time A branch created between TowerPlan and TowerSpawn is no longer silently checked out as the mission's base: addWorktree now refuses it unless the mission already has an owner (a genuine continuation) or the worktree directory exists (a retry of an earlier spawn attempt). * fix(agent-core-v2): abort tower spawns on worktree protocol refusals TowerSpawn used to downgrade every addWorktree failure to a continuing warning, so a branch-ownership refusal still registered the worker and recorded an owner, which then satisfied the ownership check for later spawns; protocol errors now abort the spawn while git-level reuse cases (existing worktree directory) continue as warnings. * fix(tower): select the review stamped for the mission being merged Review rounds are per-reviewer, so a higher-round review written for a closed sibling mission shadowed a fresh clean review stamped for the mission being merged, and the gate's re-review advice could not succeed until the new reviewer exceeded the old round count. The merge gate now prefers reviews stamped for the resolved mission and falls back to unstamped legacy reviews only when no stamped review exists; a branch whose reviews all belong to other missions reports 'no review'. * fix(tower): create unowned mission branches atomically The spawn-time branch ownership check and the subsequent worktree creation were a check-then-act sequence: a branch created by another process in between was silently checked out instead of created from the recorded base, letting unrelated history into the worker's worktree. worktreeAddNewBranch now attempts the creation directly so git itself refuses an existing ref, and the store maps that refusal to a TowerProtocolError so the spawn aborts instead of degrading to a warning. * fix(tower): weigh later legacy verdicts on unshared branches Review rounds are per-reviewer, so ordering reviews by round said nothing about recency across reviewers: a mission-stamped clean review shadowed a later unstamped P1 from a legacy (unpinned) reviewer, and the gate merged on the stale clean verdict. Reviews are now ordered by file mtime, and on a branch with a single mission the candidate set keeps unstamped reviews alongside stamped ones — an unstamped verdict there is unambiguous. Shared branches keep the stamped-only preference so the legacy ambiguity guard still applies. * fix(tower): accept only the registered worktree as proof of a prior spawn The spawn-time ownership refusal was bypassed by any directory entry at the planned worktree path: an unowned branch plus a plain mkdir let the spawn continue past the refusal (the failed git worktree add degraded to a warning), and the unrelated branch could later reach the merge gate. The exception now requires the path to be a registered worktree checked out on the mission branch — exactly what a crashed first spawn attempt leaves behind — while a plain or foreign directory is refused. * fix(tower): warn when a tower message has no running task to deliver it A TowerSend to an idle roster agent only writes a file — nothing wakes the recipient, so the fleet stalls until someone happens to resume it (seen in the field: a tower messaged a worker back for another review round without resuming it, and the mission sat idle for hours until the human nudged the session). When the tower messages a roster agent that has no active task in this session, the tool result now notes that the message sits in its inbox until it is delivered with Agent(resume=..., run_in_background=true). Broadcasts and sends from workers are unchanged: workers cannot resume peers — the tower relays wake-ups. * fix(tower): record review submission order in the review itself Review order was derived from file mtime — filesystem metadata that coarse-tick filesystems quantize and that copies or archive restores can rewrite, so a newer blocking verdict could sort behind an older clean one and let the merge gate proceed. submitReview now stamps a store-wide monotonically increasing seq into the review frontmatter and reviewsFor orders by it; mtime remains only as the tie-breaker for legacy reviews that predate the field and for same-seq races between concurrent submissions. * chore: shorten the tower changeset and cover the merge gate * chore: condense the tower changeset to the three fixed areas --------- Co-authored-by: konghuanjun <konghuanjun@moonshot.ai>
…AI#3696) * fix(remote-control): carry server token in rc local UI link - add required localServerToken to RemoteControlOutputOptions - render the Local UI line with buildOpenableUrl and dim the #token= fragment like the ready banner - pass the resolved token at both rc call sites (kimi web --rc, TUI /rc) * chore(changeset): add changeset for rc local UI token fix * fix(remote-control): align rc output test with token-bearing local UI link - assert the Local UI line carries the #token= fragment - scope the token-free ban to the relay and session URLs, which must never leak the local server token
…PI) (MoonshotAI#3532) * feat(kap-server): add flat entity message protocol (v3 WS + history API) * feat(kap-server): add task notification user messages, skill origins, and history has_more * fix(kap-server): page history by turns so oversized turns stay reachable * fix(kap-server): synthesize foreground subagent tasks in the cold fold when no task records exist * fix(kap-server): dedupe queued prompts for turn records without a prompt id * fix(kap-server): adapt v3 projection to agent-core-v2 API changes and filter empty thinking * feat(kap-server): align v3 protocol with design revision 1094 and add agent.state --------- Co-authored-by: liruifengv <liruifeng1024@gmail.com>
…d traits composed in the requester pipeline (MoonshotAI#3641) * fix(agent-core-v2): honor request-level toolMessageConversion in openai formats The requester already forwarded LlmRequestConfig.toolMessageConversion into formatRequest, but the openai chat and openai-responses formats only read the trait hook, so the explicit request config was silently ignored. Resolve the mode as request config, then trait default, then the protocol default, and pass the resolved value into lowering. * refactor(agent-core-v2): split the protocol trait into per-protocol dialects and provider connection The ProtocolTrait interface bundled endpoint/headers connection config, model capability, message/params conversion hooks, and error classification into one bag, and every format received the whole bag whether or not it consumed each hook — hooks a protocol ignores were accepted by the type system and silently dead at runtime. Split it by consumer: - ProviderConnection (protocol/connection.ts): endpoint env declaration and default headers, still resolved per request inside generate. - Per-protocol typed dialects (OpenAIDialect, OpenAIResponsesDialect, AnthropicDialect, GoogleGenAIDialect): only the customization points each protocol actually consumes; data-shaped hooks (reasoningKey, toolCallIdPolicy, toolMessageConversion, strictThinkingValidation) are data fields, and message/history hooks use the protocol wire types instead of Record<string, unknown>. - convertError moves to a requester option, capability to a provider variant field. Dialects are bound when the format is created (createOpenAIFormat and siblings), so FormatRequestInput and the stream parser carry request data only; ProtocolTrait is deleted. The thinking hook returns the kwargs and the preserveThinking flag together as ThinkingApplication, and the kimi dialect emits the final thinking params directly instead of routing them through an extra_body flatten in buildParams. The llm-adapter layer is migrated to the same {connection, dialect, convertError} assembly. * refactor(agent-core-v2): compose format stages and dialect hooks in the requester pipeline * refactor(agent-core-v2): rename protocol dialects to traits * fix(agent-core-v2): include the system message in openai mergeHistory input * refactor(agent-core-v2): enforce the format/trait contract boundary - move CONTEXT_MANAGEMENT_BETA into anthropic/contract and have the kimi trait import wire types from each protocol's contract.ts instead of format/lower; export the four contract modules from human/index.ts and guard the boundary in check-import-boundaries - rename protocol/trait.ts to protocol/thinking.ts and move TraitContext to protocol/base.ts; clean up the remaining dialect-era test variable - type extractUsage as OpenAIRawUsage / OpenAIResponsesRawUsage instead of Record<string, unknown> and drop the requester-side casts * refactor(agent-core-v2): thread the request config by spread and drop dead format types - the four requesters spread LlmRequestConfig into the plan input instead of hand-enumerating fields, so a new cross-protocol config field cannot be silently dropped per protocol - ProtocolFormat loses the phantom TRequest/TResponse type parameters; the dead OpenAIRawResponse/AnthropicRawResponse/GoogleRawChunk contract types go with them - the thinking test now names the extra_body flatten behavior explicitly * refactor(agent-core-v2): keep protocol format modules internal to the requester pipeline - drop the four format barrels (and openai/reasoning-key) from human/index.ts; each base's public seam is now exactly contract / trait / requester - stop re-exporting contract wire types from format/lower modules so the neutral vocabulary has a single home; move the *LoweredMessage staging types out of contract into the owning format module - guard the seam in check-import-boundaries: only llm/requester/bases code and tests may import format/lower/patterns/reasoning-key
…the request actor directly (MoonshotAI#3710)
…ig (MoonshotAI#3682) * fix(agent-core-v2): honor request-level toolMessageConversion in openai formats The requester already forwarded LlmRequestConfig.toolMessageConversion into formatRequest, but the openai chat and openai-responses formats only read the trait hook, so the explicit request config was silently ignored. Resolve the mode as request config, then trait default, then the protocol default, and pass the resolved value into lowering. * refactor(agent-core-v2): split the protocol trait into per-protocol dialects and provider connection The ProtocolTrait interface bundled endpoint/headers connection config, model capability, message/params conversion hooks, and error classification into one bag, and every format received the whole bag whether or not it consumed each hook — hooks a protocol ignores were accepted by the type system and silently dead at runtime. Split it by consumer: - ProviderConnection (protocol/connection.ts): endpoint env declaration and default headers, still resolved per request inside generate. - Per-protocol typed dialects (OpenAIDialect, OpenAIResponsesDialect, AnthropicDialect, GoogleGenAIDialect): only the customization points each protocol actually consumes; data-shaped hooks (reasoningKey, toolCallIdPolicy, toolMessageConversion, strictThinkingValidation) are data fields, and message/history hooks use the protocol wire types instead of Record<string, unknown>. - convertError moves to a requester option, capability to a provider variant field. Dialects are bound when the format is created (createOpenAIFormat and siblings), so FormatRequestInput and the stream parser carry request data only; ProtocolTrait is deleted. The thinking hook returns the kwargs and the preserveThinking flag together as ThinkingApplication, and the kimi dialect emits the final thinking params directly instead of routing them through an extra_body flatten in buildParams. The llm-adapter layer is migrated to the same {connection, dialect, convertError} assembly. * refactor(agent-core-v2): compose format stages and dialect hooks in the requester pipeline * refactor(agent-core-v2): rename protocol dialects to traits * fix(agent-core-v2): include the system message in openai mergeHistory input * refactor(agent-core-v2): enforce the format/trait contract boundary - move CONTEXT_MANAGEMENT_BETA into anthropic/contract and have the kimi trait import wire types from each protocol's contract.ts instead of format/lower; export the four contract modules from human/index.ts and guard the boundary in check-import-boundaries - rename protocol/trait.ts to protocol/thinking.ts and move TraitContext to protocol/base.ts; clean up the remaining dialect-era test variable - type extractUsage as OpenAIRawUsage / OpenAIResponsesRawUsage instead of Record<string, unknown> and drop the requester-side casts * refactor(agent-core-v2): thread the request config by spread and drop dead format types - the four requesters spread LlmRequestConfig into the plan input instead of hand-enumerating fields, so a new cross-protocol config field cannot be silently dropped per protocol - ProtocolFormat loses the phantom TRequest/TResponse type parameters; the dead OpenAIRawResponse/AnthropicRawResponse/GoogleRawChunk contract types go with them - the thinking test now names the extra_body flatten behavior explicitly * refactor(agent-core-v2): keep protocol format modules internal to the requester pipeline - drop the four format barrels (and openai/reasoning-key) from human/index.ts; each base's public seam is now exactly contract / trait / requester - stop re-exporting contract wire types from format/lower modules so the neutral vocabulary has a single home; move the *LoweredMessage staging types out of contract into the owning format module - guard the seam in check-import-boundaries: only llm/requester/bases code and tests may import format/lower/patterns/reasoning-key * refactor(agent-core-v2): plug llm credentials in through request config Replace the withAuth/withAuthUpload requester decorators with a credential contribution point on LlmRequestConfig: the llm machine's request actor (machine path) and ModelRequesterImpl (direct path) resolve credentials per attempt, and a recoverable 401 is recovered by invalidating and re-resolving — emitted as llm.recovering on the turn machine's credentials branch. * fix(agent-core-v2): surface request-actor failures as llm.failed.remote A rejection inside the llm machine's detached request actor (credential resolution, message resolvers, or a throwing requester) could not reach the machine, leaving the turn stuck in thinking. Convert it to an llm.failed.remote event so the turn lands in its failed state. * docs(agent-core-v2): attribute retry/recovery to the turn machine in llm.md * refactor(agent-core-v2): unify credentials in human/credentials, turn-owned 401 recovery * fix(agent-core-v2): credential recovery for direct paths, abort guard, turn-snapshotted credentials * feat(agent-core-v2): IModelCatalog.generate with stream credential recovery * refactor(agent-core-v2): inline credential recovery at call sites Remove the attemptWithCredentialRecovery/streamWithCredentialRecovery helpers from human/credentials; the single-retry recovery is now written out at each direct call site (catalog ping/generate, full compaction, media upload) so the control flow reads linearly without a wrapper hop. The credentials module keeps only the provider factories and the credential application helpers; recoverability and invalidation stay on the LlmCredentialProvider itself. * fix(agent-core-v2): settle the queued turn when a machine turn settles before gating When the llm machine fails before requester.generate() runs — for example when OAuth credential resolution rejects — the loop cleared the pending machine turn marker on turnSettled without ever binding or settling the queued reservation, leaving the submitter's ready/result promises and settled() hanging. The loop now settles the unbound reservation explicitly: cancelled on abort, failed otherwise, mirroring the evaluateSettle error propagation. * fix(agent-core-v2): bind and end pre-gate failures through the normal turn lifecycle The direct settlement resolved turn.result without endTurn(), so no TurnPrompt/TurnStarted/TurnEnded/AgentErrorEvent was published and the next queued reservation was never launched. The unbound reservation is now bound via beginActiveTurn and ended via endTurn (failed, or cancelled on abort), chained onto afterChain when the previous turn is still settling, so pre-gate failures get the same lifecycle events and queue progression as any other failed turn. * fix(agent-core-v2): settle seeded turns on pre-gate failure, preserve coded credential errors, close steps on recovering - Notification-seeded machine turns that fail before gating now bind a seeded reservation and end through endTurn like queued ones, instead of leaving the nudge pending and settled() hanging - The llm machine's request actor attaches the raw error to llm.failed.remote and the turn machine prefers it for its terminal failure, so coded errors (e.g. auth.login_required) survive to endTurn's error payload - projectMachineEvent now closes the current machine step on recovering exactly as it does on retrying, keeping step.begin/step.end balanced when credential recovery re-enters the request * fix(kap-server): add generate to IModelCatalog test fakes * fix(klient): migrate examples to the credentials API * test(agent-core-v2): drop credential recovery coverage * refactor(agent-core-v2): fold kimi-oauth credential adapter into credentials/ * refactor(agent-core-v2): pair credential refresh with invalidate, optional Model.credentials, abort-safe request actor - oauthCredentials.invalidate() now starts the forced refresh eagerly and hands the pending token to the next resolve(), so the force signal can no longer leak into or be consumed by unrelated resolves - Model.credentials becomes optional, dropping the {} as never / staticCredentials(undefined) filler in test fakes - the llm machine request actor swallows abort outcomes instead of reporting llm.failed.remote, so an aborted turn settles as aborted rather than failed * refactor(agent-core-v2): credentials recovery strategy chain, shared credential-recovery executors, single-proposal failure triage * fix(agent-core-v2): settle message-less notifications on pre-gate failure, recover credentials in media resolver uploads * test(kap-server): add the IModelCatalog.generate stub to the history suite
…I#3657) * fix(goal): remove time budget cap and exclude offline time * test(goal): refresh time budget tool snapshots
…onshotAI#3707) * feat(remote-control): compress textual tunnel responses with gzip * fix(remote-control): honor explicit gzip exclusion over accept-encoding wildcard * fix(remote-control): skip gzip for 206 responses and vary by accept-encoding * fix(remote-control): compress tunnel responses off the event loop * fix(remote-control): vary identity responses and version compressed etags * fix(remote-control): drop etags from gzipped tunnel responses
…oonshotAI#3714) * feat(agent-core-v2): allow rm -rf targeting /tmp and /temp paths The dangerous command guard flagged every recursive force rm regardless of target. rm -rf now falls through without an ask when all operands are literal paths under /tmp or /temp (segment-level prefix, no .. escape); mixed, non-literal, or out-of-prefix targets stay dangerous. * chore: add changeset for rm -rf temp path allowance
…oonshotAI#3715) * fix(agent-core-v2): stop warning on unhandled store.changed events * Delete .changeset/silence-store-changed-warning.md Signed-off-by: 7Sageer <sag77r@hotmail.com> --------- Signed-off-by: 7Sageer <sag77r@hotmail.com>
…down (MoonshotAI#3717) * fix(agent-core-v2): keep late task settlement silent after agent teardown * fix(agent-core-v2): narrow the task lifecycle guard to event dispatch
…lures, journal session-index freshness (MoonshotAI#3694) * fix(agent-core-v2): rebuild session and search indexes on unrecoverable storage failures * fix(agent-core-v2): propagate search sync truncation and track session count in index freshness * fix(minidb): wipe derived stores under their own locks during rebuild * fix(agent-core-v2): isolate wiped stores, invalidate stale projections, and account sync failures * feat(agent-core-v2): replace session index freshness scans with a dirty journal and targeted reconciliation * fix(agent-core-v2): split transient failures by op kind, surface failed startup reconciliation, and cool down search session skips
…xp stack overflow (MoonshotAI#3709) The Remote Control HTTP tunnel validated each base64 message with a backtracking regular expression. Requests larger than ~3.5MB (base64 ~5MB) exhausted the V8 Irregexp backtracking stack and threw RangeError, which the catch-all mapped to a 400 with an empty body, surfacing as a generic connection failure on the web client. Replace the regex with an O(n) character check, reject oversize requests from the base64 length before decoding, and map non-SyntaxError failures to 502 instead of 400.
…dation (MoonshotAI#3718) * feat(remote-control): cache rewritten tunnel responses with ETag validation * fix(remote-control): weaken tunnel cache etag and drop 304 content-length * fix(remote-control): restrict tunnel 304 to successful GET/HEAD and honor wildcard If-None-Match
Resolve 10 merge conflicts from upstream sync while preserving fork-owned features: squeeze-model, fallback-model, fuck-permissions, model-favorites, fork-session, x-opencode-session, proxyUrl, multi-api-key providers, and the compaction-model overlay. Closes #70
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resolved 10 merge conflicts from upstream sync while preserving all fork-owned features.
Conflicted files resolved
packages/agent-core-v2/docs/state-manifest.d.tspackages/agent-core-v2/scripts/check-import-boundaries.mjspackages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.tspackages/agent-core-v2/src/human/llm/requester/bases/anthropic/format.tspackages/agent-core-v2/src/human/llm/requester/bases/anthropic/requester.tspackages/agent-core-v2/src/human/llm/requester/bases/openai-responses/format.tspackages/agent-core-v2/src/human/llm/requester/bases/openai-responses/requester.tspackages/agent-core-v2/src/human/llm/requester/bases/openai/format.tspackages/agent-core-v2/src/human/llm/requester/bases/openai/requester.tspackages/agent-core-v2/src/llm-adapter/model/model-auth.tsResolution notes
planOpenAIRequest/planAnthropicRequest/planOpenAIResponsesRequest). The fork'sx-opencode-sessionheader andbuildProxyDispatcherproxy support were ported into the new architecture;sessionHeadersForRequestremains exported from eachformat.tsper.github/FORK_OWNED_FILESmarkers.fullCompactionService.ts: upstream'srunRequest+runWithCredentialRecoveryretry structure kept, with the fork'smodel: compactionRequestModelandeffectiveMaxOutputSizeoverlay preserved.model-auth.ts: fork's active-key selection (getActiveProviderApiKey,provider.apiKeys/activeApiKeyId) preserved; upstream's removal of the inspection subsystem (ResolutionTrace) adopted since that subsystem was upstream-owned and removed upstream in refactor(agent-core-v2): rewire the model catalog runtime onto the provider-catalog state machine MoonshotAI/kimi-code#3606.state-manifest.d.ts: index count set to 76 Agent keys (75 upstream + fork-ownedsqueezeModel; upstream's own removals ofactivityView.*andloop.nextReservedTurnIdadopted).fork-sync-resolutionbecause a branch namedsync/...cannot exist alongside thesyncbranch on the remote (git ref namespace limitation); the issue's literal branch name was used locally.Verification
tsc --noEmit -p packages/agent-core-v2passes.github/FORK_OWNED_FILESsurvival markers present (ALL MARKERS OK)check-import-boundaries.mjs: OK (1459 files);check-no-comments.mjs: OKsyncbranch (pre-existing, unrelated to this merge)Closes #70