Implement executing tasks
This commit is contained in:
@@ -24,8 +24,9 @@ from core.models import (
|
||||
PersonIdentifier,
|
||||
PlatformChatLink,
|
||||
Chat,
|
||||
ExternalChatLink,
|
||||
)
|
||||
from core.tasks.providers.mock import get_provider
|
||||
from core.tasks.providers import get_provider
|
||||
|
||||
SAFE_TASK_FLAGS_DEFAULTS = {
|
||||
"derive_enabled": True,
|
||||
@@ -170,6 +171,13 @@ def _service_label(service: str) -> str:
|
||||
return labels.get(key, key.title() if key else "Unknown")
|
||||
|
||||
|
||||
def _provider_row_map(user):
|
||||
return {
|
||||
str(row.provider or "").strip().lower(): row
|
||||
for row in TaskProviderConfig.objects.filter(user=user).order_by("provider")
|
||||
}
|
||||
|
||||
|
||||
def _resolve_channel_display(user, service: str, identifier: str) -> dict:
|
||||
service_key = str(service or "").strip().lower()
|
||||
raw_identifier = str(identifier or "").strip()
|
||||
@@ -408,12 +416,33 @@ class TaskSettings(LoginRequiredMixin, View):
|
||||
for row in sources:
|
||||
row.settings_effective = _flags_with_defaults(row.settings)
|
||||
row.allowed_prefixes_csv = ",".join(row.settings_effective["allowed_prefixes"])
|
||||
provider_map = _provider_row_map(request.user)
|
||||
codex_cfg = provider_map.get("codex_cli")
|
||||
codex_settings = dict(getattr(codex_cfg, "settings", {}) or {})
|
||||
mock_cfg = provider_map.get("mock")
|
||||
external_chat_links = list(
|
||||
ExternalChatLink.objects.filter(user=request.user).select_related(
|
||||
"person", "person_identifier"
|
||||
).order_by("-updated_at")[:200]
|
||||
)
|
||||
|
||||
return {
|
||||
"projects": projects,
|
||||
"epics": TaskEpic.objects.filter(project__user=request.user).select_related("project").order_by("project__name", "name"),
|
||||
"sources": sources,
|
||||
"patterns": TaskCompletionPattern.objects.filter(user=request.user).order_by("position", "created_at"),
|
||||
"provider_configs": TaskProviderConfig.objects.filter(user=request.user).order_by("provider"),
|
||||
"provider_configs": list(provider_map.values()),
|
||||
"mock_provider_config": mock_cfg,
|
||||
"codex_provider_config": codex_cfg,
|
||||
"codex_provider_settings": {
|
||||
"command": str(codex_settings.get("command") or "codex"),
|
||||
"workspace_root": str(codex_settings.get("workspace_root") or ""),
|
||||
"default_profile": str(codex_settings.get("default_profile") or ""),
|
||||
"timeout_seconds": int(codex_settings.get("timeout_seconds") or 60),
|
||||
"chat_link_mode": str(codex_settings.get("chat_link_mode") or "task-sync"),
|
||||
},
|
||||
"person_identifiers": PersonIdentifier.objects.filter(user=request.user).select_related("person").order_by("person__name", "service", "identifier")[:600],
|
||||
"external_chat_links": external_chat_links,
|
||||
"sync_events": ExternalSyncEvent.objects.filter(user=request.user).order_by("-updated_at")[:100],
|
||||
"prefill_service": prefill_service,
|
||||
"prefill_identifier": prefill_identifier,
|
||||
@@ -537,18 +566,81 @@ class TaskSettings(LoginRequiredMixin, View):
|
||||
defaults={"enabled": False, "settings": {}},
|
||||
)
|
||||
row.enabled = bool(request.POST.get("enabled"))
|
||||
row.save(update_fields=["enabled", "updated_at"])
|
||||
settings_payload = dict(row.settings or {})
|
||||
if provider == "codex_cli":
|
||||
timeout_raw = str(request.POST.get("timeout_seconds") or "60").strip()
|
||||
try:
|
||||
timeout_value = max(1, int(timeout_raw))
|
||||
except Exception:
|
||||
timeout_value = 60
|
||||
settings_payload = {
|
||||
"command": str(request.POST.get("command") or "codex").strip() or "codex",
|
||||
"workspace_root": str(request.POST.get("workspace_root") or "").strip(),
|
||||
"default_profile": str(request.POST.get("default_profile") or "").strip(),
|
||||
"timeout_seconds": timeout_value,
|
||||
"chat_link_mode": "task-sync",
|
||||
}
|
||||
row.settings = settings_payload
|
||||
row.save(update_fields=["enabled", "settings", "updated_at"])
|
||||
return _settings_redirect(request)
|
||||
|
||||
if action == "external_chat_link_upsert":
|
||||
provider = str(request.POST.get("provider") or "codex_cli").strip().lower() or "codex_cli"
|
||||
external_chat_id = str(request.POST.get("external_chat_id") or "").strip()
|
||||
person_identifier_id = str(request.POST.get("person_identifier_id") or "").strip()
|
||||
if not external_chat_id:
|
||||
messages.error(request, "External chat ID is required.")
|
||||
return _settings_redirect(request)
|
||||
identifier = None
|
||||
if person_identifier_id:
|
||||
identifier = get_object_or_404(
|
||||
PersonIdentifier,
|
||||
user=request.user,
|
||||
id=person_identifier_id,
|
||||
)
|
||||
row, _ = ExternalChatLink.objects.update_or_create(
|
||||
user=request.user,
|
||||
provider=provider,
|
||||
external_chat_id=external_chat_id,
|
||||
defaults={
|
||||
"person": getattr(identifier, "person", None),
|
||||
"person_identifier": identifier,
|
||||
"enabled": bool(request.POST.get("enabled")),
|
||||
"metadata": {
|
||||
"chat_link_mode": "task-sync",
|
||||
"notes": str(request.POST.get("metadata_notes") or "").strip(),
|
||||
},
|
||||
},
|
||||
)
|
||||
if identifier and row.person_id != identifier.person_id:
|
||||
row.person = identifier.person
|
||||
row.save(update_fields=["person", "updated_at"])
|
||||
return _settings_redirect(request)
|
||||
|
||||
if action == "external_chat_link_delete":
|
||||
row = get_object_or_404(
|
||||
ExternalChatLink,
|
||||
id=request.POST.get("external_link_id"),
|
||||
user=request.user,
|
||||
)
|
||||
row.delete()
|
||||
return _settings_redirect(request)
|
||||
|
||||
if action == "sync_retry":
|
||||
event = get_object_or_404(ExternalSyncEvent, id=request.POST.get("event_id"), user=request.user)
|
||||
provider = get_provider(event.provider)
|
||||
payload = dict(event.payload or {})
|
||||
result = provider.append_update({}, payload)
|
||||
event.status = "ok" if result.ok else "failed"
|
||||
event.error = str(result.error or "")
|
||||
event.payload = dict(payload, retried=True)
|
||||
event.save(update_fields=["status", "error", "payload", "updated_at"])
|
||||
if bool(getattr(provider, "run_in_worker", False)):
|
||||
event.status = "pending"
|
||||
event.error = ""
|
||||
event.payload = dict(event.payload or {}, retried=True)
|
||||
event.save(update_fields=["status", "error", "payload", "updated_at"])
|
||||
else:
|
||||
payload = dict(event.payload or {})
|
||||
result = provider.append_update({}, payload)
|
||||
event.status = "ok" if result.ok else "failed"
|
||||
event.error = str(result.error or "")
|
||||
event.payload = dict(payload, retried=True)
|
||||
event.save(update_fields=["status", "error", "payload", "updated_at"])
|
||||
return _settings_redirect(request)
|
||||
|
||||
return _settings_redirect(request)
|
||||
|
||||
Reference in New Issue
Block a user