-
Notifications
You must be signed in to change notification settings - Fork 1.4k
clai: Add ability to continue last conversation #2257
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
uriyyo
wants to merge
14
commits into
pydantic:main
Choose a base branch
from
uriyyo:feature/clai-continue-conversation
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+158
−25
Open
Changes from 13 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
bf5d828
clai: Add ability to continue last conversation
uriyyo 1278090
Fix tests
uriyyo 18ff146
Add tests
uriyyo f37042a
Fix corrupted tests
uriyyo b4fa954
try to fix coverage
uriyyo cf3b691
Revert "try to fix coverage"
uriyyo c487d58
merge with main
uriyyo c680761
Use message_history arg for run_chat; fix typos in tests
uriyyo 526069f
Use read_bytes() to load conversation JSON
uriyyo a08b5ed
Patch PYDANTIC_AI_HOME with tmp_path in test fixture
uriyyo 8ae1e62
Remove unused PYDANTIC_AI_HOME import from tests
uriyyo 1e40988
Add type annotations to empty_last_conversation_path fixture
uriyyo 6dbe144
tests: use Path.unlink(missing_ok=True) to remove file safely
uriyyo 6db9293
Support custom conversation load/store paths and optional --continue
uriyyo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,13 +12,14 @@ | |
| from pathlib import Path | ||
| from typing import Any, cast | ||
|
|
||
| from pydantic import ValidationError | ||
| from typing_inspection.introspection import get_literal_values | ||
|
|
||
| from . import __version__ | ||
| from ._run_context import AgentDepsT | ||
| from .agent import AbstractAgent, Agent | ||
| from .exceptions import UserError | ||
| from .messages import ModelMessage, ModelResponse | ||
| from .messages import ModelMessage, ModelMessagesTypeAdapter, ModelResponse | ||
| from .models import KnownModelName, infer_model | ||
| from .output import OutputDataT | ||
|
|
||
|
|
@@ -54,6 +55,7 @@ | |
| """ | ||
|
|
||
| PROMPT_HISTORY_FILENAME = 'prompt-history.txt' | ||
| LAST_CONVERSATION_FILENAME = 'last-conversation.json' | ||
|
|
||
|
|
||
| class SimpleCodeBlock(CodeBlock): | ||
|
|
@@ -148,6 +150,13 @@ def cli( # noqa: C901 | |
| help='Which colors to use for code, can be "dark", "light" or any theme from pygments.org/styles/. Defaults to "dark" which works well on dark terminals.', | ||
| default='dark', | ||
| ) | ||
| parser.add_argument( | ||
| '-c', | ||
| '--continue', | ||
| dest='continue_', | ||
| action='store_true', | ||
| help='Continue last conversation, if any, instead of starting a new one.', | ||
| ) | ||
| parser.add_argument('--no-stream', action='store_true', help='Disable streaming from the model') | ||
| parser.add_argument('--version', action='store_true', help='Show version and exit') | ||
|
|
||
|
|
@@ -207,19 +216,42 @@ def cli( # noqa: C901 | |
| else: | ||
| code_theme = args.code_theme # pragma: no cover | ||
|
|
||
| try: | ||
| history = load_last_conversation() if args.continue_ else None | ||
| except ValidationError: | ||
| console.print( | ||
| '[red]Error loading last conversation, it is corrupted or invalid.\nStarting a new conversation.[/red]' | ||
| ) | ||
uriyyo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| history = None | ||
|
|
||
| if prompt := cast(str, args.prompt): | ||
| try: | ||
| asyncio.run(ask_agent(agent, prompt, stream, console, code_theme)) | ||
| asyncio.run(ask_agent(agent, prompt, stream, console, code_theme, messages=history)) | ||
| except KeyboardInterrupt: | ||
| pass | ||
| return 0 | ||
|
|
||
| try: | ||
| return asyncio.run(run_chat(stream, agent, console, code_theme, prog_name)) | ||
| return asyncio.run(run_chat(stream, agent, console, code_theme, prog_name, message_history=history)) | ||
| except KeyboardInterrupt: # pragma: no cover | ||
| return 0 | ||
|
|
||
|
|
||
| def store_last_conversation(messages: list[ModelMessage], config_dir: Path | None = None) -> None: | ||
| last_conversation_path = (config_dir or PYDANTIC_AI_HOME) / LAST_CONVERSATION_FILENAME | ||
| last_conversation_path.parent.mkdir(parents=True, exist_ok=True) | ||
| last_conversation_path.write_bytes(ModelMessagesTypeAdapter.dump_json(messages)) | ||
|
|
||
|
|
||
| def load_last_conversation(config_dir: Path | None = None) -> list[ModelMessage] | None: | ||
| last_conversation_path = (config_dir or PYDANTIC_AI_HOME) / LAST_CONVERSATION_FILENAME | ||
|
|
||
| if not last_conversation_path.exists(): | ||
| return None | ||
|
|
||
| return ModelMessagesTypeAdapter.validate_json(last_conversation_path.read_bytes()) | ||
|
|
||
|
|
||
| async def run_chat( | ||
| stream: bool, | ||
| agent: AbstractAgent[AgentDepsT, OutputDataT], | ||
|
|
@@ -255,7 +287,7 @@ async def run_chat( | |
| return exit_value | ||
| else: | ||
| try: | ||
| messages = await ask_agent(agent, text, stream, console, code_theme, deps, messages) | ||
| messages = await ask_agent(agent, text, stream, console, code_theme, deps, messages, config_dir) | ||
| except CancelledError: # pragma: no cover | ||
| console.print('[dim]Interrupted[/dim]') | ||
| except Exception as e: # pragma: no cover | ||
|
|
@@ -273,6 +305,7 @@ async def ask_agent( | |
| code_theme: str, | ||
| deps: AgentDepsT = None, | ||
| messages: Sequence[ModelMessage] | None = None, | ||
| config_dir: Path | None = None, | ||
| ) -> list[ModelMessage]: | ||
| status = Status('[dim]Working on it…[/dim]', console=console) | ||
|
|
||
|
|
@@ -281,7 +314,10 @@ async def ask_agent( | |
| result = await agent.run(prompt, message_history=messages, deps=deps) | ||
| content = str(result.output) | ||
| console.print(Markdown(content, code_theme=code_theme)) | ||
| return result.all_messages() | ||
| result_messages = result.all_messages() | ||
| store_last_conversation(result_messages, config_dir) | ||
|
|
||
| return result_messages | ||
|
|
||
| with status, ExitStack() as stack: | ||
| async with agent.iter(prompt, message_history=messages, deps=deps) as agent_run: | ||
|
|
@@ -296,7 +332,10 @@ async def ask_agent( | |
| live.update(Markdown(str(content), code_theme=code_theme)) | ||
|
|
||
| assert agent_run.result is not None | ||
| return agent_run.result.all_messages() | ||
| result_messages = agent_run.result.all_messages() | ||
| store_last_conversation(result_messages, config_dir) | ||
|
||
|
|
||
| return result_messages | ||
|
|
||
|
|
||
| class CustomAutoSuggest(AutoSuggestFromHistory): | ||
|
|
||
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
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.
Uh oh!
There was an error while loading. Please reload this page.