praisonai-code 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- praisonai_code/__init__.py +17 -0
- praisonai_code/cli/__init__.py +12 -0
- praisonai_code/cli/_forward_shim.py +10 -0
- praisonai_code/cli/_paths.py +88 -0
- praisonai_code/cli/_warnings.py +58 -0
- praisonai_code/cli/app.py +757 -0
- praisonai_code/cli/approval_backend.py +272 -0
- praisonai_code/cli/branding.py +94 -0
- praisonai_code/cli/commands/__init__.py +114 -0
- praisonai_code/cli/commands/acp.py +80 -0
- praisonai_code/cli/commands/agent.py +116 -0
- praisonai_code/cli/commands/agents.py +80 -0
- praisonai_code/cli/commands/app.py +139 -0
- praisonai_code/cli/commands/attach.py +95 -0
- praisonai_code/cli/commands/audit.py +102 -0
- praisonai_code/cli/commands/auth.py +508 -0
- praisonai_code/cli/commands/batch.py +848 -0
- praisonai_code/cli/commands/benchmark.py +286 -0
- praisonai_code/cli/commands/browser.py +299 -0
- praisonai_code/cli/commands/call.py +45 -0
- praisonai_code/cli/commands/chat.py +332 -0
- praisonai_code/cli/commands/checkpoint.py +170 -0
- praisonai_code/cli/commands/code.py +276 -0
- praisonai_code/cli/commands/command.py +114 -0
- praisonai_code/cli/commands/commit.py +47 -0
- praisonai_code/cli/commands/completion.py +333 -0
- praisonai_code/cli/commands/config.py +681 -0
- praisonai_code/cli/commands/context.py +414 -0
- praisonai_code/cli/commands/daemon.py +203 -0
- praisonai_code/cli/commands/debug.py +142 -0
- praisonai_code/cli/commands/deploy.py +71 -0
- praisonai_code/cli/commands/diag.py +55 -0
- praisonai_code/cli/commands/docs.py +1575 -0
- praisonai_code/cli/commands/doctor.py +332 -0
- praisonai_code/cli/commands/endpoints.py +51 -0
- praisonai_code/cli/commands/environment.py +179 -0
- praisonai_code/cli/commands/eval.py +131 -0
- praisonai_code/cli/commands/examples.py +953 -0
- praisonai_code/cli/commands/flow.py +436 -0
- praisonai_code/cli/commands/github.py +752 -0
- praisonai_code/cli/commands/hooks.py +74 -0
- praisonai_code/cli/commands/init.py +174 -0
- praisonai_code/cli/commands/knowledge.py +440 -0
- praisonai_code/cli/commands/langextract.py +120 -0
- praisonai_code/cli/commands/langfuse.py +984 -0
- praisonai_code/cli/commands/loop.py +211 -0
- praisonai_code/cli/commands/lsp.py +112 -0
- praisonai_code/cli/commands/managed.py +659 -0
- praisonai_code/cli/commands/mcp.py +763 -0
- praisonai_code/cli/commands/memory.py +298 -0
- praisonai_code/cli/commands/models.py +264 -0
- praisonai_code/cli/commands/n8n.py +326 -0
- praisonai_code/cli/commands/obs.py +19 -0
- praisonai_code/cli/commands/package.py +76 -0
- praisonai_code/cli/commands/paths.py +106 -0
- praisonai_code/cli/commands/permissions.py +272 -0
- praisonai_code/cli/commands/plugins.py +609 -0
- praisonai_code/cli/commands/port.py +530 -0
- praisonai_code/cli/commands/profile.py +466 -0
- praisonai_code/cli/commands/publish.py +193 -0
- praisonai_code/cli/commands/rag.py +913 -0
- praisonai_code/cli/commands/realtime.py +52 -0
- praisonai_code/cli/commands/recipe.py +684 -0
- praisonai_code/cli/commands/registry.py +59 -0
- praisonai_code/cli/commands/replay.py +830 -0
- praisonai_code/cli/commands/research.py +49 -0
- praisonai_code/cli/commands/retrieval.py +377 -0
- praisonai_code/cli/commands/rules.py +71 -0
- praisonai_code/cli/commands/run.py +1573 -0
- praisonai_code/cli/commands/sandbox.py +371 -0
- praisonai_code/cli/commands/schedule.py +529 -0
- praisonai_code/cli/commands/serve.py +690 -0
- praisonai_code/cli/commands/session.py +450 -0
- praisonai_code/cli/commands/setup.py +174 -0
- praisonai_code/cli/commands/skills.py +545 -0
- praisonai_code/cli/commands/standardise.py +711 -0
- praisonai_code/cli/commands/templates.py +54 -0
- praisonai_code/cli/commands/test.py +558 -0
- praisonai_code/cli/commands/todo.py +74 -0
- praisonai_code/cli/commands/tools.py +205 -0
- praisonai_code/cli/commands/traces.py +145 -0
- praisonai_code/cli/commands/tracker.py +852 -0
- praisonai_code/cli/commands/train.py +613 -0
- praisonai_code/cli/commands/ui.py +172 -0
- praisonai_code/cli/commands/up.py +354 -0
- praisonai_code/cli/commands/validate.py +291 -0
- praisonai_code/cli/commands/version.py +101 -0
- praisonai_code/cli/commands/workflow.py +97 -0
- praisonai_code/cli/config_loader.py +437 -0
- praisonai_code/cli/configuration/__init__.py +27 -0
- praisonai_code/cli/configuration/config.schema.json +57 -0
- praisonai_code/cli/configuration/credentials.py +446 -0
- praisonai_code/cli/configuration/loader.py +364 -0
- praisonai_code/cli/configuration/model_resolver.py +161 -0
- praisonai_code/cli/configuration/oauth.py +389 -0
- praisonai_code/cli/configuration/paths.py +224 -0
- praisonai_code/cli/configuration/resolver.py +687 -0
- praisonai_code/cli/configuration/schema.py +317 -0
- praisonai_code/cli/execution/__init__.py +99 -0
- praisonai_code/cli/execution/core.py +208 -0
- praisonai_code/cli/execution/profiler.py +898 -0
- praisonai_code/cli/execution/request.py +85 -0
- praisonai_code/cli/execution/result.py +74 -0
- praisonai_code/cli/fallback_schema.py +416 -0
- praisonai_code/cli/features/__init__.py +278 -0
- praisonai_code/cli/features/_endpoint_registry.py +64 -0
- praisonai_code/cli/features/_search_registry.py +43 -0
- praisonai_code/cli/features/acp.py +236 -0
- praisonai_code/cli/features/action_orchestrator.py +576 -0
- praisonai_code/cli/features/agent_scheduler.py +773 -0
- praisonai_code/cli/features/agent_tools.py +603 -0
- praisonai_code/cli/features/agents.py +397 -0
- praisonai_code/cli/features/at_mentions.py +471 -0
- praisonai_code/cli/features/audit_cli.py +270 -0
- praisonai_code/cli/features/auto_memory.py +182 -0
- praisonai_code/cli/features/auto_mode.py +552 -0
- praisonai_code/cli/features/autonomy_mode.py +546 -0
- praisonai_code/cli/features/background.py +356 -0
- praisonai_code/cli/features/base.py +168 -0
- praisonai_code/cli/features/benchmark.py +1462 -0
- praisonai_code/cli/features/capabilities.py +1326 -0
- praisonai_code/cli/features/checkpoints.py +345 -0
- praisonai_code/cli/features/cli_profiler.py +335 -0
- praisonai_code/cli/features/code_intelligence.py +666 -0
- praisonai_code/cli/features/compaction.py +294 -0
- praisonai_code/cli/features/compare.py +534 -0
- praisonai_code/cli/features/config_hierarchy.py +366 -0
- praisonai_code/cli/features/context_manager.py +597 -0
- praisonai_code/cli/features/cost_tracker.py +514 -0
- praisonai_code/cli/features/csv_test_runner.py +736 -0
- praisonai_code/cli/features/custom_definitions.py +790 -0
- praisonai_code/cli/features/debug.py +810 -0
- praisonai_code/cli/features/deploy.py +605 -0
- praisonai_code/cli/features/diag.py +289 -0
- praisonai_code/cli/features/display_jsonl.py +173 -0
- praisonai_code/cli/features/doctor/__init__.py +63 -0
- praisonai_code/cli/features/doctor/checks/__init__.py +29 -0
- praisonai_code/cli/features/doctor/checks/acp_checks.py +220 -0
- praisonai_code/cli/features/doctor/checks/bot_checks.py +340 -0
- praisonai_code/cli/features/doctor/checks/config_checks.py +373 -0
- praisonai_code/cli/features/doctor/checks/db_checks.py +366 -0
- praisonai_code/cli/features/doctor/checks/env_checks.py +637 -0
- praisonai_code/cli/features/doctor/checks/gateway_checks.py +387 -0
- praisonai_code/cli/features/doctor/checks/lsp_checks.py +231 -0
- praisonai_code/cli/features/doctor/checks/mcp_checks.py +367 -0
- praisonai_code/cli/features/doctor/checks/memory_checks.py +268 -0
- praisonai_code/cli/features/doctor/checks/network_checks.py +251 -0
- praisonai_code/cli/features/doctor/checks/obs_checks.py +328 -0
- praisonai_code/cli/features/doctor/checks/packaging_checks.py +422 -0
- praisonai_code/cli/features/doctor/checks/performance_checks.py +235 -0
- praisonai_code/cli/features/doctor/checks/permissions_checks.py +259 -0
- praisonai_code/cli/features/doctor/checks/runtime_checks.py +650 -0
- praisonai_code/cli/features/doctor/checks/runtime_migration_checks.py +220 -0
- praisonai_code/cli/features/doctor/checks/selftest_checks.py +322 -0
- praisonai_code/cli/features/doctor/checks/serve_checks.py +426 -0
- praisonai_code/cli/features/doctor/checks/skills_checks.py +327 -0
- praisonai_code/cli/features/doctor/checks/tools_checks.py +371 -0
- praisonai_code/cli/features/doctor/engine.py +266 -0
- praisonai_code/cli/features/doctor/formatters.py +377 -0
- praisonai_code/cli/features/doctor/handler.py +564 -0
- praisonai_code/cli/features/doctor/models.py +276 -0
- praisonai_code/cli/features/doctor/registry.py +239 -0
- praisonai_code/cli/features/endpoints.py +1016 -0
- praisonai_code/cli/features/eval.py +559 -0
- praisonai_code/cli/features/examples.py +707 -0
- praisonai_code/cli/features/external_agents.py +231 -0
- praisonai_code/cli/features/fast_context.py +410 -0
- praisonai_code/cli/features/file_history.py +320 -0
- praisonai_code/cli/features/flow_display.py +566 -0
- praisonai_code/cli/features/git_attribution.py +159 -0
- praisonai_code/cli/features/git_integration.py +651 -0
- praisonai_code/cli/features/guardrail.py +171 -0
- praisonai_code/cli/features/handoff.py +252 -0
- praisonai_code/cli/features/hooks.py +583 -0
- praisonai_code/cli/features/hybrid_workflow.py +391 -0
- praisonai_code/cli/features/image.py +384 -0
- praisonai_code/cli/features/interactive_core_headless.py +450 -0
- praisonai_code/cli/features/interactive_runtime.py +600 -0
- praisonai_code/cli/features/interactive_test_harness.py +537 -0
- praisonai_code/cli/features/interactive_tools.py +428 -0
- praisonai_code/cli/features/interactive_tui.py +603 -0
- praisonai_code/cli/features/job_workflow.py +906 -0
- praisonai_code/cli/features/jobs.py +632 -0
- praisonai_code/cli/features/knowledge.py +531 -0
- praisonai_code/cli/features/knowledge_cli.py +438 -0
- praisonai_code/cli/features/lite.py +244 -0
- praisonai_code/cli/features/logs.py +200 -0
- praisonai_code/cli/features/lsp_cli.py +225 -0
- praisonai_code/cli/features/lsp_diagnostics.py +185 -0
- praisonai_code/cli/features/mcp.py +344 -0
- praisonai_code/cli/features/message_queue.py +587 -0
- praisonai_code/cli/features/metrics.py +210 -0
- praisonai_code/cli/features/migrate.py +1329 -0
- praisonai_code/cli/features/migration_flow.py +463 -0
- praisonai_code/cli/features/migration_spec.py +276 -0
- praisonai_code/cli/features/n8n.py +703 -0
- praisonai_code/cli/features/observability.py +293 -0
- praisonai_code/cli/features/ollama.py +361 -0
- praisonai_code/cli/features/output_modes.py +155 -0
- praisonai_code/cli/features/output_style.py +273 -0
- praisonai_code/cli/features/package.py +631 -0
- praisonai_code/cli/features/performance.py +308 -0
- praisonai_code/cli/features/persistence.py +636 -0
- praisonai_code/cli/features/profiler/__init__.py +81 -0
- praisonai_code/cli/features/profiler/core.py +558 -0
- praisonai_code/cli/features/profiler/optimizations.py +652 -0
- praisonai_code/cli/features/profiler/suite.py +386 -0
- praisonai_code/cli/features/queue/__init__.py +73 -0
- praisonai_code/cli/features/queue/manager.py +435 -0
- praisonai_code/cli/features/queue/models.py +289 -0
- praisonai_code/cli/features/queue/persistence.py +564 -0
- praisonai_code/cli/features/queue/scheduler.py +529 -0
- praisonai_code/cli/features/queue/worker.py +400 -0
- praisonai_code/cli/features/recipe.py +2187 -0
- praisonai_code/cli/features/recipe_creator.py +996 -0
- praisonai_code/cli/features/recipe_optimizer.py +1364 -0
- praisonai_code/cli/features/recipe_prompts.py +226 -0
- praisonai_code/cli/features/registry.py +229 -0
- praisonai_code/cli/features/repo_map.py +860 -0
- praisonai_code/cli/features/router.py +466 -0
- praisonai_code/cli/features/safe_shell.py +427 -0
- praisonai_code/cli/features/sandbox_cli.py +283 -0
- praisonai_code/cli/features/sandbox_executor.py +536 -0
- praisonai_code/cli/features/sdk_knowledge.py +500 -0
- praisonai_code/cli/features/session.py +222 -0
- praisonai_code/cli/features/session_checkpoints.py +208 -0
- praisonai_code/cli/features/setup/__init__.py +9 -0
- praisonai_code/cli/features/setup/handler.py +355 -0
- praisonai_code/cli/features/setup/templates.py +62 -0
- praisonai_code/cli/features/skills.py +940 -0
- praisonai_code/cli/features/slash_commands.py +692 -0
- praisonai_code/cli/features/telemetry.py +179 -0
- praisonai_code/cli/features/templates.py +1390 -0
- praisonai_code/cli/features/thinking.py +343 -0
- praisonai_code/cli/features/todo.py +334 -0
- praisonai_code/cli/features/tools.py +680 -0
- praisonai_code/cli/features/tui/__init__.py +83 -0
- praisonai_code/cli/features/tui/app.py +871 -0
- praisonai_code/cli/features/tui/cli.py +580 -0
- praisonai_code/cli/features/tui/config.py +150 -0
- praisonai_code/cli/features/tui/debug.py +526 -0
- praisonai_code/cli/features/tui/events.py +99 -0
- praisonai_code/cli/features/tui/mock_provider.py +328 -0
- praisonai_code/cli/features/tui/orchestrator.py +652 -0
- praisonai_code/cli/features/tui/screens/__init__.py +50 -0
- praisonai_code/cli/features/tui/screens/help.py +157 -0
- praisonai_code/cli/features/tui/screens/main.py +568 -0
- praisonai_code/cli/features/tui/screens/queue.py +174 -0
- praisonai_code/cli/features/tui/screens/session.py +124 -0
- praisonai_code/cli/features/tui/screens/settings.py +148 -0
- praisonai_code/cli/features/tui/session_store.py +198 -0
- praisonai_code/cli/features/tui/widgets/__init__.py +56 -0
- praisonai_code/cli/features/tui/widgets/chat.py +263 -0
- praisonai_code/cli/features/tui/widgets/command_popup.py +258 -0
- praisonai_code/cli/features/tui/widgets/composer.py +292 -0
- praisonai_code/cli/features/tui/widgets/file_popup.py +207 -0
- praisonai_code/cli/features/tui/widgets/queue_panel.py +223 -0
- praisonai_code/cli/features/tui/widgets/status.py +181 -0
- praisonai_code/cli/features/tui/widgets/tool_panel.py +307 -0
- praisonai_code/cli/features/wizard.py +289 -0
- praisonai_code/cli/features/workflow.py +802 -0
- praisonai_code/cli/features/yaml_utils.py +321 -0
- praisonai_code/cli/interactive/__init__.py +48 -0
- praisonai_code/cli/interactive/async_tui.py +1218 -0
- praisonai_code/cli/interactive/config.py +139 -0
- praisonai_code/cli/interactive/core.py +618 -0
- praisonai_code/cli/interactive/events.py +131 -0
- praisonai_code/cli/interactive/frontends/__init__.py +31 -0
- praisonai_code/cli/interactive/frontends/rich_frontend.py +462 -0
- praisonai_code/cli/interactive/frontends/textual_frontend.py +157 -0
- praisonai_code/cli/interactive/praison_io.py +502 -0
- praisonai_code/cli/interactive/repl.py +297 -0
- praisonai_code/cli/interactive/split_tui.py +456 -0
- praisonai_code/cli/interactive/tui_app.py +457 -0
- praisonai_code/cli/langfuse_client.py +360 -0
- praisonai_code/cli/main.py +7421 -0
- praisonai_code/cli/output/__init__.py +25 -0
- praisonai_code/cli/output/console.py +456 -0
- praisonai_code/cli/output/event_bridge.py +191 -0
- praisonai_code/cli/schedule_cli.py +54 -0
- praisonai_code/cli/schema_provider.py +23 -0
- praisonai_code/cli/session/__init__.py +16 -0
- praisonai_code/cli/session/resume.py +148 -0
- praisonai_code/cli/session/unified.py +548 -0
- praisonai_code/cli/state/__init__.py +31 -0
- praisonai_code/cli/state/identifiers.py +161 -0
- praisonai_code/cli/state/project_sessions.py +383 -0
- praisonai_code/cli/state/sessions.py +390 -0
- praisonai_code/cli/ui/__init__.py +160 -0
- praisonai_code/cli/ui/config.py +46 -0
- praisonai_code/cli/ui/events.py +61 -0
- praisonai_code/cli/ui/mg_backend.py +342 -0
- praisonai_code/cli/ui/plain.py +133 -0
- praisonai_code/cli/ui/rich_backend.py +162 -0
- praisonai_code/cli/unified_schema.py +655 -0
- praisonai_code/cli/utils/env_utils.py +126 -0
- praisonai_code/cli/utils/project.py +131 -0
- praisonai_code/cli_backends/__init__.py +73 -0
- praisonai_code/cli_backends/claude.py +373 -0
- praisonai_code/cli_backends/registry.py +113 -0
- praisonai_code/runtime/__init__.py +36 -0
- praisonai_code/runtime/__main__.py +81 -0
- praisonai_code/runtime/client.py +131 -0
- praisonai_code/runtime/descriptor.py +209 -0
- praisonai_code/runtime/server.py +356 -0
- praisonai_code-0.0.1.dist-info/METADATA +80 -0
- praisonai_code-0.0.1.dist-info/RECORD +309 -0
- praisonai_code-0.0.1.dist-info/WHEEL +5 -0
- praisonai_code-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Data models for the PraisonAI Queue System.
|
|
3
|
+
|
|
4
|
+
Defines QueuedRun, RunState, RunPriority, and QueueConfig.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from enum import Enum, IntEnum
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
import time
|
|
11
|
+
import uuid
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class RunState(str, Enum):
|
|
15
|
+
"""State of a queued run."""
|
|
16
|
+
QUEUED = "queued"
|
|
17
|
+
RUNNING = "running"
|
|
18
|
+
PAUSED = "paused"
|
|
19
|
+
SUCCEEDED = "succeeded"
|
|
20
|
+
FAILED = "failed"
|
|
21
|
+
CANCELLED = "cancelled"
|
|
22
|
+
|
|
23
|
+
def is_terminal(self) -> bool:
|
|
24
|
+
"""Check if this is a terminal state."""
|
|
25
|
+
return self in (RunState.SUCCEEDED, RunState.FAILED, RunState.CANCELLED)
|
|
26
|
+
|
|
27
|
+
def is_active(self) -> bool:
|
|
28
|
+
"""Check if this is an active (non-terminal) state."""
|
|
29
|
+
return not self.is_terminal()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class RunPriority(IntEnum):
|
|
33
|
+
"""Priority levels for queued runs. Higher value = higher priority."""
|
|
34
|
+
LOW = 0
|
|
35
|
+
NORMAL = 1
|
|
36
|
+
HIGH = 2
|
|
37
|
+
URGENT = 3
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def from_string(cls, s: str) -> "RunPriority":
|
|
41
|
+
"""Parse priority from string."""
|
|
42
|
+
mapping = {
|
|
43
|
+
"low": cls.LOW,
|
|
44
|
+
"normal": cls.NORMAL,
|
|
45
|
+
"high": cls.HIGH,
|
|
46
|
+
"urgent": cls.URGENT,
|
|
47
|
+
}
|
|
48
|
+
return mapping.get(s.lower(), cls.NORMAL)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class QueuedRun:
|
|
53
|
+
"""A single queued agent run."""
|
|
54
|
+
|
|
55
|
+
# Identity
|
|
56
|
+
run_id: str = field(default_factory=lambda: str(uuid.uuid4())[:8])
|
|
57
|
+
agent_name: str = ""
|
|
58
|
+
input_content: str = ""
|
|
59
|
+
|
|
60
|
+
# State
|
|
61
|
+
state: RunState = RunState.QUEUED
|
|
62
|
+
priority: RunPriority = RunPriority.NORMAL
|
|
63
|
+
|
|
64
|
+
# Attribution / tracing
|
|
65
|
+
session_id: Optional[str] = None
|
|
66
|
+
trace_id: Optional[str] = None
|
|
67
|
+
workspace: Optional[str] = None
|
|
68
|
+
user_id: Optional[str] = None
|
|
69
|
+
|
|
70
|
+
# Timing
|
|
71
|
+
created_at: float = field(default_factory=time.time)
|
|
72
|
+
started_at: Optional[float] = None
|
|
73
|
+
ended_at: Optional[float] = None
|
|
74
|
+
|
|
75
|
+
# Results
|
|
76
|
+
output_content: Optional[str] = None
|
|
77
|
+
error: Optional[str] = None
|
|
78
|
+
metrics: Dict[str, Any] = field(default_factory=dict)
|
|
79
|
+
|
|
80
|
+
# Retry tracking
|
|
81
|
+
retry_count: int = 0
|
|
82
|
+
max_retries: int = 3
|
|
83
|
+
parent_run_id: Optional[str] = None # Link to original run if this is a retry
|
|
84
|
+
|
|
85
|
+
# Configuration
|
|
86
|
+
config: Dict[str, Any] = field(default_factory=dict)
|
|
87
|
+
|
|
88
|
+
# Chat history for session continuity
|
|
89
|
+
chat_history: List[Dict[str, str]] = field(default_factory=list)
|
|
90
|
+
|
|
91
|
+
# Streaming state
|
|
92
|
+
output_chunks: List[str] = field(default_factory=list)
|
|
93
|
+
|
|
94
|
+
def __post_init__(self):
|
|
95
|
+
"""Ensure proper types after initialization."""
|
|
96
|
+
if isinstance(self.state, str):
|
|
97
|
+
self.state = RunState(self.state)
|
|
98
|
+
if isinstance(self.priority, int) and not isinstance(self.priority, RunPriority):
|
|
99
|
+
self.priority = RunPriority(self.priority)
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def duration_seconds(self) -> Optional[float]:
|
|
103
|
+
"""Get run duration in seconds."""
|
|
104
|
+
if self.started_at is None:
|
|
105
|
+
return None
|
|
106
|
+
end = self.ended_at or time.time()
|
|
107
|
+
return end - self.started_at
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def wait_seconds(self) -> float:
|
|
111
|
+
"""Get time spent waiting in queue."""
|
|
112
|
+
start = self.started_at or time.time()
|
|
113
|
+
return start - self.created_at
|
|
114
|
+
|
|
115
|
+
def can_retry(self) -> bool:
|
|
116
|
+
"""Check if this run can be retried."""
|
|
117
|
+
return (
|
|
118
|
+
self.state == RunState.FAILED and
|
|
119
|
+
self.retry_count < self.max_retries
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
123
|
+
"""Convert to dictionary for persistence."""
|
|
124
|
+
return {
|
|
125
|
+
"run_id": self.run_id,
|
|
126
|
+
"agent_name": self.agent_name,
|
|
127
|
+
"input_content": self.input_content,
|
|
128
|
+
"state": self.state.value,
|
|
129
|
+
"priority": int(self.priority),
|
|
130
|
+
"session_id": self.session_id,
|
|
131
|
+
"trace_id": self.trace_id,
|
|
132
|
+
"workspace": self.workspace,
|
|
133
|
+
"user_id": self.user_id,
|
|
134
|
+
"created_at": self.created_at,
|
|
135
|
+
"started_at": self.started_at,
|
|
136
|
+
"ended_at": self.ended_at,
|
|
137
|
+
"output_content": self.output_content,
|
|
138
|
+
"error": self.error,
|
|
139
|
+
"metrics": self.metrics,
|
|
140
|
+
"retry_count": self.retry_count,
|
|
141
|
+
"max_retries": self.max_retries,
|
|
142
|
+
"parent_run_id": self.parent_run_id,
|
|
143
|
+
"config": self.config,
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@classmethod
|
|
147
|
+
def from_dict(cls, data: Dict[str, Any]) -> "QueuedRun":
|
|
148
|
+
"""Create from dictionary."""
|
|
149
|
+
# Handle state conversion
|
|
150
|
+
state = data.get("state", "queued")
|
|
151
|
+
if isinstance(state, str):
|
|
152
|
+
state = RunState(state)
|
|
153
|
+
|
|
154
|
+
# Handle priority conversion
|
|
155
|
+
priority = data.get("priority", 1)
|
|
156
|
+
if isinstance(priority, int):
|
|
157
|
+
priority = RunPriority(priority)
|
|
158
|
+
|
|
159
|
+
return cls(
|
|
160
|
+
run_id=data.get("run_id", str(uuid.uuid4())[:8]),
|
|
161
|
+
agent_name=data.get("agent_name", ""),
|
|
162
|
+
input_content=data.get("input_content", ""),
|
|
163
|
+
state=state,
|
|
164
|
+
priority=priority,
|
|
165
|
+
session_id=data.get("session_id"),
|
|
166
|
+
trace_id=data.get("trace_id"),
|
|
167
|
+
workspace=data.get("workspace"),
|
|
168
|
+
user_id=data.get("user_id"),
|
|
169
|
+
created_at=data.get("created_at", time.time()),
|
|
170
|
+
started_at=data.get("started_at"),
|
|
171
|
+
ended_at=data.get("ended_at"),
|
|
172
|
+
output_content=data.get("output_content"),
|
|
173
|
+
error=data.get("error"),
|
|
174
|
+
metrics=data.get("metrics", {}),
|
|
175
|
+
retry_count=data.get("retry_count", 0),
|
|
176
|
+
max_retries=data.get("max_retries", 3),
|
|
177
|
+
parent_run_id=data.get("parent_run_id"),
|
|
178
|
+
config=data.get("config", {}),
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@dataclass
|
|
183
|
+
class QueueConfig:
|
|
184
|
+
"""Configuration for the queue system."""
|
|
185
|
+
|
|
186
|
+
# Concurrency limits
|
|
187
|
+
max_concurrent_global: int = 4
|
|
188
|
+
max_concurrent_per_agent: int = 2
|
|
189
|
+
max_concurrent_per_workspace: int = 4
|
|
190
|
+
|
|
191
|
+
# Queue limits
|
|
192
|
+
max_queue_size: int = 100
|
|
193
|
+
|
|
194
|
+
# Defaults
|
|
195
|
+
default_priority: RunPriority = RunPriority.NORMAL
|
|
196
|
+
default_max_retries: int = 3
|
|
197
|
+
|
|
198
|
+
# Persistence
|
|
199
|
+
enable_persistence: bool = True
|
|
200
|
+
db_path: str = ".praison/queue.db"
|
|
201
|
+
|
|
202
|
+
# Autosave
|
|
203
|
+
autosave_interval_seconds: float = 30.0
|
|
204
|
+
|
|
205
|
+
# Backpressure
|
|
206
|
+
stream_buffer_size: int = 1000
|
|
207
|
+
drop_strategy: str = "oldest" # "oldest" or "newest"
|
|
208
|
+
|
|
209
|
+
# Timeouts
|
|
210
|
+
run_timeout_seconds: Optional[float] = None # None = no timeout
|
|
211
|
+
worker_poll_interval: float = 0.1
|
|
212
|
+
|
|
213
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
214
|
+
"""Convert to dictionary."""
|
|
215
|
+
return {
|
|
216
|
+
"max_concurrent_global": self.max_concurrent_global,
|
|
217
|
+
"max_concurrent_per_agent": self.max_concurrent_per_agent,
|
|
218
|
+
"max_concurrent_per_workspace": self.max_concurrent_per_workspace,
|
|
219
|
+
"max_queue_size": self.max_queue_size,
|
|
220
|
+
"default_priority": int(self.default_priority),
|
|
221
|
+
"default_max_retries": self.default_max_retries,
|
|
222
|
+
"enable_persistence": self.enable_persistence,
|
|
223
|
+
"db_path": self.db_path,
|
|
224
|
+
"autosave_interval_seconds": self.autosave_interval_seconds,
|
|
225
|
+
"stream_buffer_size": self.stream_buffer_size,
|
|
226
|
+
"drop_strategy": self.drop_strategy,
|
|
227
|
+
"run_timeout_seconds": self.run_timeout_seconds,
|
|
228
|
+
"worker_poll_interval": self.worker_poll_interval,
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
@classmethod
|
|
232
|
+
def from_dict(cls, data: Dict[str, Any]) -> "QueueConfig":
|
|
233
|
+
"""Create from dictionary."""
|
|
234
|
+
priority = data.get("default_priority", 1)
|
|
235
|
+
if isinstance(priority, int):
|
|
236
|
+
priority = RunPriority(priority)
|
|
237
|
+
|
|
238
|
+
return cls(
|
|
239
|
+
max_concurrent_global=data.get("max_concurrent_global", 4),
|
|
240
|
+
max_concurrent_per_agent=data.get("max_concurrent_per_agent", 2),
|
|
241
|
+
max_concurrent_per_workspace=data.get("max_concurrent_per_workspace", 4),
|
|
242
|
+
max_queue_size=data.get("max_queue_size", 100),
|
|
243
|
+
default_priority=priority,
|
|
244
|
+
default_max_retries=data.get("default_max_retries", 3),
|
|
245
|
+
enable_persistence=data.get("enable_persistence", True),
|
|
246
|
+
db_path=data.get("db_path", ".praison/queue.db"),
|
|
247
|
+
autosave_interval_seconds=data.get("autosave_interval_seconds", 30.0),
|
|
248
|
+
stream_buffer_size=data.get("stream_buffer_size", 1000),
|
|
249
|
+
drop_strategy=data.get("drop_strategy", "oldest"),
|
|
250
|
+
run_timeout_seconds=data.get("run_timeout_seconds"),
|
|
251
|
+
worker_poll_interval=data.get("worker_poll_interval", 0.1),
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@dataclass
|
|
256
|
+
class QueueStats:
|
|
257
|
+
"""Statistics about the queue."""
|
|
258
|
+
queued_count: int = 0
|
|
259
|
+
running_count: int = 0
|
|
260
|
+
succeeded_count: int = 0
|
|
261
|
+
failed_count: int = 0
|
|
262
|
+
cancelled_count: int = 0
|
|
263
|
+
total_runs: int = 0
|
|
264
|
+
avg_wait_seconds: float = 0.0
|
|
265
|
+
avg_duration_seconds: float = 0.0
|
|
266
|
+
|
|
267
|
+
@property
|
|
268
|
+
def active_count(self) -> int:
|
|
269
|
+
"""Count of active (non-terminal) runs."""
|
|
270
|
+
return self.queued_count + self.running_count
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
@dataclass
|
|
274
|
+
class StreamChunk:
|
|
275
|
+
"""A chunk of streaming output."""
|
|
276
|
+
run_id: str
|
|
277
|
+
content: str
|
|
278
|
+
timestamp: float = field(default_factory=time.time)
|
|
279
|
+
chunk_index: int = 0
|
|
280
|
+
is_final: bool = False
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
@dataclass
|
|
284
|
+
class QueueEvent:
|
|
285
|
+
"""An event from the queue system."""
|
|
286
|
+
event_type: str # "run_started", "run_completed", "run_failed", "output_chunk", "state_changed"
|
|
287
|
+
run_id: str
|
|
288
|
+
timestamp: float = field(default_factory=time.time)
|
|
289
|
+
data: Dict[str, Any] = field(default_factory=dict)
|