@justin06lee/yagami 0.6.1 → 0.8.2
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 +30 -8
- package/dist/{chunk-ZYHC7PXX.js → chunk-EKN223KD.js} +685 -84
- package/dist/chunk-EKN223KD.js.map +1 -0
- package/dist/{chunk-D2PNH6GV.js → chunk-UGIJV6FZ.js} +2 -2
- package/dist/cli.js +2 -2
- package/dist/{hostConfig-HmZ3z297.d.ts → hostConfig-CbGD5-lN.d.ts} +115 -2
- package/dist/index.d.ts +31 -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 +1 -1
- package/dist/chunk-ZYHC7PXX.js.map +0 -1
- /package/dist/{chunk-D2PNH6GV.js.map → chunk-UGIJV6FZ.js.map} +0 -0
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
toApiError,
|
|
11
11
|
toChatCompletion,
|
|
12
12
|
yagamiConfigDir
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-EKN223KD.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-UGIJV6FZ.js.map
|
package/dist/cli.js
CHANGED
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
sessionCachePath,
|
|
14
14
|
startYagami,
|
|
15
15
|
writeServerState
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-UGIJV6FZ.js";
|
|
17
17
|
import {
|
|
18
18
|
VERSION,
|
|
19
19
|
YagamiEngine,
|
|
20
20
|
createProvider,
|
|
21
21
|
detectProviders
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-EKN223KD.js";
|
|
23
23
|
|
|
24
24
|
// src/cli.ts
|
|
25
25
|
import { spawn } from "child_process";
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** One model-native reasoning setting. */
|
|
2
|
+
interface EngineReasoningEffort {
|
|
3
|
+
id: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
}
|
|
6
|
+
/** One provider service tier (for example Codex's priority tier). */
|
|
7
|
+
interface EngineServiceTier {
|
|
8
|
+
id: string;
|
|
9
|
+
display_name: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
}
|
|
12
|
+
type EngineInputModality = "text" | "image" | "audio" | "document" | (string & {});
|
|
13
|
+
/** A model a provider reports as available, including its native controls. */
|
|
2
14
|
interface EngineModel {
|
|
3
15
|
id: string;
|
|
4
16
|
display_name: string;
|
|
@@ -7,6 +19,19 @@ interface EngineModel {
|
|
|
7
19
|
resolved_model?: string;
|
|
8
20
|
/** Provider that serves this model (set by the engine when aggregating). */
|
|
9
21
|
provider?: string;
|
|
22
|
+
/** Reasoning levels this particular model accepts. */
|
|
23
|
+
reasoning_efforts?: EngineReasoningEffort[];
|
|
24
|
+
default_reasoning_effort?: string;
|
|
25
|
+
input_modalities?: EngineInputModality[];
|
|
26
|
+
supports_adaptive_thinking?: boolean;
|
|
27
|
+
supports_fast_mode?: boolean;
|
|
28
|
+
supports_auto_mode?: boolean;
|
|
29
|
+
supports_personality?: boolean;
|
|
30
|
+
/** Provider-native multi-agent runtime, when the catalog reports one. */
|
|
31
|
+
multi_agent?: string;
|
|
32
|
+
service_tiers?: EngineServiceTier[];
|
|
33
|
+
default_service_tier?: string;
|
|
34
|
+
is_default?: boolean;
|
|
10
35
|
}
|
|
11
36
|
|
|
12
37
|
/**
|
|
@@ -101,6 +126,12 @@ interface ProviderCapabilities {
|
|
|
101
126
|
effort: boolean;
|
|
102
127
|
/** Token-level deltas or whole chunks per message part. */
|
|
103
128
|
streaming: "tokens" | "chunks";
|
|
129
|
+
/**
|
|
130
|
+
* Can run Anthropic server tools (web search/fetch) inside the turn. Still
|
|
131
|
+
* completions-only: results are folded into the reply, never emitted as
|
|
132
|
+
* `tool_use` blocks for the caller to execute.
|
|
133
|
+
*/
|
|
134
|
+
serverTools: boolean;
|
|
104
135
|
}
|
|
105
136
|
/** One completion turn, already normalized by the engine. */
|
|
106
137
|
interface TurnRequest {
|
|
@@ -115,6 +146,8 @@ interface TurnRequest {
|
|
|
115
146
|
resume?: string;
|
|
116
147
|
thinking?: ThinkingParam;
|
|
117
148
|
effort?: string;
|
|
149
|
+
/** CLI tool names to enable for this turn (see `core/serverTools.ts`). */
|
|
150
|
+
serverTools?: string[];
|
|
118
151
|
signal?: AbortSignal;
|
|
119
152
|
}
|
|
120
153
|
type TurnEvent = {
|
|
@@ -166,6 +199,64 @@ interface ModelRef {
|
|
|
166
199
|
declare function parseModelRef(model: string | undefined, providerIds: Iterable<string>): ModelRef;
|
|
167
200
|
declare function qualifiedModel(providerId: string, model: string): string;
|
|
168
201
|
type SessionPermissionDecision = "allow" | "allow_always" | "deny" | "deny_always";
|
|
202
|
+
type SessionInputValue = string | number | boolean | string[];
|
|
203
|
+
interface SessionInputOption {
|
|
204
|
+
value: string;
|
|
205
|
+
label: string;
|
|
206
|
+
description?: string;
|
|
207
|
+
}
|
|
208
|
+
/** One renderable field from a harness question or MCP elicitation. */
|
|
209
|
+
interface SessionInputField {
|
|
210
|
+
id: string;
|
|
211
|
+
label: string;
|
|
212
|
+
description?: string;
|
|
213
|
+
type: "string" | "number" | "integer" | "boolean" | "select" | "multiselect";
|
|
214
|
+
required: boolean;
|
|
215
|
+
secret?: boolean;
|
|
216
|
+
allowOther?: boolean;
|
|
217
|
+
options?: SessionInputOption[];
|
|
218
|
+
format?: string;
|
|
219
|
+
minimum?: number;
|
|
220
|
+
maximum?: number;
|
|
221
|
+
minLength?: number;
|
|
222
|
+
maxLength?: number;
|
|
223
|
+
default?: SessionInputValue;
|
|
224
|
+
}
|
|
225
|
+
/** A provider-neutral blocking request for human input. */
|
|
226
|
+
interface SessionInputRequest {
|
|
227
|
+
provider: string;
|
|
228
|
+
sessionId?: string;
|
|
229
|
+
kind: "questions" | "form" | "url";
|
|
230
|
+
message: string;
|
|
231
|
+
source?: string;
|
|
232
|
+
fields?: SessionInputField[];
|
|
233
|
+
url?: string;
|
|
234
|
+
blocking?: boolean;
|
|
235
|
+
raw?: unknown;
|
|
236
|
+
}
|
|
237
|
+
type SessionInputResponse = {
|
|
238
|
+
action: "accept";
|
|
239
|
+
values?: Record<string, SessionInputValue>;
|
|
240
|
+
} | {
|
|
241
|
+
action: "decline" | "cancel";
|
|
242
|
+
};
|
|
243
|
+
interface SessionInputHandler {
|
|
244
|
+
respond(req: SessionInputRequest, signal?: AbortSignal): Promise<SessionInputResponse>;
|
|
245
|
+
}
|
|
246
|
+
type SessionPlanStatus = "pending" | "in_progress" | "completed";
|
|
247
|
+
interface SessionPlanEntry {
|
|
248
|
+
content: string;
|
|
249
|
+
status: SessionPlanStatus;
|
|
250
|
+
priority?: "high" | "medium" | "low";
|
|
251
|
+
}
|
|
252
|
+
interface SessionPlan {
|
|
253
|
+
id?: string;
|
|
254
|
+
explanation?: string;
|
|
255
|
+
entries?: SessionPlanEntry[];
|
|
256
|
+
markdown?: string;
|
|
257
|
+
uri?: string;
|
|
258
|
+
removed?: boolean;
|
|
259
|
+
}
|
|
169
260
|
/** A harness asking the host whether a tool may run. */
|
|
170
261
|
interface SessionPermissionRequest {
|
|
171
262
|
provider: string;
|
|
@@ -185,6 +276,11 @@ interface SessionPermissionHandler {
|
|
|
185
276
|
type AgentEvent = {
|
|
186
277
|
type: "session";
|
|
187
278
|
sessionId: string;
|
|
279
|
+
}
|
|
280
|
+
/** Provider-native turn id, used by hosts to fork an exact exchange. */
|
|
281
|
+
| {
|
|
282
|
+
type: "turn";
|
|
283
|
+
id: string;
|
|
188
284
|
} | {
|
|
189
285
|
type: "text";
|
|
190
286
|
text: string;
|
|
@@ -204,6 +300,9 @@ type AgentEvent = {
|
|
|
204
300
|
type: "permission";
|
|
205
301
|
request: SessionPermissionRequest;
|
|
206
302
|
decision: SessionPermissionDecision;
|
|
303
|
+
} | {
|
|
304
|
+
type: "plan";
|
|
305
|
+
plan: SessionPlan;
|
|
207
306
|
} | {
|
|
208
307
|
type: "done";
|
|
209
308
|
usage?: Usage;
|
|
@@ -222,6 +321,10 @@ interface ProviderSessionOptions {
|
|
|
222
321
|
model?: string;
|
|
223
322
|
/** Provider session id to continue. */
|
|
224
323
|
resume?: string;
|
|
324
|
+
/** Fork the resumed session instead of continuing it in place. */
|
|
325
|
+
fork?: boolean;
|
|
326
|
+
/** Fork the resumed session through this provider-native turn, inclusive. */
|
|
327
|
+
forkAt?: string;
|
|
225
328
|
/**
|
|
226
329
|
* "terminal" loads the same settings the interactive CLI would — user and
|
|
227
330
|
* project config, CLAUDE.md, skills, hooks, MCP servers. "isolated" loads
|
|
@@ -229,6 +332,8 @@ interface ProviderSessionOptions {
|
|
|
229
332
|
*/
|
|
230
333
|
parity?: "terminal" | "isolated";
|
|
231
334
|
permissions: SessionPermissionHandler;
|
|
335
|
+
/** Blocking questions and MCP/ACP elicitations. Omitted means decline safely. */
|
|
336
|
+
input?: SessionInputHandler;
|
|
232
337
|
appName?: string;
|
|
233
338
|
effort?: string;
|
|
234
339
|
thinking?: ThinkingParam;
|
|
@@ -237,6 +342,10 @@ interface ProviderSessionOptions {
|
|
|
237
342
|
/** Provider-specific escape hatch (Claude: Agent SDK Options; Codex: { sandbox }; ACP: { mode }). */
|
|
238
343
|
native?: Record<string, unknown>;
|
|
239
344
|
}
|
|
345
|
+
interface ProviderSessionCapabilities {
|
|
346
|
+
/** Can fork a resumed conversation, optionally at an exact reported turn. */
|
|
347
|
+
fork: boolean;
|
|
348
|
+
}
|
|
240
349
|
/** One live conversation with a harness: send turns, get normalized events. */
|
|
241
350
|
interface ProviderSession {
|
|
242
351
|
readonly provider: string;
|
|
@@ -248,6 +357,7 @@ interface ProviderSession {
|
|
|
248
357
|
}
|
|
249
358
|
/** Providers that can host agentic sessions implement this too. */
|
|
250
359
|
interface SessionProvider extends Provider {
|
|
360
|
+
readonly sessionCapabilities: ProviderSessionCapabilities;
|
|
251
361
|
openSession(options: ProviderSessionOptions): ProviderSession;
|
|
252
362
|
}
|
|
253
363
|
declare function isSessionProvider(p: Provider): p is SessionProvider;
|
|
@@ -269,6 +379,9 @@ declare class CodexProvider implements SessionProvider {
|
|
|
269
379
|
readonly executable: string;
|
|
270
380
|
readonly loginCommand = "codex login";
|
|
271
381
|
readonly capabilities: ProviderCapabilities;
|
|
382
|
+
readonly sessionCapabilities: {
|
|
383
|
+
readonly fork: true;
|
|
384
|
+
};
|
|
272
385
|
private readonly workDir;
|
|
273
386
|
private readonly sandbox;
|
|
274
387
|
private readonly env;
|
|
@@ -490,4 +603,4 @@ interface HostEngineConfig {
|
|
|
490
603
|
}
|
|
491
604
|
declare function loadHostEngineConfig(): HostEngineConfig;
|
|
492
605
|
|
|
493
|
-
export { ApiError as A, type
|
|
606
|
+
export { type Usage as $, ApiError as A, type SessionInputField as B, CodexProvider as C, type DetectedProvider as D, type EngineModel as E, type SessionInputHandler as F, type SessionInputOption as G, type HostEngineConfig as H, type SessionInputRequest as I, type SessionInputResponse as J, type SessionInputValue as K, type LoadedProviders as L, type MessagesRequest as M, type SessionPermissionDecision as N, type SessionPermissionHandler as O, type Provider as P, type SessionPermissionRequest as Q, type SessionPlan as R, type SseEvent as S, type TurnRequest as T, type SessionPlanEntry as U, type SessionPlanStatus as V, type StreamOptions as W, type StreamResultInfo as X, YagamiEngine as Y, type StreamStart as Z, type SystemParam as _, type MessagesResponse as a, createProvider as a0, detectProviders as a1, isSessionProvider as a2, loadHostEngineConfig as a3, loadProviders as a4, parseModelRef as a5, presetFor as a6, qualifiedModel as a7, yagamiConfigDir as a8, type EngineOptions as b, type ProviderCapabilities as c, type TurnEvent as d, type SessionProvider as e, type ProviderSessionOptions as f, type ProviderSession as g, type AgentEvent as h, type ApiErrorType as i, type CodexProviderOptions as j, type CodexSandboxMode as k, type CompleteResult as l, type ContentBlock as m, type ContentBlockParam as n, type EngineInputModality as o, type EngineReasoningEffort as p, type EngineServiceTier as q, type MessageParam as r, type ModelRef as s, PROVIDER_PRESETS as t, type ProviderConfigEntry as u, type ProviderKind as v, type ProviderPreset as w, type ProviderSessionCapabilities as x, SessionCache as y, type SessionCacheOptions as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { S as SseEvent, M as MessagesRequest, E as EngineModel, A as ApiError, a as MessagesResponse, Y as YagamiEngine, b as EngineOptions, P as Provider, c as ProviderCapabilities, T as TurnRequest, d as TurnEvent, e as SessionProvider, f as ProviderSessionOptions, g as ProviderSession } from './hostConfig-
|
|
2
|
-
export { h as AgentEvent, i as ApiErrorType, C as CodexProvider, j as CodexProviderOptions, k as CodexSandboxMode, l as CompleteResult, m as ContentBlock, n as ContentBlockParam, D as DetectedProvider, H as HostEngineConfig, L as LoadedProviders,
|
|
3
|
-
import { Options, SDKUserMessage, Query, SettingSource, PermissionUpdate, CanUseTool, PermissionResult, SDKMessage, RewindFilesResult } from '@anthropic-ai/claude-agent-sdk';
|
|
1
|
+
import { S as SseEvent, M as MessagesRequest, E as EngineModel, A as ApiError, a as MessagesResponse, Y as YagamiEngine, b as EngineOptions, P as Provider, c as ProviderCapabilities, T as TurnRequest, d as TurnEvent, e as SessionProvider, f as ProviderSessionOptions, g as ProviderSession } from './hostConfig-CbGD5-lN.js';
|
|
2
|
+
export { h as AgentEvent, i as ApiErrorType, C as CodexProvider, j as CodexProviderOptions, k as CodexSandboxMode, l as CompleteResult, m as ContentBlock, n as ContentBlockParam, D as DetectedProvider, o as EngineInputModality, p as EngineReasoningEffort, q as EngineServiceTier, H as HostEngineConfig, L as LoadedProviders, r as MessageParam, s as ModelRef, t as PROVIDER_PRESETS, u as ProviderConfigEntry, v as ProviderKind, w as ProviderPreset, x as ProviderSessionCapabilities, y as SessionCache, z as SessionCacheOptions, B as SessionInputField, F as SessionInputHandler, G as SessionInputOption, I as SessionInputRequest, J as SessionInputResponse, K as SessionInputValue, N as SessionPermissionDecision, O as SessionPermissionHandler, Q as SessionPermissionRequest, R as SessionPlan, U as SessionPlanEntry, V as SessionPlanStatus, W as StreamOptions, X as StreamResultInfo, Z as StreamStart, _ as SystemParam, $ as Usage, a0 as createProvider, a1 as detectProviders, a2 as isSessionProvider, a3 as loadHostEngineConfig, a4 as loadProviders, a5 as parseModelRef, a6 as presetFor, a7 as qualifiedModel, a8 as yagamiConfigDir } from './hostConfig-CbGD5-lN.js';
|
|
3
|
+
import { Options, SDKUserMessage, Query, SettingSource, PermissionUpdate, CanUseTool, PermissionResult, SDKMessage, ModelInfo, RewindFilesResult } from '@anthropic-ai/claude-agent-sdk';
|
|
4
4
|
export { Options as AgentOptions, CanUseTool, PermissionMode, Query, RewindFilesResult, SDKMessage, SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';
|
|
5
|
-
import { ClientSideConnection, InitializeResponse, SessionNotification, RequestPermissionRequest, RequestPermissionResponse } from '@agentclientprotocol/sdk';
|
|
5
|
+
import { ClientSideConnection, InitializeResponse, SessionNotification, RequestPermissionRequest, RequestPermissionResponse, CreateElicitationRequest, CreateElicitationResponse } from '@agentclientprotocol/sdk';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* OpenAI Chat Completions dialect: translation to and from the Anthropic
|
|
@@ -89,9 +89,10 @@ interface TranslatedChatRequest {
|
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
91
|
* Translate an OpenAI Chat Completions request into the Anthropic Messages
|
|
92
|
-
* request the engine runs.
|
|
93
|
-
*
|
|
94
|
-
*
|
|
92
|
+
* request the engine runs. Function calling is rejected — nothing here ever
|
|
93
|
+
* hands a tool call back to the caller. (Anthropic server tools, which run
|
|
94
|
+
* inside the engine, are available on the Anthropic dialect.) Knobs no CLI
|
|
95
|
+
* engine exposes are collected into `extraIgnored` instead of failing.
|
|
95
96
|
*/
|
|
96
97
|
declare function chatToMessagesRequest(body: ChatCompletionsRequest): TranslatedChatRequest;
|
|
97
98
|
/** Anthropic Messages response → OpenAI chat.completion. */
|
|
@@ -358,10 +359,7 @@ declare class AgentSession implements AsyncIterable<SDKMessage> {
|
|
|
358
359
|
/** Switch permission mode mid-session (default/acceptEdits/plan/bypassPermissions). */
|
|
359
360
|
setPermissionMode(mode: "default" | "acceptEdits" | "plan" | "bypassPermissions"): Promise<void>;
|
|
360
361
|
/** Models the CLI reports as available (for a picker). */
|
|
361
|
-
supportedModels(): Promise<
|
|
362
|
-
value: string;
|
|
363
|
-
displayName: string;
|
|
364
|
-
}>>;
|
|
362
|
+
supportedModels(): Promise<ModelInfo[]>;
|
|
365
363
|
/**
|
|
366
364
|
* Rewind tracked files to their state at a user message (the CLI's
|
|
367
365
|
* /rewind). Needs `enableFileCheckpointing: true` in the session options —
|
|
@@ -450,6 +448,7 @@ declare class ClaudeProvider implements Provider {
|
|
|
450
448
|
interface AcpHandlers {
|
|
451
449
|
onUpdate?: (n: SessionNotification) => void;
|
|
452
450
|
onPermission?: (p: RequestPermissionRequest) => Promise<RequestPermissionResponse>;
|
|
451
|
+
onInput?: (p: CreateElicitationRequest) => Promise<CreateElicitationResponse>;
|
|
453
452
|
}
|
|
454
453
|
/** A live ACP agent process plus its negotiated connection. */
|
|
455
454
|
interface AcpConnection {
|
|
@@ -475,6 +474,12 @@ interface AcpProviderOptions {
|
|
|
475
474
|
installHint?: string;
|
|
476
475
|
/** Test seam: replaces process spawning. */
|
|
477
476
|
connect?: (cwd: string) => Promise<AcpConnection>;
|
|
477
|
+
/** How long a spawned agent gets to finish the ACP handshake before it is
|
|
478
|
+
* killed (default 30 s). */
|
|
479
|
+
handshakeTimeoutMs?: number;
|
|
480
|
+
/** How long a model-list or version probe may take end to end before the
|
|
481
|
+
* agent is closed and the probe fails (default 20 s). */
|
|
482
|
+
probeTimeoutMs?: number;
|
|
478
483
|
}
|
|
479
484
|
/**
|
|
480
485
|
* Any agent speaking the Agent Client Protocol over stdio — OpenCode,
|
|
@@ -487,12 +492,17 @@ declare class AcpProvider implements SessionProvider {
|
|
|
487
492
|
readonly executable: string;
|
|
488
493
|
readonly loginCommand: string;
|
|
489
494
|
readonly capabilities: ProviderCapabilities;
|
|
495
|
+
readonly sessionCapabilities: {
|
|
496
|
+
readonly fork: false;
|
|
497
|
+
};
|
|
490
498
|
private readonly args;
|
|
491
499
|
private readonly env;
|
|
492
500
|
private readonly workDir;
|
|
493
501
|
private readonly appName;
|
|
494
502
|
private readonly modelConfigId;
|
|
495
503
|
private readonly connectImpl;
|
|
504
|
+
private readonly handshakeTimeoutMs;
|
|
505
|
+
private readonly probeTimeoutMs;
|
|
496
506
|
constructor(options: AcpProviderOptions);
|
|
497
507
|
private spawnConnection;
|
|
498
508
|
private classify;
|
|
@@ -505,6 +515,15 @@ declare class AcpProvider implements SessionProvider {
|
|
|
505
515
|
*/
|
|
506
516
|
openSession(options: ProviderSessionOptions): ProviderSession;
|
|
507
517
|
private selectModel;
|
|
518
|
+
private selectEffort;
|
|
519
|
+
/**
|
|
520
|
+
* Run a short question against a fresh agent and close it, whatever
|
|
521
|
+
* happens. The deadline covers the whole exchange: an agent that answers
|
|
522
|
+
* the handshake and then sits on newSession forever (Gemini, signed out
|
|
523
|
+
* or mid-update) used to hold the probe open — and its process alive —
|
|
524
|
+
* for as long as the host ran.
|
|
525
|
+
*/
|
|
526
|
+
private probe;
|
|
508
527
|
listModels(): Promise<EngineModel[]>;
|
|
509
528
|
/**
|
|
510
529
|
* The agent's self-reported name/version from the ACP handshake. When the
|
|
@@ -535,6 +554,6 @@ declare function resolveExecutable(providerId: string, name: string, installHint
|
|
|
535
554
|
*/
|
|
536
555
|
declare function resolveClaudeExecutable(explicit?: string): string;
|
|
537
556
|
|
|
538
|
-
declare const VERSION = "0.
|
|
557
|
+
declare const VERSION = "0.8.2";
|
|
539
558
|
|
|
540
559
|
export { type AcpConnection, AcpProvider, type AcpProviderOptions, AgentSession, type AgentSessionOptions, ApiError, AuthRequiredError, ChatChunkTranslator, type ChatCompletion, type ChatCompletionChunk, type ChatCompletionsRequest, type ChatMessageParam, ClaudeProvider, type ClaudeProviderOptions, type ClaudeSessionOptions, EngineModel, EngineOptions, type MessageStreamEvent, MessagesRequest, MessagesResponse, type OpenAiUsage, type Parity, PermissionAdapter, type PermissionAdapterOptions, type PermissionDecision, type PermissionHandler, type PermissionRequest, Provider, ProviderCapabilities, ProviderError, ProviderNotInstalledError, ProviderSession, ProviderSessionOptions, SessionProvider, SseEvent, type TranslatedChatRequest, TurnEvent, TurnRequest, VERSION, type VersionSkew, Yagami, type YagamiChatCompletions, YagamiEngine, YagamiError, type YagamiMessages, type YagamiOptions, chatToMessagesRequest, claudeCodeSession, findExecutable, modelListBody, openAiErrorBody, resolveClaudeExecutable, resolveExecutable, settingSourcesFor, startAgentSession, toApiError, toChatCompletion };
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
toApiError,
|
|
32
32
|
toChatCompletion,
|
|
33
33
|
yagamiConfigDir
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-EKN223KD.js";
|
|
35
35
|
|
|
36
36
|
// src/core/client.ts
|
|
37
37
|
var Yagami = class {
|
|
@@ -278,8 +278,7 @@ var AgentSession = class {
|
|
|
278
278
|
/** Models the CLI reports as available (for a picker). */
|
|
279
279
|
async supportedModels() {
|
|
280
280
|
this.ensureStarted();
|
|
281
|
-
|
|
282
|
-
return models.map((m) => ({ value: m.value, displayName: m.displayName }));
|
|
281
|
+
return this.query.supportedModels();
|
|
283
282
|
}
|
|
284
283
|
/**
|
|
285
284
|
* Rewind tracked files to their state at a user message (the CLI's
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/client.ts","../src/core/session.ts","../src/core/agentSession.ts","../src/core/parity.ts","../src/core/permission.ts"],"sourcesContent":["/**\n * `Yagami` — the zero-config library client. `new Yagami()` needs no URL and\n * no API key: it finds the coding-agent CLIs already installed and signed in\n * on this machine (the same T3-Code trick the server does) and mirrors the\n * Anthropic and OpenAI SDK surfaces on top of them, so an app written\n * against either SDK shape drops in with nothing to configure.\n *\n * By default it also reads the host's yagami config\n * (~/.config/yagami/config.json), so an embedded client and the `yagami`\n * binary on the same machine agree on providers, paths, and defaults.\n */\n\nimport { YagamiEngine, type EngineOptions } from \"./engine.js\";\nimport { loadHostEngineConfig } from \"./hostConfig.js\";\nimport { ApiError, type MessagesRequest, type MessagesResponse } from \"./types.js\";\nimport type { EngineModel } from \"./models.js\";\nimport {\n ChatChunkTranslator,\n chatToMessagesRequest,\n modelListBody,\n toChatCompletion,\n type ChatCompletion,\n type ChatCompletionChunk,\n type ChatCompletionsRequest,\n} from \"./openai.js\";\n\nexport interface YagamiOptions extends EngineOptions {\n /**\n * Merge the host machine's yagami config (providers, defaults) under any\n * explicit options, so library and binary stay in sync. Default true;\n * ignored when explicit `providers` instances are passed.\n */\n syncHostConfig?: boolean;\n}\n\n/** An Anthropic stream event's payload (`message_start`, `content_block_delta`, …). */\nexport interface MessageStreamEvent {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface YagamiMessages {\n /** Anthropic-SDK-shaped: non-stream resolves to the message; `stream: true` yields stream events. */\n create(req: MessagesRequest & { stream: true }): AsyncGenerator<MessageStreamEvent, void, undefined>;\n create(req: MessagesRequest & { stream?: false | undefined }): Promise<MessagesResponse>;\n /** Always-streaming variant (the SDK's `messages.stream`). */\n stream(req: MessagesRequest): AsyncGenerator<MessageStreamEvent, void, undefined>;\n}\n\nexport interface YagamiChatCompletions {\n /** OpenAI-SDK-shaped: non-stream resolves to a chat.completion; `stream: true` yields chunks. */\n create(req: ChatCompletionsRequest & { stream: true }): AsyncGenerator<ChatCompletionChunk, void, undefined>;\n create(req: ChatCompletionsRequest & { stream?: false | undefined }): Promise<ChatCompletion>;\n}\n\nexport class Yagami {\n /** The underlying engine, for anything beyond the SDK-shaped surface. */\n readonly engine: YagamiEngine;\n\n constructor(options: YagamiOptions = {}) {\n const { syncHostConfig, ...engineOptions } = options;\n const host = syncHostConfig === false || engineOptions.providers ? {} : loadHostEngineConfig();\n this.engine = new YagamiEngine({ ...host, ...definedProps(engineOptions) });\n }\n\n readonly messages: YagamiMessages = (() => {\n const streamEvents = (req: MessagesRequest) => this.streamMessageEvents(req);\n const complete = async (req: MessagesRequest) => (await this.engine.complete(req)).response;\n function create(req: MessagesRequest & { stream: true }): AsyncGenerator<MessageStreamEvent, void, undefined>;\n function create(req: MessagesRequest & { stream?: false | undefined }): Promise<MessagesResponse>;\n function create(req: MessagesRequest): unknown {\n return req.stream === true ? streamEvents(req) : complete(req);\n }\n return { create, stream: streamEvents };\n })();\n\n readonly chat: { completions: YagamiChatCompletions } = (() => {\n const streamChunks = (req: ChatCompletionsRequest) => this.streamChatChunks(req);\n const complete = async (req: ChatCompletionsRequest) => {\n const { req: translated } = chatToMessagesRequest(req);\n return toChatCompletion((await this.engine.complete(translated)).response);\n };\n function create(req: ChatCompletionsRequest & { stream: true }): AsyncGenerator<ChatCompletionChunk, void, undefined>;\n function create(req: ChatCompletionsRequest & { stream?: false | undefined }): Promise<ChatCompletion>;\n function create(req: ChatCompletionsRequest): unknown {\n return req.stream === true ? streamChunks(req) : complete(req);\n }\n return { completions: { create } };\n })();\n\n readonly models = {\n /** Both SDK shapes at once (Anthropic + OpenAI model-list fields). */\n list: async (): Promise<ReturnType<typeof modelListBody>> => modelListBody(await this.engine.listModels()),\n /** The engine's raw model list. */\n raw: (): Promise<EngineModel[]> => this.engine.listModels(),\n };\n\n private async *streamMessageEvents(req: MessagesRequest): AsyncGenerator<MessageStreamEvent, void, undefined> {\n const { events } = this.engine.stream(req);\n for await (const ev of events) {\n if (ev.event === \"error\") throw errorFromEvent(ev.data);\n yield ev.data as MessageStreamEvent;\n }\n }\n\n private async *streamChatChunks(req: ChatCompletionsRequest): AsyncGenerator<ChatCompletionChunk, void, undefined> {\n const { req: translated, includeUsage } = chatToMessagesRequest({ ...req, stream: true });\n const translator = new ChatChunkTranslator(includeUsage);\n const { events } = this.engine.stream(translated);\n for await (const ev of events) {\n if (ev.event === \"error\") throw errorFromEvent(ev.data);\n for (const chunk of translator.push(ev)) yield chunk as ChatCompletionChunk;\n }\n }\n}\n\nfunction errorFromEvent(data: unknown): ApiError {\n const error = (data as { error?: { type?: string; message?: string } } | undefined)?.error;\n return new ApiError(500, (error?.type as ApiError[\"type\"]) ?? \"api_error\", error?.message ?? \"stream error\");\n}\n\nfunction definedProps<T extends object>(obj: T): Partial<T> {\n return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n","import {\n query,\n type Options,\n type Query,\n type SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { resolveClaudeExecutable } from \"./executable.js\";\n\nexport interface ClaudeSessionOptions {\n /** Path to the `claude` binary. Auto-resolved when omitted. */\n claudePath?: string;\n /** Agent SDK options; merged over yagami's defaults. */\n options?: Options;\n}\n\n/**\n * Full agentic Claude Code session (tools, permissions, plan mode — the\n * works), backed by the user's installed, signed-in CLI. This is the\n * embeddable \"what T3 Code does\" primitive for building UIs on top of\n * Claude Code: unlike the Messages-API engine, nothing is restricted here.\n *\n * Defaults to the `claude_code` system prompt preset so behavior matches the\n * interactive CLI; pass `options.systemPrompt` to override.\n */\nexport function claudeCodeSession(\n prompt: string | AsyncIterable<SDKUserMessage>,\n sessionOptions: ClaudeSessionOptions = {},\n): Query {\n const claudePath = resolveClaudeExecutable(\n sessionOptions.claudePath ?? sessionOptions.options?.pathToClaudeCodeExecutable,\n );\n return query({\n prompt,\n options: {\n systemPrompt: { type: \"preset\", preset: \"claude_code\" },\n ...sessionOptions.options,\n pathToClaudeCodeExecutable: claudePath,\n },\n });\n}\n\nexport type {\n Options as AgentOptions,\n Query,\n RewindFilesResult,\n SDKMessage,\n SDKUserMessage,\n PermissionMode,\n CanUseTool,\n} from \"@anthropic-ai/claude-agent-sdk\";\n","import {\n query,\n type Options,\n type Query,\n type RewindFilesResult,\n type SDKMessage,\n type SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { resolveClaudeExecutable } from \"./executable.js\";\nimport { classifyProviderFailure } from \"./errors.js\";\nimport { settingSourcesFor, type Parity } from \"./parity.js\";\nimport { PermissionAdapter, type PermissionHandler, type PermissionAdapterOptions } from \"./permission.js\";\nimport { AsyncQueue } from \"./providers/queue.js\";\nimport { VERSION } from \"../version.js\";\n\nexport interface AgentSessionOptions {\n /** Path to the `claude` binary. Auto-resolved when omitted. */\n claudePath?: string;\n /** Project directory the agent works in. */\n cwd?: string;\n /** How closely to mirror the interactive terminal (default \"terminal\"). */\n parity?: Parity;\n /** Model id/alias; the CLI default when omitted. */\n model?: string;\n /** Host permission callback (see {@link PermissionAdapter}). */\n onPermission?: PermissionHandler;\n /** Options for the permission adapter (fallback, auto-allow/deny). */\n permission?: PermissionAdapterOptions;\n /** Reported to the CLI as the client application (e.g. your app name). */\n appName?: string;\n /** Extra Agent SDK options, merged last (wins over the above). */\n options?: Options;\n}\n\n/**\n * A long-lived, agentic Claude Code session for building a UI on top of the\n * CLI — the ruri use case. It keeps one warm process across turns (so only\n * the first turn pays cold-start), threads permission decisions to a host\n * callback, mirrors your terminal settings by default, and exposes the\n * lifecycle the interactive CLI gives you for free: send, interrupt, resume,\n * change model/permission mode, close.\n *\n * Everything the model produces is an {@link SDKMessage} you render yourself.\n */\nexport class AgentSession implements AsyncIterable<SDKMessage> {\n readonly permissions: PermissionAdapter;\n private readonly claudePath: string;\n private readonly appName: string;\n private readonly baseOptions: Options;\n private readonly input = new AsyncQueue<SDKUserMessage>();\n private query: Query | undefined;\n private started = false;\n private closed = false;\n private currentSessionId: string | undefined;\n\n constructor(options: AgentSessionOptions = {}) {\n this.claudePath = resolveClaudeExecutable(options.claudePath ?? options.options?.pathToClaudeCodeExecutable);\n this.appName = options.appName ?? \"yagami\";\n this.permissions = new PermissionAdapter(options.permission ?? {});\n if (options.onPermission) this.permissions.setHandler(options.onPermission);\n this.baseOptions = {\n systemPrompt: { type: \"preset\", preset: \"claude_code\" },\n settingSources: settingSourcesFor(options.parity ?? \"terminal\"),\n includePartialMessages: true,\n ...(options.cwd ? { cwd: options.cwd } : {}),\n ...(options.model ? { model: options.model } : {}),\n ...options.options,\n canUseTool: options.options?.canUseTool ?? this.permissions.canUseTool,\n pathToClaudeCodeExecutable: this.claudePath,\n env: {\n ...process.env,\n CLAUDE_AGENT_SDK_CLIENT_APP: `${this.appName}/${VERSION}`,\n ...options.options?.env,\n },\n };\n }\n\n /** Set (or clear) the host permission callback after construction. */\n setPermissionHandler(handler: PermissionHandler | undefined): void {\n this.permissions.setHandler(handler);\n }\n\n /** The live Claude Code session id, once the first turn has started. */\n get sessionId(): string | undefined {\n return this.currentSessionId;\n }\n\n /** Queue a user turn. The process starts on the first send and stays warm. */\n send(text: string, options: { images?: Array<{ data: string; mediaType?: string }> } = {}): void {\n if (this.closed) throw new Error(\"session is closed\");\n const content =\n options.images && options.images.length > 0\n ? [\n ...options.images.map((img) => ({ type: \"image\" as const, source: { type: \"base64\" as const, media_type: img.mediaType ?? \"image/png\", data: img.data } })),\n { type: \"text\" as const, text },\n ]\n : text;\n this.input.push({\n type: \"user\",\n message: { role: \"user\", content } as SDKUserMessage[\"message\"],\n parent_tool_use_id: null,\n session_id: this.currentSessionId ?? \"\",\n } as SDKUserMessage);\n this.ensureStarted();\n }\n\n private ensureStarted(): void {\n if (this.started) return;\n this.started = true;\n this.query = query({ prompt: this.input, options: this.baseOptions });\n }\n\n /** Iterate every SDK message the agent produces across all turns. */\n async *[Symbol.asyncIterator](): AsyncIterator<SDKMessage> {\n this.ensureStarted();\n try {\n for await (const msg of this.query!) {\n if (msg.type === \"system\" && msg.subtype === \"init\") this.currentSessionId = msg.session_id;\n else if (msg.type === \"result\") this.currentSessionId = msg.session_id;\n yield msg;\n }\n } catch (err) {\n throw classifyProviderFailure(\"claude\", \"claude (then /login)\", err);\n }\n }\n\n /** Interrupt the in-flight turn (the CLI's Esc/Ctrl-C). */\n async interrupt(): Promise<void> {\n await this.query?.interrupt();\n }\n\n /** Switch models mid-session (the CLI's /model). */\n async setModel(model: string): Promise<void> {\n await this.query?.setModel(model);\n }\n\n /** Switch permission mode mid-session (default/acceptEdits/plan/bypassPermissions). */\n async setPermissionMode(mode: \"default\" | \"acceptEdits\" | \"plan\" | \"bypassPermissions\"): Promise<void> {\n await this.query?.setPermissionMode(mode);\n }\n\n /** Models the CLI reports as available (for a picker). */\n async supportedModels(): Promise<Array<{ value: string; displayName: string }>> {\n this.ensureStarted();\n const models = await this.query!.supportedModels();\n return models.map((m) => ({ value: m.value, displayName: m.displayName }));\n }\n\n /**\n * Rewind tracked files to their state at a user message (the CLI's\n * /rewind). Needs `enableFileCheckpointing: true` in the session options —\n * without it the CLI answers `canRewind: false`. Pass `dryRun` to preview\n * the change counts without touching the worktree. Starts the process if\n * no turn has run yet (checkpoints ride the resumed session's history).\n */\n async rewindFiles(\n userMessageId: string,\n options?: { dryRun?: boolean },\n ): Promise<RewindFilesResult> {\n if (this.closed) throw new Error(\"session is closed\");\n this.ensureStarted();\n return this.query!.rewindFiles(userMessageId, options);\n }\n\n /** End the session and tear down the process. */\n close(): void {\n if (this.closed) return;\n this.closed = true;\n this.input.end();\n this.query?.close();\n }\n}\n\n/**\n * Convenience: start an {@link AgentSession} and immediately send one turn.\n * Returns the session so callers can iterate it, interrupt, or send more.\n */\nexport function startAgentSession(prompt: string, options: AgentSessionOptions = {}): AgentSession {\n const session = new AgentSession(options);\n session.send(prompt);\n return session;\n}\n","import type { SettingSource } from \"@anthropic-ai/claude-agent-sdk\";\n\n/**\n * How closely an embedded session should mirror the interactive `claude`\n * terminal. This resolves the single most common surprise in library mode:\n * the Agent SDK loads none of your settings by default.\n *\n * - `\"terminal\"` — behave like your CLI: load user + project + local\n * settings, so CLAUDE.md, skills, hooks, and .mcp.json all apply.\n * - `\"isolated\"` — load nothing (the raw SDK default); the app supplies\n * everything explicitly. Best when the session must be reproducible or\n * must not pick up the developer's personal config.\n * - `\"project\"` — load project + local settings but not the user's global\n * ones: shared repo config without personal CLAUDE.md/skills.\n */\nexport type Parity = \"terminal\" | \"project\" | \"isolated\";\n\nconst SETTING_SOURCES: Record<Parity, SettingSource[]> = {\n terminal: [\"user\", \"project\", \"local\"],\n project: [\"project\", \"local\"],\n isolated: [],\n};\n\n/** The `settingSources` a parity level maps to. */\nexport function settingSourcesFor(parity: Parity): SettingSource[] {\n return [...SETTING_SOURCES[parity]];\n}\n","import type {\n CanUseTool,\n PermissionResult,\n PermissionUpdate,\n} from \"@anthropic-ai/claude-agent-sdk\";\n\n/** A tool-use request handed to the host for a decision. */\nexport interface PermissionRequest {\n toolName: string;\n input: Record<string, unknown>;\n signal: AbortSignal;\n /**\n * Suggested permission updates the host can echo back to stop being asked\n * again this session (e.g. behind an \"always allow\" button).\n */\n suggestions?: PermissionUpdate[];\n}\n\n/**\n * The host's answer. `allow` optionally rewrites the tool input and/or\n * persists permission updates for the rest of the session; `deny` carries a\n * message the model sees and can optionally interrupt the turn.\n */\nexport type PermissionDecision =\n | { behavior: \"allow\"; updatedInput?: Record<string, unknown>; updatedPermissions?: PermissionUpdate[] }\n | { behavior: \"deny\"; message?: string; interrupt?: boolean };\n\n/** What the app implements: show UI, return a decision. */\nexport type PermissionHandler = (req: PermissionRequest) => PermissionDecision | Promise<PermissionDecision>;\n\nexport interface PermissionAdapterOptions {\n /**\n * Decision used when no handler is set, a handler throws, or the request is\n * aborted. Defaults to denying — the safe choice for an unattended host.\n */\n fallback?: \"allow\" | \"deny\";\n /** Tool names to auto-allow without ever calling the handler. */\n autoAllow?: Iterable<string>;\n /** Tool names to auto-deny without ever calling the handler. */\n autoDeny?: Iterable<string>;\n}\n\n/**\n * Turns a host-supplied {@link PermissionHandler} into the Agent SDK's\n * {@link CanUseTool} callback, owning the state machine so the app only has\n * to answer one question: allow or deny this tool call?\n *\n * The policy (what to auto-approve) stays with the app — yagami never bakes\n * in a permissive default. Without a handler, everything falls back (deny by\n * default), so a session is safe before the UI is wired up.\n */\nexport class PermissionAdapter {\n private handler: PermissionHandler | undefined;\n private readonly fallback: \"allow\" | \"deny\";\n private readonly autoAllow: Set<string>;\n private readonly autoDeny: Set<string>;\n\n constructor(options: PermissionAdapterOptions = {}) {\n this.fallback = options.fallback ?? \"deny\";\n this.autoAllow = new Set(options.autoAllow ?? []);\n this.autoDeny = new Set(options.autoDeny ?? []);\n }\n\n /** Install (or replace) the host decision callback. */\n setHandler(handler: PermissionHandler | undefined): void {\n this.handler = handler;\n }\n\n allowTool(toolName: string): void {\n this.autoDeny.delete(toolName);\n this.autoAllow.add(toolName);\n }\n\n denyTool(toolName: string): void {\n this.autoAllow.delete(toolName);\n this.autoDeny.add(toolName);\n }\n\n private fallbackResult(reason: string): PermissionResult {\n return this.fallback === \"allow\"\n ? { behavior: \"allow\", updatedInput: {} }\n : { behavior: \"deny\", message: reason };\n }\n\n /**\n * The callback to hand to `claudeCodeSession`/the Agent SDK. Typed to\n * always resolve (never null), and assignable to the SDK's CanUseTool.\n */\n readonly canUseTool: (\n ...args: Parameters<CanUseTool>\n ) => Promise<PermissionResult> = async (toolName, input, options) => {\n if (this.autoDeny.has(toolName)) {\n return { behavior: \"deny\", message: `tool \"${toolName}\" is disabled for this session` };\n }\n if (this.autoAllow.has(toolName)) {\n return { behavior: \"allow\", updatedInput: input };\n }\n if (!this.handler) return this.fallbackResult(`no permission handler is set; denying \"${toolName}\"`);\n if (options.signal.aborted) return this.fallbackResult(\"request aborted\");\n\n let decision: PermissionDecision;\n try {\n decision = await this.handler({\n toolName,\n input,\n signal: options.signal,\n ...(options.suggestions ? { suggestions: options.suggestions } : {}),\n });\n } catch (err) {\n return this.fallbackResult(`permission handler threw: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n if (decision.behavior === \"allow\") {\n return {\n behavior: \"allow\",\n updatedInput: decision.updatedInput ?? input,\n ...(decision.updatedPermissions ? { updatedPermissions: decision.updatedPermissions } : {}),\n };\n }\n return {\n behavior: \"deny\",\n message: decision.message ?? `tool \"${toolName}\" denied by host`,\n ...(decision.interrupt ? { interrupt: true } : {}),\n };\n };\n}\n"],"mappings":"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","names":["query","query"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/client.ts","../src/core/session.ts","../src/core/agentSession.ts","../src/core/parity.ts","../src/core/permission.ts"],"sourcesContent":["/**\n * `Yagami` — the zero-config library client. `new Yagami()` needs no URL and\n * no API key: it finds the coding-agent CLIs already installed and signed in\n * on this machine (the same T3-Code trick the server does) and mirrors the\n * Anthropic and OpenAI SDK surfaces on top of them, so an app written\n * against either SDK shape drops in with nothing to configure.\n *\n * By default it also reads the host's yagami config\n * (~/.config/yagami/config.json), so an embedded client and the `yagami`\n * binary on the same machine agree on providers, paths, and defaults.\n */\n\nimport { YagamiEngine, type EngineOptions } from \"./engine.js\";\nimport { loadHostEngineConfig } from \"./hostConfig.js\";\nimport { ApiError, type MessagesRequest, type MessagesResponse } from \"./types.js\";\nimport type { EngineModel } from \"./models.js\";\nimport {\n ChatChunkTranslator,\n chatToMessagesRequest,\n modelListBody,\n toChatCompletion,\n type ChatCompletion,\n type ChatCompletionChunk,\n type ChatCompletionsRequest,\n} from \"./openai.js\";\n\nexport interface YagamiOptions extends EngineOptions {\n /**\n * Merge the host machine's yagami config (providers, defaults) under any\n * explicit options, so library and binary stay in sync. Default true;\n * ignored when explicit `providers` instances are passed.\n */\n syncHostConfig?: boolean;\n}\n\n/** An Anthropic stream event's payload (`message_start`, `content_block_delta`, …). */\nexport interface MessageStreamEvent {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface YagamiMessages {\n /** Anthropic-SDK-shaped: non-stream resolves to the message; `stream: true` yields stream events. */\n create(req: MessagesRequest & { stream: true }): AsyncGenerator<MessageStreamEvent, void, undefined>;\n create(req: MessagesRequest & { stream?: false | undefined }): Promise<MessagesResponse>;\n /** Always-streaming variant (the SDK's `messages.stream`). */\n stream(req: MessagesRequest): AsyncGenerator<MessageStreamEvent, void, undefined>;\n}\n\nexport interface YagamiChatCompletions {\n /** OpenAI-SDK-shaped: non-stream resolves to a chat.completion; `stream: true` yields chunks. */\n create(req: ChatCompletionsRequest & { stream: true }): AsyncGenerator<ChatCompletionChunk, void, undefined>;\n create(req: ChatCompletionsRequest & { stream?: false | undefined }): Promise<ChatCompletion>;\n}\n\nexport class Yagami {\n /** The underlying engine, for anything beyond the SDK-shaped surface. */\n readonly engine: YagamiEngine;\n\n constructor(options: YagamiOptions = {}) {\n const { syncHostConfig, ...engineOptions } = options;\n const host = syncHostConfig === false || engineOptions.providers ? {} : loadHostEngineConfig();\n this.engine = new YagamiEngine({ ...host, ...definedProps(engineOptions) });\n }\n\n readonly messages: YagamiMessages = (() => {\n const streamEvents = (req: MessagesRequest) => this.streamMessageEvents(req);\n const complete = async (req: MessagesRequest) => (await this.engine.complete(req)).response;\n function create(req: MessagesRequest & { stream: true }): AsyncGenerator<MessageStreamEvent, void, undefined>;\n function create(req: MessagesRequest & { stream?: false | undefined }): Promise<MessagesResponse>;\n function create(req: MessagesRequest): unknown {\n return req.stream === true ? streamEvents(req) : complete(req);\n }\n return { create, stream: streamEvents };\n })();\n\n readonly chat: { completions: YagamiChatCompletions } = (() => {\n const streamChunks = (req: ChatCompletionsRequest) => this.streamChatChunks(req);\n const complete = async (req: ChatCompletionsRequest) => {\n const { req: translated } = chatToMessagesRequest(req);\n return toChatCompletion((await this.engine.complete(translated)).response);\n };\n function create(req: ChatCompletionsRequest & { stream: true }): AsyncGenerator<ChatCompletionChunk, void, undefined>;\n function create(req: ChatCompletionsRequest & { stream?: false | undefined }): Promise<ChatCompletion>;\n function create(req: ChatCompletionsRequest): unknown {\n return req.stream === true ? streamChunks(req) : complete(req);\n }\n return { completions: { create } };\n })();\n\n readonly models = {\n /** Both SDK shapes at once (Anthropic + OpenAI model-list fields). */\n list: async (): Promise<ReturnType<typeof modelListBody>> => modelListBody(await this.engine.listModels()),\n /** The engine's raw model list. */\n raw: (): Promise<EngineModel[]> => this.engine.listModels(),\n };\n\n private async *streamMessageEvents(req: MessagesRequest): AsyncGenerator<MessageStreamEvent, void, undefined> {\n const { events } = this.engine.stream(req);\n for await (const ev of events) {\n if (ev.event === \"error\") throw errorFromEvent(ev.data);\n yield ev.data as MessageStreamEvent;\n }\n }\n\n private async *streamChatChunks(req: ChatCompletionsRequest): AsyncGenerator<ChatCompletionChunk, void, undefined> {\n const { req: translated, includeUsage } = chatToMessagesRequest({ ...req, stream: true });\n const translator = new ChatChunkTranslator(includeUsage);\n const { events } = this.engine.stream(translated);\n for await (const ev of events) {\n if (ev.event === \"error\") throw errorFromEvent(ev.data);\n for (const chunk of translator.push(ev)) yield chunk as ChatCompletionChunk;\n }\n }\n}\n\nfunction errorFromEvent(data: unknown): ApiError {\n const error = (data as { error?: { type?: string; message?: string } } | undefined)?.error;\n return new ApiError(500, (error?.type as ApiError[\"type\"]) ?? \"api_error\", error?.message ?? \"stream error\");\n}\n\nfunction definedProps<T extends object>(obj: T): Partial<T> {\n return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n","import {\n query,\n type Options,\n type Query,\n type SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { resolveClaudeExecutable } from \"./executable.js\";\n\nexport interface ClaudeSessionOptions {\n /** Path to the `claude` binary. Auto-resolved when omitted. */\n claudePath?: string;\n /** Agent SDK options; merged over yagami's defaults. */\n options?: Options;\n}\n\n/**\n * Full agentic Claude Code session (tools, permissions, plan mode — the\n * works), backed by the user's installed, signed-in CLI. This is the\n * embeddable \"what T3 Code does\" primitive for building UIs on top of\n * Claude Code: unlike the Messages-API engine, nothing is restricted here.\n *\n * Defaults to the `claude_code` system prompt preset so behavior matches the\n * interactive CLI; pass `options.systemPrompt` to override.\n */\nexport function claudeCodeSession(\n prompt: string | AsyncIterable<SDKUserMessage>,\n sessionOptions: ClaudeSessionOptions = {},\n): Query {\n const claudePath = resolveClaudeExecutable(\n sessionOptions.claudePath ?? sessionOptions.options?.pathToClaudeCodeExecutable,\n );\n return query({\n prompt,\n options: {\n systemPrompt: { type: \"preset\", preset: \"claude_code\" },\n ...sessionOptions.options,\n pathToClaudeCodeExecutable: claudePath,\n },\n });\n}\n\nexport type {\n Options as AgentOptions,\n Query,\n RewindFilesResult,\n SDKMessage,\n SDKUserMessage,\n PermissionMode,\n CanUseTool,\n} from \"@anthropic-ai/claude-agent-sdk\";\n","import {\n query,\n type Options,\n type Query,\n type RewindFilesResult,\n type ModelInfo,\n type SDKMessage,\n type SDKUserMessage,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { resolveClaudeExecutable } from \"./executable.js\";\nimport { classifyProviderFailure } from \"./errors.js\";\nimport { settingSourcesFor, type Parity } from \"./parity.js\";\nimport { PermissionAdapter, type PermissionHandler, type PermissionAdapterOptions } from \"./permission.js\";\nimport { AsyncQueue } from \"./providers/queue.js\";\nimport { VERSION } from \"../version.js\";\n\nexport interface AgentSessionOptions {\n /** Path to the `claude` binary. Auto-resolved when omitted. */\n claudePath?: string;\n /** Project directory the agent works in. */\n cwd?: string;\n /** How closely to mirror the interactive terminal (default \"terminal\"). */\n parity?: Parity;\n /** Model id/alias; the CLI default when omitted. */\n model?: string;\n /** Host permission callback (see {@link PermissionAdapter}). */\n onPermission?: PermissionHandler;\n /** Options for the permission adapter (fallback, auto-allow/deny). */\n permission?: PermissionAdapterOptions;\n /** Reported to the CLI as the client application (e.g. your app name). */\n appName?: string;\n /** Extra Agent SDK options, merged last (wins over the above). */\n options?: Options;\n}\n\n/**\n * A long-lived, agentic Claude Code session for building a UI on top of the\n * CLI — the ruri use case. It keeps one warm process across turns (so only\n * the first turn pays cold-start), threads permission decisions to a host\n * callback, mirrors your terminal settings by default, and exposes the\n * lifecycle the interactive CLI gives you for free: send, interrupt, resume,\n * change model/permission mode, close.\n *\n * Everything the model produces is an {@link SDKMessage} you render yourself.\n */\nexport class AgentSession implements AsyncIterable<SDKMessage> {\n readonly permissions: PermissionAdapter;\n private readonly claudePath: string;\n private readonly appName: string;\n private readonly baseOptions: Options;\n private readonly input = new AsyncQueue<SDKUserMessage>();\n private query: Query | undefined;\n private started = false;\n private closed = false;\n private currentSessionId: string | undefined;\n\n constructor(options: AgentSessionOptions = {}) {\n this.claudePath = resolveClaudeExecutable(options.claudePath ?? options.options?.pathToClaudeCodeExecutable);\n this.appName = options.appName ?? \"yagami\";\n this.permissions = new PermissionAdapter(options.permission ?? {});\n if (options.onPermission) this.permissions.setHandler(options.onPermission);\n this.baseOptions = {\n systemPrompt: { type: \"preset\", preset: \"claude_code\" },\n settingSources: settingSourcesFor(options.parity ?? \"terminal\"),\n includePartialMessages: true,\n ...(options.cwd ? { cwd: options.cwd } : {}),\n ...(options.model ? { model: options.model } : {}),\n ...options.options,\n canUseTool: options.options?.canUseTool ?? this.permissions.canUseTool,\n pathToClaudeCodeExecutable: this.claudePath,\n env: {\n ...process.env,\n CLAUDE_AGENT_SDK_CLIENT_APP: `${this.appName}/${VERSION}`,\n ...options.options?.env,\n },\n };\n }\n\n /** Set (or clear) the host permission callback after construction. */\n setPermissionHandler(handler: PermissionHandler | undefined): void {\n this.permissions.setHandler(handler);\n }\n\n /** The live Claude Code session id, once the first turn has started. */\n get sessionId(): string | undefined {\n return this.currentSessionId;\n }\n\n /** Queue a user turn. The process starts on the first send and stays warm. */\n send(text: string, options: { images?: Array<{ data: string; mediaType?: string }> } = {}): void {\n if (this.closed) throw new Error(\"session is closed\");\n const content =\n options.images && options.images.length > 0\n ? [\n ...options.images.map((img) => ({ type: \"image\" as const, source: { type: \"base64\" as const, media_type: img.mediaType ?? \"image/png\", data: img.data } })),\n { type: \"text\" as const, text },\n ]\n : text;\n this.input.push({\n type: \"user\",\n message: { role: \"user\", content } as SDKUserMessage[\"message\"],\n parent_tool_use_id: null,\n session_id: this.currentSessionId ?? \"\",\n } as SDKUserMessage);\n this.ensureStarted();\n }\n\n private ensureStarted(): void {\n if (this.started) return;\n this.started = true;\n this.query = query({ prompt: this.input, options: this.baseOptions });\n }\n\n /** Iterate every SDK message the agent produces across all turns. */\n async *[Symbol.asyncIterator](): AsyncIterator<SDKMessage> {\n this.ensureStarted();\n try {\n for await (const msg of this.query!) {\n if (msg.type === \"system\" && msg.subtype === \"init\") this.currentSessionId = msg.session_id;\n else if (msg.type === \"result\") this.currentSessionId = msg.session_id;\n yield msg;\n }\n } catch (err) {\n throw classifyProviderFailure(\"claude\", \"claude (then /login)\", err);\n }\n }\n\n /** Interrupt the in-flight turn (the CLI's Esc/Ctrl-C). */\n async interrupt(): Promise<void> {\n await this.query?.interrupt();\n }\n\n /** Switch models mid-session (the CLI's /model). */\n async setModel(model: string): Promise<void> {\n await this.query?.setModel(model);\n }\n\n /** Switch permission mode mid-session (default/acceptEdits/plan/bypassPermissions). */\n async setPermissionMode(mode: \"default\" | \"acceptEdits\" | \"plan\" | \"bypassPermissions\"): Promise<void> {\n await this.query?.setPermissionMode(mode);\n }\n\n /** Models the CLI reports as available (for a picker). */\n async supportedModels(): Promise<ModelInfo[]> {\n this.ensureStarted();\n return this.query!.supportedModels();\n }\n\n /**\n * Rewind tracked files to their state at a user message (the CLI's\n * /rewind). Needs `enableFileCheckpointing: true` in the session options —\n * without it the CLI answers `canRewind: false`. Pass `dryRun` to preview\n * the change counts without touching the worktree. Starts the process if\n * no turn has run yet (checkpoints ride the resumed session's history).\n */\n async rewindFiles(\n userMessageId: string,\n options?: { dryRun?: boolean },\n ): Promise<RewindFilesResult> {\n if (this.closed) throw new Error(\"session is closed\");\n this.ensureStarted();\n return this.query!.rewindFiles(userMessageId, options);\n }\n\n /** End the session and tear down the process. */\n close(): void {\n if (this.closed) return;\n this.closed = true;\n this.input.end();\n this.query?.close();\n }\n}\n\n/**\n * Convenience: start an {@link AgentSession} and immediately send one turn.\n * Returns the session so callers can iterate it, interrupt, or send more.\n */\nexport function startAgentSession(prompt: string, options: AgentSessionOptions = {}): AgentSession {\n const session = new AgentSession(options);\n session.send(prompt);\n return session;\n}\n","import type { SettingSource } from \"@anthropic-ai/claude-agent-sdk\";\n\n/**\n * How closely an embedded session should mirror the interactive `claude`\n * terminal. This resolves the single most common surprise in library mode:\n * the Agent SDK loads none of your settings by default.\n *\n * - `\"terminal\"` — behave like your CLI: load user + project + local\n * settings, so CLAUDE.md, skills, hooks, and .mcp.json all apply.\n * - `\"isolated\"` — load nothing (the raw SDK default); the app supplies\n * everything explicitly. Best when the session must be reproducible or\n * must not pick up the developer's personal config.\n * - `\"project\"` — load project + local settings but not the user's global\n * ones: shared repo config without personal CLAUDE.md/skills.\n */\nexport type Parity = \"terminal\" | \"project\" | \"isolated\";\n\nconst SETTING_SOURCES: Record<Parity, SettingSource[]> = {\n terminal: [\"user\", \"project\", \"local\"],\n project: [\"project\", \"local\"],\n isolated: [],\n};\n\n/** The `settingSources` a parity level maps to. */\nexport function settingSourcesFor(parity: Parity): SettingSource[] {\n return [...SETTING_SOURCES[parity]];\n}\n","import type {\n CanUseTool,\n PermissionResult,\n PermissionUpdate,\n} from \"@anthropic-ai/claude-agent-sdk\";\n\n/** A tool-use request handed to the host for a decision. */\nexport interface PermissionRequest {\n toolName: string;\n input: Record<string, unknown>;\n signal: AbortSignal;\n /**\n * Suggested permission updates the host can echo back to stop being asked\n * again this session (e.g. behind an \"always allow\" button).\n */\n suggestions?: PermissionUpdate[];\n}\n\n/**\n * The host's answer. `allow` optionally rewrites the tool input and/or\n * persists permission updates for the rest of the session; `deny` carries a\n * message the model sees and can optionally interrupt the turn.\n */\nexport type PermissionDecision =\n | { behavior: \"allow\"; updatedInput?: Record<string, unknown>; updatedPermissions?: PermissionUpdate[] }\n | { behavior: \"deny\"; message?: string; interrupt?: boolean };\n\n/** What the app implements: show UI, return a decision. */\nexport type PermissionHandler = (req: PermissionRequest) => PermissionDecision | Promise<PermissionDecision>;\n\nexport interface PermissionAdapterOptions {\n /**\n * Decision used when no handler is set, a handler throws, or the request is\n * aborted. Defaults to denying — the safe choice for an unattended host.\n */\n fallback?: \"allow\" | \"deny\";\n /** Tool names to auto-allow without ever calling the handler. */\n autoAllow?: Iterable<string>;\n /** Tool names to auto-deny without ever calling the handler. */\n autoDeny?: Iterable<string>;\n}\n\n/**\n * Turns a host-supplied {@link PermissionHandler} into the Agent SDK's\n * {@link CanUseTool} callback, owning the state machine so the app only has\n * to answer one question: allow or deny this tool call?\n *\n * The policy (what to auto-approve) stays with the app — yagami never bakes\n * in a permissive default. Without a handler, everything falls back (deny by\n * default), so a session is safe before the UI is wired up.\n */\nexport class PermissionAdapter {\n private handler: PermissionHandler | undefined;\n private readonly fallback: \"allow\" | \"deny\";\n private readonly autoAllow: Set<string>;\n private readonly autoDeny: Set<string>;\n\n constructor(options: PermissionAdapterOptions = {}) {\n this.fallback = options.fallback ?? \"deny\";\n this.autoAllow = new Set(options.autoAllow ?? []);\n this.autoDeny = new Set(options.autoDeny ?? []);\n }\n\n /** Install (or replace) the host decision callback. */\n setHandler(handler: PermissionHandler | undefined): void {\n this.handler = handler;\n }\n\n allowTool(toolName: string): void {\n this.autoDeny.delete(toolName);\n this.autoAllow.add(toolName);\n }\n\n denyTool(toolName: string): void {\n this.autoAllow.delete(toolName);\n this.autoDeny.add(toolName);\n }\n\n private fallbackResult(reason: string): PermissionResult {\n return this.fallback === \"allow\"\n ? { behavior: \"allow\", updatedInput: {} }\n : { behavior: \"deny\", message: reason };\n }\n\n /**\n * The callback to hand to `claudeCodeSession`/the Agent SDK. Typed to\n * always resolve (never null), and assignable to the SDK's CanUseTool.\n */\n readonly canUseTool: (\n ...args: Parameters<CanUseTool>\n ) => Promise<PermissionResult> = async (toolName, input, options) => {\n if (this.autoDeny.has(toolName)) {\n return { behavior: \"deny\", message: `tool \"${toolName}\" is disabled for this session` };\n }\n if (this.autoAllow.has(toolName)) {\n return { behavior: \"allow\", updatedInput: input };\n }\n if (!this.handler) return this.fallbackResult(`no permission handler is set; denying \"${toolName}\"`);\n if (options.signal.aborted) return this.fallbackResult(\"request aborted\");\n\n let decision: PermissionDecision;\n try {\n decision = await this.handler({\n toolName,\n input,\n signal: options.signal,\n ...(options.suggestions ? { suggestions: options.suggestions } : {}),\n });\n } catch (err) {\n return this.fallbackResult(`permission handler threw: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n if (decision.behavior === \"allow\") {\n return {\n behavior: \"allow\",\n updatedInput: decision.updatedInput ?? input,\n ...(decision.updatedPermissions ? { updatedPermissions: decision.updatedPermissions } : {}),\n };\n }\n return {\n behavior: \"deny\",\n message: decision.message ?? `tool \"${toolName}\" denied by host`,\n ...(decision.interrupt ? { interrupt: true } : {}),\n };\n };\n}\n"],"mappings":"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","names":["query","query"]}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ServerType } from '@hono/node-server';
|
|
2
|
-
import {
|
|
3
|
-
export {
|
|
2
|
+
import { u as ProviderConfigEntry, M as MessagesRequest, l as CompleteResult, W as StreamOptions, Z as StreamStart, E as EngineModel, Y as YagamiEngine, y as SessionCache } from './hostConfig-CbGD5-lN.js';
|
|
3
|
+
export { a8 as yagamiConfigDir } from './hostConfig-CbGD5-lN.js';
|
|
4
4
|
import { Hono } from 'hono';
|
|
5
5
|
|
|
6
6
|
interface YagamiConfig {
|
package/dist/server.js
CHANGED
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
sessionCachePath,
|
|
14
14
|
startYagami,
|
|
15
15
|
writeServerState
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-UGIJV6FZ.js";
|
|
17
17
|
import {
|
|
18
18
|
yagamiConfigDir
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-EKN223KD.js";
|
|
20
20
|
export {
|
|
21
21
|
clearServerState,
|
|
22
22
|
configFilePath,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justin06lee/yagami",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Self-hosted Anthropic- and OpenAI-compatible API backed by your signed-in coding-agent CLIs, plus a zero-config library for driving them from your own apps — no API keys needed.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|