Skip to content

feat(soul): RalphFlow architecture with ephemeral context and convergence detection - #1960

Closed
ORDL-AMF wants to merge 53 commits into
mainfrom
unknown repository
Closed

feat(soul): RalphFlow architecture with ephemeral context and convergence detection#1960
ORDL-AMF wants to merge 53 commits into
mainfrom
unknown repository

Conversation

@ORDL-AMF

@ORDL-AMF ORDL-AMF commented Apr 20, 2026

Copy link
Copy Markdown

Summary

This PR introduces the RalphFlow architecture — an automated iteration framework for the Kimi Code CLI agent that prevents infinite loops while enabling robust multi-step workflows.

Key Changes

  • Ephemeral Context: Flow iterations run in isolated temporary context files. Main conversation history stays clean unless explicitly merged.
  • Flow Decision Tool: Replaces brittle ... text parsing with a structured flow_decision tool that models choose CONTINUE/STOP/PAUSE.
  • Convergence Detection: Auto-stops flows when the model repeats identical assistant responses across iterations (Jaccard-like fingerprint similarity ≥ 0.85).
  • Cancel/Pause Support: Flows can be cancelled mid-run or paused to allow user interjection.
  • Agent Gateway Support: Anthropic Messages API format for agent-gw.kimi.com endpoints, with OAuth token refresh and custom base_url preservation.
  • MCP Server Mode: New kimi mcp serve command exposes the CLI as an MCP server via stdio transport.

Safety

  • Max 3 retries for invalid flow choices before abort.
  • Ephemeral context discarded by default (commit_mode="discard").
  • Convergence detector triggers after 2 repeated similar iterations.

Tests

  • tests/core/test_kimisoul_ralph_loop.py — 9 scenarios covering ephemeral context, flow decision tool, convergence, cancel, pause, and max retries.
  • tests/test_mcp_serve.py — MCP server result collector and tool registration tests.
  • Full suite: 2278 passed.

Open in Devin Review

chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

- fix(soul): merge ralph_loop ephemeral context to preserve cross-turn memory
- fix(ui): gate usage URL early-return to Kimi Code providers only
- fix(llm): remove duplicate custom_headers that clobber Authorization
- fix(llm): apply KIMI_MODEL_* env overrides for agent-gw providers
- fix(auth): refresh Anthropic default_headers Authorization on OAuth token rotation
- test: update ralph loop test expectation for merge mode
chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

- fix(auth): mutate _custom_headers instead of default_headers property
  when refreshing Anthropic Authorization header on OAuth token rotation.
  default_headers is a property that returns a new dict each call, so
  mutating it had no effect.
- fix(soul): handle ephemeral context compaction in _merge_ephemeral_to_main.
  If compact_context() runs during a flow, the ephemeral history is rebuilt
  and can become shorter than _parent_history_len. Fall back to merging all
  ephemeral messages so flow results are not lost.
