Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a3fbcb3
refactor: 创建 @anthropic-ai/model-provider 包骨架与类型定义
claude-code-best Apr 13, 2026
670cad6
refactor: 提升 OpenAI 转换器和模型映射到 model-provider 包
claude-code-best Apr 13, 2026
a99375b
refactor: 搬入 Gemini 兼容层到 model-provider 包
claude-code-best Apr 13, 2026
ac0ca4a
refactor: 搬入 errorUtils 并迁移消费者导入到 model-provider
claude-code-best Apr 13, 2026
e458d63
feat: compact 模型降级为 -1 模式(Opus→Sonnet, Sonnet→Haiku)
claude-code-best Apr 14, 2026
befcd2b
docs: 添加 agent-loop 绘图
claude-code-best Apr 14, 2026
67a77ba
Revert "feat: compact 模型降级为 -1 模式(Opus→Sonnet, Sonnet→Haiku)"
claude-code-best Apr 14, 2026
3c9112f
docs: 添加简化版 agent loop
claude-code-best Apr 14, 2026
46593d9
fix: 修复 n 快捷键导致关闭的问题
claude-code-best Apr 14, 2026
a36ab55
fix: 修复 node 下 ws 没打包问题
claude-code-best Apr 14, 2026
e601557
docs: 修复链接
claude-code-best Apr 14, 2026
3c4fa38
test: 添加测试支持
claude-code-best Apr 14, 2026
aa0f868
fix: 修复类型问题(#267) (#271)
claude-code-best Apr 15, 2026
920a7ff
test: 修复类型校验 (#279)
claude-code-best Apr 16, 2026
962ed75
fix(remote-control): harden self-hosted session flows (#278)
solthx Apr 16, 2026
6fb3639
docs: update contributors
claude-code-best Apr 16, 2026
40b5e44
build: 新增 vite 构建流程
claude-code-best Apr 16, 2026
49869ff
feat: 添加环境变量支持以覆盖 max_tokens 设置
claude-code-best Apr 16, 2026
1171f48
feat(langfuse): LLM generation 记录工具定义
claude-code-best Apr 16, 2026
9c1db0e
feat: 添加对 ACP 协议的支持 (#284)
claude-code-best Apr 16, 2026
54e33b3
chore: 1.4.0
claude-code-best Apr 16, 2026
b30a28f
conflict: 解决冲突
claude-code-best Apr 16, 2026
f937828
Merge branch 'refactor/provider'
claude-code-best Apr 16, 2026
05f9260
Merge branch 'main' into refactor/provider
claude-code-best Apr 16, 2026
8cb6c9c
feat: 添加测试覆盖率上报
claude-code-best Apr 16, 2026
ed62439
style: 改名加移动文件夹位置
claude-code-best Apr 16, 2026
1917d52
refactor: 移动测试用例及实现
claude-code-best Apr 16, 2026
2da83c4
test: 修复测试用例完成
claude-code-best Apr 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ jobs:
- name: Type check
run: bunx tsc --noEmit

- name: Test
run: bun test
- name: Test with Coverage
run: bun test --coverage --coverage-reporter=lcov

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}

- name: Build
run: bun run build:vite
11 changes: 11 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions docs/diagrams/agent-loop-simple.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
flowchart TB
START((输入)) --> CTX["Context 管理"]
CTX --> LLM["LLM 流式输出"]
LLM --> TC{tool_use?}

TC --> |是| EXEC["执行工具"]
EXEC --> CTX

TC --> |否| DONE((完成))

classDef proc fill:#eef,stroke:#66c,color:#224
classDef decision fill:#fee,stroke:#c66,color:#422
classDef io fill:#eff,stroke:#6cc,color:#244

class CTX,LLM,EXEC proc
class TC decision
class START,DONE io
40 changes: 40 additions & 0 deletions docs/diagrams/agent-loop.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
flowchart TB
START((输入)) --> CTX["Context 管理"]
CTX --> PRE["Pre-sampling Hook"]
PRE --> LLM["LLM 流式输出"]
LLM --> TC{tool_use?}

TC --> |是| PERM{需权限?}
PERM --> |是| USER["👤 用户审批"]
USER --> |allow| TOOL_PRE
USER --> |deny| DENIED["拒绝"]
PERM --> |否| TOOL_PRE["Pre-tool Hook"]
TOOL_PRE --> EXEC["并发执行工具"]
EXEC --> TOOL_POST["Post-tool Hook"]
TOOL_POST --> CTX
DENIED --> CTX

TC --> |否| POST["Post-sampling Hook"]
POST --> STOP{"Stop Hook"}
STOP --> |不通过| CTX
STOP --> |通过| BUDGET{"Token Budget"}
BUDGET --> |继续| CTX
BUDGET --> |完成| DONE((完成))

subgraph SUB["子 Agent"]
FORK["AgentTool"] --> RECURSE["递归调用"]
end

EXEC -.-> FORK

classDef proc fill:#eef,stroke:#66c,color:#224
classDef decision fill:#fee,stroke:#c66,color:#422
classDef hook fill:#ffe,stroke:#cc6,color:#442
classDef io fill:#eff,stroke:#6cc,color:#244
classDef sub fill:#efe,stroke:#6a6,color:#242

class CTX,LLM,EXEC proc
class TC,PERM,STOP,BUDGET decision
class PRE,TOOL_PRE,TOOL_POST,POST hook
class START,DONE,USER,DENIED io
class FORK,RECURSE sub
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
},
"workspaces": [
"packages/*",
"packages/@ant/*"
"packages/@ant/*",
"packages/@anthropic-ai/*"
],
"files": [
"dist",
Expand Down Expand Up @@ -65,6 +66,7 @@
},
"devDependencies": {
"@alcalzone/ansi-tokenize": "^0.3.0",
"@ant/model-provider": "workspace:*",
"@ant/claude-for-chrome-mcp": "workspace:*",
"@ant/computer-use-input": "workspace:*",
"@ant/computer-use-mcp": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/@ant/claude-for-chrome-mcp/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "../../../tsconfig.json",
"extends": "../../../tsconfig.base.json",
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
2 changes: 1 addition & 1 deletion packages/@ant/computer-use-input/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "../../../tsconfig.json",
"extends": "../../../tsconfig.base.json",
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
2 changes: 1 addition & 1 deletion packages/@ant/computer-use-mcp/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "../../../tsconfig.json",
"extends": "../../../tsconfig.base.json",
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
2 changes: 1 addition & 1 deletion packages/@ant/ink/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "../../../tsconfig.json",
"extends": "../../../tsconfig.base.json",
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": ["node_modules", "dist"]
}
18 changes: 18 additions & 0 deletions packages/@ant/model-provider/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "@ant/model-provider",
"version": "1.0.0",
"private": true,
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts",
"./types": "./src/types/index.ts",
"./hooks": "./src/hooks/index.ts",
"./client": "./src/client/index.ts"
},
"dependencies": {
"@anthropic-ai/sdk": "^0.80.0",
"openai": "^6.33.0"
}
}
27 changes: 27 additions & 0 deletions packages/@ant/model-provider/src/client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { ClientFactories } from './types.js'

