subrouter-cli 0.0.0-stage → 0.1.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/CLAUDE.md +51 -0
- package/README.md +397 -2
- package/config.example.json +9 -0
- package/package.json +21 -4
- package/scripts/sse-harness.ts +252 -0
- package/scripts/sub-wrapper.sh +11 -0
- package/src/adapters/anthropic.ts +311 -0
- package/src/adapters/openai.ts +227 -0
- package/src/approval.ts +21 -0
- package/src/chatviewport.ts +123 -0
- package/src/client.ts +398 -0
- package/src/clipboard.ts +62 -0
- package/src/commandpolicy.ts +272 -0
- package/src/commands.ts +18 -0
- package/src/config.ts +107 -0
- package/src/effort.ts +18 -0
- package/src/images.ts +77 -0
- package/src/index.ts +248 -0
- package/src/lineinput.ts +726 -0
- package/src/loop.ts +201 -0
- package/src/markdown.ts +244 -0
- package/src/repl.ts +700 -0
- package/src/sessions.ts +58 -0
- package/src/sse.ts +64 -0
- package/src/terminal.ts +228 -0
- package/src/token.ts +36 -0
- package/src/toolpreview.ts +54 -0
- package/src/tools.ts +790 -0
- package/src/types.ts +73 -0
- package/src/ui.ts +813 -0
- package/src/usage.ts +186 -0
- package/test/absolute-tools.test.ts +296 -0
- package/test/absolute-ui.test.ts +153 -0
- package/test/adapters.test.ts +205 -0
- package/test/anthropic.test.ts +246 -0
- package/test/auto-ui.test.ts +106 -0
- package/test/chatviewport.test.ts +49 -0
- package/test/client.test.ts +327 -0
- package/test/clipboard.test.ts +63 -0
- package/test/command-input.test.ts +183 -0
- package/test/command-tools.test.ts +141 -0
- package/test/commandpolicy.test.ts +252 -0
- package/test/disk-tools.test.ts +220 -0
- package/test/effort.test.ts +123 -0
- package/test/fixtures/openai-tools.sse +84 -0
- package/test/image-adapters.test.ts +78 -0
- package/test/image-ui.test.ts +151 -0
- package/test/images.test.ts +60 -0
- package/test/loop.test.ts +387 -0
- package/test/m5.test.ts +127 -0
- package/test/markdown.test.ts +201 -0
- package/test/repl-ui.test.ts +293 -0
- package/test/sse.test.ts +74 -0
- package/test/steering-ui.test.ts +182 -0
- package/test/steering.test.ts +68 -0
- package/test/terminal-ui.test.ts +144 -0
- package/test/terminal.test.ts +229 -0
- package/test/toolpreview.test.ts +51 -0
- package/test/tools.test.ts +227 -0
- package/test/ui.test.ts +635 -0
- package/test/usage-footer.test.ts +180 -0
- package/tsconfig.json +17 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Shared normalized types — everything above the adapters speaks these.
|
|
2
|
+
// Only the adapters in src/adapters/ know wire shapes.
|
|
3
|
+
|
|
4
|
+
import type { EffortLevel } from './effort.ts';
|
|
5
|
+
import type { ImageAttachment } from './images.ts';
|
|
6
|
+
|
|
7
|
+
export type Dialect = 'openai' | 'anthropic';
|
|
8
|
+
export type AnthropicThinkingBlock =
|
|
9
|
+
| { type: 'thinking'; thinking: string; signature: string }
|
|
10
|
+
| { type: 'redacted_thinking'; data: string };
|
|
11
|
+
export type Role = 'system' | 'user' | 'assistant' | 'tool';
|
|
12
|
+
|
|
13
|
+
export interface ToolCall {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
/** Parsed arguments; {} plus argumentsInvalid on malformed JSON. */
|
|
17
|
+
arguments: Record<string, unknown>;
|
|
18
|
+
/** Raw JSON string as received from the wire, for faithful echo-back. */
|
|
19
|
+
argumentsJson: string;
|
|
20
|
+
argumentsInvalid?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ChatMessage {
|
|
24
|
+
role: Role;
|
|
25
|
+
content: string;
|
|
26
|
+
images?: ImageAttachment[]; // explicit user attachments; output remains text-only
|
|
27
|
+
toolCalls?: ToolCall[]; // assistant only
|
|
28
|
+
thinkingBlocks?: AnthropicThinkingBlock[]; // signed provider blocks, never displayed
|
|
29
|
+
toolCallId?: string; // tool role only
|
|
30
|
+
isError?: boolean; // tool role; maps to is_error on the anthropic wire
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ToolDefinition {
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
parameters: Record<string, unknown>; // JSON Schema object
|
|
37
|
+
requiresApproval: boolean;
|
|
38
|
+
approvalScope?: 'always'; // per-call authorization, never covered by file approve-all
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type StopReason = 'stop' | 'tool_calls' | 'length' | 'refusal' | 'unknown';
|
|
42
|
+
|
|
43
|
+
export interface TokenUsage {
|
|
44
|
+
inputTokens: number;
|
|
45
|
+
outputTokens: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// One wire chunk, dialect-agnostic and order-preserving.
|
|
49
|
+
// 'reasoning' carries thinking/reasoning deltas (openai reasoning_content, anthropic
|
|
50
|
+
// thinking_delta) — kept separate from answers and hidden by the REPL.
|
|
51
|
+
export type StreamEvent =
|
|
52
|
+
| { kind: 'text'; text: string }
|
|
53
|
+
| { kind: 'reasoning'; text: string }
|
|
54
|
+
| { kind: 'tool_call_start'; index: number; id: string; name: string }
|
|
55
|
+
| { kind: 'tool_call_args'; index: number; delta: string }
|
|
56
|
+
| { kind: 'stop'; stopReason: StopReason; usage?: TokenUsage };
|
|
57
|
+
|
|
58
|
+
export interface AssistantTurn {
|
|
59
|
+
message: ChatMessage;
|
|
60
|
+
stopReason: StopReason;
|
|
61
|
+
usage?: TokenUsage;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface ChatRequest {
|
|
65
|
+
model: string;
|
|
66
|
+
dialect: Dialect;
|
|
67
|
+
messages: ChatMessage[]; // full conversation, excluding the system prompt
|
|
68
|
+
system: string;
|
|
69
|
+
tools?: ToolDefinition[];
|
|
70
|
+
stream: boolean;
|
|
71
|
+
maxTokens?: number;
|
|
72
|
+
effort?: EffortLevel;
|
|
73
|
+
}
|