tina4-python 3.13.89__tar.gz → 3.13.90__tar.gz
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.
- {tina4_python-3.13.89 → tina4_python-3.13.90}/PKG-INFO +1 -1
- {tina4_python-3.13.89 → tina4_python-3.13.90}/pyproject.toml +1 -1
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/cli/__init__.py +5 -3
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/js/tina4-dev-admin.min.js +2 -2
- {tina4_python-3.13.89 → tina4_python-3.13.90}/.gitignore +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/README.md +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/CLAUDE.md +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/HtmlElement.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/Testing.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/ai/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/api/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/auth/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/cache/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/container/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/context/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/context/chunker.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/core/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/core/cache.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/core/constants.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/core/events.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/core/middleware.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/core/rate_limiter.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/core/request.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/core/response.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/core/router.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/core/server.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/crud/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/database/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/database/adapter.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/database/connection.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/database/firebird.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/database/mongodb.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/database/mssql.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/database/mysql.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/database/odbc.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/database/postgres.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/database/sqlite.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/debug/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/debug/error_overlay.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/dev_admin/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/dev_admin/metrics.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/dev_admin/plan.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/dev_admin/project_index.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/docs.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/docstore/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/dotenv/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/env.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/frond/FROND.md +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/frond/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/frond/compiler.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/frond/engine.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/frond/parser.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/auth/meta.json +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/database/meta.json +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/error-overlay/meta.json +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/orm/meta.json +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/queue/meta.json +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/rest-api/meta.json +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/templates/meta.json +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/graphql/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/i18n/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/mcp/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/mcp/protocol.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/mcp/tools.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/messenger/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/migration/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/migration/runner.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/mqtt/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/mqtt/message.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/orm/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/orm/fields.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/orm/model.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/__feedback/widget.js +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/css/tina4.css +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/css/tina4.min.css +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/favicon.ico +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/images/logo.svg +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/js/frond.js +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/js/frond.min.js +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/js/tina4.min.js +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/js/tina4js.min.js +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/swagger/index.html +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/query_builder/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue/job.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue/kafka_backend.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue/lite_backend.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue/mongo_backend.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue/rabbitmq_backend.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue_backends/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue_backends/kafka_backend.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue_backends/mongo_backend.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/realtime/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/realtime/models/Attachment.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/realtime/models/Channel.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/realtime/models/ChannelMember.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/realtime/models/Message.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/realtime/models/Workspace.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/realtime/models/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/realtime/storage.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_alerts.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_badges.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_buttons.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_cards.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_forms.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_grid.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_modals.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_nav.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_pagination.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_reset.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_tables.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_typography.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_utilities.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/_variables.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/base.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/colors.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/scss/tina4css/tina4.scss +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/seeder/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/service/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/session/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/session_handlers/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/session_handlers/mongodb_handler.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/session_handlers/redis_handler.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/session_handlers/valkey_handler.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/swagger/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/components/crud.twig +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/docker/python/Dockerfile +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/docker/uv/Dockerfile +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/errors/302.twig +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/errors/401.twig +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/errors/403.twig +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/errors/404.twig +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/errors/500.twig +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/errors/502.twig +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/errors/503.twig +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/errors/base.twig +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/frontend/README.md +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/readme.md +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/test/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/test_client/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/validator/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/websocket/__init__.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/websocket/backplane.py +0 -0
- {tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/wsdl/__init__.py +0 -0
|
@@ -1766,7 +1766,9 @@ def _sample_literal(field_type: str) -> str:
|
|
|
1766
1766
|
|
|
1767
1767
|
def _emit_model_test(model: str, table: str, fields: list) -> None:
|
|
1768
1768
|
"""model → real SQLite roundtrip (create / read back / missing → None)."""
|
|
1769
|
-
|
|
1769
|
+
# Reuse the single DEFAULT_FIELDS constant rather than re-stating the literal,
|
|
1770
|
+
# so the co-emitted test can never describe a shape the model does not have.
|
|
1771
|
+
fields = fields or list(DEFAULT_FIELDS)
|
|
1770
1772
|
payload = ", ".join(f'"{fname}": {_sample_literal(ftype)}' for fname, ftype in fields)
|
|
1771
1773
|
# Assert a STRING field round-trips (type-safe); else just the id round-trips
|
|
1772
1774
|
# (avoids datetime/bool/float equality pitfalls on the read-back).
|
|
@@ -2615,7 +2617,7 @@ def _gen_form(name: str, flags: dict = None):
|
|
|
2615
2617
|
tina4python generate form Product --fields "name:string,price:float"
|
|
2616
2618
|
"""
|
|
2617
2619
|
flags = flags or {}
|
|
2618
|
-
fields =
|
|
2620
|
+
fields = _fields_or_default(flags.get("fields", ""))
|
|
2619
2621
|
table = _to_table(name)
|
|
2620
2622
|
route_name = table + "s"
|
|
2621
2623
|
|
|
@@ -2637,7 +2639,7 @@ def _gen_form(name: str, flags: dict = None):
|
|
|
2637
2639
|
|
|
2638
2640
|
# Build form fields
|
|
2639
2641
|
field_html = ""
|
|
2640
|
-
for fname, ftype in
|
|
2642
|
+
for fname, ftype in fields:
|
|
2641
2643
|
itype = input_types.get(ftype, "text")
|
|
2642
2644
|
label = fname.replace("_", " ").title()
|
|
2643
2645
|
step = ' step="0.01"' if ftype in ("float", "numeric", "decimal") else ""
|
|
@@ -985,7 +985,7 @@ ${t.traceback||""}`;window.__switchTab("chat"),setTimeout(()=>{window.__prefillC
|
|
|
985
985
|
<span class="thread-pip"></span>
|
|
986
986
|
<span class="thread-title">${g(t.title)}</span>
|
|
987
987
|
${o}
|
|
988
|
-
</div>`}).join("")}let cd=!1;async function Qa(i=0){for(let e=0;;e++)try{Se=await NZ(),cd=!1,EQ();return}catch(t){if(e>=i){cd=!0,console.error("refreshThreadList failed",t);return}await new Promise(n=>setTimeout(n,250*2**e))}}function HZ(i){const e=document.getElementById("editor-ai-messages");if(!e)return;const t=rt.get(i)||[];if(!t.length){e.innerHTML='<div class="ai-msg ai-bot" style="opacity:0.6">Start the conversation…</div>';return}e.innerHTML="";for(const n of t){const r=document.createElement("div");r.className=`ai-msg ai-${n.role==="user"?"user":"bot"}`,n.role==="user"?r.textContent=n.content:r.innerHTML=fs(n.content),e.appendChild(r)}e.scrollTop=e.scrollHeight}async function AQ(i,e=!1){if(!(!e&&rt.has(i)))try{const t=await FZ(i);rt.set(i,t)}catch(t){console.error(`loadThreadMessages(${i}) failed`,t),rt.set(i,[])}}async function dd(i){if(i!==ve){ve=i;try{localStorage.setItem(WQ,i)}catch{}EQ(),await AQ(i),HZ(i)}}async function KZ(){try{const i=await cs();Se.push(i),rt.set(i.id,[]),await dd(i.id);const e=document.getElementById("editor-ai-input");e==null||e.focus()}catch(i){AZ(`<span style="color:var(--danger)">Couldn't create thread: ${g(String((i==null?void 0:i.message)||i))}</span>`,"bot")}}async function JZ(i){const e=document.querySelector(`.thread-row[data-thread-id="${CSS.escape(i)}"]`),t=e==null?void 0:e.querySelector(".thread-title");if(!e||!t)return;const n=t.textContent||"",r=document.createElement("input");r.className="thread-title-edit",r.value=n,t.replaceWith(r),r.focus(),r.select();const s=a=>{const l=document.createElement("span");l.className="thread-title",l.textContent=a,r.replaceWith(l)},o=async()=>{const a=r.value.trim();if(!a||a===n){s(n);return}try{const l=await ga(i,{title:a}),O=Se.find(c=>c.id===i);O&&(O.title=l.title),s(l.title)}catch(l){console.error("rename failed",l),s(n)}};r.addEventListener("blur",()=>{o()}),r.addEventListener("keydown",a=>{a.key==="Enter"?(a.preventDefault(),r.blur()):a.key==="Escape"&&(a.preventDefault(),s(n))})}async function ez(){if(await Qa(4),!Se.length){ve=null,er();return}try{const i=localStorage.getItem(WQ);i&&Se.some(e=>e.id===i)&&(ve=i)}catch{}ya()}window.__editorThreadNew=()=>{KZ()},window.__editorThreadSwitch=i=>{dd(i)},window.__editorThreadRename=i=>{JZ(i)};const tz={done:"DONE",awaiting_customer:"AWAITING YOU",wont_do:"WONT DO",blocked:"BLOCKED",feedback:"NEW FEEDBACK",idle:"IDLE",running:"RUNNING"};function hd(i){const e=tz[i]||i.toUpperCase();return`<span class="status-pill" data-status="${g(i)}">${g(e)}</span>`}function fd(i){if(!i)return"";let e;if(/^\d+Z$/.test(i)?e=new Date(parseInt(i,10)*1e3):e=new Date(i),isNaN(e.getTime()))return i;const t=n=>String(n).padStart(2,"0");return`${t(e.getDate())}/${t(e.getMonth()+1)}/${e.getFullYear()} ${t(e.getHours())}:${t(e.getMinutes())}`}let Jn=null;function ya(){const i=
|
|
988
|
+
</div>`}).join("")}let cd=!1;async function Qa(i=0){for(let e=0;;e++)try{Se=await NZ(),cd=!1,EQ();return}catch(t){if(e>=i){cd=!0,console.error("refreshThreadList failed",t);return}await new Promise(n=>setTimeout(n,250*2**e))}}function HZ(i){const e=document.getElementById("editor-ai-messages");if(!e)return;const t=rt.get(i)||[];if(!t.length){e.innerHTML='<div class="ai-msg ai-bot" style="opacity:0.6">Start the conversation…</div>';return}e.innerHTML="";for(const n of t){const r=document.createElement("div");r.className=`ai-msg ai-${n.role==="user"?"user":"bot"}`,n.role==="user"?r.textContent=n.content:r.innerHTML=fs(n.content),e.appendChild(r)}e.scrollTop=e.scrollHeight}async function AQ(i,e=!1){if(!(!e&&rt.has(i)))try{const t=await FZ(i);rt.set(i,t)}catch(t){console.error(`loadThreadMessages(${i}) failed`,t),rt.set(i,[])}}async function dd(i){if(i!==ve){ve=i;try{localStorage.setItem(WQ,i)}catch{}EQ(),await AQ(i),HZ(i)}}async function KZ(){try{const i=await cs();Se.push(i),rt.set(i.id,[]),await dd(i.id);const e=document.getElementById("editor-ai-input");e==null||e.focus()}catch(i){AZ(`<span style="color:var(--danger)">Couldn't create thread: ${g(String((i==null?void 0:i.message)||i))}</span>`,"bot")}}async function JZ(i){const e=document.querySelector(`.thread-row[data-thread-id="${CSS.escape(i)}"]`),t=e==null?void 0:e.querySelector(".thread-title");if(!e||!t)return;const n=t.textContent||"",r=document.createElement("input");r.className="thread-title-edit",r.value=n,t.replaceWith(r),r.focus(),r.select();const s=a=>{const l=document.createElement("span");l.className="thread-title",l.textContent=a,r.replaceWith(l)},o=async()=>{const a=r.value.trim();if(!a||a===n){s(n);return}try{const l=await ga(i,{title:a}),O=Se.find(c=>c.id===i);O&&(O.title=l.title),s(l.title)}catch(l){console.error("rename failed",l),s(n)}};r.addEventListener("blur",()=>{o()}),r.addEventListener("keydown",a=>{a.key==="Enter"?(a.preventDefault(),r.blur()):a.key==="Escape"&&(a.preventDefault(),s(n))})}async function ez(){if(await Qa(4),!Se.length){ve=null,er();return}try{const i=localStorage.getItem(WQ);i&&Se.some(e=>e.id===i)&&(ve=i)}catch{}ya()}window.__editorThreadNew=()=>{KZ()},window.__editorThreadSwitch=i=>{dd(i)},window.__editorThreadRename=i=>{JZ(i)};const tz={done:"DONE",awaiting_customer:"AWAITING YOU",wont_do:"WONT DO",blocked:"BLOCKED",feedback:"NEW FEEDBACK",idle:"IDLE",running:"RUNNING"};function hd(i){const e=tz[i]||i.toUpperCase();return`<span class="status-pill" data-status="${g(i)}">${g(e)}</span>`}function fd(i){if(!i)return"";let e;if(/^\d+Z$/.test(i)?e=new Date(parseInt(i,10)*1e3):e=new Date(i),isNaN(e.getTime()))return i;const t=n=>String(n).padStart(2,"0");return`${t(e.getDate())}/${t(e.getMonth()+1)}/${e.getFullYear()} ${t(e.getHours())}:${t(e.getMinutes())}`}let Jn=null;function ya(){const i=s=>document.getElementById(s),e=i("threads-pane-head-list");e&&(e.hidden=!1);const t=i("threads-pane-head-detail");t&&(t.hidden=!0);const n=i("threads-list-view");n&&(n.hidden=!1);const r=i("threads-detail-view");r&&(r.hidden=!0),Qa().then(er)}async function ba(i){await dd(i);const e=Se.find(c=>c.id===i);if(!e)return;const t=c=>document.getElementById(c),n=t("threads-pane-head-list");n&&(n.hidden=!0);const r=t("threads-pane-head-detail");r&&(r.hidden=!1);const s=t("threads-list-view");s&&(s.hidden=!0);const o=t("threads-detail-view");o&&(o.hidden=!1);const a=t("threads-detail-title");a&&(a.textContent=e.title||"Thread");const l=t("threads-detail-meta"),O=e.sender?`<span>📨 from ${g(e.sender)}</span>`:"";l&&(l.innerHTML=`${hd(e.status_hint||"idle")} <span>${g(fd(e.last_message_at))}</span> ${O}`),pd(i),setTimeout(()=>{var c;return(c=t("threads-reply-input"))==null?void 0:c.focus()},30)}async function iz(){if(!ve)return;const i=ve;try{await ga(i,{archived:!0,closure_reason:"done"});const e=Se.find(t=>t.id===i);e&&(e.archived=!0,e.closure_reason="done"),ve=null,ya()}catch(e){console.error("archive failed",e)}}async function nz(i){try{await ga(i,{archived:!0});const e=Se.find(t=>t.id===i);e&&(e.archived=!0),ve===i?(ve=null,ya()):er()}catch(e){console.error("archive-from-list failed",e)}}function er(){const i=document.getElementById("threads-rows");if(!i)return;if(!Se.length){i.innerHTML=cd?`<div class="threads-empty">
|
|
989
989
|
<div style="margin-bottom:0.6rem">Can't reach the agent — threads unavailable.</div>
|
|
990
990
|
<button type="button" class="action-pill"
|
|
991
991
|
onclick="window.__threadsRetry()">Retry</button>
|
|
@@ -1012,7 +1012,7 @@ ${t.traceback||""}`;window.__switchTab("chat"),setTimeout(()=>{window.__prefillC
|
|
|
1012
1012
|
<span>severity: ${g(e.severity||"-")}</span>
|
|
1013
1013
|
</div>
|
|
1014
1014
|
<div style="margin-top:0.3rem">${g(e.summary||"")}</div>
|
|
1015
|
-
</div>`}catch{return fs(i)}}async function az(){try{const i=await cs();Se.push(i),rt.set(i.id,[]),await ba(i.id)}catch(i){console.error("threadsNew failed",i)}}async function lz(){if(!ve)return;const i=Se.find(t=>t.id===ve);if(!i)return;const e=window.prompt("Rename thread:",i.title);if(!(e==null||e.trim()===""||e===i.title))try{const t=await ga(ve,{title:e.trim()});i.title=t.title;const n=document.getElementById("threads-detail-title");n&&(n.textContent=t.title),er()}catch(t){console.error("rename failed",t)}}function Oz(i){return i?i.status_hint==="done"||i.status_hint==="wont_do"||i.closure_reason==="done"||i.closure_reason==="wont_do":!1}async function md(){const i=document.getElementById("threads-reply-input");if(!i)return;let e=i.value.trim();if(!e)return;i.value="";const t=e.match(/^new topic:\s*(.*)$/is);if(t){const o=t[1].trim();try{const a=await cs(o.slice(0,80)||void 0);if(Se.push(a),rt.set(a.id,[]),await ba(a.id),!o)return;e=o}catch(a){console.error("New Topic spawn failed",a);return}}if(!t&&ve&&Oz(Se.find(o=>o.id===ve)))try{const o=await cs(e.slice(0,80)||void 0);Se.push(o),rt.set(o.id,[]),await ba(o.id)}catch(o){console.error("auto-new-thread on done reply failed",o);return}if(!ve)try{const o=await cs(e.slice(0,80));Se.push(o),rt.set(o.id,[]),ve=o.id}catch(o){console.error("auto-create failed",o);return}const n=ve,r=rt.get(n)||[];r.push({id:`local-${Date.now()}`,role:"user",content:e,timestamp:new Date().toISOString(),thread_id:n}),rt.set(n,r),pd(n),$a.add(n),er();const s=document.getElementById("threads-chat");Jn==null||Jn.abort(),Jn=new AbortController;try{await pz(e,n,Jn.signal,s)}catch(o){if((o==null?void 0:o.name)!=="AbortError"){const a=document.createElement("div");a.className="ai-msg ai-bot",a.style.color="var(--danger,#f38ba8)",a.textContent=`Connection failed: ${(o==null?void 0:o.message)||o}`,s==null||s.appendChild(a)}}finally{$a.delete(n),Jn=null;try{await AQ(n,!0)}catch{}await Qa(),pd(n);const o=Se.find(
|
|
1015
|
+
</div>`}catch{return fs(i)}}async function az(){try{const i=await cs();Se.push(i),rt.set(i.id,[]),await ba(i.id)}catch(i){console.error("threadsNew failed",i)}}async function lz(){if(!ve)return;const i=Se.find(t=>t.id===ve);if(!i)return;const e=window.prompt("Rename thread:",i.title);if(!(e==null||e.trim()===""||e===i.title))try{const t=await ga(ve,{title:e.trim()});i.title=t.title;const n=document.getElementById("threads-detail-title");n&&(n.textContent=t.title),er()}catch(t){console.error("rename failed",t)}}function Oz(i){return i?i.status_hint==="done"||i.status_hint==="wont_do"||i.closure_reason==="done"||i.closure_reason==="wont_do":!1}async function md(){const i=document.getElementById("threads-reply-input");if(!i)return;let e=i.value.trim();if(!e)return;i.value="";const t=e.match(/^new topic:\s*(.*)$/is);if(t){const o=t[1].trim();try{const a=await cs(o.slice(0,80)||void 0);if(Se.push(a),rt.set(a.id,[]),await ba(a.id),!o)return;e=o}catch(a){console.error("New Topic spawn failed",a);return}}if(!t&&ve&&Oz(Se.find(o=>o.id===ve)))try{const o=await cs(e.slice(0,80)||void 0);Se.push(o),rt.set(o.id,[]),await ba(o.id)}catch(o){console.error("auto-new-thread on done reply failed",o);return}if(!ve)try{const o=await cs(e.slice(0,80));Se.push(o),rt.set(o.id,[]),ve=o.id}catch(o){console.error("auto-create failed",o);return}const n=ve,r=rt.get(n)||[];r.push({id:`local-${Date.now()}`,role:"user",content:e,timestamp:new Date().toISOString(),thread_id:n}),rt.set(n,r),pd(n),$a.add(n),er();const s=document.getElementById("threads-chat");Jn==null||Jn.abort(),Jn=new AbortController;try{await pz(e,n,Jn.signal,s)}catch(o){if((o==null?void 0:o.name)!=="AbortError"){const a=document.createElement("div");a.className="ai-msg ai-bot",a.style.color="var(--danger,#f38ba8)",a.textContent=`Connection failed: ${(o==null?void 0:o.message)||o}`,s==null||s.appendChild(a)}}finally{$a.delete(n),Jn=null;try{await AQ(n,!0)}catch{}await Qa(),pd(n);const o=Se.find(l=>l.id===n),a=document.getElementById("threads-detail-meta");if(o&&a){const l=o.sender?`<span>📨 from ${g(o.sender)}</span>`:"";a.innerHTML=`${hd(o.status_hint||"idle")} <span>${g(fd(o.last_message_at))}</span> ${l}`}}}queueMicrotask(()=>{const i=document.getElementById("threads-reply-form");i&&i.addEventListener("submit",t=>{t.preventDefault(),md()});const e=document.getElementById("threads-reply-input");e&&e.addEventListener("keydown",t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),t.stopPropagation(),md())})}),window.__threadsShowList=()=>ya(),window.__threadsShowDetail=i=>{ba(i)},window.__threadsNew=()=>{az()},window.__threadsRetry=()=>{Qa(2).then(er)},window.__threadsRenameActive=()=>{lz()};let un=!1;async function jQ(){const i=document.getElementById("plans-panel"),e=document.getElementById("plans-toggle-btn");i&&(un=!un,i.hidden=!un,e==null||e.classList.toggle("active",un),un&&await cz())}async function cz(){const i=document.getElementById("plans-rows");if(i){i.innerHTML='<div class="threads-empty">Loading plans…</div>';try{const e=await Mi("plan_list",{}),t=e.ok&&Array.isArray(e.result)?e.result:[];if(!t.length){i.innerHTML='<div class="threads-empty">No plans yet — they appear here when the planner agent creates one.</div>';return}const n=[...t].sort((r,s)=>String(s.name||s.file||"").localeCompare(String(r.name||r.file||"")));i.innerHTML=n.map(r=>{var h,f;const s=String(r.name||r.file||""),o=String(r.path||`plan/${s}`),a=String(r.title||s).slice(0,60),l=r.steps_done??((h=r.progress)==null?void 0:h.done)??0,O=r.steps_total??((f=r.progress)==null?void 0:f.total)??0,c=O>0?`${l}/${O} steps`:"",d=r.is_current||r.current?" · ★ current":"";return`<div class="plan-row" onclick="window.__plansOpen('${g(o)}')" title="Open ${g(o)} in editor">
|
|
1016
1016
|
<div class="plan-name">${g(a)}</div>
|
|
1017
1017
|
<div class="plan-meta">${g(s)}${c?" · "+g(c):""}${d}</div>
|
|
1018
1018
|
</div>`}).join("")}catch{i.innerHTML='<div class="threads-empty" style="color:var(--danger,#f38ba8)">Failed to load plans</div>'}}}async function dz(i){var t;try{await ui(i)}catch(n){console.error("plansOpen failed",n)}un=!1;const e=document.getElementById("plans-panel");e&&(e.hidden=!0),(t=document.getElementById("plans-toggle-btn"))==null||t.classList.remove("active")}window.__plansToggle=()=>{jQ()},window.__plansOpen=i=>{dz(i)};let ds=!1;async function hz(){const i=document.getElementById("grounding-panel"),e=document.getElementById("grounding-toggle-btn");i&&(un&&jQ(),ds=!ds,i.hidden=!ds,e==null||e.classList.toggle("active",ds),ds&&await MQ())}async function MQ(){const i=document.getElementById("grounding-body");if(!i)return;i.innerHTML='<div class="threads-empty">Loading…</div>';let e={};try{const r=await fetch("/__dev/api/grounding/status");r.ok&&(e=await r.json())}catch{}const t=g(e.url||"https://mcp.tina4.com"),n=e.configured?`<span style="color:var(--success,#a6e3a1)">● Configured</span> <span style="opacity:0.6">(…${g(e.last4||"")})</span>`:'<span style="color:var(--warn,#f9e2af)">○ Not set</span> — using local corpus fallback';i.innerHTML=`
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/images/tina4-logo-icon.webp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/public/swagger/oauth2-redirect.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/queue_backends/rabbitmq_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/session_handlers/mongodb_handler.py
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/session_handlers/redis_handler.py
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/session_handlers/valkey_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/docker/distroless/Dockerfile
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/docker/poetry/Dockerfile
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/templates/docker/python/Dockerfile
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/af/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/af/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/en/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/en/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/es/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/es/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/fr/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/fr/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/ja/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/ja/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/zh/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.89 → tina4_python-3.13.90}/tina4_python/translations/zh/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|