@agentex/agent 0.0.5 → 0.0.7
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.
- package/README.md +107 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,8 @@ const result = await claude.execute({
|
|
|
26
26
|
},
|
|
27
27
|
onEvent: (event) => {
|
|
28
28
|
if (event.type === "assistant") process.stdout.write(event.text);
|
|
29
|
-
if (event.type === "tool_call") console.log(`Tool
|
|
29
|
+
if (event.type === "tool_call") console.log(`Tool ${event.name} (toolCallId=${event.toolCallId})`);
|
|
30
|
+
// event.sessionId, event.messageId, event.eventId are populated per-provider
|
|
30
31
|
},
|
|
31
32
|
});
|
|
32
33
|
|
|
@@ -34,7 +35,11 @@ console.log(result.status); // "completed"
|
|
|
34
35
|
console.log(result.summary); // "Added try/catch to all route handlers..."
|
|
35
36
|
console.log(result.durationMs); // 12340
|
|
36
37
|
console.log(result.costUsd); // 0.0342
|
|
37
|
-
console.log(result.usage); // { "claude-sonnet-4-6": { inputTokens: 1200, outputTokens: 350, ... } }
|
|
38
|
+
console.log(result.usage); // { "claude-sonnet-4-6": { inputTokens: 1200, outputTokens: 350, costUsd: 0.0342, ... } }
|
|
39
|
+
console.log(result.stopReason); // "end_turn"
|
|
40
|
+
console.log(result.numTurns); // 3
|
|
41
|
+
console.log(result.rateLimits); // [{ status: "allowed", ... }]
|
|
42
|
+
console.log(result.raw); // the final provider-native event, verbatim (escape hatch)
|
|
38
43
|
```
|
|
39
44
|
|
|
40
45
|
## Built-in Providers
|
|
@@ -109,7 +114,7 @@ interface ExecutionResult {
|
|
|
109
114
|
durationMs: number;
|
|
110
115
|
errorMessage: string | null;
|
|
111
116
|
errorCode: string | null;
|
|
112
|
-
usage?: Record<string,
|
|
117
|
+
usage?: Record<string, ModelUsage>; // keyed by model ID
|
|
113
118
|
costUsd: number | null;
|
|
114
119
|
model: string | null;
|
|
115
120
|
summary: string | null;
|
|
@@ -117,8 +122,40 @@ interface ExecutionResult {
|
|
|
117
122
|
sessionDisplayId: string | null;
|
|
118
123
|
clearSession: boolean;
|
|
119
124
|
billingType: "api" | "subscription" | "metered_api" | null;
|
|
120
|
-
|
|
121
|
-
|
|
125
|
+
|
|
126
|
+
// Provider-reported run metadata — populated when the provider emits it.
|
|
127
|
+
// Claude populates all of these; Codex leaves them undefined/null.
|
|
128
|
+
stopReason?: string | null; // "end_turn" | "max_turns" | "tool_use" | ...
|
|
129
|
+
terminalReason?: string | null; // CLI's own terminal reason ("completed" | "error" | ...)
|
|
130
|
+
numTurns?: number | null;
|
|
131
|
+
durationApiMs?: number | null; // Time in model API calls, separate from wall clock
|
|
132
|
+
permissionDenials?: unknown[]; // Claude permission_denials array, verbatim
|
|
133
|
+
rateLimits?: RateLimitInfo[]; // Rate-limit signals observed during the run
|
|
134
|
+
|
|
135
|
+
raw?: Record<string, unknown> | null; // True escape hatch: final provider-native event verbatim
|
|
136
|
+
workspace?: PreparedWorkspace; // Present if config.workspace was set
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
interface TokenUsage {
|
|
140
|
+
inputTokens: number;
|
|
141
|
+
outputTokens: number;
|
|
142
|
+
cachedInputTokens?: number; // Claude cache_read ∪ Codex cached_input_tokens
|
|
143
|
+
cacheCreationInputTokens?: number; // Claude only
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface ModelUsage extends TokenUsage {
|
|
147
|
+
costUsd?: number; // Per-model cost (Claude's modelUsage)
|
|
148
|
+
webSearchRequests?: number;
|
|
149
|
+
contextWindow?: number;
|
|
150
|
+
maxOutputTokens?: number;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
interface RateLimitInfo {
|
|
154
|
+
status: string; // "allowed" | "rejected" | ...
|
|
155
|
+
limitType: string | null; // "five_hour" | "weekly" | ...
|
|
156
|
+
resetAt: string | null; // ISO timestamp when the window resets
|
|
157
|
+
overageStatus: string | null;
|
|
158
|
+
isUsingOverage: boolean | null;
|
|
122
159
|
}
|
|
123
160
|
```
|
|
124
161
|
|
|
@@ -126,17 +163,77 @@ Use `aggregateUsage(result.usage)` to collapse per-model usage into a single tot
|
|
|
126
163
|
|
|
127
164
|
## Stream Events
|
|
128
165
|
|
|
129
|
-
Emitted during execution via `onEvent`.
|
|
166
|
+
Emitted during execution via `onEvent`. Every event carries the same normalized ID set on top of its variant-specific fields:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
interface BaseStreamEventFields {
|
|
170
|
+
timestamp: string;
|
|
171
|
+
providerType: string; // "claude" | "codex" | "cursor" | ...
|
|
172
|
+
sessionId: string | null; // Stable session/thread ID across turns
|
|
173
|
+
messageId: string | null; // Provider-native message ID
|
|
174
|
+
eventId: string | null; // Per-event-line ID (Claude only — Codex = null)
|
|
175
|
+
turnId: string | null; // Native turn ID (Codex v2 app-server only; NDJSON & Claude = null)
|
|
176
|
+
parentToolCallId: string | null; // Sub-agent origin — same namespace as tool_call.toolCallId (Claude only)
|
|
177
|
+
raw: Record<string, unknown>; // Original provider event verbatim
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Variants:
|
|
130
182
|
|
|
131
|
-
- `system` — Session init (`
|
|
183
|
+
- `system` — Session init (`subtype`, `model`, `cwd`, `tools`, `permissionMode`)
|
|
132
184
|
- `assistant` — Text output from the agent (`text`)
|
|
133
185
|
- `thinking` — Agent's internal reasoning (`text`)
|
|
134
|
-
- `tool_call` — Agent invoked a tool (`
|
|
135
|
-
- `
|
|
136
|
-
- `
|
|
186
|
+
- `tool_call` — Agent invoked a tool (`toolCallId: string | null`, `name`, `input`)
|
|
187
|
+
- `unknown` — Fallback for unrecognized wire events (`subtype` = the provider's `type` field). Forward-compat access to new CLI events via `raw` without a library update.
|
|
188
|
+
- `tool_result` — Tool returned a result (`toolCallId: string | null`, `content`, `isError`, `exitCode: number | null`)
|
|
189
|
+
- `rate_limit` — Provider reported rate-limit state (`status`, `limitType`, `resetAt`, `overageStatus`, `isUsingOverage`)
|
|
190
|
+
- `result` — Final result (`text`, `costUsd`, `isError`, `stopReason`, `terminalReason`, `numTurns`, `durationMs`)
|
|
137
191
|
|
|
138
192
|
Lifecycle events (via `onLifecycle`) report phases: `preparing`, `spawning`, `running`, `waiting_for_input`, `completed`, `cancelled`, `error`.
|
|
139
193
|
|
|
194
|
+
### What each provider surfaces on stream events
|
|
195
|
+
|
|
196
|
+
Verified live against `claude 2.1.116` and `codex-cli 0.122.0` (2026-04-21). Other providers emit stubs — see precedence table at the end of this section.
|
|
197
|
+
|
|
198
|
+
| Field on `StreamEvent` | Claude source | Codex source |
|
|
199
|
+
| ---------------------- | -------------------------------------------------- | ------------------------------------------------ |
|
|
200
|
+
| `sessionId` | `session_id` (UUID, stable across turns + resume) | `thread_id` (UUIDv7, emitted once on `thread.started`, tracked across lines) |
|
|
201
|
+
| `messageId` | `message.id` (Anthropic API message, e.g. `msg_*`) | v2 app-server: globally unique (`msg_*`, `rs_*`, `call_*`). NDJSON: `item_N` — **turn-local, not globally unique** |
|
|
202
|
+
| `eventId` | Top-level per-line `uuid` | **null** — Codex doesn't emit a per-event ID |
|
|
203
|
+
| `turnId` | **null** — Claude doesn't model turns | v2 app-server: native UUIDv7 from `params.turnId`. NDJSON: **null** — no turn id in legacy format |
|
|
204
|
+
| `parentToolCallId` | `parent_tool_use_id` (set for sub-agent messages) | **null** — not emitted |
|
|
205
|
+
| Tool correlation | `tool_use.id` (`toolu_*`) ↔ `tool_result.tool_use_id` | `item.id` reappears on the same item's `item.completed` |
|
|
206
|
+
| `tool_result.exitCode` | **null** (Claude doesn't expose shell exit codes) | `item.exit_code` for `command_execution` |
|
|
207
|
+
| Assistant message span | One `message.id` may span multiple event lines (thinking + tool_use emitted separately with distinct `uuid`s) | One `item.completed` per agent message |
|
|
208
|
+
|
|
209
|
+
On `ExecutionResult`:
|
|
210
|
+
|
|
211
|
+
| Field | Claude | Codex |
|
|
212
|
+
| ------------------ | -------------------------------------------------------------- | -------------------------------------------------------------------- |
|
|
213
|
+
| `costUsd` | ✓ `total_cost_usd` | **always null** — Codex JSONL doesn't report cost |
|
|
214
|
+
| `usage.*.costUsd` | ✓ per-model from `modelUsage` payload | — not available |
|
|
215
|
+
| `usage` cache keys | ✓ `cachedInputTokens` + `cacheCreationInputTokens` | ✓ `cachedInputTokens` only (maps from `cached_input_tokens`) |
|
|
216
|
+
| `model` | ✓ from `system.init` / `message.model` | **null from stdout** — falls back to the requested model |
|
|
217
|
+
| `raw.stopReason` | ✓ `result.stop_reason` | — not emitted |
|
|
218
|
+
| `raw.terminalReason` | ✓ `result.terminal_reason` | — not emitted |
|
|
219
|
+
| `raw.numTurns` | ✓ | — not emitted |
|
|
220
|
+
| `raw.rateLimits` | ✓ parsed from `rate_limit_event` events | — not emitted |
|
|
221
|
+
| `raw.permissionDenials` | ✓ `result.permission_denials` | — not emitted |
|
|
222
|
+
| `raw.finalEvent` | ✓ the `result` event verbatim | ✓ the `turn.completed` / `turn.failed` / `error` event verbatim |
|
|
223
|
+
| Per-model breakdown | ✓ multiple models can appear — Claude quietly calls haiku alongside the main model for summarization | single requested model only |
|
|
224
|
+
|
|
225
|
+
### Storing events in a database
|
|
226
|
+
|
|
227
|
+
For Claude, `eventId` is a safe unique key for a per-event row. `messageId` is a safe key for "one logical assistant message" — multiple event lines can share it when the message contains both thinking and tool_use blocks.
|
|
228
|
+
|
|
229
|
+
For Codex, `item.id` values like `item_0`, `item_1` **reset every turn** (including on `codex exec resume`). Do not use them as unique keys on their own. Use `(sessionId, turn_index, messageId)` or mint your own UUID at insert time. There is no `eventId` — Codex doesn't emit one.
|
|
230
|
+
|
|
231
|
+
When in doubt, `raw` is the verbatim provider event — parse it yourself for anything the normalized fields don't cover.
|
|
232
|
+
|
|
233
|
+
### Other providers
|
|
234
|
+
|
|
235
|
+
`cursor`, `gemini`, `opencode`, `pi`, `openclaw` emit the same `StreamEvent` shape but currently stub most IDs to `null`. Their `raw` field is populated; enrichment to match the Claude/Codex level of fidelity is tracked separately and has not been audited against live CLI output.
|
|
236
|
+
|
|
140
237
|
## Sessions (multi-turn)
|
|
141
238
|
|
|
142
239
|
Providers with `capabilities.sessions = true` (Claude, Codex) can host a persistent session where you send multiple user messages and reuse context across turns.
|