persona-sdk-python 0.2.18__tar.gz → 0.2.20__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.
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/PKG-INFO +1 -1
- persona_sdk_python-0.2.20/bitbucket-pipelines.yml +18 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/__init__.py +14 -5
- persona_sdk_python-0.2.20/persona_sdk/api/human_tasks.py +55 -0
- persona_sdk_python-0.2.20/persona_sdk/api/markup_rules.py +44 -0
- persona_sdk_python-0.2.20/persona_sdk/api/providers.py +65 -0
- persona_sdk_python-0.2.20/persona_sdk/api/workflows.py +234 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/pyproject.toml +1 -1
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/uv.lock +1 -9
- persona_sdk_python-0.2.18/bitbucket-pipelines.yml +0 -17
- persona_sdk_python-0.2.18/persona_sdk/api/known_models.py +0 -49
- persona_sdk_python-0.2.18/persona_sdk/api/workflows.py +0 -72
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/.gitignore +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/DEPLOY.md +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/README.md +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/_serde.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/api/__init__.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/api/agents.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/api/credentials.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/api/features.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/api/knowledge_bases.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/api/missions.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/api/projects.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/api/service_prices.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/api/sessions.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/api/triggers.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/auth/__init__.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/auth/api_key_auth.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/auth/base.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/auth/bearer_token_auth.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/client.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/runners/__init__.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/runners/agent_runner.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/runners/resource_retriever.py +0 -0
- {persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/runners/tool_invoker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: persona-sdk-python
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.20
|
|
4
4
|
Summary: Async Python SDK for the Persona AI platform
|
|
5
5
|
Project-URL: Homepage, https://persona.applica.guru
|
|
6
6
|
Project-URL: Repository, https://bitbucket.org/applicaguru/persona-sdk-python
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
image: python:3.12
|
|
2
|
+
|
|
3
|
+
pipelines:
|
|
4
|
+
branches:
|
|
5
|
+
main:
|
|
6
|
+
- step:
|
|
7
|
+
name: Publish to PyPI
|
|
8
|
+
caches:
|
|
9
|
+
- pip
|
|
10
|
+
script:
|
|
11
|
+
- apt-get update && apt-get install -y git
|
|
12
|
+
- pip install build twine
|
|
13
|
+
- export VERSION=0.2.$BITBUCKET_BUILD_NUMBER
|
|
14
|
+
- sed -i "s/^version = .*/version = \"$VERSION\"/" pyproject.toml
|
|
15
|
+
- python -m build
|
|
16
|
+
- twine upload dist/* -u __token__ -p $PYPI_TOKEN
|
|
17
|
+
- git tag -a $VERSION -m "$VERSION"
|
|
18
|
+
- git push origin $VERSION
|
|
@@ -3,14 +3,16 @@ from typing import Union
|
|
|
3
3
|
from persona_sdk.api.agents import AgentsApi
|
|
4
4
|
from persona_sdk.api.credentials import CredentialsApi
|
|
5
5
|
from persona_sdk.api.features import FeaturesApi
|
|
6
|
-
from persona_sdk.api.known_models import KnownModelsApi
|
|
7
6
|
from persona_sdk.api.knowledge_bases import KnowledgeBasesApi
|
|
7
|
+
from persona_sdk.api.markup_rules import MarkupRulesApi
|
|
8
8
|
from persona_sdk.api.missions import MissionsApi
|
|
9
9
|
from persona_sdk.api.projects import ProjectsApi
|
|
10
|
+
from persona_sdk.api.providers import ProvidersApi
|
|
10
11
|
from persona_sdk.api.service_prices import ServicePricesApi
|
|
11
12
|
from persona_sdk.api.sessions import SessionsApi
|
|
12
13
|
from persona_sdk.api.triggers import TriggersApi
|
|
13
14
|
from persona_sdk.api.workflows import WorkflowsApi
|
|
15
|
+
from persona_sdk.api.human_tasks import HumanTasksApi
|
|
14
16
|
from persona_sdk.auth import (
|
|
15
17
|
ApiKeyAuthenticationProvider,
|
|
16
18
|
AuthenticationProvider,
|
|
@@ -30,10 +32,11 @@ from persona_models.knowledge_bases import (
|
|
|
30
32
|
KnowledgeBaseDocument,
|
|
31
33
|
SearchChunksRequest,
|
|
32
34
|
)
|
|
33
|
-
from persona_models.
|
|
35
|
+
from persona_models.markup import MarkupRule
|
|
34
36
|
from persona_models.mcp import GenerationRequest
|
|
35
37
|
from persona_models.missions import CreateMissionRequest, Mission
|
|
36
38
|
from persona_models.projects import Project
|
|
39
|
+
from persona_models.providers import Provider, ProviderModel
|
|
37
40
|
from persona_models.service_prices import ServicePrice, UsageCost
|
|
38
41
|
from persona_models.sessions import GenerationResponse, Message, Session
|
|
39
42
|
from persona_models.triggers import Trigger, TriggerExecutionResult
|
|
@@ -48,14 +51,16 @@ __all__ = [
|
|
|
48
51
|
"AgentsApi",
|
|
49
52
|
"CredentialsApi",
|
|
50
53
|
"FeaturesApi",
|
|
51
|
-
"KnownModelsApi",
|
|
52
54
|
"KnowledgeBasesApi",
|
|
55
|
+
"MarkupRulesApi",
|
|
53
56
|
"MissionsApi",
|
|
54
57
|
"ProjectsApi",
|
|
58
|
+
"ProvidersApi",
|
|
55
59
|
"ServicePricesApi",
|
|
56
60
|
"SessionsApi",
|
|
57
61
|
"TriggersApi",
|
|
58
62
|
"WorkflowsApi",
|
|
63
|
+
"HumanTasksApi",
|
|
59
64
|
# Domain models (re-exported from persona-models)
|
|
60
65
|
"Paginated",
|
|
61
66
|
"AgentConfiguration",
|
|
@@ -66,12 +71,14 @@ __all__ = [
|
|
|
66
71
|
"KnowledgeBase",
|
|
67
72
|
"KnowledgeBaseDocument",
|
|
68
73
|
"SearchChunksRequest",
|
|
69
|
-
"KnownModel",
|
|
70
74
|
"GenerationRequest",
|
|
71
75
|
"GenerationResponse",
|
|
72
76
|
"CreateMissionRequest",
|
|
73
77
|
"Mission",
|
|
74
78
|
"Project",
|
|
79
|
+
"Provider",
|
|
80
|
+
"ProviderModel",
|
|
81
|
+
"MarkupRule",
|
|
75
82
|
"ServicePrice",
|
|
76
83
|
"UsageCost",
|
|
77
84
|
"Message",
|
|
@@ -131,6 +138,7 @@ class PersonaSdk:
|
|
|
131
138
|
)
|
|
132
139
|
self.agents = AgentsApi(self.client)
|
|
133
140
|
self.workflows = WorkflowsApi(self.workflows_client)
|
|
141
|
+
self.human_tasks = HumanTasksApi(self.workflows_client)
|
|
134
142
|
self.triggers = TriggersApi(self.client)
|
|
135
143
|
self.sessions = SessionsApi(self.client)
|
|
136
144
|
self.credentials = CredentialsApi(self.client)
|
|
@@ -139,7 +147,8 @@ class PersonaSdk:
|
|
|
139
147
|
self.features = FeaturesApi(self.client)
|
|
140
148
|
self.missions = MissionsApi(self.client)
|
|
141
149
|
self.service_prices = ServicePricesApi(self.client)
|
|
142
|
-
self.
|
|
150
|
+
self.providers = ProvidersApi(self.client)
|
|
151
|
+
self.markup_rules = MarkupRulesApi(self.client)
|
|
143
152
|
|
|
144
153
|
async def close(self):
|
|
145
154
|
await self.client.close()
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from persona_sdk.client import PersonaClient
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class HumanTasksApi:
|
|
9
|
+
"""
|
|
10
|
+
Human-in-the-loop tasks. A task is created when a workflow step
|
|
11
|
+
suspends waiting for a human (a declared ``human`` node or an agent
|
|
12
|
+
escalation); responding to it resumes the run.
|
|
13
|
+
|
|
14
|
+
Lives on the workflows service (same client as ``WorkflowsApi``).
|
|
15
|
+
Tasks are returned as plain dicts — the contract is owned by the
|
|
16
|
+
workflows service and intentionally not constrained here.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, client: PersonaClient):
|
|
20
|
+
self._client = client
|
|
21
|
+
|
|
22
|
+
async def list(
|
|
23
|
+
self,
|
|
24
|
+
status: str | None = "pending",
|
|
25
|
+
assignee: str | None = None,
|
|
26
|
+
workflow_id: str | None = None,
|
|
27
|
+
execution_id: str | None = None,
|
|
28
|
+
page: int = 1,
|
|
29
|
+
size: int = 50,
|
|
30
|
+
) -> dict[str, Any]:
|
|
31
|
+
"""The project's human-task inbox (``Paginated[HumanTask]`` shape)."""
|
|
32
|
+
params: dict[str, Any] = {"page": page, "size": size}
|
|
33
|
+
if status:
|
|
34
|
+
params["status"] = status
|
|
35
|
+
if assignee:
|
|
36
|
+
params["assignee"] = assignee
|
|
37
|
+
if workflow_id:
|
|
38
|
+
params["workflowId"] = workflow_id
|
|
39
|
+
if execution_id:
|
|
40
|
+
params["executionId"] = execution_id
|
|
41
|
+
return await self._client.get("/human-tasks", params=params)
|
|
42
|
+
|
|
43
|
+
async def respond(
|
|
44
|
+
self,
|
|
45
|
+
human_task_id: str,
|
|
46
|
+
response: Any,
|
|
47
|
+
responded_by: str | None = None,
|
|
48
|
+
) -> dict[str, Any]:
|
|
49
|
+
"""Answer a pending human task and resume the suspended execution."""
|
|
50
|
+
body: dict[str, Any] = {"response": response}
|
|
51
|
+
if responded_by:
|
|
52
|
+
body["respondedBy"] = responded_by
|
|
53
|
+
return await self._client.post(
|
|
54
|
+
f"/human-tasks/{human_task_id}/respond", json=body
|
|
55
|
+
)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from persona_models.common import Paginated
|
|
6
|
+
from persona_models.markup import MarkupRule
|
|
7
|
+
|
|
8
|
+
from persona_sdk._serde import dump_payload
|
|
9
|
+
from persona_sdk.client import PersonaClient
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MarkupRulesApi:
|
|
13
|
+
"""Global markup rules (super admin)."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, client: PersonaClient):
|
|
16
|
+
self._client = client
|
|
17
|
+
|
|
18
|
+
async def list(
|
|
19
|
+
self, keyword: str | None = None, page: int = 1, size: int = 50
|
|
20
|
+
) -> Paginated[MarkupRule]:
|
|
21
|
+
params: dict[str, Any] = {"page": page, "size": size}
|
|
22
|
+
if keyword:
|
|
23
|
+
params["keyword"] = keyword
|
|
24
|
+
data = await self._client.get("/markup-rules", params=params)
|
|
25
|
+
return Paginated[MarkupRule].model_validate(data)
|
|
26
|
+
|
|
27
|
+
async def get(self, markup_rule_id: str) -> MarkupRule:
|
|
28
|
+
data = await self._client.get(f"/markup-rules/{markup_rule_id}")
|
|
29
|
+
return MarkupRule.model_validate(data)
|
|
30
|
+
|
|
31
|
+
async def create(self, markup_rule: MarkupRule | dict[str, Any]) -> MarkupRule:
|
|
32
|
+
data = await self._client.post("/markup-rules", json=dump_payload(markup_rule))
|
|
33
|
+
return MarkupRule.model_validate(data)
|
|
34
|
+
|
|
35
|
+
async def update(
|
|
36
|
+
self, markup_rule_id: str, markup_rule: MarkupRule | dict[str, Any]
|
|
37
|
+
) -> MarkupRule:
|
|
38
|
+
data = await self._client.put(
|
|
39
|
+
f"/markup-rules/{markup_rule_id}", json=dump_payload(markup_rule)
|
|
40
|
+
)
|
|
41
|
+
return MarkupRule.model_validate(data)
|
|
42
|
+
|
|
43
|
+
async def delete(self, markup_rule_id: str) -> None:
|
|
44
|
+
await self._client.delete(f"/markup-rules/{markup_rule_id}")
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from persona_models.common import Paginated
|
|
6
|
+
from persona_models.providers import Provider, ProviderModel
|
|
7
|
+
|
|
8
|
+
from persona_sdk._serde import dump_payload
|
|
9
|
+
from persona_sdk.client import PersonaClient
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ProvidersApi:
|
|
13
|
+
"""Managed LLM providers (super admin). Global or per-project; api keys are
|
|
14
|
+
stored encrypted and returned masked."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, client: PersonaClient):
|
|
17
|
+
self._client = client
|
|
18
|
+
|
|
19
|
+
async def list(
|
|
20
|
+
self,
|
|
21
|
+
project_id: str | None = None,
|
|
22
|
+
keyword: str | None = None,
|
|
23
|
+
page: int = 1,
|
|
24
|
+
size: int = 100,
|
|
25
|
+
) -> Paginated[Provider]:
|
|
26
|
+
params: dict[str, Any] = {"page": page, "size": size}
|
|
27
|
+
if project_id:
|
|
28
|
+
params["projectId"] = project_id
|
|
29
|
+
if keyword:
|
|
30
|
+
params["keyword"] = keyword
|
|
31
|
+
data = await self._client.get("/providers", params=params)
|
|
32
|
+
return Paginated[Provider].model_validate(data)
|
|
33
|
+
|
|
34
|
+
async def get(self, provider_id: str) -> Provider:
|
|
35
|
+
data = await self._client.get(f"/providers/{provider_id}")
|
|
36
|
+
return Provider.model_validate(data)
|
|
37
|
+
|
|
38
|
+
async def create(self, provider: Provider | dict[str, Any]) -> Provider:
|
|
39
|
+
data = await self._client.post("/providers", json=dump_payload(provider))
|
|
40
|
+
return Provider.model_validate(data)
|
|
41
|
+
|
|
42
|
+
async def update(
|
|
43
|
+
self, provider_id: str, provider: Provider | dict[str, Any]
|
|
44
|
+
) -> Provider:
|
|
45
|
+
data = await self._client.put(
|
|
46
|
+
f"/providers/{provider_id}", json=dump_payload(provider)
|
|
47
|
+
)
|
|
48
|
+
return Provider.model_validate(data)
|
|
49
|
+
|
|
50
|
+
async def delete(self, provider_id: str) -> None:
|
|
51
|
+
await self._client.delete(f"/providers/{provider_id}")
|
|
52
|
+
|
|
53
|
+
async def available(self) -> list[str]:
|
|
54
|
+
"""Provider names litellm supports (for the 'add provider' picker). Admin."""
|
|
55
|
+
return await self._client.get("/providers/available")
|
|
56
|
+
|
|
57
|
+
async def names(self) -> list[str]:
|
|
58
|
+
"""Names of providers configured for the caller (global + their project),
|
|
59
|
+
no credentials. Authenticated (not admin) — for the model selector."""
|
|
60
|
+
return await self._client.get("/provider-names")
|
|
61
|
+
|
|
62
|
+
async def models(self, provider: str) -> list[ProviderModel]:
|
|
63
|
+
"""Model suggestions (chat, with capabilities) for a provider, from litellm."""
|
|
64
|
+
data = await self._client.get("/provider-models", params={"provider": provider})
|
|
65
|
+
return [ProviderModel.model_validate(m) for m in data]
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from persona_models.common import Paginated
|
|
6
|
+
from persona_models.workflows import Workflow
|
|
7
|
+
|
|
8
|
+
from persona_sdk._serde import dump_payload
|
|
9
|
+
from persona_sdk.client import PersonaClient
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class WorkflowsApi:
|
|
13
|
+
def __init__(self, client: PersonaClient):
|
|
14
|
+
self._client = client
|
|
15
|
+
|
|
16
|
+
async def list(
|
|
17
|
+
self, keyword: str | None = None, page: int = 1, size: int = 20
|
|
18
|
+
) -> Paginated[Workflow]:
|
|
19
|
+
params: dict[str, Any] = {"page": page, "size": size}
|
|
20
|
+
if keyword:
|
|
21
|
+
params["keyword"] = keyword
|
|
22
|
+
data = await self._client.get("/workflows", params=params)
|
|
23
|
+
return Paginated[Workflow].model_validate(data)
|
|
24
|
+
|
|
25
|
+
async def get(self, workflow_id: str) -> Workflow:
|
|
26
|
+
data = await self._client.get(f"/workflows/{workflow_id}")
|
|
27
|
+
return Workflow.model_validate(data)
|
|
28
|
+
|
|
29
|
+
async def create(self, workflow: Workflow | dict[str, Any]) -> Workflow:
|
|
30
|
+
data = await self._client.post("/workflows", json=dump_payload(workflow))
|
|
31
|
+
return Workflow.model_validate(data)
|
|
32
|
+
|
|
33
|
+
async def update(
|
|
34
|
+
self, workflow_id: str, workflow: Workflow | dict[str, Any]
|
|
35
|
+
) -> Workflow:
|
|
36
|
+
data = await self._client.put(
|
|
37
|
+
f"/workflows/{workflow_id}", json=dump_payload(workflow)
|
|
38
|
+
)
|
|
39
|
+
return Workflow.model_validate(data)
|
|
40
|
+
|
|
41
|
+
async def delete(self, workflow_id: str) -> dict[str, Any]:
|
|
42
|
+
return await self._client.delete(f"/workflows/{workflow_id}")
|
|
43
|
+
|
|
44
|
+
# ------------------------------------------------------------------ #
|
|
45
|
+
# Executions
|
|
46
|
+
#
|
|
47
|
+
# Executions, human tasks, traces and stats are returned as plain
|
|
48
|
+
# dicts: the execution contract is owned by the workflows service and
|
|
49
|
+
# intentionally not constrained here.
|
|
50
|
+
# ------------------------------------------------------------------ #
|
|
51
|
+
|
|
52
|
+
def _run_body(
|
|
53
|
+
self,
|
|
54
|
+
data: dict[str, Any] | None,
|
|
55
|
+
user_id: str | None,
|
|
56
|
+
callback_url: str | None,
|
|
57
|
+
events_hook: str | None,
|
|
58
|
+
) -> dict[str, Any]:
|
|
59
|
+
body: dict[str, Any] = {"initialData": data or {}}
|
|
60
|
+
if user_id:
|
|
61
|
+
body["userId"] = user_id
|
|
62
|
+
if callback_url:
|
|
63
|
+
body["callbackUrl"] = callback_url
|
|
64
|
+
if events_hook:
|
|
65
|
+
body["eventsHook"] = events_hook
|
|
66
|
+
return body
|
|
67
|
+
|
|
68
|
+
async def execute(
|
|
69
|
+
self,
|
|
70
|
+
workflow_id: str,
|
|
71
|
+
data: dict[str, Any] | None = None,
|
|
72
|
+
user_id: str | None = None,
|
|
73
|
+
callback_url: str | None = None,
|
|
74
|
+
events_hook: str | None = None,
|
|
75
|
+
) -> dict[str, Any]:
|
|
76
|
+
"""Run a workflow synchronously (returns when terminal or suspended)."""
|
|
77
|
+
return await self._client.post(
|
|
78
|
+
f"/workflows/{workflow_id}/executions",
|
|
79
|
+
json=self._run_body(data, user_id, callback_url, events_hook),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
async def queue(
|
|
83
|
+
self,
|
|
84
|
+
workflow_id: str,
|
|
85
|
+
data: dict[str, Any] | None = None,
|
|
86
|
+
user_id: str | None = None,
|
|
87
|
+
callback_url: str | None = None,
|
|
88
|
+
events_hook: str | None = None,
|
|
89
|
+
) -> dict[str, Any]:
|
|
90
|
+
"""Queue a workflow for asynchronous execution (returns an ``Execution``)."""
|
|
91
|
+
return await self._client.post(
|
|
92
|
+
f"/workflows/{workflow_id}/executions/queue",
|
|
93
|
+
json=self._run_body(data, user_id, callback_url, events_hook),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
async def list_executions(
|
|
97
|
+
self, workflow_id: str, page: int = 1, size: int = 20
|
|
98
|
+
) -> dict[str, Any]:
|
|
99
|
+
"""List executions for a workflow (``Paginated[Execution]`` shape)."""
|
|
100
|
+
params: dict[str, Any] = {"page": page, "size": size}
|
|
101
|
+
return await self._client.get(
|
|
102
|
+
f"/workflows/{workflow_id}/executions", params=params
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
async def get_execution(
|
|
106
|
+
self, workflow_id: str, execution_id: str
|
|
107
|
+
) -> dict[str, Any]:
|
|
108
|
+
"""Get a single execution (run) with its steps, status and outputs."""
|
|
109
|
+
return await self._client.get(
|
|
110
|
+
f"/workflows/{workflow_id}/executions/{execution_id}"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
async def list_runs(
|
|
114
|
+
self,
|
|
115
|
+
status: str | None = None,
|
|
116
|
+
workflow_id: str | None = None,
|
|
117
|
+
date_from: str | None = None,
|
|
118
|
+
date_to: str | None = None,
|
|
119
|
+
page: int = 1,
|
|
120
|
+
size: int = 20,
|
|
121
|
+
) -> dict[str, Any]:
|
|
122
|
+
"""List runs across all workflows in the project."""
|
|
123
|
+
params: dict[str, Any] = {"page": page, "size": size}
|
|
124
|
+
if status:
|
|
125
|
+
params["status"] = status
|
|
126
|
+
if workflow_id:
|
|
127
|
+
params["workflowId"] = workflow_id
|
|
128
|
+
if date_from:
|
|
129
|
+
params["dateFrom"] = date_from
|
|
130
|
+
if date_to:
|
|
131
|
+
params["dateTo"] = date_to
|
|
132
|
+
return await self._client.get("/executions", params=params)
|
|
133
|
+
|
|
134
|
+
async def cancel_execution(
|
|
135
|
+
self, workflow_id: str, execution_id: str
|
|
136
|
+
) -> dict[str, Any]:
|
|
137
|
+
"""Request cancellation of a running/waiting execution."""
|
|
138
|
+
return await self._client.post(
|
|
139
|
+
f"/workflows/{workflow_id}/executions/{execution_id}/cancel", json={}
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
async def rerun_execution(
|
|
143
|
+
self,
|
|
144
|
+
workflow_id: str,
|
|
145
|
+
execution_id: str,
|
|
146
|
+
from_node_id: str,
|
|
147
|
+
mode: str = "reuse_outputs",
|
|
148
|
+
user_id: str | None = None,
|
|
149
|
+
) -> dict[str, Any]:
|
|
150
|
+
"""Re-run an execution from a given node. mode: 'reuse_outputs' | 'fresh'."""
|
|
151
|
+
body: dict[str, Any] = {"fromNodeId": from_node_id, "mode": mode}
|
|
152
|
+
if user_id:
|
|
153
|
+
body["userId"] = user_id
|
|
154
|
+
return await self._client.post(
|
|
155
|
+
f"/workflows/{workflow_id}/executions/{execution_id}/rerun", json=body
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
async def dry_run_node(
|
|
159
|
+
self,
|
|
160
|
+
workflow_id: str,
|
|
161
|
+
node_id: str,
|
|
162
|
+
inputs: dict[str, Any] | None = None,
|
|
163
|
+
user_id: str | None = None,
|
|
164
|
+
) -> dict[str, Any]:
|
|
165
|
+
"""Execute a single node in isolation with the given inputs (debugging)."""
|
|
166
|
+
body: dict[str, Any] = {"inputs": inputs or {}}
|
|
167
|
+
if user_id:
|
|
168
|
+
body["userId"] = user_id
|
|
169
|
+
return await self._client.post(
|
|
170
|
+
f"/workflows/{workflow_id}/nodes/{node_id}/dry-run", json=body
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
async def get_step_trace(
|
|
174
|
+
self,
|
|
175
|
+
workflow_id: str,
|
|
176
|
+
execution_id: str,
|
|
177
|
+
step_id: str,
|
|
178
|
+
page: int = 1,
|
|
179
|
+
size: int = 200,
|
|
180
|
+
) -> dict[str, Any]:
|
|
181
|
+
"""Normalized action trace of an agent step (reasoning, tool calls, messages)."""
|
|
182
|
+
params: dict[str, Any] = {"page": page, "size": size}
|
|
183
|
+
return await self._client.get(
|
|
184
|
+
f"/workflows/{workflow_id}/executions/{execution_id}/steps/{step_id}/trace",
|
|
185
|
+
params=params,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
# ------------------------------------------------------------------ #
|
|
189
|
+
# Stats
|
|
190
|
+
# ------------------------------------------------------------------ #
|
|
191
|
+
|
|
192
|
+
async def stats_overview(self) -> dict[str, Any]:
|
|
193
|
+
return await self._client.get("/stats/overview")
|
|
194
|
+
|
|
195
|
+
async def stats_executions_timeseries(
|
|
196
|
+
self,
|
|
197
|
+
date_from: str | None = None,
|
|
198
|
+
date_to: str | None = None,
|
|
199
|
+
workflow_id: str | None = None,
|
|
200
|
+
bucket: str = "day",
|
|
201
|
+
) -> Any:
|
|
202
|
+
params: dict[str, Any] = {"bucket": bucket}
|
|
203
|
+
if date_from:
|
|
204
|
+
params["dateFrom"] = date_from
|
|
205
|
+
if date_to:
|
|
206
|
+
params["dateTo"] = date_to
|
|
207
|
+
if workflow_id:
|
|
208
|
+
params["workflowId"] = workflow_id
|
|
209
|
+
return await self._client.get("/stats/executions/timeseries", params=params)
|
|
210
|
+
|
|
211
|
+
async def stats_failing_nodes(
|
|
212
|
+
self,
|
|
213
|
+
date_from: str | None = None,
|
|
214
|
+
workflow_id: str | None = None,
|
|
215
|
+
limit: int = 10,
|
|
216
|
+
) -> Any:
|
|
217
|
+
params: dict[str, Any] = {"limit": limit}
|
|
218
|
+
if date_from:
|
|
219
|
+
params["dateFrom"] = date_from
|
|
220
|
+
if workflow_id:
|
|
221
|
+
params["workflowId"] = workflow_id
|
|
222
|
+
return await self._client.get(
|
|
223
|
+
"/stats/executions/failing-nodes", params=params
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
async def stats_human_response_times(
|
|
227
|
+
self, date_from: str | None = None
|
|
228
|
+
) -> dict[str, Any]:
|
|
229
|
+
params: dict[str, Any] = {}
|
|
230
|
+
if date_from:
|
|
231
|
+
params["dateFrom"] = date_from
|
|
232
|
+
return await self._client.get(
|
|
233
|
+
"/stats/human-tasks/response-times", params=params
|
|
234
|
+
)
|
|
@@ -116,7 +116,7 @@ dependencies = [
|
|
|
116
116
|
[package.metadata]
|
|
117
117
|
requires-dist = [
|
|
118
118
|
{ name = "httpx", specifier = ">=0.27.0" },
|
|
119
|
-
{ name = "persona-models", specifier = ">=0.2.
|
|
119
|
+
{ name = "persona-models", specifier = ">=0.2.4" },
|
|
120
120
|
]
|
|
121
121
|
|
|
122
122
|
[[package]]
|
|
@@ -226,14 +226,6 @@ wheels = [
|
|
|
226
226
|
{ url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906 },
|
|
227
227
|
{ url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607 },
|
|
228
228
|
{ url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769 },
|
|
229
|
-
{ url = "https://files.pythonhosted.org/packages/11/72/90fda5ee3b97e51c494938a4a44c3a35a9c96c19bba12372fb9c634d6f57/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", size = 2115441 },
|
|
230
|
-
{ url = "https://files.pythonhosted.org/packages/1f/53/8942f884fa33f50794f119012dc6a1a02ac43a56407adaac20463df8e98f/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", size = 1930291 },
|
|
231
|
-
{ url = "https://files.pythonhosted.org/packages/79/c8/ecb9ed9cd942bce09fc888ee960b52654fbdbede4ba6c2d6e0d3b1d8b49c/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", size = 1948632 },
|
|
232
|
-
{ url = "https://files.pythonhosted.org/packages/2e/1b/687711069de7efa6af934e74f601e2a4307365e8fdc404703afc453eab26/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad", size = 2138905 },
|
|
233
|
-
{ url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495 },
|
|
234
|
-
{ url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388 },
|
|
235
|
-
{ url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879 },
|
|
236
|
-
{ url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017 },
|
|
237
229
|
{ url = "https://files.pythonhosted.org/packages/e6/b0/1a2aa41e3b5a4ba11420aba2d091b2d17959c8d1519ece3627c371951e73/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8", size = 2103351 },
|
|
238
230
|
{ url = "https://files.pythonhosted.org/packages/a4/ee/31b1f0020baaf6d091c87900ae05c6aeae101fa4e188e1613c80e4f1ea31/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a", size = 1925363 },
|
|
239
231
|
{ url = "https://files.pythonhosted.org/packages/e1/89/ab8e86208467e467a80deaca4e434adac37b10a9d134cd2f99b28a01e483/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b", size = 2135615 },
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
image: python:3.12
|
|
2
|
-
|
|
3
|
-
pipelines:
|
|
4
|
-
default:
|
|
5
|
-
- step:
|
|
6
|
-
name: Publish to PyPI
|
|
7
|
-
caches:
|
|
8
|
-
- pip
|
|
9
|
-
script:
|
|
10
|
-
- apt-get update && apt-get install -y git
|
|
11
|
-
- pip install build twine
|
|
12
|
-
- export VERSION=0.2.$BITBUCKET_BUILD_NUMBER
|
|
13
|
-
- sed -i "s/^version = .*/version = \"$VERSION\"/" pyproject.toml
|
|
14
|
-
- python -m build
|
|
15
|
-
- twine upload dist/* -u __token__ -p $PYPI_TOKEN
|
|
16
|
-
- git tag -a $VERSION -m "$VERSION"
|
|
17
|
-
- git push origin $VERSION
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Any
|
|
4
|
-
|
|
5
|
-
from persona_models.common import Paginated
|
|
6
|
-
from persona_models.known_models import KnownModel
|
|
7
|
-
|
|
8
|
-
from persona_sdk._serde import dump_payload
|
|
9
|
-
from persona_sdk.client import PersonaClient
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class KnownModelsApi:
|
|
13
|
-
def __init__(self, client: PersonaClient):
|
|
14
|
-
self._client = client
|
|
15
|
-
|
|
16
|
-
async def list(
|
|
17
|
-
self, keyword: str | None = None, page: int = 1, size: int = 100
|
|
18
|
-
) -> Paginated[KnownModel]:
|
|
19
|
-
params: dict[str, Any] = {"page": page, "size": size}
|
|
20
|
-
if keyword:
|
|
21
|
-
params["keyword"] = keyword
|
|
22
|
-
data = await self._client.get("/known-models", params=params)
|
|
23
|
-
return Paginated[KnownModel].model_validate(data)
|
|
24
|
-
|
|
25
|
-
async def get(self, known_model_id: str) -> KnownModel:
|
|
26
|
-
data = await self._client.get(f"/known-models/{known_model_id}")
|
|
27
|
-
return KnownModel.model_validate(data)
|
|
28
|
-
|
|
29
|
-
async def create(
|
|
30
|
-
self, known_model: KnownModel | dict[str, Any]
|
|
31
|
-
) -> KnownModel:
|
|
32
|
-
data = await self._client.post(
|
|
33
|
-
"/known-models", json=dump_payload(known_model)
|
|
34
|
-
)
|
|
35
|
-
return KnownModel.model_validate(data)
|
|
36
|
-
|
|
37
|
-
async def update(
|
|
38
|
-
self,
|
|
39
|
-
known_model_id: str,
|
|
40
|
-
known_model: KnownModel | dict[str, Any],
|
|
41
|
-
) -> KnownModel:
|
|
42
|
-
data = await self._client.put(
|
|
43
|
-
f"/known-models/{known_model_id}", json=dump_payload(known_model)
|
|
44
|
-
)
|
|
45
|
-
return KnownModel.model_validate(data)
|
|
46
|
-
|
|
47
|
-
async def delete(self, known_model_id: str) -> KnownModel:
|
|
48
|
-
data = await self._client.delete(f"/known-models/{known_model_id}")
|
|
49
|
-
return KnownModel.model_validate(data)
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Any
|
|
4
|
-
|
|
5
|
-
from persona_models.common import Paginated
|
|
6
|
-
from persona_models.workflows import Workflow
|
|
7
|
-
|
|
8
|
-
from persona_sdk._serde import dump_payload
|
|
9
|
-
from persona_sdk.client import PersonaClient
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class WorkflowsApi:
|
|
13
|
-
def __init__(self, client: PersonaClient):
|
|
14
|
-
self._client = client
|
|
15
|
-
|
|
16
|
-
async def list(
|
|
17
|
-
self, keyword: str | None = None, page: int = 1, size: int = 20
|
|
18
|
-
) -> Paginated[Workflow]:
|
|
19
|
-
params: dict[str, Any] = {"page": page, "size": size}
|
|
20
|
-
if keyword:
|
|
21
|
-
params["keyword"] = keyword
|
|
22
|
-
data = await self._client.get("/workflows", params=params)
|
|
23
|
-
return Paginated[Workflow].model_validate(data)
|
|
24
|
-
|
|
25
|
-
async def get(self, workflow_id: str) -> Workflow:
|
|
26
|
-
data = await self._client.get(f"/workflows/{workflow_id}")
|
|
27
|
-
return Workflow.model_validate(data)
|
|
28
|
-
|
|
29
|
-
async def create(self, workflow: Workflow | dict[str, Any]) -> Workflow:
|
|
30
|
-
data = await self._client.post("/workflows", json=dump_payload(workflow))
|
|
31
|
-
return Workflow.model_validate(data)
|
|
32
|
-
|
|
33
|
-
async def update(
|
|
34
|
-
self, workflow_id: str, workflow: Workflow | dict[str, Any]
|
|
35
|
-
) -> Workflow:
|
|
36
|
-
data = await self._client.put(
|
|
37
|
-
f"/workflows/{workflow_id}", json=dump_payload(workflow)
|
|
38
|
-
)
|
|
39
|
-
return Workflow.model_validate(data)
|
|
40
|
-
|
|
41
|
-
async def delete(self, workflow_id: str) -> dict[str, Any]:
|
|
42
|
-
return await self._client.delete(f"/workflows/{workflow_id}")
|
|
43
|
-
|
|
44
|
-
async def execute(
|
|
45
|
-
self, workflow_id: str, data: dict[str, Any] | None = None
|
|
46
|
-
) -> dict[str, Any]:
|
|
47
|
-
"""Execute a workflow synchronously.
|
|
48
|
-
|
|
49
|
-
Returns the workflow ``Execution`` (``status``, ``steps``, ``output``,
|
|
50
|
-
``error``, ...) as a plain dict; the execution contract is owned by the
|
|
51
|
-
workflows service and intentionally not constrained here.
|
|
52
|
-
"""
|
|
53
|
-
return await self._client.post(
|
|
54
|
-
f"/workflows/{workflow_id}/execute", json=data or {}
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
async def queue(
|
|
58
|
-
self, workflow_id: str, data: dict[str, Any] | None = None
|
|
59
|
-
) -> dict[str, Any]:
|
|
60
|
-
"""Queue a workflow for asynchronous execution (returns an ``Execution``)."""
|
|
61
|
-
return await self._client.post(
|
|
62
|
-
f"/workflows/{workflow_id}/queue", json=data or {}
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
async def list_executions(
|
|
66
|
-
self, workflow_id: str, page: int = 1, size: int = 20
|
|
67
|
-
) -> dict[str, Any]:
|
|
68
|
-
"""List executions for a workflow (``Paginated[Execution]`` shape)."""
|
|
69
|
-
params: dict[str, Any] = {"page": page, "size": size}
|
|
70
|
-
return await self._client.get(
|
|
71
|
-
f"/workflows/{workflow_id}/executions", params=params
|
|
72
|
-
)
|
|
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
|
{persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/auth/bearer_token_auth.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persona_sdk_python-0.2.18 → persona_sdk_python-0.2.20}/persona_sdk/runners/resource_retriever.py
RENAMED
|
File without changes
|
|
File without changes
|