agentshim 0.6.8__tar.gz → 0.8.0__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.
- {agentshim-0.6.8 → agentshim-0.8.0}/CHANGELOG.md +91 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/PKG-INFO +4 -3
- {agentshim-0.6.8 → agentshim-0.8.0}/README.md +3 -2
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/__init__.py +25 -1
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/agent.py +4 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/__init__.py +24 -2
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/events.py +32 -0
- agentshim-0.8.0/agentshim/core/pricing.py +466 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/profile.py +19 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/schema.py +14 -9
- agentshim-0.8.0/agentshim/core/skills.py +75 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/turn.py +5 -1
- agentshim-0.8.0/agentshim/core/usage.py +287 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/__init__.py +7 -2
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/claude/events.py +9 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/claude/parser.py +59 -10
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/claude/provider.py +10 -1
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/claude/scripted.py +27 -8
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/codex/events.py +7 -2
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/codex/parser.py +12 -6
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/codex/provider.py +4 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/codex/scripted.py +30 -5
- agentshim-0.8.0/agentshim/providers/codex/skills.py +27 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/copilot/parser.py +7 -8
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/copilot/scripted.py +14 -4
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/gemini/parser.py +9 -8
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/gemini/scripted.py +12 -1
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/opencode/parser.py +9 -8
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/opencode/scripted.py +15 -4
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/testing/__init__.py +12 -1
- {agentshim-0.6.8 → agentshim-0.8.0}/pyproject.toml +1 -1
- agentshim-0.6.8/agentshim/core/usage.py +0 -78
- {agentshim-0.6.8 → agentshim-0.8.0}/.gitignore +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/_files.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/env.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/errors.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/mcp.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/provider.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/core/stream.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/execution/__init__.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/execution/executor.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/execution/host.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/execution/transform.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/claude/__init__.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/claude/hooks/__init__.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/claude/hooks/confine_reads.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/claude/sandbox.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/claude/user_hooks.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/codex/__init__.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/codex/_toml.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/codex/rules.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/codex/sandbox.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/copilot/__init__.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/copilot/events.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/copilot/provider.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/gemini/__init__.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/gemini/events.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/gemini/provider.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/opencode/__init__.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/opencode/events.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/providers/opencode/provider.py +0 -0
- {agentshim-0.6.8 → agentshim-0.8.0}/agentshim/py.typed +0 -0
|
@@ -1,5 +1,96 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.0 (2026-10-03)
|
|
4
|
+
|
|
5
|
+
Skill observability. Additive: a caller that ignores the new events and the
|
|
6
|
+
new `TurnResult` field sees no change, but an exhaustive match over
|
|
7
|
+
`AgentEvent` gains two members.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `SkillsDiscovered(names)` and `SkillInvoked(name, source_path, tool_id)`
|
|
12
|
+
events. `SkillInvoked` sits directly after the `ToolCall` that loaded the
|
|
13
|
+
skill.
|
|
14
|
+
- `TurnResult.skills`: a `SkillSummary` (`discovered`, `invocations`,
|
|
15
|
+
`invoked`, `invocation_count`) folded from those events by `SkillTracker`,
|
|
16
|
+
which callers can also register as a handler to cover several turns.
|
|
17
|
+
`None` means unknown, never zero.
|
|
18
|
+
- `ProviderProfile.skill_discovery` and `skill_invocation`, each a
|
|
19
|
+
`SkillSignal` (`NONE`, `STRUCTURED`, `INFERRED`).
|
|
20
|
+
- Claude Code: discovery from the `system/init` `skills` list; a load is a
|
|
21
|
+
`Skill` tool call or a `Read` of a `SKILL.md`.
|
|
22
|
+
- Codex: a load is inferred from a shell command that names a `SKILL.md`
|
|
23
|
+
under a `skills/` directory. `codex exec --json` does not list offered
|
|
24
|
+
skills, so discovery is unknown.
|
|
25
|
+
- Gemini, opencode and Copilot report unknown for both.
|
|
26
|
+
- `scripted_turn(..., skills_offered=[...], skills_invoked=[...])` scripts the
|
|
27
|
+
offered list (Claude) and skill loads (Claude, Codex) in each provider's own
|
|
28
|
+
format; a provider whose stream cannot carry them raises `ValueError`.
|
|
29
|
+
- Recorded skill streams under `tests/fixtures/{claude,codex}/` and a live
|
|
30
|
+
e2e suite, `tests/e2e/test_skills_e2e.py`, with a positive and a negative
|
|
31
|
+
turn per provider.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- `normalize(schema, SchemaDialect.STRICT)` no longer closes an open map
|
|
36
|
+
(`additionalProperties` a schema or `true`), which silently turned
|
|
37
|
+
`dict[str, float]` into an object that can only be empty. The map is kept
|
|
38
|
+
and `dialect_problems` on the normalized schema reports it, so
|
|
39
|
+
`dialect_problems(normalize(s, d), d) == []` is the check for whether a
|
|
40
|
+
generated schema can go native.
|
|
41
|
+
|
|
42
|
+
## 0.7.0 (2026-09-27)
|
|
43
|
+
|
|
44
|
+
First-class cache accounting and a static pricing table. Additive except one
|
|
45
|
+
change of meaning: `cached_input_tokens` now counts cache reads only (see
|
|
46
|
+
Changed).
|
|
47
|
+
|
|
48
|
+
### Added
|
|
49
|
+
|
|
50
|
+
- `TokenUsage.cache_read_input_tokens` (input served from the prompt cache),
|
|
51
|
+
`cache_write_1h_input_tokens` (the one-hour-TTL part of cache writes, from
|
|
52
|
+
Claude's `cache_creation` breakdown) and the derived
|
|
53
|
+
`uncached_input_tokens` (`input - cache_read - cache_write`). `to_dict()`
|
|
54
|
+
gains the three keys; no key was removed.
|
|
55
|
+
- Codex turns now report `cache_write_input_tokens` and
|
|
56
|
+
`reasoning_output_tokens` from `turn.completed` (both used to be dropped).
|
|
57
|
+
- `TokenUsage` checks its invariants on construction:
|
|
58
|
+
`cache_read + cache_write <= input`, `cache_write_1h <= cache_write`,
|
|
59
|
+
`reasoning <= output`, no negative counts. Parsers build it through the new
|
|
60
|
+
`normalized_usage`, which clamps a CLI's inconsistent counts instead.
|
|
61
|
+
- `TokenUsage.from_dict` reads a `to_dict()` mapping back, including one
|
|
62
|
+
written before 0.7.0.
|
|
63
|
+
- `TokenWeights` and `TokenUsage.weighted_total(weights)`: a total weighted by
|
|
64
|
+
token class (uncached input, cache reads, 5m and 1h cache writes, output,
|
|
65
|
+
reasoning), each token weighted once.
|
|
66
|
+
- A static, versioned pricing table (`agentshim.core.pricing`):
|
|
67
|
+
`ModelPricing`, `PricingTable`, `default_pricing()`,
|
|
68
|
+
`price_for(provider, model, table=None)` (`None` for an unknown model, never
|
|
69
|
+
zero), `cost_usd(usage, pricing)` and `ModelPricing.relative_weights()`.
|
|
70
|
+
It covers OpenAI GPT-6 (astra, sol, luna), GPT-5.6, GPT-5.5 and earlier
|
|
71
|
+
GPT-5 models, and Claude Fable 5.1, Fable 5, Opus 5.5, Opus 5, Opus 4.8,
|
|
72
|
+
Sonnet 5, Sonnet 4.6 and Haiku 4.5, each with its official source URL and
|
|
73
|
+
check date (all 2026-09-27). Callers override or extend it with
|
|
74
|
+
`PricingTable.with_entries` or `PricingTable.from_dict`. Holding prices in
|
|
75
|
+
agentshim is a user-directed decision; see `docs/pricing.md`.
|
|
76
|
+
- Recorded Codex, Claude (5m and 1h cache writes), opencode and Gemini
|
|
77
|
+
streams under `tests/fixtures/`, with tests pinning each provider's mapping.
|
|
78
|
+
The Claude Haiku 4.5 recording's `total_cost_usd` is reproduced exactly by
|
|
79
|
+
the table.
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
|
|
83
|
+
- `cached_input_tokens` is a deprecated alias of `cache_read_input_tokens`.
|
|
84
|
+
On Claude, opencode and Copilot it used to be reads plus writes; it is now
|
|
85
|
+
reads only, since a cache write is billed above base input and a read far
|
|
86
|
+
below it. Codex and Gemini report no writes in their cached count, so their
|
|
87
|
+
value is unchanged. Constructing with `cached_input_tokens=` still works.
|
|
88
|
+
|
|
89
|
+
### Documented
|
|
90
|
+
|
|
91
|
+
- Claude's `result.usage` covers the main conversation only; a Task
|
|
92
|
+
subagent's tokens appear only in `modelUsage` and `total_cost_usd`.
|
|
93
|
+
|
|
3
94
|
## 0.6.8 (2026-09-27)
|
|
4
95
|
|
|
5
96
|
A tightening of the Codex (`STRICT`) schema check: schemas it now rejects
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agentshim
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: Provider-agnostic coding-agent CLI shims
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Provides-Extra: test
|
|
@@ -23,8 +23,9 @@ No required runtime dependencies. Python 3.10+.
|
|
|
23
23
|
|
|
24
24
|
- `CliAgent` / `AgentSession`: one turn at a time, resumable, cancellable
|
|
25
25
|
- typed events delivered on the calling thread
|
|
26
|
-
- normalized token accounting
|
|
27
|
-
every provider
|
|
26
|
+
- normalized token accounting (total input, cache reads, cache writes,
|
|
27
|
+
uncached input, output and reasoning) on every provider, plus a static,
|
|
28
|
+
versioned pricing table (see [Usage and Pricing](docs/pricing.md))
|
|
28
29
|
- declared capabilities on `ProviderProfile`, so no caller probes a provider
|
|
29
30
|
- injectable `CommandExecutor`s for running the CLI in a container or over a
|
|
30
31
|
remote shell
|
|
@@ -14,8 +14,9 @@ No required runtime dependencies. Python 3.10+.
|
|
|
14
14
|
|
|
15
15
|
- `CliAgent` / `AgentSession`: one turn at a time, resumable, cancellable
|
|
16
16
|
- typed events delivered on the calling thread
|
|
17
|
-
- normalized token accounting
|
|
18
|
-
every provider
|
|
17
|
+
- normalized token accounting (total input, cache reads, cache writes,
|
|
18
|
+
uncached input, output and reasoning) on every provider, plus a static,
|
|
19
|
+
versioned pricing table (see [Usage and Pricing](docs/pricing.md))
|
|
19
20
|
- declared capabilities on `ProviderProfile`, so no caller probes a provider
|
|
20
21
|
- injectable `CommandExecutor`s for running the CLI in a container or over a
|
|
21
22
|
remote shell
|
|
@@ -29,11 +29,13 @@ from .core import (
|
|
|
29
29
|
McpMechanism,
|
|
30
30
|
McpServer,
|
|
31
31
|
McpTransport,
|
|
32
|
+
ModelPricing,
|
|
32
33
|
NoopInstallation,
|
|
33
34
|
NullEventHandler,
|
|
34
35
|
OutputSchema,
|
|
35
36
|
OutputSchemaStyle,
|
|
36
37
|
ParsedTurn,
|
|
38
|
+
PricingTable,
|
|
37
39
|
Provider,
|
|
38
40
|
ProviderCapabilityError,
|
|
39
41
|
ProviderError,
|
|
@@ -47,10 +49,16 @@ from .core import (
|
|
|
47
49
|
SchemaDialectError,
|
|
48
50
|
SessionResumeError,
|
|
49
51
|
SessionStarted,
|
|
52
|
+
SkillInvoked,
|
|
53
|
+
SkillsDiscovered,
|
|
54
|
+
SkillSignal,
|
|
55
|
+
SkillSummary,
|
|
56
|
+
SkillTracker,
|
|
50
57
|
Stderr,
|
|
51
58
|
StdioMcpServer,
|
|
52
59
|
StreamParser,
|
|
53
60
|
TokenUsage,
|
|
61
|
+
TokenWeights,
|
|
54
62
|
ToolCall,
|
|
55
63
|
ToolResult,
|
|
56
64
|
ToolTracker,
|
|
@@ -59,12 +67,16 @@ from .core import (
|
|
|
59
67
|
UsageReport,
|
|
60
68
|
compact_json,
|
|
61
69
|
compose_event_handlers,
|
|
70
|
+
cost_usd,
|
|
71
|
+
default_pricing,
|
|
62
72
|
dialect_problems,
|
|
63
73
|
install_config_file,
|
|
64
74
|
interactive_env,
|
|
65
75
|
materialize,
|
|
66
76
|
normalize,
|
|
77
|
+
normalized_usage,
|
|
67
78
|
parse_json_object,
|
|
79
|
+
price_for,
|
|
68
80
|
)
|
|
69
81
|
from .execution import (
|
|
70
82
|
CallbackCommandStreamSink,
|
|
@@ -84,7 +96,7 @@ from .providers.copilot import CopilotProvider
|
|
|
84
96
|
from .providers.gemini import GeminiProvider
|
|
85
97
|
from .providers.opencode import OpencodeProvider
|
|
86
98
|
|
|
87
|
-
__version__ = "0.
|
|
99
|
+
__version__ = "0.8.0"
|
|
88
100
|
|
|
89
101
|
__all__ = [
|
|
90
102
|
"AgentEvent",
|
|
@@ -123,6 +135,7 @@ __all__ = [
|
|
|
123
135
|
"McpMechanism",
|
|
124
136
|
"McpServer",
|
|
125
137
|
"McpTransport",
|
|
138
|
+
"ModelPricing",
|
|
126
139
|
"NoopInstallation",
|
|
127
140
|
"NullEventHandler",
|
|
128
141
|
"NullSink",
|
|
@@ -130,6 +143,7 @@ __all__ = [
|
|
|
130
143
|
"OutputSchema",
|
|
131
144
|
"OutputSchemaStyle",
|
|
132
145
|
"ParsedTurn",
|
|
146
|
+
"PricingTable",
|
|
133
147
|
"Provider",
|
|
134
148
|
"ProviderCapabilityError",
|
|
135
149
|
"ProviderError",
|
|
@@ -144,10 +158,16 @@ __all__ = [
|
|
|
144
158
|
"SchemaDialectError",
|
|
145
159
|
"SessionResumeError",
|
|
146
160
|
"SessionStarted",
|
|
161
|
+
"SkillInvoked",
|
|
162
|
+
"SkillSignal",
|
|
163
|
+
"SkillSummary",
|
|
164
|
+
"SkillTracker",
|
|
165
|
+
"SkillsDiscovered",
|
|
147
166
|
"Stderr",
|
|
148
167
|
"StdioMcpServer",
|
|
149
168
|
"StreamParser",
|
|
150
169
|
"TokenUsage",
|
|
170
|
+
"TokenWeights",
|
|
151
171
|
"ToolCall",
|
|
152
172
|
"ToolResult",
|
|
153
173
|
"ToolTracker",
|
|
@@ -158,12 +178,16 @@ __all__ = [
|
|
|
158
178
|
"__version__",
|
|
159
179
|
"compact_json",
|
|
160
180
|
"compose_event_handlers",
|
|
181
|
+
"cost_usd",
|
|
182
|
+
"default_pricing",
|
|
161
183
|
"dialect_problems",
|
|
162
184
|
"get_provider",
|
|
163
185
|
"install_config_file",
|
|
164
186
|
"interactive_env",
|
|
165
187
|
"materialize",
|
|
166
188
|
"normalize",
|
|
189
|
+
"normalized_usage",
|
|
167
190
|
"parse_json_object",
|
|
191
|
+
"price_for",
|
|
168
192
|
"provider_names",
|
|
169
193
|
]
|
|
@@ -26,6 +26,7 @@ from agentshim.core.events import RunFinished, RunStarted, compose_event_handler
|
|
|
26
26
|
from agentshim.core.profile import McpMechanism, OutputSchemaStyle, SchemaDialect
|
|
27
27
|
from agentshim.core.provider import ArgvContext
|
|
28
28
|
from agentshim.core.schema import compact_json, dialect_problems, materialize
|
|
29
|
+
from agentshim.core.skills import SkillTracker
|
|
29
30
|
from agentshim.core.turn import TurnRequest, TurnResult, coerce_request
|
|
30
31
|
from agentshim.execution.executor import CommandRequest
|
|
31
32
|
from agentshim.execution.host import HostCommandExecutor
|
|
@@ -278,8 +279,10 @@ class AgentSession:
|
|
|
278
279
|
agent = self._agent
|
|
279
280
|
handler = agent.event_handler
|
|
280
281
|
resumed = self.session_id is not None
|
|
282
|
+
skills = SkillTracker(self.profile)
|
|
281
283
|
|
|
282
284
|
def emit(event: AgentEvent) -> None:
|
|
285
|
+
skills.on_event(event)
|
|
283
286
|
handler.on_event(event)
|
|
284
287
|
|
|
285
288
|
argv = list(command.argv)
|
|
@@ -305,6 +308,7 @@ class AgentSession:
|
|
|
305
308
|
cost_usd=parsed.cost_usd,
|
|
306
309
|
duration_ms=duration_ms,
|
|
307
310
|
exit_code=result.returncode,
|
|
311
|
+
skills=skills.summary(),
|
|
308
312
|
)
|
|
309
313
|
self.last_result = turn_result
|
|
310
314
|
return turn_result
|
|
@@ -34,6 +34,8 @@ from .events import (
|
|
|
34
34
|
RunFinished,
|
|
35
35
|
RunStarted,
|
|
36
36
|
SessionStarted,
|
|
37
|
+
SkillInvoked,
|
|
38
|
+
SkillsDiscovered,
|
|
37
39
|
Stderr,
|
|
38
40
|
ToolCall,
|
|
39
41
|
ToolResult,
|
|
@@ -50,12 +52,20 @@ from .mcp import (
|
|
|
50
52
|
StdioMcpServer,
|
|
51
53
|
install_config_file,
|
|
52
54
|
)
|
|
53
|
-
from .
|
|
55
|
+
from .pricing import ModelPricing, PricingTable, cost_usd, default_pricing, price_for
|
|
56
|
+
from .profile import (
|
|
57
|
+
McpMechanism,
|
|
58
|
+
OutputSchemaStyle,
|
|
59
|
+
ProviderProfile,
|
|
60
|
+
SchemaDialect,
|
|
61
|
+
SkillSignal,
|
|
62
|
+
)
|
|
54
63
|
from .provider import ArgvContext, McpInstallation, ParsedTurn, Provider, StreamParser
|
|
55
64
|
from .schema import compact_json, dialect_problems, materialize, normalize
|
|
65
|
+
from .skills import SkillSummary, SkillTracker
|
|
56
66
|
from .stream import ToolTracker, parse_json_object
|
|
57
67
|
from .turn import OutputSchema, TurnRequest, TurnResult
|
|
58
|
-
from .usage import ProviderUsage, TokenUsage
|
|
68
|
+
from .usage import ProviderUsage, TokenUsage, TokenWeights, normalized_usage
|
|
59
69
|
|
|
60
70
|
__all__ = [
|
|
61
71
|
"AgentEvent",
|
|
@@ -79,11 +89,13 @@ __all__ = [
|
|
|
79
89
|
"McpMechanism",
|
|
80
90
|
"McpServer",
|
|
81
91
|
"McpTransport",
|
|
92
|
+
"ModelPricing",
|
|
82
93
|
"NoopInstallation",
|
|
83
94
|
"NullEventHandler",
|
|
84
95
|
"OutputSchema",
|
|
85
96
|
"OutputSchemaStyle",
|
|
86
97
|
"ParsedTurn",
|
|
98
|
+
"PricingTable",
|
|
87
99
|
"Provider",
|
|
88
100
|
"ProviderCapabilityError",
|
|
89
101
|
"ProviderError",
|
|
@@ -97,10 +109,16 @@ __all__ = [
|
|
|
97
109
|
"SchemaDialectError",
|
|
98
110
|
"SessionResumeError",
|
|
99
111
|
"SessionStarted",
|
|
112
|
+
"SkillInvoked",
|
|
113
|
+
"SkillSignal",
|
|
114
|
+
"SkillSummary",
|
|
115
|
+
"SkillTracker",
|
|
116
|
+
"SkillsDiscovered",
|
|
100
117
|
"Stderr",
|
|
101
118
|
"StdioMcpServer",
|
|
102
119
|
"StreamParser",
|
|
103
120
|
"TokenUsage",
|
|
121
|
+
"TokenWeights",
|
|
104
122
|
"ToolCall",
|
|
105
123
|
"ToolResult",
|
|
106
124
|
"ToolTracker",
|
|
@@ -109,10 +127,14 @@ __all__ = [
|
|
|
109
127
|
"UsageReport",
|
|
110
128
|
"compact_json",
|
|
111
129
|
"compose_event_handlers",
|
|
130
|
+
"cost_usd",
|
|
131
|
+
"default_pricing",
|
|
112
132
|
"dialect_problems",
|
|
113
133
|
"install_config_file",
|
|
114
134
|
"interactive_env",
|
|
115
135
|
"materialize",
|
|
116
136
|
"normalize",
|
|
137
|
+
"normalized_usage",
|
|
117
138
|
"parse_json_object",
|
|
139
|
+
"price_for",
|
|
118
140
|
]
|
|
@@ -74,6 +74,34 @@ class ToolResult:
|
|
|
74
74
|
duration_s: float | None
|
|
75
75
|
|
|
76
76
|
|
|
77
|
+
@dataclass(frozen=True)
|
|
78
|
+
class SkillsDiscovered:
|
|
79
|
+
"""The provider listed the skills it offers this session.
|
|
80
|
+
|
|
81
|
+
``names`` are the skill names as the provider reports them (a plugin
|
|
82
|
+
skill may carry a ``plugin:`` prefix). Only emitted by a provider whose
|
|
83
|
+
profile declares ``skill_discovery`` other than ``SkillSignal.NONE``, and
|
|
84
|
+
only when its stream actually carried the list.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
names: tuple[str, ...]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@dataclass(frozen=True)
|
|
91
|
+
class SkillInvoked:
|
|
92
|
+
"""The agent loaded a skill's instructions.
|
|
93
|
+
|
|
94
|
+
Emitted at the point in the stream where the load happened, directly
|
|
95
|
+
after the ``ToolCall`` that performed it; ``tool_id`` names that call.
|
|
96
|
+
``source_path`` is the skill file or directory when the stream reveals
|
|
97
|
+
it, and ``None`` otherwise.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
name: str
|
|
101
|
+
source_path: str | None = None
|
|
102
|
+
tool_id: str | None = None
|
|
103
|
+
|
|
104
|
+
|
|
77
105
|
@dataclass(frozen=True)
|
|
78
106
|
class UsageReport:
|
|
79
107
|
"""Provider accounting for the turn so far."""
|
|
@@ -119,6 +147,8 @@ AgentEvent = (
|
|
|
119
147
|
| Reasoning
|
|
120
148
|
| ToolCall
|
|
121
149
|
| ToolResult
|
|
150
|
+
| SkillsDiscovered
|
|
151
|
+
| SkillInvoked
|
|
122
152
|
| UsageReport
|
|
123
153
|
| Lifecycle
|
|
124
154
|
| Stderr
|
|
@@ -351,6 +381,8 @@ class ConsoleEventHandler:
|
|
|
351
381
|
"""
|
|
352
382
|
if isinstance(event, Stderr):
|
|
353
383
|
self._line(f"[stderr] {event.text.rstrip()}")
|
|
384
|
+
elif isinstance(event, SkillInvoked):
|
|
385
|
+
self._line(self._paint(f"[Skill] {event.name}", self._BLUE))
|
|
354
386
|
elif isinstance(event, ProviderError):
|
|
355
387
|
self._line(f"[error] {event.message}")
|
|
356
388
|
elif isinstance(event, Lifecycle) and self._show_lifecycle:
|