devin-ai-integration[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

- fix(soul): replace main context file on compaction during auto-ralph flow
  to prevent duplicate messages in ephemeral-to-main merge
- fix(soul): merge paused auto-Ralph ephemeral history into main context
  so context is not lost when user interjects
- fix(mcp): propagate StepInterrupted as an error to MCP callers instead
  of returning a partial success result
- fix(kosong): pass VideoURLPart through Anthropic provider for agent-gw
  video-in support
@ORDL-AMF

Copy link
Copy Markdown
Author

@codex review

@devin-ai-integration review

chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

- Fix MCP StepInterrupted propagation: don't break on StepInterrupted,
  let the underlying exception surface to callers instead of returning
  partial success.
- Fix ToolCallPart attribute name: arguments_part (was arguments).
- Reset FlowRunner._paused at start of run() to prevent stale state
  across reused runner instances.
- Base convergence detection on actual task assistant messages from
  context history, not the decision turn output, avoiding false
  convergence on stable CONTINUE rationales.
- Add regression test for pause reset behavior.
chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

- Populate tool_call_names in IterationFingerprint from assistant message
  tool calls, and include them in similarity scoring. This prevents false
  convergence when the model emits stable text but makes different tool
  calls across iterations.
- Update last_task_message from every node (not just non-decision nodes)
  so ralph_loop decision-only self-loops get fresh convergence input on
  each iteration instead of re-hashing the same R1 message forever.
- Preserve original flow_decision tool object when restoring toolset after
  a flow run, instead of replacing a custom implementation with a fresh
  FlowDecisionTool instance.
@ORDL-AMF

Copy link
Copy Markdown
Author

@codex address that feedback

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

@ORDL-AMF

Copy link
Copy Markdown
Author

@codex address that feedback

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

@ORDL-AMF

Copy link
Copy Markdown
Author

@chatgpt-codex-connector I did create an environment. Can you please re-review the latest commit?

@ORDL-AMF

Copy link
Copy Markdown
Author

@chatgpt-codex-connector I already created an environment. Please re-review the latest commit (dfc66df).

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…ence

- P1: Detect compaction by comparing parent prefix hash instead of
  relying solely on history length. Compaction can rewrite history
  such that final length exceeds the original parent length, causing
  the index-based merge to use wrong offsets.
- P2: Pass tool results (reconstructed from tool messages in context
  history) into convergence detector so tool output changes are
  included in similarity scoring.
chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

…g 0.53.0

Upstream changes:
- fix(yolo): unblock AskUserQuestion; add orthogonal afk mode (#2045)
- chore(release): bump kimi-cli to 1.40.0 and kosong 0.53.0 (#2108)

The yolo/afk refactor separates 'away from keyboard' mode from
'yolo' (auto-approve) mode, making them orthogonal concerns.

No merge conflicts with our RalphFlow changes.
All 44 tests pass (11 ralph_loop + 33 afk/yolo).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 13bfecc68f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/kimi_cli/soul/kimisoul.py Outdated
Comment on lines +1752 to +1754
for tool_name in list(toolset._tool_dict.keys()):
if tool_name != "flow_decision" and toolset.hide(tool_name):
hidden_tools.append(tool_name)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep non-decision tools enabled on CONTINUE path

The decision-node tool masking hides every tool except flow_decision, but Ralph Loop routes CONTINUE from R2 back to R2 (outgoing["R2"] self-loop), so subsequent iterations cannot execute Shell/file/web tools at all and can only emit another decision. In practice this turns CONTINUE into a no-op loop (re-decide repeatedly) instead of “keep working and refining,” which can prematurely stall multi-iteration runs after only the first task node.

Useful? React with 👍 / 👎.

Co-authored-by: Open Research and Development Laboratories | https://ordl.org | ordl@ordl.org
Co-authored-by: Open Research and Development Laboratories | https://ordl.org | ordl@ordl.org
Co-authored-by: Open Research and Development Laboratories | https://ordl.org | ordl@ordl.org

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 92e8ca973d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +21 to +25
async def __call__(self, params: Params) -> ToolReturnValue:
return ToolOk(
output="",
message="No archived context is available for this session.",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Implement archive lookup before exposing ArchiveSearch

This tool is now added to all default agents, but its handler always returns the same hardcoded "No archived context" response regardless of query or session state. In long sessions where compaction has already removed earlier turns, the model will call this tool expecting retrieval and get no data every time, so references to prior decisions/files cannot be recovered and flow quality regresses. Either connect this to a real archive backend or keep the tool out of default toolsets until it is functional.

Useful? React with 👍 / 👎.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 57 additional findings in Devin Review.

Open in Devin Review

Comment on lines +168 to +173
scores: list[float] = []

if a.assistant_text_hash == b.assistant_text_hash:
scores.append(1.0)
else:
scores.append(0.0)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Convergence similarity inflated by ignored text, causing false auto-stop

When ignore_text=True is passed to IterationFingerprint.from_turn, both fingerprints get assistant_text_hash="". In _compute_similarity, the empty-string equality check at line 170 contributes a free 1.0 to the scores list, inflating the average similarity. The intent of ignore_text is to exclude text from comparison, but the current code still includes it with a perfect score. This inflates the similarity denominator from 2 (tool names + tool outputs) to 3, and can trigger false convergence — e.g., if tool names match (1.0) but outputs differ moderately (0.55): (1.0 + 1.0 + 0.55) / 3 = 0.85 >= threshold, triggering convergence. The correct result excluding text would be (1.0 + 0.55) / 2 = 0.775 < 0.85, which should NOT converge. This causes the flow to auto-stop prematurely when the model is still making progress (different tool outputs).

Suggested change
scores: list[float] = []
if a.assistant_text_hash == b.assistant_text_hash:
scores.append(1.0)
else:
scores.append(0.0)
scores: list[float] = []
if a.assistant_text_hash or b.assistant_text_hash:
if a.assistant_text_hash == b.assistant_text_hash:
scores.append(1.0)
else:
scores.append(0.0)
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


def run_mcp_server() -> None:
"""Entry point for `kimi mcp serve`."""
enable_logging(debug=False, redirect_stderr=True)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MCP serve enable_logging with redirect_stderr=True hides startup errors from stdio transport

In run_mcp_server() at src/kimi_cli/mcp_serve/__init__.py:205, enable_logging(debug=False, redirect_stderr=True) redirects stderr to the log file via dup2. Because the MCP server uses stdio transport (server.run(transport="stdio")), both stdin and stdout are occupied by the MCP protocol. Redirecting stderr means that any startup errors (e.g., missing config, import errors in tools) that would normally print to stderr are silently swallowed into the log file. The MCP client sees no error, and the server appears to hang. redirect_stderr=False should be used to preserve stderr as the only error channel available during stdio-based MCP communication.

Suggested change
enable_logging(debug=False, redirect_stderr=True)
enable_logging(debug=False, redirect_stderr=False)
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Co-authored-by: Open Research and Development Laboratories | https://ordl.org | ordl@ordl.org

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f4ce36675

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +130 to +133
and llm.provider_config.type == "kimi"
and llm.provider_config.base_url
and "agent-gw" in llm.provider_config.base_url
):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Upload agent-gw videos for Anthropic provider configs

The new fallback uploader is gated on llm.provider_config.type == "kimi", so sessions configured as provider.type="anthropic" with an agent-gw base URL skip video upload and always embed local videos as base64 data: URLs. Fresh evidence in this revision is create_llm now explicitly supports Anthropic providers pointed at agent-gw, so this path is reachable and can produce oversized prompts/request failures for normal multi‑MB clips instead of using the lightweight uploaded video_url reference.

Useful? React with 👍 / 👎.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 57 additional findings in Devin Review.

Open in Devin Review

Comment on lines +1561 to +1568
async def _cleanup_ephemeral_context(self) -> None:
if self._paused:
# Keep temp file around for resume
return
if self._tmp_file and self._tmp_file.exists():
self._tmp_file.unlink(missing_ok=True)
self._ephemeral_context = None
self._tmp_file = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Ephemeral context temp file leaked when PAUSE is followed by a new user turn

When the flow model selects PAUSE, FlowRunner._cleanup_ephemeral_context (src/kimi_cli/soul/kimisoul.py:1561-1568) intentionally preserves the temp file for a potential resume. However, on the next user message, KimiSoul.run() creates a brand-new FlowRunner via FlowRunner.ralph_loop() — the old runner (and its preserved temp file path) is garbage-collected without cleanup. The orphaned flow_anonymous_<uuid>_context.jsonl file remains in the session directory indefinitely.

This accumulates one leaked file per PAUSE event across auto-Ralph turns. While each file is bounded in size and lives in the session directory (cleaned up on session deletion), repeated PAUSE events could accumulate significant disk usage in long-lived sessions.

Prompt for agents
In FlowRunner._cleanup_ephemeral_context (src/kimi_cli/soul/kimisoul.py:1561-1568), when _paused is True, the temp file is preserved for potential resume. But when a new auto-Ralph FlowRunner is created on the next user turn, the old runner is discarded without deleting its temp file.

Possible fixes:
1. Add a __del__ or explicit cleanup method to FlowRunner that deletes the temp file on garbage collection.
2. Track temp files at the session level and clean up stale flow temp files when a new flow starts.
3. In _setup_ephemeral_context, scan the session directory for stale flow temp files (matching the pattern flow_*_context.jsonl) and delete them before creating the new one.

Option 3 is the simplest and most robust since it doesn't rely on GC behavior.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Update vulnerable Python dependency pins and keep FastMCP OAuth storage working after the FastMCP 3.2 upgrade.

Co-authored-by: Open Research and Development Laboratories | https://ordl.org | ordl@ordl.org
Update the locked Black formatter dependency to the patched 26.3.1 release required by GitHub Dependabot.

Co-authored-by: Open Research and Development Laboratories | https://ordl.org | ordl@ordl.org

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 58 additional findings in Devin Review.

Open in Devin Review

Comment on lines +1758 to +1762
# Hide all non-flow_decision tools to prevent the model from
# calling shell/file/etc. instead of making a flow decision.
for tool_name in list(toolset._tool_dict.keys()): # pyright: ignore[reportPrivateUsage]
if tool_name != "flow_decision" and toolset.hide(tool_name):
hidden_tools.append(tool_name)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Flow decision node unhides tools that were intentionally hidden by external code

In _execute_flow_node, when processing a decision node, all non-flow_decision tools are hidden via toolset.hide(). The finally block then unhides every tool in the hidden_tools list. However, hide() returns True and records the tool even if it was already hidden by external code (e.g., the Wire server hiding AskUserQuestion because the client doesn't support questions at src/kimi_cli/wire/server.py:574-578, or plan mode tools at src/kimi_cli/wire/server.py:583-602). After the finally block calls unhide() on these already-hidden tools, they become visible to the LLM on subsequent turns — even though the Wire server intentionally hid them.

Example scenario
  1. Wire server hides AskUserQuestion because client doesn't support questions
  2. RalphFlow decision node hides all tools (including already-hidden AskUserQuestion) and records them in hidden_tools
  3. Finally block unhides everything in hidden_tools, including AskUserQuestion
  4. On the next task node (after CONTINUE), the LLM sees AskUserQuestion in its tool list even though the client can't handle it

Same issue affects EnterPlanMode/ExitPlanMode when client doesn't support plan mode.

Suggested change
# Hide all non-flow_decision tools to prevent the model from
# calling shell/file/etc. instead of making a flow decision.
for tool_name in list(toolset._tool_dict.keys()): # pyright: ignore[reportPrivateUsage]
if tool_name != "flow_decision" and toolset.hide(tool_name):
hidden_tools.append(tool_name)
# Hide all non-flow_decision tools to prevent the model from
# calling shell/file/etc. instead of making a flow decision.
# Only track tools that were NOT already hidden so the finally
# block does not accidentally unhide externally-hidden tools.
for tool_name in list(toolset._tool_dict.keys()): # pyright: ignore[reportPrivateUsage]
if tool_name != "flow_decision" and tool_name not in toolset._hidden_tools and toolset.hide(tool_name): # pyright: ignore[reportPrivateUsage]
hidden_tools.append(tool_name)
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Remove the RECLONE/REPO_URL flow from the RHEL clean builder so the script only operates on an existing checkout and fails closed when SRC is not a git tree.

Co-authored-by: Open Research and Development Laboratories | https://ordl.org | ordl@ordl.org

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3d49c11551

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1547 to +1554
for i in range(start, len(self._ephemeral_context.history)):
message = self._ephemeral_context.history[i]
prov = self._ephemeral_context.get_provenance(i)
source = prov.source if prov else "flow"
ts = prov.timestamp if prov else None
await soul._context.append_message( # type: ignore[reportPrivateUsage]
message, source=source, timestamp=ts
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Persist flow metadata when replay-merging ephemeral context

This merge path replays only Message objects into the main context file via append_message, so _checkpoint and _usage records produced during the flow are dropped from disk even though in-memory counters are later overwritten. The session appears correct until restart, then Context.restore() rebuilds state from a file that is missing those metadata records, which can rewind checkpoint IDs (breaking D-Mail/back-to-checkpoint references) and lose token-baseline markers for subsequent compaction decisions.

Useful? React with 👍 / 👎.

Detect available CPUs, export parallel build settings, and let the RHEL clean builder drive prepare/build/binary/install steps with explicit opt-in flags.

Co-authored-by: Open Research and Development Laboratories | https://ordl.org | ordl@ordl.org

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: db55a868a3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1482 to +1484
if self._tmp_file is not None and self._tmp_file.exists():
self._tmp_file.unlink(missing_ok=True)
self._tmp_file = session_dir / f"flow_{safe_name}_{unique_suffix}_context.jsonl"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve paused flow context across reruns

The PAUSE path is currently non-resumable: _cleanup_ephemeral_context explicitly keeps the temp context for resume, but the next run() immediately deletes self._tmp_file and creates a brand-new ephemeral context from the main history. When a flow chooses PAUSE, all paused-loop progress is discarded on the next invocation, so users cannot actually continue from where they paused despite the advertised PAUSE semantics.

Useful? React with 👍 / 👎.

Restore the Unix-socket Wire IPC entrypoint and runtime controls that RalphFlow persistent lanes depend on. Add coverage for the socket initialize path plus runtime instructions and AFK control.

Co-authored-by: Open Research and Development Laboratories | https://ordl.org | ordl@ordl.org
Mirror stdio Wire JSON-RPC validation in the IPC socket server so protocol errors reply to the originating client instead of hanging callers.

Replace Anthropic custom headers during OAuth token refresh so Authorization updates persist when the headers object is typed as a mapping.

Co-authored-by: Open Research and Development Laboratories | https://ordl.org | ordl@ordl.org

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 74c251634a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

socket_dir = os.getenv("KIMI_WIRE_IPC_SOCKET_DIR")
if socket_dir:
Path(socket_dir).mkdir(parents=True, exist_ok=True)
return os.path.join(socket_dir, f"kimi-{os.getpid()}-{id(object()):x}.sock")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Replace id(object()) suffix with a real unique token

_make_socket_path() uses id(object()) as the uniqueness source, but CPython can immediately reuse object IDs, so repeated calls in the same process often produce the same value. That makes the generated socket path non-unique for multiple IPC server instances in one process, causing collisions (the later server can unlink or fail to bind the earlier server’s socket). Use a stable unique source like uuid.uuid4().hex (or tempfile.mkstemp) for the suffix.

Useful? React with 👍 / 👎.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants