oc_chat
Loading...
Searching...
No Matches
tool_results.py
Go to the documentation of this file.
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
# oc_chat/core/tool_results.py
4
5
"""
6
TypedDict shapes for tool return values (CONTRACTS.md §4).
7
8
Purpose
9
-------
10
Every public tool function returns a JSON-serialisable ``dict`` — but
11
until now those dicts were typed only as ``dict`` or ``dict[str, Any]``,
12
leaving callers (the ReAct loop, the dependency healer, the presenter)
13
without static guarantees about which keys exist. This module gives
14
each conventional shape a TypedDict so callers and tool authors share
15
a single source of truth.
16
17
These are plain TypedDicts — at runtime they are still ``dict``s, so
18
no behavior changes. Annotations only.
19
20
Responsibilities
21
----------------
22
- :class:`CommandResult` — shell / subprocess output
23
(``run_command``, all ``oct_*`` tools).
24
- :class:`ReadFileResult` — successful ``read_file`` payload.
25
- :class:`WriteFileResult` — successful ``write_file`` payload.
26
- :class:`ToolError` — the universal ``{"error": "..."}`` fallback.
27
- :class:`ConfirmationRequired` — Tier-2 gating prompt returned by
28
destructive tools before the user has confirmed.
29
- :class:`MissingDependency` — structured hint emitted when a tool's
30
optional dependency (httpx, oct binary, etc.) is not installed; the
31
:mod:`~oc_chat.core.dependency_healer` watches for these.
32
- :data:`ToolReturn` — the union; the return type for tool dispatch.
33
34
Diagnostics
35
-----------
36
Domain: OC_CHAT.TOOLS
37
Levels:
38
L2 — lifecycle events
39
L3 — semantic details
40
L4 — deep tracing
41
42
Contracts
43
---------
44
- Every TypedDict here mirrors a return shape currently produced by an
45
existing tool. The classes themselves carry no validation logic — at
46
runtime the underlying ``dict`` may still have extra keys (TypedDicts
47
are structural).
48
- ``total=False`` is used wherever a key is conditionally present at
49
runtime. Required keys are kept required.
50
- Consumers should branch on key presence (e.g. ``"error" in result``)
51
rather than ``isinstance`` checks; TypedDict isinstance is a
52
type-checker-only construct.
53
54
Dependencies
55
------------
56
- oc_diagnostics (structured debug logging via _dbg)
57
"""
58
from
__future__
import
annotations
59
60
from
typing
import
Any, NotRequired, TypedDict, Union
61
62
from
oc_diagnostics
import
_dbg
63
64
_dbg(
"OC_CHAT.TOOLS"
,
"module"
,
"loaded"
, 4)
65
66
67
class
CommandResult
(TypedDict, total=
False
):
68
"""Result of a subprocess invocation (run_command, oct_* tools).
69
70
Required on success: ``stdout``, ``stderr``, ``returncode``.
71
Optional metadata: ``command_info`` (run_command only), ``warnings``
72
(run_command only).
73
"""
74
75
stdout: str
76
stderr: str
77
returncode: int
78
command_info: dict[str, Any]
79
warnings: list[str]
80
81
82
class
ReadFileResult
(TypedDict):
83
"""Successful ``read_file`` return shape.
84
85
``next_offset`` is ``None`` when the file is fully read; otherwise
86
it is the byte offset to pass to a follow-up
87
``read_file(path, offset=N)`` call.
88
89
``path`` is the RESOLVED absolute path actually read — model-independent
90
ground truth (plan 172 / F13/F25). When the discovery fallback rescued a
91
different path than the one requested, ``resolved_via_discovery`` is ``True``
92
and ``requested_path`` carries the original argument, so a silent rescue is
93
visible instead of masking a wrong path.
94
"""
95
96
content: str
97
truncated: bool
98
total_size: int
99
offset: int
100
next_offset: int |
None
101
lines_count: int
102
path: NotRequired[str]
103
resolved_via_discovery: NotRequired[bool]
104
requested_path: NotRequired[str]
105
106
107
class
WriteFileResult
(TypedDict):
108
"""Successful ``write_file`` return shape.
109
110
``redirected`` is true when the tool re-routed the write to a safer
111
path (e.g. ``logs/<name>`` for protected directories); ``actual_path``
112
is then the path actually written. ``chunks`` is non-empty when the
113
write was split (``chunked=True``).
114
"""
115
116
written: str
117
original_path: str
118
redirected: bool
119
actual_path: str
120
size_bytes: int
121
timestamp: str
122
chunked: bool
123
chunks: list[dict[str, Any]]
124
125
126
class
ToolError
(TypedDict):
127
"""Universal error fallback: ``{"error": "<human-readable message>"}``.
128
129
Returned by any tool that can fail before producing a typed success
130
payload. Callers should detect failures by ``"error" in result``
131
(not by absence of success keys).
132
"""
133
134
error: str
135
136
137
class
ConfirmationRequired
(TypedDict):
138
"""Tier-2 gating prompt from destructive tools (e.g. ``rm``, ``mv``).
139
140
Emitted by :func:`~oc_chat.tools.shell.run_command` and similar
141
callers when a sensitive command would proceed without explicit
142
user confirmation. Callers re-invoke with ``confirmed=True``.
143
"""
144
145
requires_confirmation: bool
146
command: str
147
message: str
148
149
150
class
MissingDependency
(TypedDict):
151
"""Signal that a tool's optional dependency is not installed.
152
153
Consumed by :mod:`~oc_chat.core.dependency_healer`, which offers to
154
install the dependency on the user's behalf. ``missing_dependency``
155
is the package name; ``install_hint`` is a copy-pasteable pip
156
command.
157
"""
158
159
missing_dependency: str
160
install_hint: str
161
162
163
ToolReturn = Union[
164
CommandResult,
165
ReadFileResult,
166
WriteFileResult,
167
ToolError,
168
ConfirmationRequired,
169
MissingDependency,
170
]
171
"""Union of every conventional tool return shape.
172
173
Tool functions whose success shape is none of the six (e.g.
174
``list_dir``, ``text_search``, ``fetch_url``) declare their own
175
TypedDict locally or remain ``dict[str, Any]`` — they are
176
single-purpose and do not need the six-way union.
177
"""
178
179
180
__all__ = [
181
"CommandResult"
,
182
"ReadFileResult"
,
183
"WriteFileResult"
,
184
"ToolError"
,
185
"ConfirmationRequired"
,
186
"MissingDependency"
,
187
"ToolReturn"
,
188
]
oc_chat.core.tool_results.CommandResult
Definition
tool_results.py:67
oc_chat.core.tool_results.ConfirmationRequired
Definition
tool_results.py:137
oc_chat.core.tool_results.MissingDependency
Definition
tool_results.py:150
oc_chat.core.tool_results.ReadFileResult
Definition
tool_results.py:82
oc_chat.core.tool_results.ToolError
Definition
tool_results.py:126
oc_chat.core.tool_results.WriteFileResult
Definition
tool_results.py:107
oc_chat
core
tool_results.py
Generated by
1.15.0