minder-cli 0.5.2__tar.gz → 0.5.3__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.
- {minder_cli-0.5.2 → minder_cli-0.5.3}/PKG-INFO +1 -1
- {minder_cli-0.5.2 → minder_cli-0.5.3}/pyproject.toml +1 -1
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/application/admin/dto.py +24 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/application/admin/use_cases.py +137 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/api.py +99 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/.gitignore +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/LICENSE +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/README-pypi.md +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/README.md +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/api/routers/prompts.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/application/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/application/admin/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/application/admin/jobs.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/auth/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/auth/context.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/auth/middleware.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/auth/principal.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/auth/rate_limiter.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/auth/rbac.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/auth/service.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/bootstrap/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/bootstrap/agent_seeder.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/bootstrap/providers.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/bootstrap/transport.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/cache/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/cache/providers.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/chunking/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/chunking/code_splitter.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/chunking/splitter.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/cli.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/config.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/context_compactor.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/continuity.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/dev.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/embedding/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/embedding/base.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/embedding/local.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/embedding/openai.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/edges.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/executor.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/graph.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/clarification.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/evaluator.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/guard.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/llm.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/planning.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/reasoning.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/reflection.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/reranker.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/retriever.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/verification.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/nodes/workflow_planner.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/runtime.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/graph/state.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/learning/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/learning/error_learner.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/learning/pattern_extractor.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/learning/quality_optimizer.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/learning/skill_synthesizer.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/llm/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/llm/base.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/llm/factory.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/llm/llama_cpp_llm.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/llm/openai.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/agent.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/base.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/client.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/document.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/error.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/graph.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/history.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/job.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/prompt.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/repository.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/rule.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/session.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/skill.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/user.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/models/workflow.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/observability/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/observability/audit.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/observability/logging.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/observability/metrics.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/observability/tracing.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/commands/agent.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/commands/auth.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/commands/ide.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/commands/mcp.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/commands/sync.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/commands/update.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/main.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/utils/common.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/utils/config.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/utils/git.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/cli/utils/version.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/agents.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/context.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/dashboard.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/jobs.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/memories.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/prompts.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/routes.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/runtime.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/search.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/presentation/http/admin/skills.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/prompts/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/prompts/formatter.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/resources/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/retrieval/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/retrieval/hybrid.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/retrieval/mmr.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/retrieval/multi_hop.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/runtime.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/server.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/document.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/error.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/feedback.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/graph.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/history.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/interfaces.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/milvus/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/milvus/client.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/milvus/collections.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/milvus/vector_store.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/mongodb/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/mongodb/client.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/mongodb/graph_store.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/mongodb/indexes.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/mongodb/operational_store.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/relational.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/repo_state.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/rule.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/store/vector.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/agents.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/auth.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/graph.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/ingest.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/memory.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/query.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/registry.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/repo_scanner.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/seeds/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/seeds/default_agents.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/session.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/skills.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/tools/workflow.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/transport/__init__.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/transport/base.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/transport/sse.py +0 -0
- {minder_cli-0.5.2 → minder_cli-0.5.3}/src/minder/transport/stdio.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: minder-cli
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.3
|
|
4
4
|
Summary: Minder CLI is the command-line interface for the Minder self-hosted MCP platform.
|
|
5
5
|
Project-URL: Homepage, https://github.com/hiimtrung/minder
|
|
6
6
|
Project-URL: Repository, https://github.com/hiimtrung/minder
|
|
@@ -479,3 +479,27 @@ class RepositoryLandscapePayload(TypedDict):
|
|
|
479
479
|
nodes: list[RepositoryLandscapeNodePayload]
|
|
480
480
|
edges: list[RepositoryLandscapeEdgePayload]
|
|
481
481
|
summary: dict[str, int]
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
class AgentPayload(TypedDict):
|
|
486
|
+
id: str
|
|
487
|
+
name: str
|
|
488
|
+
title: str
|
|
489
|
+
description: str
|
|
490
|
+
system_prompt: str
|
|
491
|
+
tools: list[str]
|
|
492
|
+
workflow_steps: list[str]
|
|
493
|
+
artifact_types: list[str]
|
|
494
|
+
tags: list[str]
|
|
495
|
+
is_default: bool
|
|
496
|
+
created_at: str | None
|
|
497
|
+
updated_at: str | None
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
class AgentListPayload(TypedDict):
|
|
501
|
+
agents: list[AgentPayload]
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
class AgentDetailPayload(TypedDict):
|
|
505
|
+
agent: AgentPayload
|
|
@@ -13,6 +13,9 @@ from minder.application.admin.dto import (
|
|
|
13
13
|
ActivityEventPayload,
|
|
14
14
|
AdminLoginPayload,
|
|
15
15
|
AdminSessionPayload,
|
|
16
|
+
AgentDetailPayload,
|
|
17
|
+
AgentListPayload,
|
|
18
|
+
AgentPayload,
|
|
16
19
|
AuditEventPayload,
|
|
17
20
|
AuditListPayload,
|
|
18
21
|
ClientConnectionTestPayload,
|
|
@@ -651,6 +654,116 @@ class AdminConsoleUseCases:
|
|
|
651
654
|
),
|
|
652
655
|
}
|
|
653
656
|
|
|
657
|
+
# ------------------------------------------------------------------
|
|
658
|
+
# SubAgent management
|
|
659
|
+
# ------------------------------------------------------------------
|
|
660
|
+
|
|
661
|
+
async def list_agents(self) -> AgentListPayload:
|
|
662
|
+
agents = await self._store.list_agents()
|
|
663
|
+
return {"agents": [self.serialize_agent(a) for a in agents]}
|
|
664
|
+
|
|
665
|
+
async def get_agent_detail(self, agent_id: uuid.UUID) -> AgentDetailPayload:
|
|
666
|
+
agent = await self._store.get_agent_by_id(agent_id)
|
|
667
|
+
if agent is None:
|
|
668
|
+
raise LookupError(f"Agent {agent_id} not found")
|
|
669
|
+
return {"agent": self.serialize_agent(agent)}
|
|
670
|
+
|
|
671
|
+
async def create_agent(
|
|
672
|
+
self,
|
|
673
|
+
*,
|
|
674
|
+
name: str,
|
|
675
|
+
title: str = "",
|
|
676
|
+
description: str = "",
|
|
677
|
+
system_prompt: str = "",
|
|
678
|
+
tools: list[str] | None = None,
|
|
679
|
+
workflow_steps: list[str] | None = None,
|
|
680
|
+
artifact_types: list[str] | None = None,
|
|
681
|
+
tags: list[str] | None = None,
|
|
682
|
+
is_default: bool = False,
|
|
683
|
+
) -> AgentDetailPayload:
|
|
684
|
+
agent = await self._store.create_agent(
|
|
685
|
+
name=name,
|
|
686
|
+
title=title,
|
|
687
|
+
description=description,
|
|
688
|
+
system_prompt=system_prompt,
|
|
689
|
+
tools=tools or [],
|
|
690
|
+
workflow_steps=workflow_steps or [],
|
|
691
|
+
artifact_types=artifact_types or [],
|
|
692
|
+
tags=tags or [],
|
|
693
|
+
is_default=is_default,
|
|
694
|
+
)
|
|
695
|
+
return {"agent": self.serialize_agent(agent)}
|
|
696
|
+
|
|
697
|
+
async def update_agent(
|
|
698
|
+
self,
|
|
699
|
+
agent_id: uuid.UUID,
|
|
700
|
+
*,
|
|
701
|
+
name: str | None = None,
|
|
702
|
+
title: str | None = None,
|
|
703
|
+
description: str | None = None,
|
|
704
|
+
system_prompt: str | None = None,
|
|
705
|
+
tools: list[str] | None = None,
|
|
706
|
+
workflow_steps: list[str] | None = None,
|
|
707
|
+
artifact_types: list[str] | None = None,
|
|
708
|
+
tags: list[str] | None = None,
|
|
709
|
+
is_default: bool | None = None,
|
|
710
|
+
) -> AgentDetailPayload:
|
|
711
|
+
kwargs: dict[str, Any] = {}
|
|
712
|
+
if name is not None:
|
|
713
|
+
kwargs["name"] = name
|
|
714
|
+
if title is not None:
|
|
715
|
+
kwargs["title"] = title
|
|
716
|
+
if description is not None:
|
|
717
|
+
kwargs["description"] = description
|
|
718
|
+
if system_prompt is not None:
|
|
719
|
+
kwargs["system_prompt"] = system_prompt
|
|
720
|
+
if tools is not None:
|
|
721
|
+
kwargs["tools"] = tools
|
|
722
|
+
if workflow_steps is not None:
|
|
723
|
+
kwargs["workflow_steps"] = workflow_steps
|
|
724
|
+
if artifact_types is not None:
|
|
725
|
+
kwargs["artifact_types"] = artifact_types
|
|
726
|
+
if tags is not None:
|
|
727
|
+
kwargs["tags"] = tags
|
|
728
|
+
if is_default is not None:
|
|
729
|
+
kwargs["is_default"] = is_default
|
|
730
|
+
updated = await self._store.update_agent(agent_id, **kwargs)
|
|
731
|
+
if updated is None:
|
|
732
|
+
raise LookupError(f"Agent {agent_id} not found")
|
|
733
|
+
return {"agent": self.serialize_agent(updated)}
|
|
734
|
+
|
|
735
|
+
async def delete_agent(self, agent_id: uuid.UUID) -> dict[str, bool]:
|
|
736
|
+
existing = await self._store.get_agent_by_id(agent_id)
|
|
737
|
+
if existing is None:
|
|
738
|
+
raise LookupError(f"Agent {agent_id} not found")
|
|
739
|
+
await self._store.delete_agent(agent_id)
|
|
740
|
+
return {"deleted": True}
|
|
741
|
+
|
|
742
|
+
@staticmethod
|
|
743
|
+
def serialize_agent(agent: Any) -> AgentPayload:
|
|
744
|
+
return {
|
|
745
|
+
"id": str(agent.id),
|
|
746
|
+
"name": getattr(agent, "name", ""),
|
|
747
|
+
"title": getattr(agent, "title", ""),
|
|
748
|
+
"description": getattr(agent, "description", ""),
|
|
749
|
+
"system_prompt": getattr(agent, "system_prompt", ""),
|
|
750
|
+
"tools": list(getattr(agent, "tools", []) or []),
|
|
751
|
+
"workflow_steps": list(getattr(agent, "workflow_steps", []) or []),
|
|
752
|
+
"artifact_types": list(getattr(agent, "artifact_types", []) or []),
|
|
753
|
+
"tags": list(getattr(agent, "tags", []) or []),
|
|
754
|
+
"is_default": bool(getattr(agent, "is_default", False)),
|
|
755
|
+
"created_at": (
|
|
756
|
+
agent.created_at.isoformat()
|
|
757
|
+
if getattr(agent, "created_at", None)
|
|
758
|
+
else None
|
|
759
|
+
),
|
|
760
|
+
"updated_at": (
|
|
761
|
+
agent.updated_at.isoformat()
|
|
762
|
+
if getattr(agent, "updated_at", None)
|
|
763
|
+
else None
|
|
764
|
+
),
|
|
765
|
+
}
|
|
766
|
+
|
|
654
767
|
# ------------------------------------------------------------------
|
|
655
768
|
# Session management
|
|
656
769
|
# ------------------------------------------------------------------
|
|
@@ -788,19 +901,43 @@ class AdminConsoleUseCases:
|
|
|
788
901
|
if not normalized_path:
|
|
789
902
|
raise ValueError("Repository path is required")
|
|
790
903
|
updates["state_path"] = normalized_path
|
|
904
|
+
new_workflow_id: uuid.UUID | None = _UNSET # type: ignore[assignment]
|
|
791
905
|
if workflow_id is not _UNSET:
|
|
792
906
|
if workflow_id is None or str(workflow_id).strip() == "":
|
|
793
907
|
updates["workflow_id"] = None
|
|
908
|
+
new_workflow_id = None
|
|
794
909
|
else:
|
|
795
910
|
wf_id = uuid.UUID(str(workflow_id))
|
|
796
911
|
workflow = await self._store.get_workflow_by_id(wf_id)
|
|
797
912
|
if workflow is None:
|
|
798
913
|
raise LookupError(f"Workflow {wf_id} not found")
|
|
799
914
|
updates["workflow_id"] = str(wf_id)
|
|
915
|
+
new_workflow_id = wf_id
|
|
800
916
|
|
|
801
917
|
updated = await self._store.update_repository(repo_id, **updates)
|
|
802
918
|
if updated is None:
|
|
803
919
|
raise LookupError("Repository not found")
|
|
920
|
+
|
|
921
|
+
# Create workflow_state when a workflow is first assigned to a repo
|
|
922
|
+
if new_workflow_id is not _UNSET and new_workflow_id is not None: # type: ignore[comparison-overlap]
|
|
923
|
+
existing_state = await self._store.get_workflow_state_by_repo(repo_id)
|
|
924
|
+
if existing_state is None:
|
|
925
|
+
workflow_obj = await self._store.get_workflow_by_id(new_workflow_id)
|
|
926
|
+
steps = list(getattr(workflow_obj, "steps", []) or []) if workflow_obj else []
|
|
927
|
+
step_names = [
|
|
928
|
+
s["name"] for s in steps if isinstance(s, dict) and "name" in s
|
|
929
|
+
]
|
|
930
|
+
first_step = step_names[0] if step_names else ""
|
|
931
|
+
second_step = step_names[1] if len(step_names) > 1 else None
|
|
932
|
+
await self._store.create_workflow_state(
|
|
933
|
+
repo_id=repo_id,
|
|
934
|
+
current_step=first_step,
|
|
935
|
+
completed_steps=[],
|
|
936
|
+
blocked_by=[],
|
|
937
|
+
artifacts={},
|
|
938
|
+
next_step=second_step,
|
|
939
|
+
)
|
|
940
|
+
|
|
804
941
|
return await self.get_repository_detail(repo_id)
|
|
805
942
|
|
|
806
943
|
async def delete_repository(self, repo_id: uuid.UUID) -> DeleteRepositoryPayload:
|
|
@@ -520,6 +520,98 @@ def build_admin_api_routes(context: AdminRouteContext) -> list[BaseRoute]:
|
|
|
520
520
|
|
|
521
521
|
return JSONResponse({"error": "Method not allowed"}, status_code=405)
|
|
522
522
|
|
|
523
|
+
# ------------------------------------------------------------------
|
|
524
|
+
# SubAgent management
|
|
525
|
+
# ------------------------------------------------------------------
|
|
526
|
+
|
|
527
|
+
async def admin_agents(request):
|
|
528
|
+
try:
|
|
529
|
+
await context.admin_user_from_request(request)
|
|
530
|
+
except PermissionError:
|
|
531
|
+
return JSONResponse({"error": "Admin role required"}, status_code=403)
|
|
532
|
+
except Exception as exc:
|
|
533
|
+
return JSONResponse({"error": str(exc)}, status_code=401)
|
|
534
|
+
|
|
535
|
+
if request.method == "GET":
|
|
536
|
+
return JSONResponse(await context.use_cases.list_agents())
|
|
537
|
+
|
|
538
|
+
if request.method == "POST":
|
|
539
|
+
try:
|
|
540
|
+
payload = await request.json()
|
|
541
|
+
except Exception:
|
|
542
|
+
return JSONResponse({"error": "Invalid JSON"}, status_code=400)
|
|
543
|
+
name = str(payload.get("name", "")).strip()
|
|
544
|
+
if not name:
|
|
545
|
+
return JSONResponse({"error": "name is required"}, status_code=400)
|
|
546
|
+
try:
|
|
547
|
+
return JSONResponse(
|
|
548
|
+
await context.use_cases.create_agent(
|
|
549
|
+
name=name,
|
|
550
|
+
title=str(payload.get("title", "")),
|
|
551
|
+
description=str(payload.get("description", "")),
|
|
552
|
+
system_prompt=str(payload.get("system_prompt", "")),
|
|
553
|
+
tools=payload.get("tools") or [],
|
|
554
|
+
workflow_steps=payload.get("workflow_steps") or [],
|
|
555
|
+
artifact_types=payload.get("artifact_types") or [],
|
|
556
|
+
tags=payload.get("tags") or [],
|
|
557
|
+
is_default=bool(payload.get("is_default", False)),
|
|
558
|
+
),
|
|
559
|
+
status_code=201,
|
|
560
|
+
)
|
|
561
|
+
except Exception as exc:
|
|
562
|
+
return JSONResponse({"error": str(exc)}, status_code=400)
|
|
563
|
+
|
|
564
|
+
return JSONResponse({"error": "Method not allowed"}, status_code=405)
|
|
565
|
+
|
|
566
|
+
async def agent_detail(request):
|
|
567
|
+
try:
|
|
568
|
+
await context.admin_user_from_request(request)
|
|
569
|
+
except PermissionError:
|
|
570
|
+
return JSONResponse({"error": "Admin role required"}, status_code=403)
|
|
571
|
+
except Exception as exc:
|
|
572
|
+
return JSONResponse({"error": str(exc)}, status_code=401)
|
|
573
|
+
|
|
574
|
+
agent_id = uuid.UUID(str(request.path_params["agent_id"]))
|
|
575
|
+
|
|
576
|
+
if request.method == "GET":
|
|
577
|
+
try:
|
|
578
|
+
return JSONResponse(await context.use_cases.get_agent_detail(agent_id))
|
|
579
|
+
except LookupError:
|
|
580
|
+
return JSONResponse({"error": "Agent not found"}, status_code=404)
|
|
581
|
+
|
|
582
|
+
if request.method == "PATCH":
|
|
583
|
+
try:
|
|
584
|
+
payload = await request.json()
|
|
585
|
+
except Exception:
|
|
586
|
+
return JSONResponse({"error": "Invalid JSON"}, status_code=400)
|
|
587
|
+
try:
|
|
588
|
+
return JSONResponse(
|
|
589
|
+
await context.use_cases.update_agent(
|
|
590
|
+
agent_id,
|
|
591
|
+
name=payload.get("name"),
|
|
592
|
+
title=payload.get("title"),
|
|
593
|
+
description=payload.get("description"),
|
|
594
|
+
system_prompt=payload.get("system_prompt"),
|
|
595
|
+
tools=payload.get("tools"),
|
|
596
|
+
workflow_steps=payload.get("workflow_steps"),
|
|
597
|
+
artifact_types=payload.get("artifact_types"),
|
|
598
|
+
tags=payload.get("tags"),
|
|
599
|
+
is_default=payload.get("is_default"),
|
|
600
|
+
)
|
|
601
|
+
)
|
|
602
|
+
except LookupError:
|
|
603
|
+
return JSONResponse({"error": "Agent not found"}, status_code=404)
|
|
604
|
+
except Exception as exc:
|
|
605
|
+
return JSONResponse({"error": str(exc)}, status_code=400)
|
|
606
|
+
|
|
607
|
+
if request.method == "DELETE":
|
|
608
|
+
try:
|
|
609
|
+
return JSONResponse(await context.use_cases.delete_agent(agent_id))
|
|
610
|
+
except LookupError:
|
|
611
|
+
return JSONResponse({"error": "Agent not found"}, status_code=404)
|
|
612
|
+
|
|
613
|
+
return JSONResponse({"error": "Method not allowed"}, status_code=405)
|
|
614
|
+
|
|
523
615
|
# ------------------------------------------------------------------
|
|
524
616
|
# Workflow management
|
|
525
617
|
# ------------------------------------------------------------------
|
|
@@ -1331,6 +1423,13 @@ def build_admin_api_routes(context: AdminRouteContext) -> list[BaseRoute]:
|
|
|
1331
1423
|
user_detail,
|
|
1332
1424
|
methods=["GET", "PATCH", "DELETE"],
|
|
1333
1425
|
),
|
|
1426
|
+
# SubAgent management
|
|
1427
|
+
Route("/v1/admin/agents", admin_agents, methods=["GET", "POST"]),
|
|
1428
|
+
Route(
|
|
1429
|
+
"/v1/admin/agents/{agent_id:uuid}",
|
|
1430
|
+
agent_detail,
|
|
1431
|
+
methods=["GET", "PATCH", "DELETE"],
|
|
1432
|
+
),
|
|
1334
1433
|
# Workflow management
|
|
1335
1434
|
Route("/v1/admin/workflows", admin_workflows, methods=["GET", "POST"]),
|
|
1336
1435
|
Route(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|