kimiflare 0.70.0 → 0.71.0

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 CHANGED
@@ -266,6 +266,120 @@ Disable the file sink entirely with `KIMIFLARE_LOG_SINK=off`. The
266
266
  separate `KIMIFLARE_LOG_LEVEL` env var (default `off`) controls stderr
267
267
  output — independent of the file sink.
268
268
 
269
+ ### Shipping to an OpenTelemetry collector
270
+
271
+ If you set `KIMIFLARE_OTEL_ENDPOINT`, KimiFlare also ships each log
272
+ entry to that endpoint over [OTLP/HTTP](https://opentelemetry.io/docs/specs/otlp/)
273
+ so it lands in Datadog, Honeycomb, Grafana Loki, an internal collector,
274
+ or any other backend that speaks OTel. Batched every 5 s (or every
275
+ 100 entries, whichever first) and best-effort — never blocks the agent
276
+ loop.
277
+
278
+ ```sh
279
+ # Full path:
280
+ export KIMIFLARE_OTEL_ENDPOINT="https://otel.example.com/v1/logs"
281
+ # Or just the base URL (we auto-append /v1/logs):
282
+ export KIMIFLARE_OTEL_ENDPOINT="https://otel.example.com"
283
+
284
+ # Optional headers (comma-separated key=value pairs) — e.g. for auth:
285
+ export KIMIFLARE_OTEL_HEADERS="Authorization=Bearer xyz,X-Tenant=acme"
286
+ ```
287
+
288
+ Each log entry maps to one OTel `LogRecord`. Correlation IDs
289
+ (`session_id`, `turn_id`, `request_id`) become record attributes,
290
+ `data.*` fields are flattened to attributes with type-preserving
291
+ encoding, and a `service.name=kimiflare` + `service.version` pair sits
292
+ on the resource. The same `request_id` joins to Cloudflare AI Gateway's
293
+ per-request log without any extra work.
294
+
295
+ ## Hooks
296
+
297
+ KimiFlare can fire shell commands at five points in an agent turn,
298
+ configured per-project (`.kimiflare/settings.json`) or globally
299
+ (`~/.config/kimiflare/settings.json`):
300
+
301
+ | Event | Fires when | Veto? |
302
+ |--------------------|-------------------------------------------------|-------|
303
+ | `PreToolUse` | A tool call is about to run | Yes |
304
+ | `PostToolUse` | A tool call just finished | No |
305
+ | `UserPromptSubmit` | You hit Enter on a prompt | Yes |
306
+ | `Stop` | A turn ended cleanly | No |
307
+ | `PreCompact` | Auto-compaction is about to run | No |
308
+
309
+ Hooks receive the event payload as JSON on stdin **and** as
310
+ `KIMIFLARE_HOOK_*` env vars (for shell-one-liner ergonomics).
311
+ Non-zero exit on a veto event cancels the underlying action and
312
+ surfaces the hook's stdout as the rejection reason.
313
+
314
+ ### Browse + enable from the TUI
315
+
316
+ ```text
317
+ /hooks # list configured hooks
318
+ /hooks recommended # list starter hooks shipped with kimiflare
319
+ /hooks enable stop-bell # enable one (writes to .kimiflare/settings.json)
320
+ /hooks enable stop-bell global # ...or the global file
321
+ /hooks disable stop-bell
322
+ /hooks path # print settings.json paths
323
+ /hooks reload # re-read settings.json after a manual edit
324
+ ```
325
+
326
+ The recommended catalog includes terminal bells / macOS notifications
327
+ on `Stop`, secret-file guards on `PreToolUse` (e.g. block edits to
328
+ `*.env`), auto-format-with-prettier on `PostToolUse`, and a tool-call
329
+ audit log. All ship disabled — `/hooks recommended` lists them.
330
+
331
+ ### Schema example
332
+
333
+ ```json
334
+ {
335
+ "hooks": {
336
+ "PreToolUse": [
337
+ {
338
+ "id": "no-secrets",
339
+ "matcher": "^(edit|write)$",
340
+ "command": "case \"$KIMIFLARE_HOOK_PATH\" in *.env|*.pem) echo 'blocked'; exit 1;; esac"
341
+ }
342
+ ],
343
+ "PostToolUse": [
344
+ {
345
+ "id": "format-ts",
346
+ "matcher": "^(edit|write)$",
347
+ "command": "npx --no-install prettier --write \"$KIMIFLARE_HOOK_PATH\" >/dev/null 2>&1 || true"
348
+ }
349
+ ],
350
+ "Stop": [
351
+ { "id": "bell", "command": "printf '\\a'" }
352
+ ]
353
+ }
354
+ }
355
+ ```
356
+
357
+ Per-hook fields:
358
+ - `command` (required) — the shell command.
359
+ - `matcher` (optional) — anchored regex matched against the tool name
360
+ for `PreToolUse` / `PostToolUse`. Ignored for other events.
361
+ - `id` (optional) — stable handle for `/hooks enable|disable`.
362
+ Auto-derived from `event + command` when omitted.
363
+ - `enabled` (default `true`) — set `false` to keep a hook in config
364
+ but skip it.
365
+ - `timeoutMs` (default `30000`) — hard kill if the hook hangs.
366
+ - `description` (optional) — shown by `/hooks list`.
367
+
368
+ Hooks are always-on infrastructure: they fire whether the TUI is open
369
+ or kimiflare is running in `--print` mode. They also fire for tool
370
+ calls generated from inside the Code Mode sandbox (heavy-tier turns),
371
+ because hook firing lives on the `ToolExecutor` itself — every call
372
+ path uses the same plumbing.
373
+
374
+ When intent classification has assigned a tier, hook payloads include
375
+ it as `tier: "light" | "medium" | "heavy"` (on `UserPromptSubmit`,
376
+ `PreToolUse`, `PostToolUse`) and as `$KIMIFLARE_HOOK_TIER`. Useful for
377
+ "skip auto-format on light turns" or "audit every heavy-turn write."
378
+
379
+ SDK consumers opt in to hooks with `enableHooks: true` on
380
+ `createAgentSession`. Default is off because the SDK is a primitive,
381
+ not the TUI.
382
+
269
383
  ## Development
270
384
 
271
385
  ```sh