diff --git a/src/kimi_cli/acp/convert.py b/src/kimi_cli/acp/convert.py
index 48297be3f..84f8c62ad 100644
--- a/src/kimi_cli/acp/convert.py
+++ b/src/kimi_cli/acp/convert.py
@@ -28,6 +28,23 @@ def acp_blocks_to_content_parts(prompt: list[ACPContentBlock]) -> list[ContentPa
)
)
)
+ case acp.schema.EmbeddedResourceContentBlock():
+ resource = block.resource
+ if isinstance(resource, acp.schema.TextResourceContents):
+ uri = resource.uri
+ text = resource.text
+ content.append(TextPart(text=f"\n{text}\n"))
+ else:
+ logger.warning(
+ "Unsupported embedded resource type: {type}",
+ type=type(resource).__name__,
+ )
+ case acp.schema.ResourceContentBlock():
+ # ResourceContentBlock is a link reference without inline content;
+ # include the URI so the model is at least aware of the reference.
+ content.append(
+ TextPart(text=f"")
+ )
case _:
logger.warning("Unsupported prompt content block: {block}", block=block)
return content
diff --git a/src/kimi_cli/acp/server.py b/src/kimi_cli/acp/server.py
index 5e77a0eed..a2cb2e711 100644
--- a/src/kimi_cli/acp/server.py
+++ b/src/kimi_cli/acp/server.py
@@ -63,7 +63,7 @@ async def initialize(
agent_capabilities=acp.schema.AgentCapabilities(
load_session=True,
prompt_capabilities=acp.schema.PromptCapabilities(
- embedded_context=False, image=True, audio=False
+ embedded_context=True, image=True, audio=False
),
mcp_capabilities=acp.schema.McpCapabilities(http=True, sse=False),
session_capabilities=acp.schema.SessionCapabilities(
diff --git a/tests/ui_and_conv/test_acp_convert.py b/tests/ui_and_conv/test_acp_convert.py
index 57f8accc9..f933482d8 100644
--- a/tests/ui_and_conv/test_acp_convert.py
+++ b/tests/ui_and_conv/test_acp_convert.py
@@ -1,7 +1,7 @@
import acp
-from kimi_cli.acp.convert import tool_result_to_acp_content
-from kimi_cli.wire.types import DiffDisplayBlock, ToolReturnValue
+from kimi_cli.acp.convert import acp_blocks_to_content_parts, tool_result_to_acp_content
+from kimi_cli.wire.types import DiffDisplayBlock, TextPart, ToolReturnValue
def test_tool_result_to_acp_content_handles_diff_display():
@@ -21,3 +21,62 @@ def test_tool_result_to_acp_content_handles_diff_display():
assert content.path == "foo.txt"
assert content.old_text == "before"
assert content.new_text == "after"
+
+
+def test_acp_blocks_to_content_parts_handles_embedded_text_resource():
+ block = acp.schema.EmbeddedResourceContentBlock(
+ type="resource",
+ resource=acp.schema.TextResourceContents(
+ uri="file:///path/to/foo.py",
+ text="print('hello')",
+ ),
+ )
+ parts = acp_blocks_to_content_parts([block])
+ assert len(parts) == 1
+ assert isinstance(parts[0], TextPart)
+ assert "file:///path/to/foo.py" in parts[0].text
+ assert "print('hello')" in parts[0].text
+
+
+def test_acp_blocks_to_content_parts_handles_resource_link():
+ block = acp.schema.ResourceContentBlock(
+ type="resource_link",
+ uri="file:///path/to/bar.py",
+ name="bar.py",
+ )
+ parts = acp_blocks_to_content_parts([block])
+ assert len(parts) == 1
+ assert isinstance(parts[0], TextPart)
+ assert "file:///path/to/bar.py" in parts[0].text
+ assert "bar.py" in parts[0].text
+
+
+def test_acp_blocks_to_content_parts_skips_blob_resource():
+ block = acp.schema.EmbeddedResourceContentBlock(
+ type="resource",
+ resource=acp.schema.BlobResourceContents(
+ uri="file:///path/to/image.png",
+ blob="iVBORw0KGgo=",
+ ),
+ )
+ parts = acp_blocks_to_content_parts([block])
+ assert len(parts) == 0
+
+
+def test_acp_blocks_to_content_parts_mixed_blocks():
+ blocks = [
+ acp.schema.TextContentBlock(type="text", text="Check this file:"),
+ acp.schema.EmbeddedResourceContentBlock(
+ type="resource",
+ resource=acp.schema.TextResourceContents(
+ uri="file:///src/main.py",
+ text="def main(): pass",
+ ),
+ ),
+ ]
+ parts = acp_blocks_to_content_parts(blocks)
+ assert len(parts) == 2
+ assert isinstance(parts[0], TextPart)
+ assert parts[0].text == "Check this file:"
+ assert isinstance(parts[1], TextPart)
+ assert "def main(): pass" in parts[1].text