Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ Brief description of changes.

- [ ] Tests pass locally
- [ ] PoW solvers tested (C + JS)
- [ ] Live tests if applicable

## Checklist

Expand Down
30 changes: 0 additions & 30 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,36 +48,6 @@ jobs:
- name: Run tests
run: python tests.py -j 2

live-test:
needs: test
runs-on: ubuntu-latest
timeout-minutes: 30
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v7

- uses: actions/setup-python@v7
with:
python-version: "3.12"
cache: pip
cache-dependency-path: requirements-dev.txt

- name: Install system tools
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends clang nodejs

- name: Install dependencies
run: pip install -r requirements-dev.txt

- name: Build native PoW solver
run: clang -O3 -pthread -funroll-loops -flto -march=native -mtune=native -o danyapi/deepseek/pow_solver danyapi/deepseek/pow_solver.c

- name: Run live tests
env:
DEEPSEEK_TOKENS: ${{ secrets.DEEPSEEK_TOKENS }}
run: python -m pytest tests/test_live.py -v

docker-build:
needs: test
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions danyapi/api/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,8 @@ async def list_models() -> dict:
}
)
qwen_models: list[dict] = getattr(app.state, "qwen_models", [])
if not qwen_models and _byok_mode():
qwen_models = QWEN_DEFAULT_MODELS
for model in qwen_models:
models.append(
{
Expand Down
3 changes: 0 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ select = ["B", "C4", "E", "F", "FURB", "I", "PLW", "RUF", "UP"]
testpaths = ["tests"]
asyncio_mode = "auto"
filterwarnings = ["ignore:Using `httpx` with `starlette.testclient` is deprecated.*"]
markers = [
"live: tests that hit the real DeepSeek API (requires DEEPSEEK_TOKENS env var)",
]

[tool.mypy]
python_version = "3.12"
Expand Down
12 changes: 12 additions & 0 deletions tests/test_byok.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,18 @@ def test_health_reports_byok_mode():
assert payload["byok_pools"]["qwen"] == 0


def test_list_models_byok_without_env_tokens_lists_qwen_defaults():
app.state.byok = True
app.state.qwen_models = []
client = TestClient(app)
data = client.get("/v1/models").json()
client.close()
ids = [m["id"] for m in data["data"]]
assert "deepseek-v4.1-flash" in ids
for model in openai_mod.QWEN_DEFAULT_MODELS:
assert model["id"] in ids


def test_health_no_byok_key_when_disabled():
app.state.byok = False
client = TestClient(app)
Expand Down
127 changes: 0 additions & 127 deletions tests/test_live.py

This file was deleted.

56 changes: 39 additions & 17 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -530,29 +530,33 @@
</svg>
<span class="brand-name">Dany<span class="brand-accent">API</span></span>
</a>
<h1><span class="grad-text">Token Manager</span></h1>
<p>Support the project add your free provider tokens</p>
<div id="token-heading">
<h1><span class="grad-text">Token Manager</span></h1>
<p>Support the project add your free provider tokens</p>
</div>
</div>

<div class="form-group">
<label for="deepseek-tokens">DeepSeek Tokens</label>
<input type="text" id="deepseek-tokens"
placeholder="token1, token2, token3..." value="" autocomplete="off" spellcheck="false" />
</div>
<section class="token-manager" id="token-manager">
<div class="form-group">
<label for="deepseek-tokens">DeepSeek Tokens</label>
<input type="text" id="deepseek-tokens"
placeholder="token1, token2, token3..." value="" autocomplete="off" spellcheck="false" />
</div>

<div class="form-group">
<label for="qwen-tokens">Qwen Tokens</label>
<input type="text" id="qwen-tokens"
placeholder="token1, token2, token3..." value="" autocomplete="off" spellcheck="false" />
</div>
<div class="form-group">
<label for="qwen-tokens">Qwen Tokens</label>
<input type="text" id="qwen-tokens"
placeholder="token1, token2, token3..." value="" autocomplete="off" spellcheck="false" />
</div>

<div class="info-box">
<strong>No limits.</strong> Tokens are used server-side. Your consumers just point their OpenAI client at this instance no keys needed on their side. Each token adds parallel generation capacity.
</div>
<div class="info-box">
<strong>No limits.</strong> Tokens are used server-side. Your consumers just point their OpenAI client at this instance no keys needed on their side. Each token adds parallel generation capacity.
</div>

<div id="status" class="status"></div>
<div id="status" class="status"></div>

<button class="btn btn-primary" type="button" id="btn-save">Add Tokens</button>
<button class="btn btn-primary" type="button" id="btn-save">Add Tokens</button>
</section>

<div class="usage-section">
<h2 class="usage-title">Usage</h2>
Expand Down Expand Up @@ -617,6 +621,24 @@ <h2 class="usage-title">Usage</h2>
});
}

function initMode() {
fetch(BASE + "/health")
.then(function (r) {
if (!r.ok) throw new Error("HTTP " + r.status);
return r.json();
})
.then(function (data) {
if (data.byok) {
var heading = document.getElementById("token-heading");
if (heading) heading.style.display = "none";
var manager = document.getElementById("token-manager");
if (manager) manager.style.display = "none";
}
})
.catch(function () {});
}

initMode();
loadUsage();

function showStatus(msg, type) {
Expand Down
Loading