Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .verification/object-settings-sources/advertisements.plan.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"recipes": [
{
"recipe_id": "retain-empty-advertisements-and-popup-setup-as-distinct-views",
"operations": [
{
"operation": "patch_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/acp/agent_configuration.py",
"target_qualname": "AgentConfiguration.editing",
"replacements": [
{
"old_source": " declarations = [\n (f\"option_{index}\", setting.annotation, field(default=setting.current))\n for index, setting in enumerate(self.picker_settings)\n ]\n return ObjectState(make_dataclass(\"SessionConfiguration\", declarations)())",
"new_source": " return self.editing_settings(self.picker_settings)\n\n def editing_settings(self, settings: tuple[ConfigurationSetting, ...]) -> ObjectState:\n \"\"\"Project original settings without adding fields the source did not advertise.\"\"\"\n declarations = [\n (f\"option_{index}\", setting.annotation, field(default=setting.current))\n for index, setting in enumerate(settings)\n ]\n return ObjectState(make_dataclass(\"SessionConfiguration\", declarations)())"
}
]
},
{
"operation": "insert_before_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/widgets/model_switcher.py",
"target_qualname": "SessionForm.for_prompt",
"source": " @classmethod\n def settings(cls, configuration):\n return tuple(configuration.selections.values())\n\n"
},
{
"operation": "patch_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/widgets/model_switcher.py",
"target_qualname": "SessionForm.for_prompt",
"replacements": [
{
"old_source": " state = prompt.agent_binding.configuration.editing()",
"new_source": " configuration = prompt.agent_binding.configuration\n state = configuration.editing_settings(cls.settings(configuration))"
}
]
},
{
"operation": "patch_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/widgets/model_switcher.py",
"target_qualname": "SessionForm.represents",
"replacements": [
{
"old_source": "for row in self.values.values()) == settings.picker_settings",
"new_source": "for row in self.values.values()) == self.settings(settings)"
}
]
},
{
"operation": "insert_before_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/widgets/model_switcher.py",
"target_qualname": "PopupSessionForm.open_model",
"source": " @classmethod\n def settings(cls, configuration):\n return configuration.picker_settings\n\n"
},
{
"operation": "ensure_import",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/configured_view.py",
"import_source": "from textual.widgets import Static"
},
{
"operation": "patch_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/configured_view.py",
"target_qualname": "AgentProperties.compose",
"replacements": [
{
"old_source": " yield self.form",
"new_source": " if not self.form.values:\n yield Static(\"This session has not advertised any settings.\", markup=False)\n yield self.form"
}
]
},
{
"operation": "patch_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/screens/main.py",
"target_qualname": "MainScreen.configuration_panels",
"replacements": [
{
"old_source": " yield from self.operational_sources.configuration_panels(self)\n yield from super().configuration_panels",
"new_source": " yield from super().configuration_panels\n yield from self.operational_sources.configuration_panels(self)"
}
]
}
]
}
]
}
43 changes: 43 additions & 0 deletions .verification/object-settings-sources/advertisements_author.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import json
from pathlib import Path
r=Path.cwd();ops=[]
def patch(f,t,o,n):ops.append(dict(operation='patch_target',file_path=str(r/f),target_qualname=t,replacements=[dict(old_source=o,new_source=n)]))
def insert(f,t,s):ops.append(dict(operation='insert_before_target',file_path=str(r/f),target_qualname=t,source=s))
f='src/toad/acp/agent_configuration.py'
patch(f,'AgentConfiguration.editing',''' declarations = [
(f"option_{index}", setting.annotation, field(default=setting.current))
for index, setting in enumerate(self.picker_settings)
]
return ObjectState(make_dataclass("SessionConfiguration", declarations)())''',''' return self.editing_settings(self.picker_settings)

def editing_settings(self, settings: tuple[ConfigurationSetting, ...]) -> ObjectState:
"""Project original settings without adding fields the source did not advertise."""
declarations = [
(f"option_{index}", setting.annotation, field(default=setting.current))
for index, setting in enumerate(settings)
]
return ObjectState(make_dataclass("SessionConfiguration", declarations)())''')
f='src/toad/widgets/model_switcher.py'
insert(f,'SessionForm.for_prompt',''' @classmethod
def settings(cls, configuration):
return tuple(configuration.selections.values())

''')
patch(f,'SessionForm.for_prompt',''' state = prompt.agent_binding.configuration.editing()''',''' configuration = prompt.agent_binding.configuration
state = configuration.editing_settings(cls.settings(configuration))''')
patch(f,'SessionForm.represents','''for row in self.values.values()) == settings.picker_settings''','''for row in self.values.values()) == self.settings(settings)''')
insert(f,'PopupSessionForm.open_model',''' @classmethod
def settings(cls, configuration):
return configuration.picker_settings

''')
f='src/toad/configured_view.py'
ops.append(dict(operation='ensure_import',file_path=str(r/f),import_source='from textual.widgets import Static'))
patch(f,'AgentProperties.compose',''' yield self.form''',''' if not self.form.values:
yield Static("This session has not advertised any settings.", markup=False)
yield self.form''')
f='src/toad/screens/main.py'
patch(f,'MainScreen.configuration_panels',''' yield from self.operational_sources.configuration_panels(self)
yield from super().configuration_panels''',''' yield from super().configuration_panels
yield from self.operational_sources.configuration_panels(self)''')
Path('.verification/object-settings-sources/advertisements.plan.json').write_text(json.dumps({'recipes':[{'recipe_id':'retain-empty-advertisements-and-popup-setup-as-distinct-views','operations':ops}]},indent=2))
43 changes: 43 additions & 0 deletions .verification/object-settings-sources/inspection.plan.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"recipes": [
{
"recipe_id": "read-the-held-coverage-and-retain-form-focus",
"operations": [
{
"operation": "patch_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/tools/physical_ui_remote.py",
"target_qualname": "ObserveOperation.execute",
"replacements": [
{
"old_source": "history.state.reports_coverage for history in histories",
"new_source": "history.state.coverage.retained_through(history) for history in histories"
}
]
},
{
"operation": "patch_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/widgets/model_switcher.py",
"target_qualname": "SessionModelEditor.opened",
"replacements": [
{
"old_source": "self.focus_content(False)",
"new_source": "self.query_ancestor(SessionForm).open_model(self)"
}
]
},
{
"operation": "insert_before_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/widgets/model_switcher.py",
"target_qualname": "SessionForm.dismiss_control",
"source": " def open_model(self, editor):\n \"\"\"An inline form paints its model choices without taking keyboard focus.\"\"\"\n editor.configuration_changed()\n\n"
},
{
"operation": "insert_before_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/src/toad/widgets/model_switcher.py",
"target_qualname": "PopupSessionForm.dismiss_control",
"source": " def open_model(self, editor):\n if self.query_ancestor(ModelSwitcher).is_open:\n editor.focus_content(False)\n\n"
}
]
}
]
}
18 changes: 18 additions & 0 deletions .verification/object-settings-sources/inspection_author.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import json
from pathlib import Path
r=Path.cwd();ops=[]
def patch(f,t,o,n):ops.append(dict(operation='patch_target',file_path=str(r/f),target_qualname=t,replacements=[dict(old_source=o,new_source=n)]))
def insert(f,t,s):ops.append(dict(operation='insert_before_target',file_path=str(r/f),target_qualname=t,source=s))
patch('tools/physical_ui_remote.py','ObserveOperation.execute','history.state.reports_coverage for history in histories','history.state.coverage.retained_through(history) for history in histories')
patch('src/toad/widgets/model_switcher.py','SessionModelEditor.opened','self.focus_content(False)','self.query_ancestor(SessionForm).open_model(self)')
insert('src/toad/widgets/model_switcher.py','SessionForm.dismiss_control',''' def open_model(self, editor):
"""An inline form paints its model choices without taking keyboard focus."""
editor.configuration_changed()

''')
insert('src/toad/widgets/model_switcher.py','PopupSessionForm.dismiss_control',''' def open_model(self, editor):
if self.query_ancestor(ModelSwitcher).is_open:
editor.focus_content(False)

''')
Path('.verification/object-settings-sources/inspection.plan.json').write_text(json.dumps({'recipes':[{'recipe_id':'read-the-held-coverage-and-retain-form-focus','operations':ops}]},indent=2))
20 changes: 20 additions & 0 deletions .verification/object-settings-sources/retire-diagnostic.plan.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"recipes": [
{
"recipe_id": "retire-temporary-select-geometry-observation",
"operations": [
{
"operation": "patch_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/tools/physical_ui_remote.py",
"target_qualname": "ObserveOperation.execute",
"replacements": [
{
"old_source": " from textual.widgets import Select\n from textual.widgets._select import SelectOverlay\n (directory / \"select-layout.json\").write_text(json.dumps([\n dict(select=type(select).__name__, expanded=select.expanded,\n overlay=type(overlay).__name__, displayed=overlay.display,\n geometry=str(screen._compositor._published_map.get(overlay)),\n source=str(screen._compositor._published_map.get(select)))\n for select in screen.query(Select) for overlay in select.query(SelectOverlay)\n ], indent=2))\n frontend = FrontendIdentity(",
"new_source": " frontend = FrontendIdentity("
}
]
}
]
}
]
}
8 changes: 8 additions & 0 deletions .verification/object-settings-sources/retire_diagnostic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import json
from pathlib import Path
r=Path.cwd();p=json.loads(Path('.verification/object-settings-sources/select-observation.plan.json').read_text())
p['recipes'][0]['recipe_id']='retire-temporary-select-geometry-observation'
for op in p['recipes'][0]['operations']:
for pair in op['replacements']:
pair['old_source'],pair['new_source']=pair['new_source'],pair['old_source']
Path('.verification/object-settings-sources/retire-diagnostic.plan.json').write_text(json.dumps(p,indent=2))
20 changes: 20 additions & 0 deletions .verification/object-settings-sources/select-observation.plan.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"recipes": [
{
"recipe_id": "retain-the-actual-dropdown-paint-placement",
"operations": [
{
"operation": "patch_target",
"file_path": "/home/ts/wt/codex-live--P181--toad/tools/physical_ui_remote.py",
"target_qualname": "ObserveOperation.execute",
"replacements": [
{
"old_source": " frontend = FrontendIdentity(",
"new_source": " from textual.widgets import Select\n from textual.widgets._select import SelectOverlay\n (directory / \"select-layout.json\").write_text(json.dumps([\n dict(select=type(select).__name__, expanded=select.expanded,\n overlay=type(overlay).__name__, displayed=overlay.display,\n geometry=str(screen._compositor._published_map.get(overlay)),\n source=str(screen._compositor._published_map.get(select)))\n for select in screen.query(Select) for overlay in select.query(SelectOverlay)\n ], indent=2))\n frontend = FrontendIdentity("
}
]
}
]
}
]
}
6 changes: 5 additions & 1 deletion src/toad/acp/agent_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,13 @@ def named(self, key: str) -> ConfigurationSetting:

