diff --git a/chatkit/agents.py b/chatkit/agents.py
index 5f3b9ca..6fdff22 100644
--- a/chatkit/agents.py
+++ b/chatkit/agents.py
@@ -690,10 +690,26 @@ async def hidden_context_to_input(
) -> TResponseInputItem | list[TResponseInputItem] | None:
"""
Convert a HiddenContextItem into input item(s) to send to the model.
- Required when HiddenContextItem are used.
+ Required to override when HiddenContextItems with non-string content are used.
"""
- raise NotImplementedError(
- "HiddenContextItem were present in a user message but Converter.hidden_context_to_input was not implemented"
+ if not isinstance(item.content, str):
+ raise NotImplementedError(
+ "HiddenContextItems with non-string content were present in a user message but a Converter.hidden_context_to_input was not implemented"
+ )
+
+ text = (
+ "Hidden context for the agent (not shown to the user):\n"
+ f"\n{item.content}\n"
+ )
+ return Message(
+ type="message",
+ content=[
+ ResponseInputTextParam(
+ type="input_text",
+ text=text,
+ )
+ ],
+ role="user",
)
async def task_to_input(
diff --git a/tests/test_agents.py b/tests/test_agents.py
index dcd7bd0..8185651 100644
--- a/tests/test_agents.py
+++ b/tests/test_agents.py
@@ -38,6 +38,7 @@
ResponseContentPartAddedEvent,
)
from openai.types.responses.response_file_search_tool_call import Result
+from openai.types.responses.response_input_item_param import Message
from openai.types.responses.response_output_text import (
AnnotationContainerFileCitation as ResponsesAnnotationContainerFileCitation,
)
@@ -77,6 +78,7 @@
CustomTask,
DurationSummary,
FileSource,
+ HiddenContextItem,
InferenceOptions,
Page,
TaskItem,
@@ -542,6 +544,72 @@ async def test_input_item_converter_user_input_with_tags_throws_by_default():
await simple_to_agent_input(items)
+async def test_input_item_converter_for_hidden_context_with_string_content():
+ items = [
+ HiddenContextItem(
+ id="123",
+ content="User pressed the red button",
+ thread_id=thread.id,
+ created_at=datetime.now(),
+ )
+ ]
+
+ # The default converter works for string content
+ items = await simple_to_agent_input(items)
+ assert len(items) == 1
+ assert items[0] == {
+ "content": [
+ {
+ "text": "Hidden context for the agent (not shown to the user):\n\nUser pressed the red button\n",
+ "type": "input_text",
+ },
+ ],
+ "role": "user",
+ "type": "message",
+ }
+
+
+async def test_input_item_converter_for_hidden_context_with_non_string_content():
+ items = [
+ HiddenContextItem(
+ id="123",
+ content={"harry": "potter", "hermione": "granger"},
+ thread_id=thread.id,
+ created_at=datetime.now(),
+ )
+ ]
+
+ # Default converter should throw
+ with pytest.raises(NotImplementedError):
+ await simple_to_agent_input(items)
+
+ class MyThreadItemConverter(ThreadItemConverter):
+ async def hidden_context_to_input(self, item: HiddenContextItem):
+ content = ",".join(item.content.keys())
+ return Message(
+ type="message",
+ content=[
+ ResponseInputTextParam(
+ type="input_text", text=f"{content}"
+ )
+ ],
+ role="user",
+ )
+
+ items = await MyThreadItemConverter().to_agent_input(items)
+ assert len(items) == 1
+ assert items[0] == {
+ "content": [
+ {
+ "text": "harry,hermione",
+ "type": "input_text",
+ },
+ ],
+ "role": "user",
+ "type": "message",
+ }
+
+
async def test_input_item_converter_with_client_tool_call():
items = [
UserMessageItem(