codex-agent-framework 0.1.11__tar.gz → 0.1.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/CHANGELOG.md +14 -0
- {codex_agent_framework-0.1.11/codex_agent_framework.egg-info → codex_agent_framework-0.1.12}/PKG-INFO +4 -4
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/README.md +2 -1
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/agent.py +53 -11
- codex_agent_framework-0.1.12/codex_agent/browser.py +651 -0
- codex_agent_framework-0.1.12/codex_agent/builtin_providers.py +74 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/builtin_tools.py +197 -1
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/get_text/get_text.py +22 -44
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/prompts/system_prompt.txt +3 -1
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/utils.py +1 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12/codex_agent_framework.egg-info}/PKG-INFO +4 -4
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent_framework.egg-info/SOURCES.txt +3 -1
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent_framework.egg-info/requires.txt +1 -2
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/pyproject.toml +2 -3
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_agent.py +52 -2
- codex_agent_framework-0.1.12/tests/test_browser.py +235 -0
- codex_agent_framework-0.1.12/tests/test_get_text_browser.py +55 -0
- codex_agent_framework-0.1.11/codex_agent/builtin_providers.py +0 -42
- codex_agent_framework-0.1.11/codex_agent/get_webdriver.py +0 -44
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/LICENSE +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/MANIFEST.in +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/__init__.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/__main__.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/agent_runtime.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/ai.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/builtin_commands.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/chat.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/client.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/command.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/event.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/get_text/__init__.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/get_text/default_gitignore +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/get_text/simpler_get_text.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/image.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/latex.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/memory.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/message.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/prompts/image_generation_system_prompt.txt +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/provider.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/scheduler.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/server.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/service.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/stream_utils.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/tool.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/tray.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/tui.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/voice.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent/worker.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent_framework.egg-info/dependency_links.txt +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent_framework.egg-info/entry_points.txt +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/codex_agent_framework.egg-info/top_level.txt +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/setup.cfg +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_ai.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_chat.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_cli.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_client.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_events.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_image_message.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_memory.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_messages.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_scheduler.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_server.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_service.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_tray.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_tui.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_utils.py +0 -0
- {codex_agent_framework-0.1.11 → codex_agent_framework-0.1.12}/tests/test_worker.py +0 -0
|
@@ -3,6 +3,20 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
5
|
This project loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and uses semantic versioning where practical.
|
|
6
|
+
|
|
7
|
+
## [0.1.12] - 2026-05-05
|
|
8
|
+
### Added
|
|
9
|
+
- Add a persistent Playwright/Chromium browser controller with tools to open/close the browser, select tabs, navigate, click, fill, select options, press keys, inspect action snapshots, and capture screenshots.
|
|
10
|
+
- Add `browser_goto(url)` to navigate the active tab without opening or switching tabs.
|
|
11
|
+
- Add screenshot-backed visual fallback for pages where DOM snapshots are insufficient, including PDF viewers and image-heavy pages.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Replace the Selenium/Gecko rendered extraction path with Playwright-managed Chromium.
|
|
15
|
+
- Update web extraction dependencies and documentation to install Chromium with Playwright.
|
|
16
|
+
|
|
17
|
+
### Tests
|
|
18
|
+
- Add browser controller and rendered extraction regression coverage.
|
|
19
|
+
|
|
6
20
|
## [0.1.11] - 2026-05-05
|
|
7
21
|
### Added
|
|
8
22
|
- Add a separate `view` tool for folders, URLs, rich document extraction, and Python object inspection.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-agent-framework
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12
|
|
4
4
|
Summary: A lightweight event-driven Codex agent runtime.
|
|
5
5
|
Author: Baptiste
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,7 +20,6 @@ Requires-Dist: beautifulsoup4
|
|
|
20
20
|
Requires-Dist: codex-backend-sdk
|
|
21
21
|
Requires-Dist: fastapi
|
|
22
22
|
Requires-Dist: filetype
|
|
23
|
-
Requires-Dist: get-gecko-driver
|
|
24
23
|
Requires-Dist: modict
|
|
25
24
|
Requires-Dist: numpy
|
|
26
25
|
Requires-Dist: odfpy
|
|
@@ -28,6 +27,7 @@ Requires-Dist: openai
|
|
|
28
27
|
Requires-Dist: openpyxl
|
|
29
28
|
Requires-Dist: pathspec
|
|
30
29
|
Requires-Dist: pillow
|
|
30
|
+
Requires-Dist: playwright
|
|
31
31
|
Requires-Dist: pydub
|
|
32
32
|
Requires-Dist: pypdf
|
|
33
33
|
Requires-Dist: pynteract
|
|
@@ -36,7 +36,6 @@ Requires-Dist: PyYAML
|
|
|
36
36
|
Requires-Dist: regex
|
|
37
37
|
Requires-Dist: requests
|
|
38
38
|
Requires-Dist: rich
|
|
39
|
-
Requires-Dist: selenium
|
|
40
39
|
Requires-Dist: textual
|
|
41
40
|
Requires-Dist: tiktoken
|
|
42
41
|
Requires-Dist: trafilatura
|
|
@@ -73,7 +72,7 @@ It provides a reusable `Agent` abstraction with persistent sessions, local tools
|
|
|
73
72
|
- Python 3.10 or newer.
|
|
74
73
|
- A working model backend configuration compatible with `codex-backend-sdk` / OpenAI usage.
|
|
75
74
|
- GTK 3 plus Ayatana AppIndicator or AppIndicator bindings are needed for the tray controller on Linux.
|
|
76
|
-
-
|
|
75
|
+
- Playwright's managed Chromium browser is used for rendered web extraction when static fetching is insufficient. Install it with `python -m playwright install chromium` if needed.
|
|
77
76
|
|
|
78
77
|
## Installation
|
|
79
78
|
|
|
@@ -400,6 +399,7 @@ python -m build
|
|
|
400
399
|
The distribution includes prompt text files and `codex_agent/get_text/default_gitignore` through package data and `MANIFEST.in`.
|
|
401
400
|
|
|
402
401
|
## Recent changes
|
|
402
|
+
- `0.1.12`: add a persistent Playwright/Chromium browser controller with tab navigation, DOM/action snapshots, screenshots, form/click/key tools, and `browser_goto(url)` for active-tab navigation.
|
|
403
403
|
- `0.1.11`: split strict line-numbered UTF-8 `read` from unnumbered extracted `view`, preserve blank lines in read snippets, and show persistent+temporary message counts in the TUI status bar.
|
|
404
404
|
- `0.1.10`: persist only backend compaction summaries, drop bulky compacted conversation payloads, and refresh context status after compaction.
|
|
405
405
|
- `0.1.9`: maintenance packaging release after validating the local execution environment and deploy workflow.
|
|
@@ -25,7 +25,7 @@ It provides a reusable `Agent` abstraction with persistent sessions, local tools
|
|
|
25
25
|
- Python 3.10 or newer.
|
|
26
26
|
- A working model backend configuration compatible with `codex-backend-sdk` / OpenAI usage.
|
|
27
27
|
- GTK 3 plus Ayatana AppIndicator or AppIndicator bindings are needed for the tray controller on Linux.
|
|
28
|
-
-
|
|
28
|
+
- Playwright's managed Chromium browser is used for rendered web extraction when static fetching is insufficient. Install it with `python -m playwright install chromium` if needed.
|
|
29
29
|
|
|
30
30
|
## Installation
|
|
31
31
|
|
|
@@ -352,6 +352,7 @@ python -m build
|
|
|
352
352
|
The distribution includes prompt text files and `codex_agent/get_text/default_gitignore` through package data and `MANIFEST.in`.
|
|
353
353
|
|
|
354
354
|
## Recent changes
|
|
355
|
+
- `0.1.12`: add a persistent Playwright/Chromium browser controller with tab navigation, DOM/action snapshots, screenshots, form/click/key tools, and `browser_goto(url)` for active-tab navigation.
|
|
355
356
|
- `0.1.11`: split strict line-numbered UTF-8 `read` from unnumbered extracted `view`, preserve blank lines in read snippets, and show persistent+temporary message counts in the TUI status bar.
|
|
356
357
|
- `0.1.10`: persist only backend compaction summaries, drop bulky compacted conversation payloads, and refresh context status after compaction.
|
|
357
358
|
- `0.1.9`: maintenance packaging release after validating the local execution environment and deploy workflow.
|
|
@@ -952,9 +952,10 @@ class Agent:
|
|
|
952
952
|
def add_provider(self, func=None, name=None):
|
|
953
953
|
"""Register an ephemeral context provider.
|
|
954
954
|
|
|
955
|
-
Providers are called each time context is built. They
|
|
956
|
-
string
|
|
957
|
-
|
|
955
|
+
Providers are called each time context is built. They may return None,
|
|
956
|
+
a string, a Message instance, or a list/tuple mixing strings and Message
|
|
957
|
+
instances. Strings are wrapped in ProviderMessage; Message instances are
|
|
958
|
+
passed through as already formatted ephemeral context.
|
|
958
959
|
"""
|
|
959
960
|
if func is None:
|
|
960
961
|
def decorator(f):
|
|
@@ -1090,11 +1091,52 @@ class Agent:
|
|
|
1090
1091
|
return [msg for msg in self.session.messages if filter(msg)]
|
|
1091
1092
|
return sort(self.session.messages)
|
|
1092
1093
|
|
|
1094
|
+
def provider_context_wrapper(self, provider_name, content):
|
|
1095
|
+
return f'<context_provider name="{provider_name}">\n{content}\n</context_provider>'
|
|
1096
|
+
|
|
1097
|
+
def provider_message_from_output(self, provider_name, output):
|
|
1098
|
+
if isinstance(output, str):
|
|
1099
|
+
return ProviderMessage(name=provider_name, content=output)
|
|
1100
|
+
if not isinstance(output, Message):
|
|
1101
|
+
raise TypeError(
|
|
1102
|
+
f"Provider {provider_name!r} items must be str or Message, got {type(output).__name__}."
|
|
1103
|
+
)
|
|
1104
|
+
|
|
1105
|
+
message = output.copy()
|
|
1106
|
+
if isinstance(message, ProviderMessage):
|
|
1107
|
+
if not message.get("name"):
|
|
1108
|
+
message.name = provider_name
|
|
1109
|
+
return message
|
|
1110
|
+
|
|
1111
|
+
if isinstance(message, ImageMessage):
|
|
1112
|
+
description = message.get("description") or "Image provided by an ephemeral context provider."
|
|
1113
|
+
message.description = self.provider_context_wrapper(provider_name, description)
|
|
1114
|
+
return message
|
|
1115
|
+
|
|
1116
|
+
content = message.get("content")
|
|
1117
|
+
if isinstance(content, str):
|
|
1118
|
+
message.content = self.provider_context_wrapper(provider_name, content)
|
|
1119
|
+
elif isinstance(content, list):
|
|
1120
|
+
wrapped_parts = []
|
|
1121
|
+
for part in content:
|
|
1122
|
+
if isinstance(part, str):
|
|
1123
|
+
wrapped_parts.append(self.provider_context_wrapper(provider_name, part))
|
|
1124
|
+
elif isinstance(part, dict) and part.get("type") == "text":
|
|
1125
|
+
part = dict(part)
|
|
1126
|
+
part["text"] = self.provider_context_wrapper(provider_name, part.get("text", ""))
|
|
1127
|
+
wrapped_parts.append(part)
|
|
1128
|
+
else:
|
|
1129
|
+
wrapped_parts.append(part)
|
|
1130
|
+
message.content = wrapped_parts
|
|
1131
|
+
return message
|
|
1132
|
+
|
|
1093
1133
|
def get_providers_messages(self):
|
|
1094
|
-
"""Retrieves messages from all registered providers.
|
|
1134
|
+
"""Retrieves ephemeral messages from all registered providers.
|
|
1095
1135
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1136
|
+
Providers may return None, a string, a Message, or a list/tuple of
|
|
1137
|
+
strings and Messages. Each output item becomes its own message; strings
|
|
1138
|
+
are wrapped in ProviderMessage, while existing Messages keep their type
|
|
1139
|
+
and only their textual content is marked as provider context.
|
|
1098
1140
|
"""
|
|
1099
1141
|
provider_msgs=[]
|
|
1100
1142
|
for provider_name, provider in self.providers.items():
|
|
@@ -1105,11 +1147,11 @@ class Agent:
|
|
|
1105
1147
|
reset_current_agent(agent_context)
|
|
1106
1148
|
if provider_output is None:
|
|
1107
1149
|
continue
|
|
1108
|
-
if
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1150
|
+
outputs = provider_output if isinstance(provider_output, (list, tuple)) else [provider_output]
|
|
1151
|
+
for output in outputs:
|
|
1152
|
+
if output is None:
|
|
1153
|
+
continue
|
|
1154
|
+
provider_msgs.append(self.provider_message_from_output(provider_name, output))
|
|
1113
1155
|
return provider_msgs
|
|
1114
1156
|
|
|
1115
1157
|
def context_status(self):
|