def editing(self) -> ObjectState:
"""An editable projection; every field retains its exact advertisement and writer."""
return self.editing_settings(self.picker_settings)

def editing_settings(self, settings: tuple[ConfigurationSetting, ...]) -> ObjectState:
"""Project original settings without adding fields the source did not advertise."""
declarations = [
(f"option_{index}", setting.annotation, field(default=setting.current))
for index, setting in enumerate(self.picker_settings)
for index, setting in enumerate(settings)
]
return ObjectState(make_dataclass("SessionConfiguration", declarations)())

Expand Down
3 changes: 3 additions & 0 deletions src/toad/configured_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from metaclass_registry.mro_dispatch import handles
from textual import events, on, work
from textual.geometry import Region
from textual.widgets import Static
from toad.core.events import ConfigurationChanged
from toad.core_event_carrier import CoreEventReceiver
from toad.forms.object_configuration import ObjectFieldView, ObjectFormView
Expand Down Expand Up @@ -60,6 +61,8 @@ def panel(cls, view):

def compose(self):
self.form = SessionForm.for_prompt(self.view.conversation.prompt)
if not self.form.values:
yield Static("This session has not advertised any settings.", markup=False)
yield self.form

def follow_binding(self):
Expand Down
2 changes: 1 addition & 1 deletion src/toad/screens/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,8 @@ def initial_editing_mode(self) -> EditingMode:

