Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Update conversation history handling#24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
gabor-openai merged 2 commits intomainfromdev/steven/conversation_history
Oct 20, 2025

Conversation

@steven10a
Copy link
Collaborator

@steven10asteven10a commentedOct 17, 2025
edited
Loading

Updates handling of conversation history

  • Normalizes conversation history regardless of the endpoint used by the user. Logic extracted toconversation.py helper
  • Conversation history is now accessible by any check
  • Supports usingprevious_response_id for conversation history withresponses endpoint
  • GuardrailAgent usessession if passed intoRunner.run(). Otherwise treats theinput as the conversation history
  • Fixed streaming to provide correct conversation history
  • Updated and created new tests

CopilotAI review requested due to automatic review settingsOctober 17, 2025 17:13
Copy link

CopilotAI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR updates conversation history handling to normalize conversation data across different endpoints and provide consistent access to conversation history for guardrails. The main goal is to ensure that conversation history is accessible by all guardrail checks regardless of which API endpoint is used.

  • Extracts conversation normalization logic to a dedicatedconversation.py utility module
  • UpdatesGuardrailAgent to use session-based conversation history when available, falling back to input conversation
  • Fixes streaming to provide proper conversation history context during output guardrails

Reviewed Changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 6 comments.

Show a summary per file
FileDescription
src/guardrails/utils/conversation.pyNew module providing conversation normalization utilities across different API formats
src/guardrails/agents.pyRefactors agent conversation handling to use sessions and normalized conversation history
src/guardrails/client.pyUpdates client methods to use normalized conversation handling
src/guardrails/_streaming.pyFixes streaming to include conversation history in output guardrail checks
src/guardrails/resources/responses/responses.pyUpdates to use normalized conversation history
src/guardrails/resources/chat/chat.pyUpdates to use normalized conversation history
tests/unit/test_agents.pyUpdates tests for new agent conversation handling patterns
tests/unit/test_client_sync.pyUpdates test assertions for normalized conversation format

Tip: Customize your code reviews with copilot-instructions.md.Create the file orlearn how to get started.

