coderouter-cli 2.13.0__py3-none-any.whl → 2.15.0__py3-none-any.whl
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.
- coderouter/adapters/anthropic_native.py +110 -3
- coderouter/adapters/base.py +65 -0
- coderouter/adapters/openai_compat.py +65 -2
- coderouter/cli.py +140 -2
- coderouter/config/loader.py +24 -1
- coderouter/config/schemas.py +209 -0
- coderouter/credentials.py +332 -0
- coderouter/doctor_apply.py +54 -9
- coderouter/ingress/anthropic_routes.py +82 -12
- coderouter/ingress/dashboard_routes.py +24 -4
- coderouter/ingress/metrics_routes.py +13 -2
- coderouter/ingress/openai_routes.py +31 -2
- coderouter/ingress/ui_auth.py +94 -0
- coderouter/logging.py +150 -0
- coderouter/metrics/collector.py +40 -0
- coderouter/metrics/prometheus.py +46 -0
- coderouter/rollback.py +217 -0
- coderouter/routing/__init__.py +8 -0
- coderouter/routing/fallback.py +304 -4
- coderouter/routing/fallback_trace.py +501 -0
- coderouter/secret_redaction.py +606 -0
- coderouter/state/audit_log.py +10 -0
- coderouter/state/request_log.py +6 -0
- coderouter/vscode_init.py +166 -23
- {coderouter_cli-2.13.0.dist-info → coderouter_cli-2.15.0.dist-info}/METADATA +2 -2
- {coderouter_cli-2.13.0.dist-info → coderouter_cli-2.15.0.dist-info}/RECORD +29 -24
- {coderouter_cli-2.13.0.dist-info → coderouter_cli-2.15.0.dist-info}/WHEEL +1 -1
- {coderouter_cli-2.13.0.dist-info → coderouter_cli-2.15.0.dist-info}/entry_points.txt +0 -0
- {coderouter_cli-2.13.0.dist-info → coderouter_cli-2.15.0.dist-info}/licenses/LICENSE +0 -0
coderouter/vscode_init.py
CHANGED
|
@@ -24,9 +24,16 @@ The design contract:
|
|
|
24
24
|
until a human debugged it.
|
|
25
25
|
* Nothing an operator wrote is destroyed without a copy: before any
|
|
26
26
|
existing file is rewritten, its previous bytes (and mode) land in
|
|
27
|
-
``<name>.bak
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
``<name>.bak``, which ``coderouter rollback`` can swap back.
|
|
28
|
+
* Since v2.14.0, ``.envrc`` is edited through a marker-delimited block
|
|
29
|
+
(``# BEGIN coderouter-managed`` … ``# END coderouter-managed``): only
|
|
30
|
+
that block is rewritten and every other line survives byte-for-byte.
|
|
31
|
+
A re-run over an already-fenced file therefore needs no ``--force``;
|
|
32
|
+
``--force`` now means "adopt a file I did not write". Before v2.14.0
|
|
33
|
+
this was a whole-file replace, which is how the lost
|
|
34
|
+
``source_env_if_exists .envrc.local`` line (H-11) happened — see the
|
|
35
|
+
"marker-delimited managed block in .envrc" section below for the full
|
|
36
|
+
rationale and the conflict rules.
|
|
30
37
|
* A freshly generated ``.envrc`` is created 0600 — it carries
|
|
31
38
|
``ANTHROPIC_AUTH_TOKEN`` and sits next to the operator's real
|
|
32
39
|
secrets. An existing file's mode is preserved across rewrites
|
|
@@ -395,7 +402,19 @@ def _apply_envrc(
|
|
|
395
402
|
force: bool,
|
|
396
403
|
dry_run: bool,
|
|
397
404
|
) -> FileOutcome:
|
|
398
|
-
|
|
405
|
+
"""Write (or refresh) the managed block in ``.envrc``.
|
|
406
|
+
|
|
407
|
+
Three cases, and only the third can refuse:
|
|
408
|
+
|
|
409
|
+
* **No file** — create it with the fenced block.
|
|
410
|
+
* **Fenced file** — replace the block, keep everything outside it
|
|
411
|
+
byte-for-byte. No ``--force`` needed; this is not destructive.
|
|
412
|
+
* **Unfenced file we did not write** — refuse, unless ``--force``,
|
|
413
|
+
which now *appends* the block rather than replacing the file. The
|
|
414
|
+
operator's lines survive either way.
|
|
415
|
+
"""
|
|
416
|
+
block = _render_envrc_block(base_url=base_url, profile=profile)
|
|
417
|
+
|
|
399
418
|
old_text = ""
|
|
400
419
|
if path.exists():
|
|
401
420
|
try:
|
|
@@ -407,32 +426,76 @@ def _apply_envrc(
|
|
|
407
426
|
reason=f"cannot read existing file: {exc}",
|
|
408
427
|
)
|
|
409
428
|
|
|
429
|
+
if not old_text:
|
|
430
|
+
new_text = block + "\n"
|
|
431
|
+
else:
|
|
432
|
+
split = _split_managed_block(old_text)
|
|
433
|
+
if split is None and _looks_like_our_legacy_output(
|
|
434
|
+
old_text, base_url=base_url, profile=profile
|
|
435
|
+
):
|
|
436
|
+
# Our own pre-v2.14.0 output: adopt it into the fence silently.
|
|
437
|
+
split = ("", "")
|
|
438
|
+
if split is None:
|
|
439
|
+
outside = "" # --force adopts the file wholesale; see below
|
|
440
|
+
if not force:
|
|
441
|
+
would = old_text.rstrip("\n") + "\n\n" + block + "\n"
|
|
442
|
+
return FileOutcome(
|
|
443
|
+
path=path,
|
|
444
|
+
action="conflict",
|
|
445
|
+
diff=_text_diff(old_text, would, path),
|
|
446
|
+
reason=(
|
|
447
|
+
".envrc exists and carries no "
|
|
448
|
+
f"`{_ENVRC_BEGIN}` fence, so CodeRouter did not write it. "
|
|
449
|
+
"Re-run with --force to APPEND the managed block "
|
|
450
|
+
"(your existing lines are kept — unlike before "
|
|
451
|
+
"v2.14.0, --force no longer replaces the whole file); "
|
|
452
|
+
f"the previous contents are still saved to "
|
|
453
|
+
f"{_backup_path(path).name}."
|
|
454
|
+
),
|
|
455
|
+
)
|
|
456
|
+
# --force on an unfenced file means "adopt it, mine wins". The
|
|
457
|
+
# block is APPENDED, not substituted for the file: direnv applies
|
|
458
|
+
# exports in order, so a duplicate the operator already had is
|
|
459
|
+
# shadowed rather than deleted, and their other lines survive. The
|
|
460
|
+
# conflict scan is skipped here on purpose — refusing would leave
|
|
461
|
+
# --force with nothing it could actually do.
|
|
462
|
+
new_text = old_text.rstrip("\n") + "\n\n" + block + "\n"
|
|
463
|
+
else:
|
|
464
|
+
before, after = split
|
|
465
|
+
outside = before + after
|
|
466
|
+
new_text = (
|
|
467
|
+
before.rstrip("\n") + ("\n\n" if before.strip() else "")
|
|
468
|
+
) + block + ("\n\n" + after.lstrip("\n") if after.strip() else "\n")
|
|
469
|
+
|
|
470
|
+
conflicts = _unmanaged_conflicts(outside)
|
|
471
|
+
if conflicts:
|
|
472
|
+
# direnv applies exports in order, so a duplicate outside the
|
|
473
|
+
# fence would silently win or lose depending on placement.
|
|
474
|
+
# Refusing is the only answer that cannot surprise anyone.
|
|
475
|
+
return FileOutcome(
|
|
476
|
+
path=path,
|
|
477
|
+
action="conflict",
|
|
478
|
+
diff=_text_diff(old_text, new_text, path),
|
|
479
|
+
reason=(
|
|
480
|
+
"these variables are already exported outside the managed "
|
|
481
|
+
f"block: {', '.join(conflicts)}. CodeRouter will not write "
|
|
482
|
+
"a second export for a value you own — direnv would apply "
|
|
483
|
+
"whichever comes last. Remove your line, or move it inside "
|
|
484
|
+
f"`{_ENVRC_BEGIN}` … `{_ENVRC_END}`."
|
|
485
|
+
),
|
|
486
|
+
)
|
|
487
|
+
|
|
410
488
|
if new_text == old_text:
|
|
411
489
|
return FileOutcome(path=path, action="unchanged")
|
|
412
490
|
|
|
413
491
|
diff = _text_diff(old_text, new_text, path)
|
|
414
492
|
|
|
415
|
-
if old_text and not force:
|
|
416
|
-
return FileOutcome(
|
|
417
|
-
path=path,
|
|
418
|
-
action="conflict",
|
|
419
|
-
diff=diff,
|
|
420
|
-
reason=(
|
|
421
|
-
".envrc already exists and its contents differ. "
|
|
422
|
-
"Re-run with --force to replace the WHOLE file with the "
|
|
423
|
-
"generated contents (this is not a merge — custom lines "
|
|
424
|
-
"such as `source_env_if_exists .envrc.local` are dropped); "
|
|
425
|
-
f"the previous contents are saved to {_backup_path(path).name}. "
|
|
426
|
-
"(Tip: keep secrets in a separate .envrc.local and "
|
|
427
|
-
"``source_env_if_exists`` from .envrc.)"
|
|
428
|
-
),
|
|
429
|
-
)
|
|
430
|
-
|
|
431
493
|
reason = ""
|
|
432
494
|
if not dry_run:
|
|
433
|
-
# H-11:
|
|
434
|
-
#
|
|
435
|
-
# on purpose — --dry-run must not
|
|
495
|
+
# H-11: keep the old bytes (mode included) even though the write is
|
|
496
|
+
# now surgical. A bug in the fence logic would take exactly this
|
|
497
|
+
# path. Inside the dry_run guard on purpose — --dry-run must not
|
|
498
|
+
# touch the filesystem at all.
|
|
436
499
|
if old_text:
|
|
437
500
|
backup = _make_backup(path)
|
|
438
501
|
reason = (
|
|
@@ -463,6 +526,86 @@ def _apply_envrc(
|
|
|
463
526
|
)
|
|
464
527
|
|
|
465
528
|
|
|
529
|
+
# ---------------------------------------------------------------------------
|
|
530
|
+
# v2.14.0 — marker-delimited managed block in .envrc
|
|
531
|
+
# ---------------------------------------------------------------------------
|
|
532
|
+
#
|
|
533
|
+
# Until now, ``--force`` on ``.envrc`` was a whole-file replace: it wrote the
|
|
534
|
+
# generated contents over whatever was there, dropping any line the operator
|
|
535
|
+
# had added. That is how H-11 happened, and "we back it up first" only helps
|
|
536
|
+
# somebody who knows to look for the backup.
|
|
537
|
+
#
|
|
538
|
+
# The fix is the one codex-router uses on ``~/.codex/config.toml``: fence the
|
|
539
|
+
# part we own between markers, rewrite only that, and leave everything else
|
|
540
|
+
# byte-for-byte. Once the fence exists, a re-run is no longer destructive, so
|
|
541
|
+
# it needs no ``--force`` at all — ``--force`` shrinks back to its honest
|
|
542
|
+
# meaning of "yes, adopt a file I did not write".
|
|
543
|
+
|
|
544
|
+
_ENVRC_BEGIN = "# BEGIN coderouter-managed"
|
|
545
|
+
_ENVRC_END = "# END coderouter-managed"
|
|
546
|
+
|
|
547
|
+
# The variables the managed block owns. A value for one of these sitting
|
|
548
|
+
# OUTSIDE the block is a conflict we refuse rather than silently shadow —
|
|
549
|
+
# direnv applies exports in order, so whichever came last would win and the
|
|
550
|
+
# operator would have no idea which one is live.
|
|
551
|
+
_MANAGED_ENVRC_VARS = ("ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN", "CODEROUTER_MODE")
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
def _split_managed_block(text: str) -> tuple[str, str] | None:
|
|
555
|
+
"""Split ``text`` around the managed block.
|
|
556
|
+
|
|
557
|
+
Returns ``(before, after)`` with the block (and its markers) removed,
|
|
558
|
+
or ``None`` when the file carries no fence. A file with a begin marker
|
|
559
|
+
and no end marker also returns ``None`` — a half-written fence is not
|
|
560
|
+
something to guess at, and the caller turns that into a refusal.
|
|
561
|
+
"""
|
|
562
|
+
start = text.find(_ENVRC_BEGIN)
|
|
563
|
+
if start == -1:
|
|
564
|
+
return None
|
|
565
|
+
end = text.find(_ENVRC_END, start)
|
|
566
|
+
if end == -1:
|
|
567
|
+
return None
|
|
568
|
+
return text[:start], text[end + len(_ENVRC_END) :].lstrip("\n")
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
def _render_envrc_block(*, base_url: str, profile: str | None) -> str:
|
|
572
|
+
"""The fenced block CodeRouter owns, markers included."""
|
|
573
|
+
lines = [
|
|
574
|
+
_ENVRC_BEGIN,
|
|
575
|
+
"# Managed by `coderouter vscode-init`. Edits inside this block are",
|
|
576
|
+
"# overwritten on the next run; put your own lines outside it.",
|
|
577
|
+
f'export ANTHROPIC_BASE_URL="{base_url}"',
|
|
578
|
+
f'export ANTHROPIC_AUTH_TOKEN="{DEFAULT_TOKEN}"',
|
|
579
|
+
]
|
|
580
|
+
if profile:
|
|
581
|
+
lines.append(f'export CODEROUTER_MODE="{profile}"')
|
|
582
|
+
lines.append(_ENVRC_END)
|
|
583
|
+
return "\n".join(lines)
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
def _unmanaged_conflicts(outside_text: str) -> list[str]:
|
|
587
|
+
"""Managed variables the operator exports outside our block."""
|
|
588
|
+
found: list[str] = []
|
|
589
|
+
for line in outside_text.splitlines():
|
|
590
|
+
stripped = line.strip()
|
|
591
|
+
if stripped.startswith("#"):
|
|
592
|
+
continue
|
|
593
|
+
for var in _MANAGED_ENVRC_VARS:
|
|
594
|
+
if stripped.startswith((f"export {var}=", f"{var}=")) and var not in found:
|
|
595
|
+
found.append(var)
|
|
596
|
+
return found
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
def _looks_like_our_legacy_output(text: str, *, base_url: str, profile: str | None) -> bool:
|
|
600
|
+
"""True when the file is byte-identical to a pre-v2.14.0 generation.
|
|
601
|
+
|
|
602
|
+
An operator upgrading has an unfenced ``.envrc`` that we wrote — asking
|
|
603
|
+
them to pass ``--force`` to adopt our own previous output would be
|
|
604
|
+
rude, and appending a second block would double the exports.
|
|
605
|
+
"""
|
|
606
|
+
return text == _render_envrc(base_url=base_url, profile=profile)
|
|
607
|
+
|
|
608
|
+
|
|
466
609
|
def _render_envrc(*, base_url: str, profile: str | None) -> str:
|
|
467
610
|
"""Build the .envrc contents. Kept split for test targeting."""
|
|
468
611
|
lines = [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: coderouter-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.15.0
|
|
4
4
|
Summary: Local-first, free-first, fallback-built-in LLM router. Claude Code / OpenAI compatible.
|
|
5
5
|
Project-URL: Homepage, https://github.com/zephel01/CodeRouter
|
|
6
6
|
Project-URL: Repository, https://github.com/zephel01/CodeRouter
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
coderouter/__init__.py,sha256=ghdjPrLtnRzY8fyQ4CJZI1UJKADyNTLtA3G7se8H7Ns,696
|
|
2
2
|
coderouter/__main__.py,sha256=-LCgxJnvgUV240HjQKv7ly-mn2NuKHpC4nCpvTHjeSU,130
|
|
3
|
-
coderouter/cli.py,sha256=
|
|
3
|
+
coderouter/cli.py,sha256=Nbx1ur_HnssFtuM48yPELwhY40veVNnTAfK7OVF2uVc,42400
|
|
4
4
|
coderouter/cli_stats.py,sha256=CCjzc1G4hTRHZ2gG1XhxhDpUkJnnl3NXbcbp1T18jpg,29894
|
|
5
5
|
coderouter/cost.py,sha256=32h6uzb4nxh2eA5d2Hn3kD9yJbtis6CFDAbeIy5KRkM,7431
|
|
6
|
+
coderouter/credentials.py,sha256=R_PdrcA941_jJX_U8hxrjPDTCVVzLd4dsw2c00KwAwE,12991
|
|
6
7
|
coderouter/doctor.py,sha256=wmPunlvqm2s7x3VGLjexqHPLD2oejwE3Mu04V8y-xn4,89869
|
|
7
|
-
coderouter/doctor_apply.py,sha256=
|
|
8
|
+
coderouter/doctor_apply.py,sha256=tZT3bEd1G6t67YRhf1TGY4NlSvZuJJbnEqN-3AKy8Hc,29972
|
|
8
9
|
coderouter/env_security.py,sha256=FEBZnXfJ0xE39kmMMn39zk0W_DRRnmcB_REmP9f4xWo,14796
|
|
9
10
|
coderouter/errors.py,sha256=Xmq67lheyw8iv3Ox39jh2c4tvNI5RcUR4QkoxVDN6l4,1130
|
|
10
11
|
coderouter/gguf_introspect.py,sha256=Scu0JjUfLHj7T7TL0HQIm1AZcGYrXsjkaMMSN9HkTro,16121
|
|
@@ -13,21 +14,23 @@ coderouter/language_tax.py,sha256=LTbE3tIfoJuV2O3T0NixRKhzq_dEOTUuPEerJv2q9uk,93
|
|
|
13
14
|
coderouter/launcher_devices.py,sha256=DAV34Q1crGptmj1zOAk21YQzlxQNAt5Ud7qcldTD95w,29406
|
|
14
15
|
coderouter/launcher_speculative.py,sha256=h0RTGsD1Y56sJVywDJwybrT75_Ta3GF1Jz_B1d42aPg,12931
|
|
15
16
|
coderouter/launcher_swap.py,sha256=tMW5ZElDdf9T1VQGsUkvfLiSCdj_oXN_UtkV7DE8ySY,24175
|
|
16
|
-
coderouter/logging.py,sha256=
|
|
17
|
+
coderouter/logging.py,sha256=nQlMFKJ-Q9I-yripOw8QBjMZRRHHK2IAGwBvgTQp6w8,64116
|
|
17
18
|
coderouter/output_filters.py,sha256=0ry_rPiS_kC-FnHgaNVP6v7e6Al2djxzu9vBzZ8kEkE,25314
|
|
19
|
+
coderouter/rollback.py,sha256=Bqxx1MALTDLYc0BtGMEMqRyiZIWFoAZJH_RBQw-M5ow,7675
|
|
20
|
+
coderouter/secret_redaction.py,sha256=Rg71gqKN6jnybZ6UvCvXIvnThI9uRBvmOqC2grSUSUk,23159
|
|
18
21
|
coderouter/token_estimation.py,sha256=7klQYA4FIg1vtjQGWAhwiBhiLwyz8KTetrLVXFJLGIc,16957
|
|
19
22
|
coderouter/token_estimation_accurate.py,sha256=GTfzrBVnvAGjeVzmzAeUdOYZvWZKLAxcxPpFiJGlzjk,4609
|
|
20
|
-
coderouter/vscode_init.py,sha256=
|
|
23
|
+
coderouter/vscode_init.py,sha256=ZEROtETsHjyBkLzZKPnF-zsBpLJx4ph0vmgyty6kNYQ,33433
|
|
21
24
|
coderouter/adapters/__init__.py,sha256=7dIDSZ-FE_0iSqLSDc_lK1idRdLTKcM2hP9tCJipgPI,463
|
|
22
|
-
coderouter/adapters/anthropic_native.py,sha256
|
|
23
|
-
coderouter/adapters/base.py,sha256=
|
|
24
|
-
coderouter/adapters/openai_compat.py,sha256=
|
|
25
|
+
coderouter/adapters/anthropic_native.py,sha256=JxOaU-ymU1K3Tnvhufi_li1qChW69XtUszKJ2DdFlDQ,29936
|
|
26
|
+
coderouter/adapters/base.py,sha256=qW0QMbO08Dw2ZDruL9rCvCxA0FXhKnSodlK9g-8Y350,13535
|
|
27
|
+
coderouter/adapters/openai_compat.py,sha256=Kl5AACqOHxTPUn8c-4IFu4ug9_E3loLKTm2yYmvalho,23872
|
|
25
28
|
coderouter/adapters/registry.py,sha256=XNc1wmFv_oZlqKS0rA693TRDdbq1sZ-OIcofXOVOtq0,3680
|
|
26
29
|
coderouter/config/__init__.py,sha256=FODEn74fN-qZnt4INPSHswqhOlEgpL6-_onxsitSx8g,274
|
|
27
30
|
coderouter/config/capability_registry.py,sha256=RZgzHF54dXy0CCDocRCz2ee21qXGbbgTSKTkRI9iLL4,16936
|
|
28
31
|
coderouter/config/env_file.py,sha256=CoMK27fuAXm-NtoLzXb8yN2E-wDFjHQuFwiIlmgTBQw,10356
|
|
29
|
-
coderouter/config/loader.py,sha256=
|
|
30
|
-
coderouter/config/schemas.py,sha256=
|
|
32
|
+
coderouter/config/loader.py,sha256=7FoJXWaO_vN9FAjUStJDwI4aAYcUQQgMJtq5BNy8Pnc,12419
|
|
33
|
+
coderouter/config/schemas.py,sha256=0NM5KtVGsjH8BPBeBfgM-ItfOYQKhyI-P_3EbJjIaps,146436
|
|
31
34
|
coderouter/data/__init__.py,sha256=uNyfD9jaCvTWsBAWtaw1Fr25OSxzv3psGMfBjT1z0Cc,328
|
|
32
35
|
coderouter/data/model-capabilities.yaml,sha256=S9jt6SC6-3s2-icZ_n-a14iEMnc2yB1C2R6q-N_tZWQ,19309
|
|
33
36
|
coderouter/guards/__init__.py,sha256=5qliYBqygvVPneej7nx0uSjxDKsz7t8VzvrDgVBJlvU,1170
|
|
@@ -42,29 +45,31 @@ coderouter/guards/memory_pressure.py,sha256=9Xm-b7rv9Td5kPNmAFoL3sNmaOR5zT8NLdn6
|
|
|
42
45
|
coderouter/guards/self_healing.py,sha256=XeUlgFWGqMQ5E9YvvzR2CsHRJOAJEyDChqRN0xmZ0vo,16841
|
|
43
46
|
coderouter/guards/tool_loop.py,sha256=EzeMcmU7BLeTW2jsRVevU81l5rhWcn1oUr7EpzgXjVM,15209
|
|
44
47
|
coderouter/ingress/__init__.py,sha256=WQsCH2CGJCAhy0mS6GSEdeYZRkkQu2OHDsP4CJWTLug,155
|
|
45
|
-
coderouter/ingress/anthropic_routes.py,sha256=
|
|
48
|
+
coderouter/ingress/anthropic_routes.py,sha256=wlOb7ChWHMvuERR0lj8TF4MfPis2ZKegceoak4eREes,31131
|
|
46
49
|
coderouter/ingress/app.py,sha256=ZOx7dSvMxaWS4CzXOOEwgzFuycAVgAeWKCN6lFNF-F0,22433
|
|
47
|
-
coderouter/ingress/dashboard_routes.py,sha256=
|
|
50
|
+
coderouter/ingress/dashboard_routes.py,sha256=nPW5_pJe27-hzqCs4sqVVn0BrgXB_7Wcd4qZ6cirvWo,26736
|
|
48
51
|
coderouter/ingress/launcher_routes.py,sha256=uP_Otp9JE0fydUt1YP-wYcnS8Kj5RPLNIFf88YpfkPM,141535
|
|
49
|
-
coderouter/ingress/metrics_routes.py,sha256=
|
|
50
|
-
coderouter/ingress/openai_routes.py,sha256=
|
|
52
|
+
coderouter/ingress/metrics_routes.py,sha256=4s_f9CY8nVIdQBfXxyUMlN7r5_cXHOaAu7PvNbUuoxg,4609
|
|
53
|
+
coderouter/ingress/openai_routes.py,sha256=9DHVtGe1mpcUBH3ziDL4RGpEA-LzjyANpBIN3Kfbpxc,14193
|
|
54
|
+
coderouter/ingress/ui_auth.py,sha256=uCWB5IaMQRNFYdY39FQ5DDVhsoRQJoqimZNSAu_QK_Q,3742
|
|
51
55
|
coderouter/metrics/__init__.py,sha256=7Es351DPS7yLM0yVF_F0eesmiD83n7Zzhie44chht38,1465
|
|
52
|
-
coderouter/metrics/collector.py,sha256
|
|
53
|
-
coderouter/metrics/prometheus.py,sha256=
|
|
56
|
+
coderouter/metrics/collector.py,sha256=-744UrUS6_aEY7hbwuvoX0Nn7wuOsQ57IIVr52nPe2M,63268
|
|
57
|
+
coderouter/metrics/prometheus.py,sha256=jcOThXTRCMIYS1loCiCoPKMGoA6zFkmgpcaitu8Ea4I,26517
|
|
54
58
|
coderouter/plugins/__init__.py,sha256=76hMLe5dV_ilripHXzWn3HSYoIALjzlw4EJVyI-GyIM,1974
|
|
55
59
|
coderouter/plugins/base.py,sha256=HACgppdfPyQRlHWXgwSvUeImaG_KRB0uLjhhQr1Ohyk,7267
|
|
56
60
|
coderouter/plugins/loader.py,sha256=KLnKgO6_GE7OJulwo292cTYPvxqWZlLL8S0k_O3ZDcg,7139
|
|
57
61
|
coderouter/plugins/registry.py,sha256=8UDmRpHnRdB-ES_xpprvrvbDlhIhonOvFFXobR6MGJA,3739
|
|
58
|
-
coderouter/routing/__init__.py,sha256=
|
|
62
|
+
coderouter/routing/__init__.py,sha256=oLQXPvKfrwy0OiGYNXngM9G_OxmJVLShv-nqyDaqSOs,441
|
|
59
63
|
coderouter/routing/adaptive.py,sha256=G2o377twGSjbUh65wiIFx6klnpFGjsD_nI3oDvcBwhY,21257
|
|
60
64
|
coderouter/routing/auto_router.py,sha256=y4v0c8u5F9f98Vmhx1vRcKPiOgAvpzbFqr6TIh058h0,13341
|
|
61
65
|
coderouter/routing/budget.py,sha256=PblmVKJGs_BwNa9uDHAA8hmZ4XIVKv38mHAeU0V3OMs,8451
|
|
62
66
|
coderouter/routing/capability.py,sha256=rRQhzTgQYFTFDNYcSLKvq3xjdw6B1w7T-3jS7PTMI14,27864
|
|
63
|
-
coderouter/routing/fallback.py,sha256=
|
|
67
|
+
coderouter/routing/fallback.py,sha256=Hzy-_2_zK64GUqGGcOZP-RgOq8wZ4PdBpVu4OBTx8dM,172282
|
|
68
|
+
coderouter/routing/fallback_trace.py,sha256=0BysXY1CZqSvVTuePbgmHbu1AKkHLMX7hsuG6rKlDdE,19787
|
|
64
69
|
coderouter/state/__init__.py,sha256=XoGcPmmBQSiZWML2S0juSveQ78xfhtdeCliNnVyzu7E,1088
|
|
65
|
-
coderouter/state/audit_log.py,sha256=
|
|
70
|
+
coderouter/state/audit_log.py,sha256=CEFNJht2WZ8mqesI8CzeuL63NfzFzAZ7wF88auyl6l0,11444
|
|
66
71
|
coderouter/state/replay.py,sha256=Z_YHKroTKZdrL8qObFxcoLOAQWWXZvXFdLfxzvBhEJg,11230
|
|
67
|
-
coderouter/state/request_log.py,sha256=
|
|
72
|
+
coderouter/state/request_log.py,sha256=JlEvkWHwGtoLesnqr0XJy9CyXQDX4ZRHFMTPJ_0FegQ,8898
|
|
68
73
|
coderouter/state/store.py,sha256=h-rsMJq8GILsOfCP94nI40cuHaj4Vqycsm9UNN77REI,7445
|
|
69
74
|
coderouter/state/suggest_rules.py,sha256=FvdhEvao5NvdKp9zs8AkcoFKHY4yqqXY2HekvSjpDFA,16670
|
|
70
75
|
coderouter/translation/__init__.py,sha256=PYXN7XVEwpG1uC8RLy6fvnGbzEZhhrEuUapH8IYOtG8,1788
|
|
@@ -72,8 +77,8 @@ coderouter/translation/anthropic.py,sha256=ZQQGS9itN_3o7IKD68lKr5gR_Kem32Jsd7OcG
|
|
|
72
77
|
coderouter/translation/convert.py,sha256=VrstDAMsUpcQ1VgMTn_-ETp1OjGX8v0ZGhCkcd4icyU,53037
|
|
73
78
|
coderouter/translation/tool_repair.py,sha256=1p8rmdyyscGX2g0DDOYitMnLv-nKfR1SLuLaRB4z7GM,64244
|
|
74
79
|
coderouter/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
|
-
coderouter_cli-2.
|
|
76
|
-
coderouter_cli-2.
|
|
77
|
-
coderouter_cli-2.
|
|
78
|
-
coderouter_cli-2.
|
|
79
|
-
coderouter_cli-2.
|
|
80
|
+
coderouter_cli-2.15.0.dist-info/METADATA,sha256=1TbuS8h0n05w9EzQ25lzLSF38CH05QLjz1tLjY-3nR0,16897
|
|
81
|
+
coderouter_cli-2.15.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
82
|
+
coderouter_cli-2.15.0.dist-info/entry_points.txt,sha256=-dnLfD1YZ2WjH2zSdNCvlO65wYltM9bsHt9Fhg3yGss,51
|
|
83
|
+
coderouter_cli-2.15.0.dist-info/licenses/LICENSE,sha256=wkEzoR86jFw33jvfOHjULqmkGEfxTFMgMaJnpR8mPRw,1065
|
|
84
|
+
coderouter_cli-2.15.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|