@property
def configuration_panels(self):
yield from self.operational_sources.configuration_panels(self)
yield from super().configuration_panels
yield from self.operational_sources.configuration_panels(self)

def keyboard_scopes(self) -> tuple[DeclaredWidgetActions, ...]:
return self.content.keyboard_scopes(self)
Expand Down
23 changes: 20 additions & 3 deletions src/toad/widgets/model_switcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def bind_control(self) -> None:
self.listen(events.Mount, self.opened)

def opened(self, event: events.Mount) -> None:
self.focus_content(False)
self.query_ancestor(SessionForm).open_model(self)

def compose(self) -> ComposeResult:
yield from self.compose_content()
Expand Down Expand Up @@ -72,17 +72,26 @@ def __init__(self, state, parts, prompt):
super().__init__(state, parts)
self.prompt = prompt

@classmethod
def settings(cls, configuration):
return tuple(configuration.selections.values())

@classmethod
def for_prompt(cls, prompt):
state = prompt.agent_binding.configuration.editing()
configuration = prompt.agent_binding.configuration
state = configuration.editing_settings(cls.settings(configuration))
return cls(state, cls.field_family.of(state), prompt)

def open_model(self, editor):
"""An inline form paints its model choices without taking keyboard focus."""
editor.configuration_changed()

def dismiss_control(self):
"""An inline selection leaves its form open."""

def represents(self, settings) -> bool:
return tuple(row.field.metadata(AdvertisedSetting).setting
for row in self.values.values()) == settings.picker_settings
for row in self.values.values()) == self.settings(settings)

def values_changed(self, paths: set[str]) -> None:
super().values_changed(paths)
Expand All @@ -96,6 +105,14 @@ def values_changed(self, paths: set[str]) -> None:
class PopupSessionForm(SessionForm):
"""The popup adds dismissal to the same advertised settings form."""

@classmethod
def settings(cls, configuration):
return configuration.picker_settings

def open_model(self, editor):
if self.query_ancestor(ModelSwitcher).is_open:
editor.focus_content(False)

def dismiss_control(self):
self.query_ancestor(ModelSwitcher).dismiss_control()

Expand Down
2 changes: 1 addition & 1 deletion tools/physical_ui_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ def execute(self, directory: Path) -> None:
# The pager's original publication state also supplies the footer's
# saved-history availability. Agent status is an independent fact.
history_published = bool(histories) and all(
history.state.reports_coverage for history in histories)
history.state.coverage.retained_through(history) for history in histories)
frontend = FrontendIdentity(
self.identity, Path(toad.__file__).resolve(), Path(agent_comms.__file__).resolve(),
Path(textual.__file__).resolve(),
Expand Down
Loading