let registeredFactories: ClientFactories | null = null

/**
* Register client factories from the main project.
* Call this during application initialization.
*/
export function registerClientFactories(factories: ClientFactories): void {
registeredFactories = factories
}

/**
* Get registered client factories.
* Throws if not registered (fail-fast).
*/
export function getClientFactories(): ClientFactories {
if (!registeredFactories) {
throw new Error(
'Client factories not registered. ' +
'Call registerClientFactories() during app initialization.',
)
}
return registeredFactories
}

export type { ClientFactories }
35 changes: 35 additions & 0 deletions packages/@ant/model-provider/src/client/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Client factory interfaces.
* Authentication is handled externally — main project provides factory implementations.
*/
export interface ClientFactories {
/** Get Anthropic client (1st party, Bedrock, Foundry, Vertex) */
getAnthropicClient: (params: {
model?: string
maxRetries: number
fetchOverride?: unknown
source?: string
}) => Promise<unknown>

/** Get OpenAI-compatible client */
getOpenAIClient: (params: {
maxRetries: number
fetchOverride?: unknown
source?: string
}) => unknown

/** Stream Gemini generate content */
streamGeminiGenerateContent: (params: {
model: string
signal?: AbortSignal
fetchOverride?: unknown
body: Record<string, unknown>
}) => AsyncIterable<unknown>

/** Get Grok client (OpenAI-compatible) */
getGrokClient: (params: {
maxRetries: number
fetchOverride?: unknown
source?: string
}) => unknown
}
Loading
Loading