Comment on lines +19 to +29
"""Normalized representation of a conversation item.
Attributes:
role: Logical speaker role (user, assistant, system, tool, etc.).
type: Optional type discriminator for non-message items such as
``function_call`` or ``function_call_output``.
content: Primary text payload for message-like items.
tool_name: Name of the tool/function associated with the entry.
arguments: Serialized tool/function arguments when available.
output: Serialized tool result payload when available.
call_id: Identifier that links tool calls and outputs.

Choose a reason for hiding this comment

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

The ConversationEntry class is missing a comprehensive docstring that should explain its purpose as a normalized conversation item and provide examples of usage.

Suggested change
"""Normalizedrepresentationofaconversationitem.
Attributes:
role:Logicalspeakerrole (user,assistant,system,tool,etc.).
type:Optional typediscriminatorfornon-messageitemssuchas
``function_call``or``function_call_output``.
content:Primarytextpayloadformessage-likeitems.
tool_name:Nameofthetool/functionassociatedwiththeentry.
arguments:Serializedtool/functionargumentswhenavailable.
output:Serializedtoolresultpayloadwhenavailable.
call_id:Identifierthatlinkstoolcallsandoutputs.
"""
Representsanormalizediteminaconversationhistory,suchasausermessage,
assistantresponse,tool/functioncall,ortooloutput.Thisclassprovidesa
consistentstructureforconversationentries,regardlessoftheoriginating
APIorprovider,enablingguardrailstoprocessandreasonaboutconversation
turnsinauniformway.
Eachentrymayrepresentamessage (fromuser,assistant,orsystem),atool
call (functioninvocation),oratooloutput (functionresult).Thefields
capturethesemanticrole,type,content,andanyassociatedtool/function
metadata.
Attributes:
role:Logicalspeakerrole (e.g.,"user","assistant","system","tool").
type:Optional typediscriminatorfornon-messageitemssuchas
"function_call"or"function_call_output".
content:Primarytextpayloadformessage-likeitems.
tool_name:Nameofthetool/functionassociatedwiththeentry.
arguments:Serializedtool/functionargumentswhenavailable.
output:Serializedtoolresultpayloadwhenavailable.
call_id:Identifierthatlinkstoolcallsandoutputs.
Example:
>>># User message
>>>entry=ConversationEntry(role="user",content="Hello, assistant!")
>>>entry.to_payload()
{'role':'user','content':'Hello, assistant!'}
>>># Assistant response
>>>entry=ConversationEntry(role="assistant",content="Hello! How can I help you?")
>>>entry.to_payload()
{'role':'assistant','content':'Hello! How can I help you?'}
>>># Tool/function call
>>>entry=ConversationEntry(
...role="assistant",
...type="function_call",
...tool_name="get_weather",
...arguments='{"location": "London"}',
...call_id="abc123"
... )
>>>entry.to_payload()
{
...'role':'assistant',
...'type':'function_call',
...'tool_name':'get_weather',
...'arguments':'{"location": "London"}',
...'call_id':'abc123'
}

Copilot uses AI. Check for mistakes.
Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

In my opinion this is an unnecessary expansion of the current doc string. The current version is concise and matches the codebase style.

returntext
return_extract_text(content.get("content"))

ifisinstance(content,Sequence)andnotisinstance(content,bytes|bytearray):

Choose a reason for hiding this comment

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

The union syntaxbytes | bytearray requires Python 3.10+. Consider using(bytes, bytearray) for broader compatibility.

Suggested change
ifisinstance(content,Sequence)andnotisinstance(content,bytes|bytearray):
ifisinstance(content,Sequence)andnotisinstance(content,(bytes,bytearray)):

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +30
"""Stub tool context carrying name, arguments,andoptional call id."""

tool_name:str
tool_arguments:dict[str,Any]
tool_arguments:dict[str,Any]|str
tool_call_id:str|None=None

Choose a reason for hiding this comment

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

The union syntaxdict[str, Any] | str andstr | None require Python 3.10+. Consider usingUnion[dict[str, Any], str] andOptional[str] for broader compatibility.

Copilot uses AI. Check for mistakes.
_user_messages:ContextVar[list[str]]=ContextVar("user_messages",default=[])# noqa: B039
# Context variables used to expose conversation information during guardrail checks.
_agent_session:ContextVar[Any|None]=ContextVar("guardrails_agent_session",default=None)
_agent_conversation:ContextVar[tuple[dict[str,Any], ...]|None]=ContextVar(

Choose a reason for hiding this comment

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

The union syntaxtuple[dict[str, Any], ...] | None requires Python 3.10+. Consider usingOptional[tuple[dict[str, Any], ...]] for broader compatibility.

Copilot uses AI. Check for mistakes.
llm_stream:Any,# coroutine or async iterator of OpenAI chunks
preflight_results:list[GuardrailResult],
input_results:list[GuardrailResult],
conversation_history:list[dict[str,Any]]|None=None,

Choose a reason for hiding this comment

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

The union syntaxlist[dict[str, Any]] | None requires Python 3.10+. Consider usingOptional[list[dict[str, Any]]] for broader compatibility.

Copilot uses AI. Check for mistakes.
llm_stream:Any,# iterator of OpenAI chunks
preflight_results:list[GuardrailResult],
input_results:list[GuardrailResult],
conversation_history:list[dict[str,Any]]|None=None,

Choose a reason for hiding this comment

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

The union syntaxlist[dict[str, Any]] | None requires Python 3.10+. Consider usingOptional[list[dict[str, Any]]] for broader compatibility.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

@gabor-openaigabor-openai left a comment

Choose a reason for hiding this comment

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

LGTM

@gabor-openaigabor-openai merged commitbdb0de6 intomainOct 20, 2025
3 checks passed
@gabor-openaigabor-openai deleted the dev/steven/conversation_history branchOctober 20, 2025 18:00
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

Copilot code reviewCopilotCopilot left review comments

@gabor-openaigabor-openaigabor-openai approved these changes

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

3 participants

@steven10a@gabor-openai

[8]ページ先頭

©2009-2025 Movatter.jp