ms-tau-sdk 2.0.3.dev37__tar.gz → 2.0.3.dev38__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.
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/CHANGELOG.md +10 -1
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/PKG-INFO +1 -1
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/pyproject.toml +1 -1
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/agent_skills/tau_project_customization/SKILL.md +3 -2
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/a2a.py +11 -2
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/backend/models.py +5 -1
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/manager.py +36 -4
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/requester.py +14 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/sessions/storage.py +5 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/.gitignore +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/README.md +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/__init__.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/app.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/cli.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/config.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/env_file.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/logs.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/proxy.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/state.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/static/BULMA-LICENSE.txt +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/static/app.js +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/static/board.css +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/static/bulma.min.css +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/static/index.html +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/__init__.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/agent_skills/tau_a2a_runtime_adapter/SKILL.md +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/agent_skills/tau_local_development/SKILL.md +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/agent_skills/tau_repository_integration/SKILL.md +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/__init__.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/chat.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/conversations.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/dependencies.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/health.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/inspection.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/local_chat.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/models.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/request_identity.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/api/sessions.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/app.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/application.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/backend/__init__.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/backend/assertions.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/backend/auth.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/backend/client.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/backend/local.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/backend/mcp.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/backend/routes.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/cli.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/errors.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/logging.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/protocols/__init__.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/protocols/a2a_failure.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/protocols/a2a_message.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/protocols/a2a_roles.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/protocols/assistant_ui.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/protocols/chat_history.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/protocols/strict_json.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/providers/__init__.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/providers/definitions.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/providers/factory.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/providers/tau_compat.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/resources/SYSTEM.md +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/resources/__init__.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/resources/loader.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/resources/prompts/review-code-repository.md +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/__init__.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/deployment_health.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/events.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/extensions.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/failures.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/live_turns.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/observability.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/provenance.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/secret_entry.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/session.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/snapshots.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/task_context.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/sessions/__init__.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/settings.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/skills.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/tools/__init__.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/tools/mainsequence_mcp.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/tools/secret_entry.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/tools/skill_read.py +0 -0
- {ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/tools/task_control.py +0 -0
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- A turn that a caller delivery resumes serves the person who asked for the delegated work. When
|
|
6
|
+
`POST /internal/a2a/task-caller-delivery` resumes a hosted session, the turn presents no
|
|
7
|
+
assertion. It names the delivery in `caller_delivery_uid` on the
|
|
8
|
+
`PATCH /api/v1/agent-sessions/<uid>/tau-runtime-activity/` transition that marks it active, and
|
|
9
|
+
the platform answers with the requester it recorded for the turn: the person who asked for the
|
|
10
|
+
turn that delegated with `resume_caller`. `current_requester()` returns that person, with empty
|
|
11
|
+
`team_uids`, and `requester_client()` reads for them, only when the delivery signal names the
|
|
12
|
+
same User with `requester_identity_type` `human`. Local mode and a runtime that is not hosted
|
|
13
|
+
name no delivery.
|
|
5
14
|
- Main Sequence MCP no longer offers `agent_session.resolve_runtime_access` to the model. Its
|
|
6
15
|
result carries a short-lived runtime token for direct-runtime clients, and Tau's generic MCP
|
|
7
16
|
projection copied that token into model-visible tool content and into tool details, which reach
|
|
@@ -24,7 +33,7 @@
|
|
|
24
33
|
platform's dispatch takes its requester from the dispatch's same two facts. Two new public
|
|
25
34
|
functions:
|
|
26
35
|
- `current_requester()` returns that person inside the turn (`uid`, `team_uids`), or `None` for
|
|
27
|
-
Agent callers, the platform's
|
|
36
|
+
Agent callers, the platform's other calls, local mode, a runtime that is not hosted, and code
|
|
28
37
|
outside a turn;
|
|
29
38
|
- `requester_client()` returns a client bound to the turn. `request(method, path, ...)` calls a
|
|
30
39
|
platform API path with the runtime's credential and `X-MainSequence-Acting-For-Session`,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: ms-tau-sdk
|
|
3
|
-
Version: 2.0.3.
|
|
3
|
+
Version: 2.0.3.dev38
|
|
4
4
|
Summary: Workspace-bound Tau application primitives for Main Sequence projects
|
|
5
5
|
Project-URL: Changelog, https://github.com/mainsequence-sdk/ms-tau-sdk/blob/development/CHANGELOG.md
|
|
6
6
|
Project-URL: Documentation, https://github.com/mainsequence-sdk/ms-tau-sdk/tree/development/docs
|
|
@@ -129,8 +129,9 @@ async def revenue_by_region(tool_call_id, arguments, signal=None, on_update=None
|
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
- `current_requester()` returns the turn's verified requester, with `uid` and `team_uids`, or
|
|
132
|
-
`None`. It is `None` for Agent callers, the platform's own calls
|
|
133
|
-
|
|
132
|
+
`None`. It is `None` for Agent callers, the platform's own calls other than a caller delivery
|
|
133
|
+
(which resumes delegated work for the person who asked), local mode, and code outside a turn.
|
|
134
|
+
Only it names the requester:
|
|
134
135
|
never take a person's UID from tool arguments, the prompt, history, or a header.
|
|
135
136
|
- `requester_client()` returns a client bound to the turn. `await client.request("GET",
|
|
136
137
|
"/api/v1/...")` reads a platform API path for the requester. `await client.call_release(
|
|
@@ -63,7 +63,7 @@ from ms_tau_sdk.runtime.provenance import (
|
|
|
63
63
|
TurnProvenance,
|
|
64
64
|
turn_provenance_from_request,
|
|
65
65
|
)
|
|
66
|
-
from ms_tau_sdk.runtime.requester import Requester, canonical_requester_uid
|
|
66
|
+
from ms_tau_sdk.runtime.requester import CallerDelivery, Requester, canonical_requester_uid
|
|
67
67
|
from ms_tau_sdk.runtime.task_context import (
|
|
68
68
|
TaskExecutionContext,
|
|
69
69
|
active_task_execution,
|
|
@@ -2150,7 +2150,7 @@ def _durable_task_execution_input(
|
|
|
2150
2150
|
|
|
2151
2151
|
|
|
2152
2152
|
def _dispatched_requester(body: dict[str, Any], config: TauSDKSettings) -> Requester | None:
|
|
2153
|
-
"""Return the
|
|
2153
|
+
"""Return the requester that the platform's verified dispatch or caller delivery names.
|
|
2154
2154
|
|
|
2155
2155
|
Only a person is a requester: an Agent's workload User never is. A runtime that does not
|
|
2156
2156
|
verify the platform's assertion on its internal routes takes no requester from them.
|
|
@@ -2213,6 +2213,7 @@ async def _resume_caller_delivery(
|
|
|
2213
2213
|
task_id: str,
|
|
2214
2214
|
task_status: str,
|
|
2215
2215
|
caller_agent_session_uid: str,
|
|
2216
|
+
delivery: CallerDelivery,
|
|
2216
2217
|
) -> None:
|
|
2217
2218
|
prompt = (
|
|
2218
2219
|
"A delegated asynchronous A2A Task has new actionable state. "
|
|
@@ -2229,6 +2230,9 @@ async def _resume_caller_delivery(
|
|
|
2229
2230
|
"actorKind": "platform",
|
|
2230
2231
|
"actorUid": "mainsequence",
|
|
2231
2232
|
},
|
|
2233
|
+
# The turn names its delivery, so that the platform records the requester of the
|
|
2234
|
+
# delegated work for it.
|
|
2235
|
+
caller_delivery=delivery,
|
|
2232
2236
|
):
|
|
2233
2237
|
pass
|
|
2234
2238
|
manager.mark_response_delivered(caller_agent_session_uid)
|
|
@@ -2238,6 +2242,7 @@ async def _resume_caller_delivery(
|
|
|
2238
2242
|
async def task_caller_delivery_available(
|
|
2239
2243
|
body: dict[str, Any],
|
|
2240
2244
|
manager: RuntimeManagerDep,
|
|
2245
|
+
config: SettingsDep,
|
|
2241
2246
|
) -> dict[str, Any]:
|
|
2242
2247
|
delivery_uid = str(body.get("delivery_uid") or "").strip()
|
|
2243
2248
|
task_uid = str(body.get("task_uid") or "").strip()
|
|
@@ -2284,6 +2289,10 @@ async def task_caller_delivery_available(
|
|
|
2284
2289
|
task_id=task_id,
|
|
2285
2290
|
task_status=task_status,
|
|
2286
2291
|
caller_agent_session_uid=caller_agent_session_uid,
|
|
2292
|
+
delivery=CallerDelivery(
|
|
2293
|
+
uid=delivery_uid,
|
|
2294
|
+
requester=_dispatched_requester(body, config),
|
|
2295
|
+
),
|
|
2287
2296
|
),
|
|
2288
2297
|
name=f"a2a-caller-delivery-{delivery_uid}",
|
|
2289
2298
|
)
|
|
@@ -295,7 +295,8 @@ class RuntimeState(BackendModel):
|
|
|
295
295
|
cancel_requested: bool = False
|
|
296
296
|
cancellation_id: str | None = None
|
|
297
297
|
# The person the platform recorded as the active turn's requester, from the caller assertion
|
|
298
|
-
# the runtime presented when it marked the turn active.
|
|
298
|
+
# the runtime presented, or the caller delivery it named, when it marked the turn active.
|
|
299
|
+
# None when it recorded nobody.
|
|
299
300
|
requester_user_uid: str | None = None
|
|
300
301
|
|
|
301
302
|
@model_validator(mode="after")
|
|
@@ -322,6 +323,9 @@ class RuntimeActivityPatch(BackendRequestModel):
|
|
|
322
323
|
activity_sequence: int | None = Field(default=None, ge=1)
|
|
323
324
|
runtime_activity: AgentRuntimeActivity
|
|
324
325
|
active_turn_uid: str | None = None
|
|
326
|
+
# The caller delivery a turn the platform starts resumes the session for, sent only with the
|
|
327
|
+
# transition that marks that turn active, and never together with a caller assertion.
|
|
328
|
+
caller_delivery_uid: str | None = None
|
|
325
329
|
|
|
326
330
|
@model_validator(mode="after")
|
|
327
331
|
def validate_concurrency_mode(self) -> RuntimeActivityPatch:
|
|
@@ -65,6 +65,7 @@ from ms_tau_sdk.runtime.live_turns import LiveTurn, LocalChatTurn
|
|
|
65
65
|
from ms_tau_sdk.runtime.observability import TauTurnObserver
|
|
66
66
|
from ms_tau_sdk.runtime.provenance import TurnProvenance
|
|
67
67
|
from ms_tau_sdk.runtime.requester import (
|
|
68
|
+
CallerDelivery,
|
|
68
69
|
Requester,
|
|
69
70
|
TurnRequesterBinding,
|
|
70
71
|
bind_turn_requester,
|
|
@@ -1323,11 +1324,14 @@ class SessionRuntimeManager:
|
|
|
1323
1324
|
platform_event: PlatformEvent | None = None,
|
|
1324
1325
|
turn_uid: str | None = None,
|
|
1325
1326
|
caller_assertion: CallerAssertion | None = None,
|
|
1327
|
+
caller_delivery: CallerDelivery | None = None,
|
|
1326
1328
|
) -> AsyncIterator[TauRuntimeEvent]:
|
|
1327
1329
|
"""Run one turn in a session.
|
|
1328
1330
|
|
|
1329
1331
|
``caller_assertion`` is the verified caller assertion of the hosted chat or A2A Message
|
|
1330
1332
|
request that starts the turn. It is presented only when the turn is marked active.
|
|
1333
|
+
``caller_delivery`` is, instead, the caller delivery that a turn the platform starts
|
|
1334
|
+
resumes the session for. It is named only when the turn is marked active.
|
|
1331
1335
|
"""
|
|
1332
1336
|
|
|
1333
1337
|
agent_run_uid = str(uuid.uuid4())
|
|
@@ -1345,6 +1349,7 @@ class SessionRuntimeManager:
|
|
|
1345
1349
|
provenance=provenance,
|
|
1346
1350
|
platform_event=platform_event,
|
|
1347
1351
|
caller_assertion=caller_assertion,
|
|
1352
|
+
caller_delivery=caller_delivery,
|
|
1348
1353
|
):
|
|
1349
1354
|
yield event
|
|
1350
1355
|
|
|
@@ -1356,6 +1361,7 @@ class SessionRuntimeManager:
|
|
|
1356
1361
|
provenance: TurnProvenance | None = None,
|
|
1357
1362
|
platform_event: PlatformEvent | None = None,
|
|
1358
1363
|
caller_assertion: CallerAssertion | None = None,
|
|
1364
|
+
caller_delivery: CallerDelivery | None = None,
|
|
1359
1365
|
) -> AsyncIterator[TauRuntimeEvent]:
|
|
1360
1366
|
live_turn = self._open_live_turn(session_uid, content, provenance)
|
|
1361
1367
|
try:
|
|
@@ -1365,6 +1371,7 @@ class SessionRuntimeManager:
|
|
|
1365
1371
|
provenance=provenance,
|
|
1366
1372
|
platform_event=platform_event,
|
|
1367
1373
|
caller_assertion=caller_assertion,
|
|
1374
|
+
caller_delivery=caller_delivery,
|
|
1368
1375
|
):
|
|
1369
1376
|
if live_turn is not None:
|
|
1370
1377
|
live_turn.observe(event)
|
|
@@ -1497,6 +1504,7 @@ class SessionRuntimeManager:
|
|
|
1497
1504
|
provenance: TurnProvenance | None = None,
|
|
1498
1505
|
platform_event: PlatformEvent | None = None,
|
|
1499
1506
|
caller_assertion: CallerAssertion | None = None,
|
|
1507
|
+
caller_delivery: CallerDelivery | None = None,
|
|
1500
1508
|
) -> AsyncIterator[TauRuntimeEvent]:
|
|
1501
1509
|
logger.info(
|
|
1502
1510
|
"agent.run.accepted",
|
|
@@ -1522,18 +1530,25 @@ class SessionRuntimeManager:
|
|
|
1522
1530
|
context = get_contextvars()
|
|
1523
1531
|
turn_uid = str(context.get("turn_uid") or uuid.uuid4())
|
|
1524
1532
|
task_context = active_task_execution()
|
|
1525
|
-
# Only a hosted chat or A2A Message turn presents its request's caller assertion
|
|
1533
|
+
# Only a hosted chat or A2A Message turn presents its request's caller assertion, and only
|
|
1534
|
+
# a hosted turn the platform starts for a caller delivery names that delivery. A Task
|
|
1526
1535
|
# attempt takes its requester from the platform's dispatch instead.
|
|
1527
1536
|
presented = (
|
|
1528
1537
|
caller_assertion
|
|
1529
1538
|
if task_context is None and self._requester_identity_verified()
|
|
1530
1539
|
else None
|
|
1531
1540
|
)
|
|
1541
|
+
delivery = (
|
|
1542
|
+
caller_delivery
|
|
1543
|
+
if presented is None and task_context is None and self._requester_identity_verified()
|
|
1544
|
+
else None
|
|
1545
|
+
)
|
|
1532
1546
|
runtime = await self._begin_turn_with_one_reload(
|
|
1533
1547
|
session_uid=session_uid,
|
|
1534
1548
|
runtime=runtime,
|
|
1535
1549
|
turn_uid=turn_uid,
|
|
1536
1550
|
caller_assertion=presented,
|
|
1551
|
+
caller_delivery_uid=delivery.uid if delivery is not None else None,
|
|
1537
1552
|
)
|
|
1538
1553
|
requester_binding = TurnRequesterBinding(
|
|
1539
1554
|
session_uid=session_uid,
|
|
@@ -1541,6 +1556,7 @@ class SessionRuntimeManager:
|
|
|
1541
1556
|
runtime,
|
|
1542
1557
|
caller_assertion=presented,
|
|
1543
1558
|
task_context=task_context,
|
|
1559
|
+
caller_delivery=delivery,
|
|
1544
1560
|
),
|
|
1545
1561
|
lease_proof=lambda: LeaseProof(
|
|
1546
1562
|
session_uid=session_uid,
|
|
@@ -1677,16 +1693,24 @@ class SessionRuntimeManager:
|
|
|
1677
1693
|
runtime: ActiveSessionRuntime,
|
|
1678
1694
|
turn_uid: str,
|
|
1679
1695
|
caller_assertion: CallerAssertion | None = None,
|
|
1696
|
+
caller_delivery_uid: str | None = None,
|
|
1680
1697
|
) -> ActiveSessionRuntime:
|
|
1681
1698
|
for begin_attempt in range(2):
|
|
1682
1699
|
runtime.activity_sequence += 1
|
|
1683
1700
|
# An expired assertion is not presented, and the platform then records nobody.
|
|
1684
1701
|
presented = caller_assertion.unexpired_token() if caller_assertion else None
|
|
1702
|
+
named: dict[str, str] = (
|
|
1703
|
+
{"caller_assertion": presented}
|
|
1704
|
+
if presented
|
|
1705
|
+
else {"caller_delivery_uid": caller_delivery_uid}
|
|
1706
|
+
if caller_delivery_uid
|
|
1707
|
+
else {}
|
|
1708
|
+
)
|
|
1685
1709
|
try:
|
|
1686
1710
|
state = await runtime.storage.begin_turn(
|
|
1687
1711
|
turn_uid=turn_uid,
|
|
1688
1712
|
activity_sequence=runtime.activity_sequence,
|
|
1689
|
-
**
|
|
1713
|
+
**named,
|
|
1690
1714
|
)
|
|
1691
1715
|
except BackendConflictError:
|
|
1692
1716
|
if begin_attempt:
|
|
@@ -1700,7 +1724,7 @@ class SessionRuntimeManager:
|
|
|
1700
1724
|
runtime.activity_sequence = state.activity_sequence or runtime.activity_sequence
|
|
1701
1725
|
requester_user_uid = state.requester_user_uid
|
|
1702
1726
|
runtime.requester_user_uid = (
|
|
1703
|
-
requester_user_uid if
|
|
1727
|
+
requester_user_uid if named and isinstance(requester_user_uid, str) else None
|
|
1704
1728
|
)
|
|
1705
1729
|
return runtime
|
|
1706
1730
|
raise AssertionError("Tau turn reload loop did not terminate")
|
|
@@ -1716,19 +1740,27 @@ class SessionRuntimeManager:
|
|
|
1716
1740
|
*,
|
|
1717
1741
|
caller_assertion: CallerAssertion | None,
|
|
1718
1742
|
task_context: TaskExecutionContext | None,
|
|
1743
|
+
caller_delivery: CallerDelivery | None = None,
|
|
1719
1744
|
) -> Requester | None:
|
|
1720
1745
|
"""Name the verified person a turn serves, or None.
|
|
1721
1746
|
|
|
1722
1747
|
A Task turn serves the person its execution context names, as the platform recorded the
|
|
1723
1748
|
Task's requester. A chat or A2A Message turn serves its verified caller only when the
|
|
1724
1749
|
platform recorded that same person as the turn's requester, which it does for a person who
|
|
1725
|
-
owns the session and never for an Agent caller.
|
|
1750
|
+
owns the session and never for an Agent caller. A turn the platform starts for a caller
|
|
1751
|
+
delivery serves the requester the delivery names, only when the platform recorded that
|
|
1752
|
+
same person for the turn.
|
|
1726
1753
|
"""
|
|
1727
1754
|
|
|
1728
1755
|
if not self._requester_identity_verified():
|
|
1729
1756
|
return None
|
|
1730
1757
|
if task_context is not None:
|
|
1731
1758
|
return task_context.requester
|
|
1759
|
+
if caller_delivery is not None:
|
|
1760
|
+
requester = caller_delivery.requester
|
|
1761
|
+
if requester is None or runtime.requester_user_uid != requester.uid:
|
|
1762
|
+
return None
|
|
1763
|
+
return requester
|
|
1732
1764
|
if caller_assertion is None or caller_assertion.caller_is_workload:
|
|
1733
1765
|
return None
|
|
1734
1766
|
caller = caller_assertion.caller
|
|
@@ -58,6 +58,19 @@ class Requester:
|
|
|
58
58
|
team_uids: tuple[str, ...] = ()
|
|
59
59
|
|
|
60
60
|
|
|
61
|
+
@dataclass(frozen=True, slots=True)
|
|
62
|
+
class CallerDelivery:
|
|
63
|
+
"""The caller delivery that a turn the platform starts resumes its session for.
|
|
64
|
+
|
|
65
|
+
``requester`` is the person the platform's verified signal names as the requester of the
|
|
66
|
+
delegated work, or None. The turn serves that person only when the platform records the same
|
|
67
|
+
person for the turn it starts.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
uid: str
|
|
71
|
+
requester: Requester | None = None
|
|
72
|
+
|
|
73
|
+
|
|
61
74
|
class RequesterBindingError(TauSDKError, PermissionError):
|
|
62
75
|
"""The turn has no verified requester, or the platform ended the requester's binding.
|
|
63
76
|
|
|
@@ -551,6 +564,7 @@ def _token_access(answer: ReleaseRuntimeAccess) -> _ReleaseAccess:
|
|
|
551
564
|
|
|
552
565
|
|
|
553
566
|
__all__ = [
|
|
567
|
+
"CallerDelivery",
|
|
554
568
|
"Requester",
|
|
555
569
|
"RequesterBindingError",
|
|
556
570
|
"RequesterClient",
|
|
@@ -68,11 +68,15 @@ class BackendSessionStorage(SessionStorage):
|
|
|
68
68
|
turn_uid: str,
|
|
69
69
|
activity_sequence: int,
|
|
70
70
|
caller_assertion: str | None = None,
|
|
71
|
+
caller_delivery_uid: str | None = None,
|
|
71
72
|
) -> RuntimeState:
|
|
72
73
|
"""Mark ``turn_uid`` active.
|
|
73
74
|
|
|
74
75
|
``caller_assertion`` is the verified caller assertion of the request that started the
|
|
75
76
|
turn. It goes only to this transition, so that the platform can record who asked.
|
|
77
|
+
``caller_delivery_uid`` names, instead, the caller delivery that a turn the platform
|
|
78
|
+
starts resumes the session for; the platform then records the requester of the delegated
|
|
79
|
+
work.
|
|
76
80
|
"""
|
|
77
81
|
|
|
78
82
|
async with self._state_lock:
|
|
@@ -89,6 +93,7 @@ class BackendSessionStorage(SessionStorage):
|
|
|
89
93
|
activity_sequence=activity_sequence,
|
|
90
94
|
runtime_activity="working",
|
|
91
95
|
active_turn_uid=turn_uid,
|
|
96
|
+
caller_delivery_uid=caller_delivery_uid,
|
|
92
97
|
),
|
|
93
98
|
**({"caller_assertion": caller_assertion} if caller_assertion else {}),
|
|
94
99
|
)
|
|
File without changes
|
|
File without changes
|
{ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/__init__.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/app.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/cli.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/config.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/env_file.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/logs.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/proxy.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/state.py
RENAMED
|
File without changes
|
|
File without changes
|
{ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/packages/tau-board/src/ms_tau_board/static/app.js
RENAMED
|
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
|
{ms_tau_sdk-2.0.3.dev37 → ms_tau_sdk-2.0.3.dev38}/src/ms_tau_sdk/runtime/deployment_health.py
RENAMED
|
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
|