@justin06lee/yagami 0.6.0 → 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 +32 -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 +26 -13
- package/dist/index.js +14 -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";
|
|
@@ -137,6 +151,9 @@ session.send("now add a test for the edge case"); // next turn resumes the sam
|
|
|
137
151
|
await session.interrupt(); // the CLI's Esc
|
|
138
152
|
await session.setModel("opus"); // the CLI's /model
|
|
139
153
|
await session.setPermissionMode("plan"); // shift+tab
|
|
154
|
+
// the CLI's /rewind: restore tracked files to their state at a user
|
|
155
|
+
// message's uuid (needs options: { enableFileCheckpointing: true })
|
|
156
|
+
await session.rewindFiles(userMessageUuid);
|
|
140
157
|
session.close();
|
|
141
158
|
```
|
|
142
159
|
|
|
@@ -158,10 +175,16 @@ if (isSessionProvider(codex)) {
|
|
|
158
175
|
permissions: {
|
|
159
176
|
decide: async (req) => (await showDialog(req.tool, req.input)) ? "allow" : "deny",
|
|
160
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
|
+
},
|
|
161
183
|
});
|
|
162
184
|
for await (const ev of session.send("fix the failing test")) {
|
|
163
|
-
// normalized AgentEvents: text / thinking / tool_call
|
|
164
|
-
//
|
|
185
|
+
// normalized AgentEvents: session / turn / text / thinking / tool_call
|
|
186
|
+
// (started→completed, including Codex multi-agent operations) / permission
|
|
187
|
+
// / plan / done
|
|
165
188
|
}
|
|
166
189
|
session.send("now add a test"); // same warm thread, context carries
|
|
167
190
|
await session.interrupt();
|
|
@@ -169,7 +192,7 @@ if (isSessionProvider(codex)) {
|
|
|
169
192
|
}
|
|
170
193
|
```
|
|
171
194
|
|
|
172
|
-
`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.
|
|
173
196
|
|
|
174
197
|
The server is also embeddable: `import { startYagami } from "@justin06lee/yagami/server"`.
|
|
175
198
|
|
|
@@ -181,7 +204,7 @@ A bare model id goes to the **default provider** (Claude Code unless you change
|
|
|
181
204
|
|---|---|---|---|---|---|
|
|
182
205
|
| `claude` — Claude Code | Agent SDK → your `claude` binary | yes, forking | yes (+ documents) | native | native |
|
|
183
206
|
| `codex` — Codex CLI | `codex exec --json` (read-only sandbox) | yes | yes | emulated | effort only |
|
|
184
|
-
| `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 |
|
|
185
208
|
|
|
186
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.
|
|
187
210
|
|
|
@@ -239,7 +262,7 @@ Env overrides: `YAGAMI_HOST`, `YAGAMI_PORT`, `YAGAMI_API_KEY`, `YAGAMI_PROVIDER`
|
|
|
239
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.
|
|
240
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`.
|
|
241
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.
|
|
242
|
-
- **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).
|
|
243
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.
|
|
244
267
|
|
|
245
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.
|
|
@@ -261,3 +284,5 @@ bun run smoke # live end-to-end through your real Claude C
|
|
|
261
284
|
bun run live:providers # live check across every installed harness (tiny token cost each)
|
|
262
285
|
make build # build dist/ only
|
|
263
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
|