@justin06lee/yagami 0.6.1 → 0.8.1
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 +29 -7
- package/dist/{chunk-D2PNH6GV.js → chunk-4S5QNDQK.js} +2 -2
- package/dist/{chunk-ZYHC7PXX.js → chunk-U3RFT7QV.js} +547 -60
- package/dist/chunk-U3RFT7QV.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{hostConfig-HmZ3z297.d.ts → hostConfig-CbGD5-lN.d.ts} +115 -2
- package/dist/index.d.ts +15 -12
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-ZYHC7PXX.js.map +0 -1
- /package/dist/{chunk-D2PNH6GV.js.map → chunk-4S5QNDQK.js.map} +0 -0
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ yagami start # first run generates + saves an API key and prints it
|
|
|
32
32
|
`make update` stops any running yagami server, rebuilds, reinstalls, and restarts it. Or install from npm: `bun add -g @justin06lee/yagami`.
|
|
33
33
|
|
|
34
34
|
```
|
|
35
|
-
yagami v0.
|
|
35
|
+
yagami v0.7.0
|
|
36
36
|
listening http://127.0.0.1:8787
|
|
37
37
|
provider claude — /Users/you/.local/bin/claude (2.1.238 (Claude Code))
|
|
38
38
|
also codex, opencode (use model "<provider>:<model>")
|
|
@@ -74,6 +74,20 @@ curl http://127.0.0.1:8787/v1/chat/completions \
|
|
|
74
74
|
-d '{"model":"codex","messages":[{"role":"user","content":"ping"}]}'
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
+
### Web search and fetch
|
|
78
|
+
|
|
79
|
+
`/v1/messages` accepts Anthropic's **server tools**, so a client can ask the engine to go look something up before it answers:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
curl http://127.0.0.1:8787/v1/messages \
|
|
83
|
+
-H "x-api-key: ygm_..." -H "content-type: application/json" \
|
|
84
|
+
-d '{"model":"sonnet","max_tokens":600,
|
|
85
|
+
"tools":[{"type":"web_search_20260209","name":"web_search"}],
|
|
86
|
+
"messages":[{"role":"user","content":"What is the current stable Rust version?"}]}'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Server tools run *inside* the engine — they map onto the CLI's own `WebSearch` and `WebFetch`, and the results are folded into the reply. Nothing changes about the endpoint's contract: it still never emits a `tool_use` block for you to execute. Every dated variant of a type works (`web_search_20250305`, `web_search_20260209`, …), `tool_choice` may be `auto` or `none`, and any other tool in the array is rejected — a custom tool would have to run on your side, and there is no round trip here to run it on. Only the claude provider serves them; asking codex or an ACP agent for them fails loudly rather than quietly answering without the lookup.
|
|
90
|
+
|
|
77
91
|
One caveat for OpenAI-dialect apps: the `model` field still routes through yagami's providers — set it to a model your CLIs actually serve (`sonnet`, `codex:gpt-5.6-sol`, `opencode:…`), not whatever `gpt-*` id the app defaults to.
|
|
78
92
|
|
|
79
93
|
## Library mode
|
|
@@ -112,7 +126,7 @@ Every provider implements one small `Provider` contract (`run(turn)` → normali
|
|
|
112
126
|
|
|
113
127
|
### Building a UI on Claude Code
|
|
114
128
|
|
|
115
|
-
`Yagami`/`YagamiEngine` are completions-only by design. To build an actual coding UI — tools, permissions, plan mode, a warm session across turns — use `AgentSession`, which wraps the full Claude Code agent with the lifecycle the interactive terminal gives you for free:
|
|
129
|
+
`Yagami`/`YagamiEngine` are completions-only by design (server tools aside, they never hand you a tool call to run). To build an actual coding UI — tools, permissions, plan mode, a warm session across turns — use `AgentSession`, which wraps the full Claude Code agent with the lifecycle the interactive terminal gives you for free:
|
|
116
130
|
|
|
117
131
|
```ts
|
|
118
132
|
import { AgentSession } from "@justin06lee/yagami";
|
|
@@ -161,10 +175,16 @@ if (isSessionProvider(codex)) {
|
|
|
161
175
|
permissions: {
|
|
162
176
|
decide: async (req) => (await showDialog(req.tool, req.input)) ? "allow" : "deny",
|
|
163
177
|
}, // "allow_always" answers like the TUI's "don't ask again"
|
|
178
|
+
input: {
|
|
179
|
+
// Codex request_user_input and MCP/ACP form or URL elicitations all
|
|
180
|
+
// arrive in this provider-neutral shape. Throwing safely cancels it.
|
|
181
|
+
respond: async (request) => renderInput(request),
|
|
182
|
+
},
|
|
164
183
|
});
|
|
165
184
|
for await (const ev of session.send("fix the failing test")) {
|
|
166
|
-
// normalized AgentEvents: text / thinking / tool_call
|
|
167
|
-
//
|
|
185
|
+
// normalized AgentEvents: session / turn / text / thinking / tool_call
|
|
186
|
+
// (started→completed, including Codex multi-agent operations) / permission
|
|
187
|
+
// / plan / done
|
|
168
188
|
}
|
|
169
189
|
session.send("now add a test"); // same warm thread, context carries
|
|
170
190
|
await session.interrupt();
|
|
@@ -172,7 +192,7 @@ if (isSessionProvider(codex)) {
|
|
|
172
192
|
}
|
|
173
193
|
```
|
|
174
194
|
|
|
175
|
-
`ProviderSessionOptions` takes `cwd`, `model`, `resume`, `effort`, `systemPrompt` (extra developer instructions where the harness supports them), and a `native` escape hatch (Codex: `{ sandbox, approvalPolicy, config }`; ACP: `{ mode }`). The completion-turn `run()` path stays for API-style callers; sessions are for hosts that want the real interactive agent.
|
|
195
|
+
`ProviderSessionOptions` takes `cwd`, `model`, `resume`, `effort`, `systemPrompt` (extra developer instructions where the harness supports them), `permissions`, optional `input`, and a `native` escape hatch (Codex: `{ sandbox, approvalPolicy, config }`; ACP: `{ mode }`). A session provider reports `sessionCapabilities.fork`; when true, `{ resume, fork: true }` branches at the tip and `{ resume, forkAt: turnId }` branches through an exact `turn` event without mutating the source conversation. Input fields preserve labels, options, required/secret flags, primitive constraints, and URLs; omitting the handler declines safely instead of hanging a turn. ACP sessions also map `effort` onto the agent's `thought_level` option when it exposes one. The completion-turn `run()` path stays for API-style callers; sessions are for hosts that want the real interactive agent.
|
|
176
196
|
|
|
177
197
|
The server is also embeddable: `import { startYagami } from "@justin06lee/yagami/server"`.
|
|
178
198
|
|
|
@@ -184,7 +204,7 @@ A bare model id goes to the **default provider** (Claude Code unless you change
|
|
|
184
204
|
|---|---|---|---|---|---|
|
|
185
205
|
| `claude` — Claude Code | Agent SDK → your `claude` binary | yes, forking | yes (+ documents) | native | native |
|
|
186
206
|
| `codex` — Codex CLI | `codex exec --json` (read-only sandbox) | yes | yes | emulated | effort only |
|
|
187
|
-
| `opencode`, `gemini`, `copilot`, `cursor`, `qwen`, `goose`, `kimi`, `kilo`, `cline`, `auggie`, `amp`, `grok`, `droid`, `codex-acp`, `claude-acp` | Agent Client Protocol over stdio | if the agent supports it | if the agent supports it | emulated |
|
|
207
|
+
| `opencode`, `gemini`, `copilot`, `cursor`, `qwen`, `goose`, `kimi`, `kilo`, `cline`, `auggie`, `amp`, `grok`, `droid`, `codex-acp`, `claude-acp` | Agent Client Protocol over stdio | if the agent supports it | if the agent supports it | emulated | `thought_level` when exposed |
|
|
188
208
|
|
|
189
209
|
"Emulated" means the system prompt is folded into the user turn as a `<system>` block; unsupported `thinking`/`effort` are accepted and reported in `x-yagami-ignored` rather than rejected. Without native forking, a resumed session is single-use: a sibling branch of the same conversation falls back to transcript replay instead of corrupting the shared session.
|
|
190
210
|
|
|
@@ -242,7 +262,7 @@ Env overrides: `YAGAMI_HOST`, `YAGAMI_PORT`, `YAGAMI_API_KEY`, `YAGAMI_PROVIDER`
|
|
|
242
262
|
- **Dialects**: `POST /v1/messages` is native. `POST /v1/chat/completions` translates OpenAI shapes at the edge — system/developer messages fold into `system`, `image_url` parts become image blocks, streams are re-emitted as `chat.completion.chunk` events ending in `[DONE]`, and thinking output rides along as `reasoning_content`. Errors on that path come back OpenAI-shaped too. `GET /v1/models` serves one merged shape both SDKs parse.
|
|
243
263
|
- **Multi-turn**: the Messages API is stateless but harness sessions aren't. yagami hashes each conversation prefix (per provider) and remembers which session produced it; a follow-up request resumes that session and sends only the new user message. Unmatched histories fall back to replaying the transcript in a single prompt, and if a cached session turns out to be gone, the stale mapping is dropped and the request transparently retries via replay. The cache persists across restarts at `~/.config/yagami/sessions.json`.
|
|
244
264
|
- **Streaming**: every harness's output is normalized into deltas and re-emitted as a proper Anthropic SSE sequence — `message_start` → thinking/text content blocks → `message_delta` → `message_stop` (or the OpenAI chunk sequence on the chat-completions path). Claude and ACP agents stream tokens; Codex streams per message part.
|
|
245
|
-
- **Models**: `GET /v1/models` asks each installed CLI what it supports (Claude via the SDK, Codex via its app-server protocol, ACP agents via their session config) — probed once per process, then cached. Failed probes are skipped and retried next time; a static fallback list is served only if nothing answers (`x-yagami-models-source` says which).
|
|
265
|
+
- **Models**: `GET /v1/models` asks each installed CLI what it supports (Claude via the SDK, Codex via its app-server protocol, ACP agents via their session config) — probed once per process, then cached. Library callers also receive native model metadata when reported: reasoning levels/default, input modalities, fast/auto/adaptive-thinking flags, personality and multi-agent support, service tiers, and the provider's default model. Failed probes are skipped and retried next time; a static fallback list is served only if nothing answers (`x-yagami-models-source` says which).
|
|
246
266
|
- **Auth**: `x-api-key` or `Authorization: Bearer`, compared in constant time. Binds to `127.0.0.1` by default and warns loudly on anything else.
|
|
247
267
|
|
|
248
268
|
Extra response headers: `x-yagami-provider`, `x-yagami-cost-usd` (what the turn would have cost at API prices, when the harness reports it), `x-yagami-session`, `x-yagami-ignored` (accepted-but-unsupported params). `/healthz` (unauthenticated) reports the default provider, installed providers, uptime, request count, and the cumulative would-be cost — `yagami status` shows the same.
|
|
@@ -264,3 +284,5 @@ bun run smoke # live end-to-end through your real Claude C
|
|
|
264
284
|
bun run live:providers # live check across every installed harness (tiny token cost each)
|
|
265
285
|
make build # build dist/ only
|
|
266
286
|
```
|
|
287
|
+
|
|
288
|
+
Codex sessions preserve proposed plan documents and stream reasoning summaries as they arrive, and completed items only fill missing text. A failed resume is reported as an error; it never silently opens an empty conversation. Only one send can run at a time, including during startup. Input and permission handlers receive an abort signal when the server resolves their request, their turn stops, or the session closes; hosts should dismiss the corresponding prompt. Close and reopen a failed session with its last ID to retry.
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
toApiError,
|
|
11
11
|
toChatCompletion,
|
|
12
12
|
yagamiConfigDir
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-U3RFT7QV.js";
|
|
14
14
|
|
|
15
15
|
// src/server.ts
|
|
16
16
|
import { serve } from "@hono/node-server";
|
|
@@ -374,4 +374,4 @@ export {
|
|
|
374
374
|
maskKey,
|
|
375
375
|
startYagami
|
|
376
376
|
};
|
|
377
|
-
//# sourceMappingURL=chunk-
|
|
377
|
+
//# sourceMappingURL=chunk-4S5QNDQK.js.map
|