refactor: rename the application package to docsgpt

The backend import package is now docsgpt, the name it will carry on PyPI;
application was far too generic to install into anyone's site-packages.
git mv plus a mechanical rewrite of every import, dotted string and path
reference: 734 Python files, the compose files, Dockerfile, workflows, docs,
setup scripts, devcontainer, k8s manifests, vscode config, pytest and coverage
config, .gitignore. Behaviour is unchanged.

Kept for one release:
- A top-level application package whose meta-path finder resolves
  application.x.y to the already-imported docsgpt.x.y object, so old imports
  and entry points (celery -A application.app.celery,
  uvicorn application.asgi:asgi_app) keep working with a FutureWarning.
- Celery registers every application.* task name as an alias of its
  docsgpt.* task on start-up, so messages queued by the previous release still
  run. The redbeat key prefix moves to redbeat:docsgpt:v2: so schedule entries
  the previous release wrote are left unread instead of firing twice.

The backend image builds from the repository root (docker build -f
docsgpt/Dockerfile .) so it can ship the alias package; a root .dockerignore
allow-lists docsgpt/ and application/ and keeps caches, local data, .env
files, the sample index files and the Dockerfile out. Compose and the image
workflows point at the new context.
This commit is contained in:
Alex committed 2026-09-07 10:20:43 +01:00
1 parent 3e7f1f91b4
commit 574f96341e
984 files changed
+9847 -9682

No files matched your search

@@ -1,6 +1,6 @@
"""Token-usage attribution tests for the always-on inline-persist model.
Persistence is owned by the per-call decorator in ``application.usage``.
Persistence is owned by the per-call decorator in ``docsgpt.usage``.
``finalize_message`` no longer writes ``token_usage`` rows. These tests
exercise the decorator path through ``stream_token_usage`` /
``gen_token_usage``:
@@ -63,7 +63,7 @@ class TestDecoratorAlwaysPersists:
"""Per-call inline persistence — no opt-in flag."""
def test_primary_stream_writes_agent_stream_row(self, pg_conn):
from application.usage import stream_token_usage
from docsgpt.usage import stream_token_usage
user_id = _seed_user(pg_conn)
@@ -81,7 +81,7 @@ class TestDecoratorAlwaysPersists:
yield "chunk-b"
llm = _PrimaryLLM()
with _patch_db_session_for(("application.usage",), pg_conn):
with _patch_db_session_for(("docsgpt.usage",), pg_conn):
for _ in llm._raw(
"m", [{"role": "user", "content": "hi"}], True, None,
):
@@ -102,7 +102,7 @@ class TestDecoratorAlwaysPersists:
def test_side_channel_source_flows_to_row(self, pg_conn):
"""``_token_usage_source`` overrides the default ``agent_stream``."""
from application.usage import stream_token_usage
from docsgpt.usage import stream_token_usage
user_id = _seed_user(pg_conn)
@@ -120,7 +120,7 @@ class TestDecoratorAlwaysPersists:
yield "chunk"
llm = _RagLLM()
with _patch_db_session_for(("application.usage",), pg_conn):
with _patch_db_session_for(("docsgpt.usage",), pg_conn):
for _ in llm._raw("m", [{"role": "user", "content": "q"}], True, None):
pass
@@ -137,7 +137,7 @@ class TestDecoratorAlwaysPersists:
"""``_request_id`` on the LLM (stamped by the route) lands in
``token_usage.request_id`` so ``count_in_range`` can DISTINCT it.
"""
from application.usage import stream_token_usage
from docsgpt.usage import stream_token_usage
user_id = _seed_user(pg_conn)
request_id = f"req-{uuid.uuid4().hex[:12]}"
@@ -156,7 +156,7 @@ class TestDecoratorAlwaysPersists:
yield "chunk"
llm = _PrimaryLLM()
with _patch_db_session_for(("application.usage",), pg_conn):
with _patch_db_session_for(("docsgpt.usage",), pg_conn):
# Call twice — the route invokes the LLM once per tool round.
for _ in llm._raw("m", [{"role": "user", "content": "q"}], True, None):
pass
@@ -173,7 +173,7 @@ class TestDecoratorAlwaysPersists:
assert all(r[0] == request_id for r in rows)
def test_zero_count_call_is_skipped(self, pg_conn):
from application.usage import gen_token_usage
from docsgpt.usage import gen_token_usage
user_id = _seed_user(pg_conn)
@@ -190,7 +190,7 @@ class TestDecoratorAlwaysPersists:
return None # empty result → 0 generated tokens, 0 prompt tokens
llm = _EmptyLLM()
with _patch_db_session_for(("application.usage",), pg_conn):
with _patch_db_session_for(("docsgpt.usage",), pg_conn):
llm._raw("m", [], False, None)
n = pg_conn.execute(
@@ -206,7 +206,7 @@ class TestDecoratorAlwaysPersists:
constraint; the decorator skips before that to keep the stream
running.
"""
from application.usage import stream_token_usage
from docsgpt.usage import stream_token_usage
class _OrphanLLM:
decoded_token = None
@@ -222,8 +222,8 @@ class TestDecoratorAlwaysPersists:
llm = _OrphanLLM()
with _patch_db_session_for(
("application.usage",), pg_conn,
), caplog.at_level(logging.WARNING, logger="application.usage"):
("docsgpt.usage",), pg_conn,
), caplog.at_level(logging.WARNING, logger="docsgpt.usage"):
for _ in llm._raw("m", [{"role": "user", "content": "q"}], True, None):
pass