htmlgraph 0.26.22__tar.gz → 0.26.24__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.
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/PKG-INFO +1 -1
- htmlgraph-0.26.24/examples/pattern_learning_demo.py +77 -0
- htmlgraph-0.26.24/examples/retry_decorator_examples.py +500 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/gemini-extension.json +1 -1
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/pyproject.toml +1 -1
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/__init__.py +6 -1
- htmlgraph-0.26.24/src/python/htmlgraph/analytics/pattern_learning.py +771 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/analytics.py +465 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/core.py +97 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/main.py +3 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/models.py +12 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/work/__init__.py +5 -0
- htmlgraph-0.26.24/src/python/htmlgraph/cli/work/report.py +727 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/db/schema.py +34 -1
- htmlgraph-0.26.24/src/python/htmlgraph/decorators.py +317 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/models.py +4 -1
- htmlgraph-0.26.24/src/python/htmlgraph/operations/bootstrap.py +288 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/sdk.py +91 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/session_manager.py +160 -2
- htmlgraph-0.26.24/src/python/htmlgraph/sessions/__init__.py +23 -0
- htmlgraph-0.26.24/src/python/htmlgraph/sessions/handoff.py +749 -0
- htmlgraph-0.26.24/tests/cli/test_bootstrap_command.py +226 -0
- htmlgraph-0.26.24/tests/python/test_costs_command.py +444 -0
- htmlgraph-0.26.24/tests/python/test_decorators.py +652 -0
- htmlgraph-0.26.24/tests/python/test_pattern_learning.py +647 -0
- htmlgraph-0.26.24/tests/python/test_session_handoff_continuity.py +508 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/.gitignore +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/agent-coordination/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/agent-coordination/demo.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/create_auth_track_demo.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/create_htmlgraph_dev_track.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/demo_agent_planning.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/demo_real_project_analytics.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/demo_sdk_operations.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/agents.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/demo.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/features/doc-api-graph.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/features/doc-api-overview.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/features/doc-api-sdk.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/features/doc-example-advanced.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/features/doc-example-basic.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/features/doc-index.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/features/doc-installation.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/documentation-site/features/doc-quickstart.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/example_query_compilation.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/handoff-demo.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/knowledge-base/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/knowledge-base/agents.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/knowledge-base/demo.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/knowledge-base/features/feat-276c615f.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/knowledge-base/features/feat-7a6f797d.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/knowledge-base/features/note-ai-agents.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/knowledge-base/features/note-graph-db.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/knowledge-base/features/note-htmlgraph.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/knowledge-base/features/note-web-standards.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/parallel_task_coordination.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/routing-demo.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/sdk_demo.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/todo-list/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/todo-list/demo.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/todo-list/index.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/todo-list/styles.css +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/todo-list/task-001.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/todo-list/task-002.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/todo-list/task-003.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/todo-list/task-004.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/todo-list/task-005.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/examples/todo-list/task-006.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/GEMINI.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_deploy.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_end.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_feature-add.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_feature-complete.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_feature-primary.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_feature-start.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_git-commit.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_help.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_init.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_plan.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_recommend.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_serve.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_spike.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_start.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_status.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/command_track.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/hooks/hooks.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/hooks/scripts/post-tool.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/hooks/scripts/session-end.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/packages/gemini-extension/hooks/scripts/session-start.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/js/htmlgraph.js +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/.htmlgraph/.session-warning-state.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/.htmlgraph/agents.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/.htmlgraph/htmlgraph.db +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/agent_detection.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/agent_registry.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/agents.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/analytics/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/analytics/cli.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/analytics/cost_analyzer.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/analytics/cost_reporter.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/analytics/cross_session.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/analytics/dependency.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/analytics/work_type.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/analytics_index.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/main.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/static/htmx.min.js +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/static/style-redesign.css +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/static/style.css +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/dashboard-redesign.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/dashboard.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/activity-feed-hierarchical.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/activity-feed.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/agents-redesign.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/agents.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/event-traces.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/features-kanban-redesign.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/features.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/metrics-redesign.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/metrics.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/orchestration-redesign.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/orchestration.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/api/templates/partials/spawners.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/archive/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/archive/bloom.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/archive/fts.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/archive/manager.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/archive/search.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/atomic_ops.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/attribute_index.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/base.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/bug.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/chore.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/epic.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/feature.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/insight.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/metric.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/pattern.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/phase.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/spike.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/builders/track.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/autonomy.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/cost.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/messages_basic.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/messaging.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/models.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/pattern_storage.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/patterns.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/posttool_analyzer.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/reporter.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cigs/tracker.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/.htmlgraph/.session-warning-state.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/.htmlgraph/agents.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/.htmlgraph/htmlgraph.db +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/__main__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/base.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/constants.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/templates/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/templates/cost_dashboard.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/work/features.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/work/orchestration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/work/sessions.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli/work/tracks.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli_commands/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli_commands/feature.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cli_framework.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/base.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/bug.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/chore.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/epic.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/feature.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/insight.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/metric.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/pattern.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/phase.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/session.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/spike.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/task_delegation.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/todo.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/collections/traces.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/config.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/context_analytics.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/converter.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cost_analysis/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/cost_analysis/analyzer.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/dashboard.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/dashboard.html.backup +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/dashboard.html.bak +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/dashboard.html.bak2 +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/dashboard.html.bak3 +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/db/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/db/queries.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/dependency_models.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/deploy.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/deployment_models.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/API_REFERENCE.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/HTTP_API.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/INTEGRATION_GUIDE.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/ORCHESTRATION_PATTERNS.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/docs_version.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/metadata.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/migrations.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/template_engine.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/templates/_sections/cli_reference.md.j2 +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/templates/_sections/core_concepts.md.j2 +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/templates/_sections/sdk_basics.md.j2 +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/templates/base_agents.md.j2 +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/templates/example_user_override.md.j2 +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/docs/version_check.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/edge_index.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/error_handler.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/event_log.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/event_migration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/exceptions.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/extensions/gemini/GEMINI.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/extensions/gemini/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/extensions/gemini/gemini-extension.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/extensions/gemini/hooks/hooks.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/extensions/gemini/hooks/scripts/post-tool.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/extensions/gemini/hooks/scripts/session-end.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/extensions/gemini/hooks/scripts/session-start.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/file_watcher.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/find_api.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/git_events.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/graph.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/.htmlgraph/.session-warning-state.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/.htmlgraph/agents.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/.htmlgraph/index.sqlite +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/bootstrap.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/cigs_pretool_enforcer.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/concurrent_sessions.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/context.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/drift_handler.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/event_tracker.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/git_commands.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/hooks-config.example.json +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/installer.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/orchestrator.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/orchestrator_reflector.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/post-checkout.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/post-commit.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/post-merge.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/post_tool_use_failure.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/post_tool_use_handler.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/posttooluse.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/pre-commit.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/pre-push.sh +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/pretooluse.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/prompt_analyzer.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/session_handler.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/session_summary.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/state_manager.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/subagent_detection.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/subagent_stop.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/task_enforcer.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/task_validator.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/hooks/validator.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/ids.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/index.d.ts +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/learning.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/mcp_server.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/operations/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/operations/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/operations/analytics.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/operations/events.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/operations/fastapi_server.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/operations/hooks.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/operations/initialization.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/operations/initialization.py.backup +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/operations/server.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/claude_launcher.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/command_builder.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/headless_spawner.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/live_events.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/model_selection.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/plugin_manager.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/prompts.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/spawners/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/spawners/base.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/spawners/claude.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/spawners/codex.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/spawners/copilot.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/spawners/gemini.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/subprocess_runner.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration/task_coordination.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestration.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestrator-system-prompt-optimized.txt +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestrator.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestrator_config.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestrator_mode.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/orchestrator_validator.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/parallel.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/parser.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/planning.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/pydantic_models.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/quality_gates.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/query_builder.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/reflection.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/repo_hash.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/routing.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/scripts/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/scripts/deploy.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/server.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/services/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/services/claiming.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/session_hooks.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/session_registry.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/session_state.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/session_warning.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/setup.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/spike_index.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/styles.css +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/sync_docs.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/system_prompts.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/templates/AGENTS.md.template +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/templates/CLAUDE.md.template +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/templates/GEMINI.md.template +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/templates/orchestration-view.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/track_builder.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/track_manager.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/transcript.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/transcript_analytics.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/types.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/validation.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/watch.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/src/python/htmlgraph/work_type_utils.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/benchmarks/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/benchmarks/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/benchmarks/bench_graph.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/benchmarks/conftest.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_bootstrap.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_concurrent_sessions.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_context.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_event_tracker.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_git_commands.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_hybrid_event_capture.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_prompt_analyzer.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_session_handler.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_state_manager.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_system_prompt_persistence.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/hooks/test_system_prompt_persistence_integration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/multi_agent/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/multi_agent/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/multi_agent/test_agent_quirks.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/multi_agent/test_git_continuity_spine.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_cigs_hook_flow.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_cigs_integration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_cigs_learning.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_codex_spawner.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_complexity_assessment.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_copilot_spawner_tracking.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_dashboard_spawner_display.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_delegation_events.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_deployment_workflow.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_discoverability.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_edge_index_bug.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_features.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_gemini_spawner_diagnosis.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_handoff_routing.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_multi_agent_coordination.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_new_features.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_orchestration_tab.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_orchestration_with_playwright.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_orchestrator_pattern.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_orchestrator_spawner_delegation.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_phase4_delegation_events.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_post_compact_delegation.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_real_workitem_integration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_redesigned_dashboard.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_spawner_integration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_spawner_live_events.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_spawner_observability_e2e.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_spawner_routing_live.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_spawner_tool_tracking.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_task_delegation.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_user_query_events.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_websocket_realtime.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/test_websocket_streaming.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/integration/verify_phase1_userquery.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/js/README.md +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/js/test_htmlgraph.html +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/manual/test-hook-input.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/operations/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/operations/test_hooks.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/operations/test_server.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/__init__.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/conftest.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_activity_feed_ui.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_agent_attribution.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_agent_detection.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_analytics.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_archive_manager.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_archive_search.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_atomic_ops.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_auto_spike.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_cigs_pretool_enforcer.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_claiming.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_cli_commands.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_cli_pydantic_models.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_cli_rich_output.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_collection_filter.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_cost_analyzer.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_cross_agent_attribution.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_cross_session_analytics.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_dashboard_attribution.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_dashboard_ui.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_delegation_fk_fix.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_delete.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_deploy.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_drift_parent_activity.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_drift_queue_cleanup.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_edge_index.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_error_handling.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_event_index.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_event_query.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_event_tracing.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_feature_track_linkage_phase1.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_find_api.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_git_events.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_graph_traversal.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_handoff.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_headless_spawner.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_headless_spawner_parent_session.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_ids.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_install_hooks.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_lifecycle.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_mcp_server.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_mcp_stdio_transport.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_models.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_orchestration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_orchestrator_circuit_breaker.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_orchestrator_cli.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_orchestrator_enforce_hook.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_orchestrator_mode.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_parent_child_event_linking.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_parent_child_linking.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_parent_linking_integration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_pattern_storage.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_plugin_update_preservation.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_post_tool_use_failure.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_post_tool_use_handler.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_posttooluse_cigs.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_pre_commit_hooks.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_pre_work_validation_integration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_pretooluse_event_hierarchy.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_quality_gates.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_query_builder.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_query_cache.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_query_compilation.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_reflection.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_repo_hash.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_routing.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_sdk_discoverability.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_sdk_get_active_work_item.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_sdk_parent_session.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_sdk_sqlite_integration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_session_cleanup.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_session_continuity.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_session_integration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_session_registry.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_session_start_cigs.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_session_start_info_validation.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_session_state_manager.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_spawner_agents.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_spawner_routing.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_sqlite_schema.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_stop_cigs.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_system_overhead_drift.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_template_system.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_todo_collection.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_traces_collection.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_track_loading.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_transcript_linking.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_update_preserves_incoming_edges.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_user_prompt_submit_cigs.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_validate_work_hook.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_version_migration.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_violation_tracker.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_work_queue.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/python/test_work_type.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_agent_routing.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_autonomy_recommender.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_cigs_cli.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_cigs_cost_calculator.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_cigs_cost_reporter.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_cigs_imperative_messages.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_cigs_messages_basic.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_cli_output_snapshots.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_cli_sdk_parity.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_deployment_models.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_event_log.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_hybrid_event_capture.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_orchestrator_config.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_orchestrator_validator.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_pattern_detector.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_sdk_api_surface.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_sdk_operations.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_transaction_snapshot.py +0 -0
- {htmlgraph-0.26.22 → htmlgraph-0.26.24}/tests/test_transcript.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: htmlgraph
|
|
3
|
-
Version: 0.26.
|
|
3
|
+
Version: 0.26.24
|
|
4
4
|
Summary: HTML is All You Need - Graph database on web standards
|
|
5
5
|
Project-URL: Homepage, https://github.com/Shakes-tzd/htmlgraph
|
|
6
6
|
Project-URL: Documentation, https://github.com/Shakes-tzd/htmlgraph#readme
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Demo: Pattern Learning from Agent Behavior
|
|
3
|
+
|
|
4
|
+
Shows how to use the Pattern Learning feature to identify workflow patterns,
|
|
5
|
+
anti-patterns, and optimization opportunities from tool call history.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from htmlgraph import SDK
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main():
|
|
12
|
+
"""Demo pattern learning capabilities."""
|
|
13
|
+
# Initialize SDK
|
|
14
|
+
sdk = SDK(agent="demo")
|
|
15
|
+
|
|
16
|
+
print("=== Pattern Learning Demo ===\n")
|
|
17
|
+
|
|
18
|
+
# 1. Detect patterns from tool call history
|
|
19
|
+
print("1. Detecting patterns from tool call history...")
|
|
20
|
+
patterns = sdk.pattern_learning.detect_patterns(
|
|
21
|
+
window_size=3, # 3-tool sequences
|
|
22
|
+
min_frequency=5, # Must occur at least 5 times
|
|
23
|
+
)
|
|
24
|
+
print(f" Found {len(patterns)} patterns\n")
|
|
25
|
+
|
|
26
|
+
# Show top 5 patterns
|
|
27
|
+
print(" Top 5 Most Frequent Patterns:")
|
|
28
|
+
for i, pattern in enumerate(patterns[:5], 1):
|
|
29
|
+
print(f" {i}. {' → '.join(pattern.sequence)}")
|
|
30
|
+
print(f" Frequency: {pattern.frequency} times")
|
|
31
|
+
print(f" Success Rate: {pattern.success_rate:.1f}%")
|
|
32
|
+
print(f" Avg Duration: {pattern.avg_duration_seconds:.1f}s\n")
|
|
33
|
+
|
|
34
|
+
# 2. Get recommendations
|
|
35
|
+
print("\n2. Getting recommendations based on patterns...")
|
|
36
|
+
recommendations = sdk.pattern_learning.get_recommendations(limit=3)
|
|
37
|
+
print(f" Generated {len(recommendations)} recommendations:\n")
|
|
38
|
+
|
|
39
|
+
for i, rec in enumerate(recommendations, 1):
|
|
40
|
+
print(f" {i}. {rec.title}")
|
|
41
|
+
print(f" {rec.description}")
|
|
42
|
+
print(f" Impact Score: {rec.impact_score:.1f}\n")
|
|
43
|
+
|
|
44
|
+
# 3. Identify anti-patterns
|
|
45
|
+
print("\n3. Identifying anti-patterns...")
|
|
46
|
+
anti_patterns = sdk.pattern_learning.get_anti_patterns()
|
|
47
|
+
print(f" Found {len(anti_patterns)} anti-patterns:\n")
|
|
48
|
+
|
|
49
|
+
for i, anti in enumerate(anti_patterns[:3], 1):
|
|
50
|
+
print(f" {i}. {anti.title}")
|
|
51
|
+
print(f" {anti.description}")
|
|
52
|
+
print(f" Impact Score: {anti.impact_score:.1f}\n")
|
|
53
|
+
|
|
54
|
+
# 4. Export learnings to markdown
|
|
55
|
+
print("\n4. Exporting learnings to markdown...")
|
|
56
|
+
output_path = ".htmlgraph/pattern_learnings.md"
|
|
57
|
+
sdk.pattern_learning.export_learnings(output_path)
|
|
58
|
+
print(f" Exported to: {output_path}\n")
|
|
59
|
+
|
|
60
|
+
# 5. Provide feedback on patterns
|
|
61
|
+
print("5. Pattern feedback loop:")
|
|
62
|
+
print(" You can provide feedback on insights to improve recommendations:")
|
|
63
|
+
print(
|
|
64
|
+
" - sdk.pattern_learning.learning_loop.update_feedback(pattern_id, 1) # Helpful"
|
|
65
|
+
)
|
|
66
|
+
print(
|
|
67
|
+
" - sdk.pattern_learning.learning_loop.update_feedback(pattern_id, 0) # Neutral"
|
|
68
|
+
)
|
|
69
|
+
print(
|
|
70
|
+
" - sdk.pattern_learning.learning_loop.update_feedback(pattern_id, -1) # Not helpful"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
print("\n=== Demo Complete ===")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
main()
|
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
"""Comprehensive examples demonstrating the retry decorator with exponential backoff.
|
|
2
|
+
|
|
3
|
+
This file showcases various use cases and patterns for the @retry decorator,
|
|
4
|
+
including basic usage, custom parameters, and integration with real-world scenarios.
|
|
5
|
+
|
|
6
|
+
Run with: uv run python examples/retry_decorator_examples.py
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
import logging
|
|
11
|
+
import time
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from htmlgraph import retry, retry_async
|
|
15
|
+
|
|
16
|
+
# Configure logging to see retry messages
|
|
17
|
+
logging.basicConfig(
|
|
18
|
+
level=logging.DEBUG,
|
|
19
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
20
|
+
)
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# ============================================================================
|
|
25
|
+
# Example 1: Basic API Call with Default Retry Logic
|
|
26
|
+
# ============================================================================
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@retry()
|
|
30
|
+
def fetch_from_api() -> dict[str, Any]:
|
|
31
|
+
"""Fetch data from an API with default retry parameters.
|
|
32
|
+
|
|
33
|
+
Uses default retry behavior:
|
|
34
|
+
- 3 maximum attempts
|
|
35
|
+
- 1 second initial delay
|
|
36
|
+
- 2x exponential backoff
|
|
37
|
+
- Jitter enabled (prevents thundering herd)
|
|
38
|
+
- Retries on any Exception
|
|
39
|
+
"""
|
|
40
|
+
logger.info("Attempting API call...")
|
|
41
|
+
# Simulate occasional API failures
|
|
42
|
+
if time.time() % 3 < 1:
|
|
43
|
+
raise ConnectionError("API temporarily unavailable")
|
|
44
|
+
return {"status": "success", "data": ["item1", "item2"]}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# ============================================================================
|
|
48
|
+
# Example 2: Database Connection with Specific Exception Handling
|
|
49
|
+
# ============================================================================
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class DatabaseConnectionError(Exception):
|
|
53
|
+
"""Raised when database connection fails."""
|
|
54
|
+
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@retry(
|
|
59
|
+
max_attempts=5,
|
|
60
|
+
initial_delay=0.5,
|
|
61
|
+
exceptions=(DatabaseConnectionError, TimeoutError),
|
|
62
|
+
)
|
|
63
|
+
def connect_to_database(db_url: str) -> str:
|
|
64
|
+
"""Connect to database with retry only on connection errors.
|
|
65
|
+
|
|
66
|
+
This approach:
|
|
67
|
+
- Retries only on DatabaseConnectionError and TimeoutError
|
|
68
|
+
- Fails immediately on other exceptions (e.g., auth errors)
|
|
69
|
+
- Attempts connection up to 5 times
|
|
70
|
+
- Initial delay is 0.5 seconds, growing exponentially
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
db_url: Database connection URL
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Connection string on success
|
|
77
|
+
|
|
78
|
+
Raises:
|
|
79
|
+
RetryError: If all 5 attempts fail
|
|
80
|
+
Other exceptions: (e.g., auth errors) propagate immediately
|
|
81
|
+
"""
|
|
82
|
+
logger.info(f"Attempting database connection to {db_url}...")
|
|
83
|
+
import random
|
|
84
|
+
|
|
85
|
+
if random.random() < 0.4: # 40% failure rate
|
|
86
|
+
raise DatabaseConnectionError("Connection refused")
|
|
87
|
+
return f"Connected to {db_url}"
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# ============================================================================
|
|
91
|
+
# Example 3: File Operations with Custom Backoff Parameters
|
|
92
|
+
# ============================================================================
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@retry(
|
|
96
|
+
max_attempts=3,
|
|
97
|
+
initial_delay=0.1,
|
|
98
|
+
max_delay=2.0,
|
|
99
|
+
exponential_base=1.5,
|
|
100
|
+
jitter=True,
|
|
101
|
+
)
|
|
102
|
+
def read_file_with_lock(filepath: str) -> str:
|
|
103
|
+
"""Read file, retrying if locked by another process.
|
|
104
|
+
|
|
105
|
+
Backoff progression with exponential_base=1.5:
|
|
106
|
+
- 1st retry: 0.1s delay
|
|
107
|
+
- 2nd retry: 0.15s delay
|
|
108
|
+
- 3rd retry: 0.225s delay
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
filepath: Path to file to read
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
File contents on success
|
|
115
|
+
"""
|
|
116
|
+
logger.info(f"Reading file: {filepath}...")
|
|
117
|
+
# Simulate file lock scenario
|
|
118
|
+
if time.time() % 2 < 0.5:
|
|
119
|
+
raise OSError("File is locked")
|
|
120
|
+
try:
|
|
121
|
+
with open(filepath) as f:
|
|
122
|
+
return f.read()
|
|
123
|
+
except FileNotFoundError:
|
|
124
|
+
# Don't retry on file not found (application error)
|
|
125
|
+
raise
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# ============================================================================
|
|
129
|
+
# Example 4: Custom Retry Callback for Detailed Logging
|
|
130
|
+
# ============================================================================
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def log_retry_attempt(attempt: int, exc: Exception, delay: float) -> None:
|
|
134
|
+
"""Custom callback for detailed retry logging.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
attempt: Attempt number (1-based)
|
|
138
|
+
exc: Exception that triggered the retry
|
|
139
|
+
delay: Delay in seconds before next attempt
|
|
140
|
+
"""
|
|
141
|
+
logger.warning(
|
|
142
|
+
f"Retry #{attempt} after {delay:.2f}s | Error: {type(exc).__name__}: {exc}"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@retry(
|
|
147
|
+
max_attempts=4,
|
|
148
|
+
initial_delay=0.5,
|
|
149
|
+
on_retry=log_retry_attempt,
|
|
150
|
+
exceptions=(ConnectionError, TimeoutError),
|
|
151
|
+
)
|
|
152
|
+
def fetch_with_detailed_logging(url: str) -> dict[str, Any]:
|
|
153
|
+
"""Fetch data with detailed retry logging.
|
|
154
|
+
|
|
155
|
+
The on_retry callback receives:
|
|
156
|
+
- Attempt number (for counting)
|
|
157
|
+
- Exception details (for diagnosis)
|
|
158
|
+
- Calculated delay (for transparency)
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
url: URL to fetch from
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
Response data on success
|
|
165
|
+
"""
|
|
166
|
+
logger.info(f"Fetching from {url}...")
|
|
167
|
+
import random
|
|
168
|
+
|
|
169
|
+
if random.random() < 0.6:
|
|
170
|
+
raise ConnectionError(f"Cannot reach {url}")
|
|
171
|
+
return {"success": True}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
# ============================================================================
|
|
175
|
+
# Example 5: Class Method with Retry
|
|
176
|
+
# ============================================================================
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class APIClient:
|
|
180
|
+
"""HTTP client with automatic retry logic for resilience."""
|
|
181
|
+
|
|
182
|
+
def __init__(self, base_url: str):
|
|
183
|
+
self.base_url = base_url
|
|
184
|
+
self.request_count = 0
|
|
185
|
+
|
|
186
|
+
@retry(
|
|
187
|
+
max_attempts=3,
|
|
188
|
+
initial_delay=0.2,
|
|
189
|
+
exceptions=(ConnectionError, TimeoutError),
|
|
190
|
+
)
|
|
191
|
+
def get(self, endpoint: str) -> dict[str, Any]:
|
|
192
|
+
"""GET request with automatic retries.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
endpoint: API endpoint path
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Response data
|
|
199
|
+
|
|
200
|
+
Raises:
|
|
201
|
+
RetryError: If all 3 attempts fail
|
|
202
|
+
"""
|
|
203
|
+
self.request_count += 1
|
|
204
|
+
url = f"{self.base_url}/{endpoint}"
|
|
205
|
+
logger.info(f"GET {url} (attempt #{self.request_count})")
|
|
206
|
+
|
|
207
|
+
import random
|
|
208
|
+
|
|
209
|
+
if random.random() < 0.5:
|
|
210
|
+
raise ConnectionError(f"Connection failed to {url}")
|
|
211
|
+
|
|
212
|
+
return {"endpoint": endpoint, "data": "response"}
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
# ============================================================================
|
|
216
|
+
# Example 6: Async Function with Retry
|
|
217
|
+
# ============================================================================
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
@retry_async(
|
|
221
|
+
max_attempts=3,
|
|
222
|
+
initial_delay=0.1,
|
|
223
|
+
max_delay=1.0,
|
|
224
|
+
exceptions=(asyncio.TimeoutError, ConnectionError),
|
|
225
|
+
)
|
|
226
|
+
async def async_fetch_data(url: str) -> dict[str, Any]:
|
|
227
|
+
"""Async function with retry (non-blocking).
|
|
228
|
+
|
|
229
|
+
Uses asyncio.sleep instead of time.sleep, making it suitable for
|
|
230
|
+
concurrent operations and event loop integration.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
url: URL to fetch from
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Response data on success
|
|
237
|
+
|
|
238
|
+
Raises:
|
|
239
|
+
RetryError: If all attempts fail
|
|
240
|
+
"""
|
|
241
|
+
logger.info(f"Async fetch from {url}...")
|
|
242
|
+
await asyncio.sleep(0.1) # Simulate async operation
|
|
243
|
+
|
|
244
|
+
import random
|
|
245
|
+
|
|
246
|
+
if random.random() < 0.4:
|
|
247
|
+
raise ConnectionError(f"Cannot reach {url}")
|
|
248
|
+
|
|
249
|
+
return {"url": url, "data": "async_response"}
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
# ============================================================================
|
|
253
|
+
# Example 7: Multiple Async Operations with Retry
|
|
254
|
+
# ============================================================================
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
async def parallel_async_operations() -> list[dict[str, Any] | BaseException]:
|
|
258
|
+
"""Execute multiple async operations with retry in parallel.
|
|
259
|
+
|
|
260
|
+
Demonstrates how retry_async integrates with asyncio.gather
|
|
261
|
+
for concurrent operations.
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
List of responses from all operations
|
|
265
|
+
"""
|
|
266
|
+
tasks = [
|
|
267
|
+
async_fetch_data("https://api1.example.com"),
|
|
268
|
+
async_fetch_data("https://api2.example.com"),
|
|
269
|
+
async_fetch_data("https://api3.example.com"),
|
|
270
|
+
]
|
|
271
|
+
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
272
|
+
return results
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# ============================================================================
|
|
276
|
+
# Example 8: Aggressive Retry for Critical Operations
|
|
277
|
+
# ============================================================================
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@retry(
|
|
281
|
+
max_attempts=10,
|
|
282
|
+
initial_delay=0.05,
|
|
283
|
+
max_delay=30.0,
|
|
284
|
+
exponential_base=2.0,
|
|
285
|
+
jitter=True,
|
|
286
|
+
)
|
|
287
|
+
def critical_operation() -> str:
|
|
288
|
+
"""Critical operation with aggressive retry strategy.
|
|
289
|
+
|
|
290
|
+
This uses:
|
|
291
|
+
- 10 attempts (many opportunities to succeed)
|
|
292
|
+
- 0.05s initial delay (fail fast initially)
|
|
293
|
+
- Exponential backoff caps at 30s (reasonable upper bound)
|
|
294
|
+
- Jitter to spread retries in distributed systems
|
|
295
|
+
|
|
296
|
+
Backoff sequence: 0.05s, 0.1s, 0.2s, 0.4s, 0.8s, 1.6s, 3.2s, 6.4s, 12.8s, 30s
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
Result on success
|
|
300
|
+
"""
|
|
301
|
+
logger.info("Executing critical operation...")
|
|
302
|
+
import random
|
|
303
|
+
|
|
304
|
+
if random.random() < 0.7: # High initial failure rate
|
|
305
|
+
raise RuntimeError("Critical operation failed")
|
|
306
|
+
return "Critical operation succeeded"
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
# ============================================================================
|
|
310
|
+
# Example 9: No Jitter for Predictable Testing
|
|
311
|
+
# ============================================================================
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@retry(
|
|
315
|
+
max_attempts=3,
|
|
316
|
+
initial_delay=0.1,
|
|
317
|
+
exponential_base=2.0,
|
|
318
|
+
jitter=False, # Deterministic delays for testing
|
|
319
|
+
)
|
|
320
|
+
def predictable_retry() -> str:
|
|
321
|
+
"""Function with deterministic retry timing (no jitter).
|
|
322
|
+
|
|
323
|
+
Without jitter, delays are exactly:
|
|
324
|
+
- 1st retry: 0.1s
|
|
325
|
+
- 2nd retry: 0.2s
|
|
326
|
+
- 3rd retry: 0.4s
|
|
327
|
+
|
|
328
|
+
Useful for testing and benchmarking where predictability matters.
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
Result on success
|
|
332
|
+
"""
|
|
333
|
+
logger.info("Running with predictable retry timing...")
|
|
334
|
+
import random
|
|
335
|
+
|
|
336
|
+
if random.random() < 0.6:
|
|
337
|
+
raise ValueError("Predictable test error")
|
|
338
|
+
return "Success with predictable timing"
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
# ============================================================================
|
|
342
|
+
# Example 10: Combining Multiple Decorators
|
|
343
|
+
# ============================================================================
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def cache_decorator(
|
|
347
|
+
func: Any,
|
|
348
|
+
) -> Any:
|
|
349
|
+
"""Simple cache decorator for demonstration."""
|
|
350
|
+
cache: dict[tuple[Any, ...], Any] = {}
|
|
351
|
+
|
|
352
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
353
|
+
key = (args, tuple(sorted(kwargs.items())))
|
|
354
|
+
if key not in cache:
|
|
355
|
+
cache[key] = func(*args, **kwargs)
|
|
356
|
+
return cache[key]
|
|
357
|
+
|
|
358
|
+
return wrapper
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
@cache_decorator
|
|
362
|
+
@retry(max_attempts=3, initial_delay=0.1)
|
|
363
|
+
def cached_api_call(user_id: int) -> dict[str, Any]:
|
|
364
|
+
"""API call with both retry and caching.
|
|
365
|
+
|
|
366
|
+
Decorator order matters:
|
|
367
|
+
- @cache_decorator (outer): Return cached result if available
|
|
368
|
+
- @retry (inner): Retry network calls (called by cache_decorator)
|
|
369
|
+
|
|
370
|
+
Args:
|
|
371
|
+
user_id: User ID to fetch
|
|
372
|
+
|
|
373
|
+
Returns:
|
|
374
|
+
User data
|
|
375
|
+
"""
|
|
376
|
+
logger.info(f"Fetching user {user_id}...")
|
|
377
|
+
import random
|
|
378
|
+
|
|
379
|
+
if random.random() < 0.4:
|
|
380
|
+
raise ConnectionError("API connection failed")
|
|
381
|
+
return {"id": user_id, "name": f"User {user_id}"}
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
# ============================================================================
|
|
385
|
+
# Main Demo
|
|
386
|
+
# ============================================================================
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def main() -> None:
|
|
390
|
+
"""Run all examples to demonstrate retry decorator usage."""
|
|
391
|
+
logger.info("=" * 70)
|
|
392
|
+
logger.info("RETRY DECORATOR EXAMPLES")
|
|
393
|
+
logger.info("=" * 70)
|
|
394
|
+
|
|
395
|
+
# Example 1: Basic API call
|
|
396
|
+
logger.info("\n1. Basic API call with default retry:")
|
|
397
|
+
try:
|
|
398
|
+
result = fetch_from_api()
|
|
399
|
+
logger.info(f" Result: {result}")
|
|
400
|
+
except Exception as e:
|
|
401
|
+
logger.error(f" Failed: {e}")
|
|
402
|
+
|
|
403
|
+
# Example 2: Database with specific exceptions
|
|
404
|
+
logger.info("\n2. Database connection with exception filtering:")
|
|
405
|
+
try:
|
|
406
|
+
result = connect_to_database("postgresql://localhost/mydb")
|
|
407
|
+
logger.info(f" Result: {result}")
|
|
408
|
+
except Exception as e:
|
|
409
|
+
logger.error(f" Failed: {e}")
|
|
410
|
+
|
|
411
|
+
# Example 3: File operations with custom backoff
|
|
412
|
+
logger.info("\n3. File read with custom backoff parameters:")
|
|
413
|
+
try:
|
|
414
|
+
# Create a test file
|
|
415
|
+
test_file = "/tmp/test_retry_example.txt"
|
|
416
|
+
with open(test_file, "w") as f:
|
|
417
|
+
f.write("Test content")
|
|
418
|
+
|
|
419
|
+
result = read_file_with_lock(test_file)
|
|
420
|
+
logger.info(f" File read successfully (length: {len(result)} chars)")
|
|
421
|
+
except Exception as e:
|
|
422
|
+
logger.error(f" Failed: {e}")
|
|
423
|
+
|
|
424
|
+
# Example 4: Custom logging callback
|
|
425
|
+
logger.info("\n4. API fetch with detailed retry logging:")
|
|
426
|
+
try:
|
|
427
|
+
result = fetch_with_detailed_logging("https://api.example.com")
|
|
428
|
+
logger.info(f" Result: {result}")
|
|
429
|
+
except Exception as e:
|
|
430
|
+
logger.error(f" Failed: {e}")
|
|
431
|
+
|
|
432
|
+
# Example 5: Class method retry
|
|
433
|
+
logger.info("\n5. HTTP client class with retry on methods:")
|
|
434
|
+
try:
|
|
435
|
+
client = APIClient("https://api.example.com")
|
|
436
|
+
result = client.get("users")
|
|
437
|
+
logger.info(f" Result: {result}")
|
|
438
|
+
except Exception as e:
|
|
439
|
+
logger.error(f" Failed: {e}")
|
|
440
|
+
|
|
441
|
+
# Example 6: Async function
|
|
442
|
+
logger.info("\n6. Async function with retry:")
|
|
443
|
+
|
|
444
|
+
async def run_async_example() -> None:
|
|
445
|
+
try:
|
|
446
|
+
result = await async_fetch_data("https://async-api.example.com")
|
|
447
|
+
logger.info(f" Async Result: {result}")
|
|
448
|
+
except Exception as e:
|
|
449
|
+
logger.error(f" Async Failed: {e}")
|
|
450
|
+
|
|
451
|
+
asyncio.run(run_async_example())
|
|
452
|
+
|
|
453
|
+
# Example 7: Parallel async operations
|
|
454
|
+
logger.info("\n7. Parallel async operations with retry:")
|
|
455
|
+
|
|
456
|
+
async def run_parallel_example() -> None:
|
|
457
|
+
try:
|
|
458
|
+
results = await parallel_async_operations()
|
|
459
|
+
logger.info(f" Parallel Results: {len(results)} operations completed")
|
|
460
|
+
except Exception as e:
|
|
461
|
+
logger.error(f" Parallel Failed: {e}")
|
|
462
|
+
|
|
463
|
+
asyncio.run(run_parallel_example())
|
|
464
|
+
|
|
465
|
+
# Example 8: Aggressive retry
|
|
466
|
+
logger.info("\n8. Critical operation with aggressive retry:")
|
|
467
|
+
try:
|
|
468
|
+
result = critical_operation()
|
|
469
|
+
logger.info(f" Result: {result}")
|
|
470
|
+
except Exception as e:
|
|
471
|
+
logger.error(f" Failed: {e}")
|
|
472
|
+
|
|
473
|
+
# Example 9: Predictable timing
|
|
474
|
+
logger.info("\n9. Function with predictable retry timing:")
|
|
475
|
+
try:
|
|
476
|
+
result = predictable_retry()
|
|
477
|
+
logger.info(f" Result: {result}")
|
|
478
|
+
except Exception as e:
|
|
479
|
+
logger.error(f" Failed: {e}")
|
|
480
|
+
|
|
481
|
+
# Example 10: Cached API call
|
|
482
|
+
logger.info("\n10. Cached API call (retry + caching):")
|
|
483
|
+
try:
|
|
484
|
+
# First call - goes to API with retry
|
|
485
|
+
result1 = cached_api_call(123)
|
|
486
|
+
logger.info(f" First call: {result1}")
|
|
487
|
+
|
|
488
|
+
# Second call - returns from cache
|
|
489
|
+
result2 = cached_api_call(123)
|
|
490
|
+
logger.info(f" Second call (cached): {result2}")
|
|
491
|
+
except Exception as e:
|
|
492
|
+
logger.error(f" Failed: {e}")
|
|
493
|
+
|
|
494
|
+
logger.info("\n" + "=" * 70)
|
|
495
|
+
logger.info("EXAMPLES COMPLETE")
|
|
496
|
+
logger.info("=" * 70)
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
if __name__ == "__main__":
|
|
500
|
+
main()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "htmlgraph",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.24",
|
|
4
4
|
"description": "HtmlGraph session tracking and documentation for Gemini CLI. Ensures proper activity attribution, feature awareness, and continuous work tracking.",
|
|
5
5
|
"author": "Shakes",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,6 +19,7 @@ from htmlgraph.atomic_ops import (
|
|
|
19
19
|
from htmlgraph.builders import BaseBuilder, FeatureBuilder, SpikeBuilder
|
|
20
20
|
from htmlgraph.collections import BaseCollection, FeatureCollection, SpikeCollection
|
|
21
21
|
from htmlgraph.context_analytics import ContextAnalytics, ContextUsage
|
|
22
|
+
from htmlgraph.decorators import RetryError, retry, retry_async
|
|
22
23
|
from htmlgraph.edge_index import EdgeIndex, EdgeRef
|
|
23
24
|
from htmlgraph.exceptions import (
|
|
24
25
|
ClaimConflictError,
|
|
@@ -95,7 +96,7 @@ from htmlgraph.types import (
|
|
|
95
96
|
)
|
|
96
97
|
from htmlgraph.work_type_utils import infer_work_type, infer_work_type_from_id
|
|
97
98
|
|
|
98
|
-
__version__ = "0.26.
|
|
99
|
+
__version__ = "0.26.24"
|
|
99
100
|
__all__ = [
|
|
100
101
|
# Exceptions
|
|
101
102
|
"HtmlGraphError",
|
|
@@ -103,6 +104,10 @@ __all__ = [
|
|
|
103
104
|
"SessionNotFoundError",
|
|
104
105
|
"ClaimConflictError",
|
|
105
106
|
"ValidationError",
|
|
107
|
+
"RetryError",
|
|
108
|
+
# Decorators
|
|
109
|
+
"retry",
|
|
110
|
+
"retry_async",
|
|
106
111
|
# Core models
|
|
107
112
|
"Node",
|
|
108
113
|
"Edge",
|