ms-tau-sdk 2.0.20.dev71__tar.gz → 2.0.21.dev72__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.20.dev71 → ms_tau_sdk-2.0.21.dev72}/CHANGELOG.md +26 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/PKG-INFO +1 -1
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/pyproject.toml +1 -1
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/a2a.py +153 -68
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/backend/client.py +42 -12
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/backend/local.py +4 -10
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/protocols/a2a_roles.py +44 -1
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/.gitignore +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/README.md +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/__init__.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/app.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/cli.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/config.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/env_file.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/logs.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/proxy.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/state.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/static/BULMA-LICENSE.txt +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/static/app.js +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/static/board.css +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/static/bulma.min.css +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/static/index.html +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/__init__.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/agent_skills/tau_a2a_runtime_adapter/SKILL.md +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/agent_skills/tau_local_development/SKILL.md +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/agent_skills/tau_project_customization/SKILL.md +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/agent_skills/tau_repository_integration/SKILL.md +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/agent_skills/tau_security_and_access/SKILL.md +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/__init__.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/chat.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/conversations.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/dependencies.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/health.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/inspection.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/local_chat.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/models.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/request_identity.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/api/sessions.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/app.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/application.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/backend/__init__.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/backend/assertions.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/backend/auth.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/backend/mcp.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/backend/models.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/backend/routes.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/backend/team_memberships.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/cli.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/errors.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/logging.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/protocols/__init__.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/protocols/a2a_failure.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/protocols/a2a_message.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/protocols/assistant_ui.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/protocols/chat_history.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/protocols/strict_json.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/providers/__init__.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/providers/definitions.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/providers/factory.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/providers/tau_compat.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/resources/SYSTEM.md +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/resources/__init__.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/resources/loader.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/resources/prompts/review-code-repository.md +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/__init__.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/deployment_health.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/events.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/extensions.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/failures.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/live_turns.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/manager.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/observability.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/provenance.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/requester.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/session.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/snapshots.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/runtime/task_context.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/sessions/__init__.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/sessions/storage.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/settings.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/skills.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/tools/__init__.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/tools/mainsequence_mcp.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/tools/mcp_applications.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/tools/mcp_connection.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/tools/skill_read.py +0 -0
- {ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/tools/task_control.py +0 -0
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.21 — 2026-10-21
|
|
4
|
+
|
|
5
|
+
- **Hosted Tasks can be sent, read and listed with their Messages
|
|
6
|
+
([#111](https://github.com/mainsequence-sdk/ms-tau-sdk/issues/111), ADR 0002).** On the platform,
|
|
7
|
+
a Task-mode `message:send` and GetTask answered HTTP 500 whenever the answer included the Task's
|
|
8
|
+
Messages. The platform stores a Task Message with the role `user` or `agent` and snake-case
|
|
9
|
+
fields such as `message_id`, and the SDK read it as one of its own binding Messages. The
|
|
10
|
+
platform client now translates every Task Message it reads, in a Task's `latest_message` and
|
|
11
|
+
`history` and in the Message tail, into a binding Message. The Task and context IDs come from
|
|
12
|
+
the Task the Message belongs to, and fields only the platform keeps, such as the request hash and
|
|
13
|
+
the requester, are left out. A2A callers get `ROLE_USER` and `ROLE_AGENT` as before.
|
|
14
|
+
- The platform's wake-up for a submitted hosted Task runs it again; the runtime had refused it
|
|
15
|
+
with HTTP 409 because it could not read the Task's requester Message.
|
|
16
|
+
- On the platform, `historyLength` returns the latest Messages instead of the first ones.
|
|
17
|
+
- `list_task_messages()` takes the Task and a `history_length` instead of a Task UID, `limit`
|
|
18
|
+
and `offset`.
|
|
19
|
+
|
|
20
|
+
- **A Task-mode `message:send` that fails after its Task was accepted names the Task
|
|
21
|
+
([#111](https://github.com/mainsequence-sdk/ms-tau-sdk/issues/111), ADR 0002).** It answered a
|
|
22
|
+
bare HTTP 500 that looked as if nothing had happened, although the Task existed and could
|
|
23
|
+
already run. It now answers HTTP 500 `INTERNAL` with an `ErrorInfo` whose reason is
|
|
24
|
+
`ACCEPTED_TASK_STATE_UNAVAILABLE` and whose metadata gives the `taskId` and `contextId`, and
|
|
25
|
+
JSON-RPC answers `-32603` with the same `ErrorInfo`. The caller reads the Task with GetTask
|
|
26
|
+
instead of sending the Message again. See the
|
|
27
|
+
[runtime contract](docs/reference/runtime-contract.md#task-terminalization-and-failure).
|
|
28
|
+
|
|
3
29
|
## 2.0.20 — 2026-10-19
|
|
4
30
|
|
|
5
31
|
- **ADR 0024 records the requirements for file attachments in chat.** The proposed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: ms-tau-sdk
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.21.dev72
|
|
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
|
|
@@ -8,7 +8,7 @@ import json
|
|
|
8
8
|
import re
|
|
9
9
|
import time
|
|
10
10
|
import uuid
|
|
11
|
-
from collections.abc import AsyncIterator
|
|
11
|
+
from collections.abc import AsyncIterator, Iterator
|
|
12
12
|
from dataclasses import dataclass, field
|
|
13
13
|
from datetime import UTC, datetime
|
|
14
14
|
from enum import StrEnum
|
|
@@ -448,6 +448,83 @@ def _message_limit_json_rpc_error(request_id: object, limit_seconds: float) -> d
|
|
|
448
448
|
}
|
|
449
449
|
|
|
450
450
|
|
|
451
|
+
class _AcceptedTaskUnanswered(Exception):
|
|
452
|
+
"""A Task was accepted, but the answer that describes it could not be prepared."""
|
|
453
|
+
|
|
454
|
+
def __init__(self, task: AgentTask) -> None:
|
|
455
|
+
super().__init__(f"Task {task.task_id} was accepted, but its state could not be returned")
|
|
456
|
+
self.task_id = task.task_id
|
|
457
|
+
self.context_id = task.context_id
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
@contextlib.contextmanager
|
|
461
|
+
def _naming_accepted_task(task: AgentTask) -> Iterator[None]:
|
|
462
|
+
"""Name ``task`` when the request fails after the Task was accepted.
|
|
463
|
+
|
|
464
|
+
The Task exists and may already run, so a bare server error would suggest that nothing
|
|
465
|
+
happened and invite the caller to send the Message again.
|
|
466
|
+
"""
|
|
467
|
+
|
|
468
|
+
try:
|
|
469
|
+
yield
|
|
470
|
+
except Exception as error:
|
|
471
|
+
logger.error(
|
|
472
|
+
"a2a.task.answer_failed",
|
|
473
|
+
message="A Task was accepted, but the answer that describes it could not be prepared",
|
|
474
|
+
task_uid=task.uid,
|
|
475
|
+
task_id=task.task_id,
|
|
476
|
+
error_type=type(error).__name__,
|
|
477
|
+
)
|
|
478
|
+
raise _AcceptedTaskUnanswered(task) from error
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
def _accepted_task_text(error: _AcceptedTaskUnanswered) -> str:
|
|
482
|
+
return (
|
|
483
|
+
f"Task {error.task_id} was accepted, but its state could not be returned. "
|
|
484
|
+
"Read it with GetTask instead of sending the Message again."
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
def _accepted_task_error_info(error: _AcceptedTaskUnanswered) -> dict[str, Any]:
|
|
489
|
+
return {
|
|
490
|
+
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
|
|
491
|
+
"reason": "ACCEPTED_TASK_STATE_UNAVAILABLE",
|
|
492
|
+
"domain": "mainsequence.ai",
|
|
493
|
+
# ErrorInfo metadata values are strings.
|
|
494
|
+
"metadata": {"taskId": error.task_id, "contextId": error.context_id},
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
def _accepted_task_rest_error(error: _AcceptedTaskUnanswered) -> JSONResponse:
|
|
499
|
+
return JSONResponse(
|
|
500
|
+
status_code=500,
|
|
501
|
+
media_type="application/a2a+json",
|
|
502
|
+
content={
|
|
503
|
+
"error": {
|
|
504
|
+
"code": 500,
|
|
505
|
+
"status": "INTERNAL",
|
|
506
|
+
"message": _accepted_task_text(error),
|
|
507
|
+
"details": [_accepted_task_error_info(error)],
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
)
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
def _accepted_task_json_rpc_error(
|
|
514
|
+
request_id: object,
|
|
515
|
+
error: _AcceptedTaskUnanswered,
|
|
516
|
+
) -> dict[str, Any]:
|
|
517
|
+
return {
|
|
518
|
+
"jsonrpc": "2.0",
|
|
519
|
+
"id": request_id,
|
|
520
|
+
"error": {
|
|
521
|
+
"code": -32603,
|
|
522
|
+
"message": _accepted_task_text(error),
|
|
523
|
+
"data": [_accepted_task_error_info(error)],
|
|
524
|
+
},
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
|
|
451
528
|
def _without_push_notification_capability(
|
|
452
529
|
agent_card: dict[str, Any] | None,
|
|
453
530
|
) -> dict[str, Any] | None:
|
|
@@ -631,7 +708,7 @@ async def _task_with_history(
|
|
|
631
708
|
) -> AgentTask:
|
|
632
709
|
if history_length == 0:
|
|
633
710
|
return task.model_copy(update={"history": None})
|
|
634
|
-
history = await client.list_task_messages(task
|
|
711
|
+
history = await client.list_task_messages(task, history_length=history_length)
|
|
635
712
|
return task.model_copy(update={"history": history})
|
|
636
713
|
|
|
637
714
|
|
|
@@ -2376,6 +2453,8 @@ async def message_send(
|
|
|
2376
2453
|
return await _message_send(body, client, manager, config, request, a2a_extensions)
|
|
2377
2454
|
except _MessageLimitExceeded as error:
|
|
2378
2455
|
return _message_limit_rest_error(error.limit_seconds) # type: ignore[return-value]
|
|
2456
|
+
except _AcceptedTaskUnanswered as error:
|
|
2457
|
+
return _accepted_task_rest_error(error) # type: ignore[return-value]
|
|
2379
2458
|
|
|
2380
2459
|
|
|
2381
2460
|
async def _message_send(
|
|
@@ -2392,7 +2471,8 @@ async def _message_send(
|
|
|
2392
2471
|
bounds a Message-mode request as a whole, including output-contract repair turns, and it ends
|
|
2393
2472
|
the wait of a Task-mode request that does not return immediately. A Message-mode request that
|
|
2394
2473
|
reaches its limit, or its turn's own limit, raises ``_MessageLimitExceeded``, which each
|
|
2395
|
-
transport answers in its own form.
|
|
2474
|
+
transport answers in its own form. A Task-mode request that fails after its Task was accepted
|
|
2475
|
+
raises ``_AcceptedTaskUnanswered``, which each transport answers with the Task named.
|
|
2396
2476
|
"""
|
|
2397
2477
|
platform_limit = config.a2a_message_limit_seconds
|
|
2398
2478
|
deadline = (
|
|
@@ -2447,48 +2527,14 @@ async def _message_send(
|
|
|
2447
2527
|
continued_message,
|
|
2448
2528
|
**_presented_assertion(caller_assertion),
|
|
2449
2529
|
)
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
client,
|
|
2459
|
-
manager,
|
|
2460
|
-
task,
|
|
2461
|
-
prompt=prompt,
|
|
2462
|
-
output_contract=output_contract,
|
|
2463
|
-
max_output_bytes=config.max_turn_output_bytes,
|
|
2464
|
-
provenance=provenance,
|
|
2465
|
-
config=config,
|
|
2466
|
-
caller=_request_caller(caller_assertion),
|
|
2467
|
-
)
|
|
2468
|
-
if return_immediately:
|
|
2469
|
-
task = await _task_with_history(client, task, history_length=history_length)
|
|
2470
|
-
return {"task": _task_payload(task, history_length=history_length)}
|
|
2471
|
-
task = await _wait_for_task_return_state(
|
|
2472
|
-
client,
|
|
2473
|
-
task,
|
|
2474
|
-
poll_interval_seconds=config.a2a_task_event_poll_interval_seconds,
|
|
2475
|
-
wait_timeout_seconds=_task_wait_seconds(config, deadline),
|
|
2476
|
-
)
|
|
2477
|
-
task = await _task_with_history(client, task, history_length=history_length)
|
|
2478
|
-
return {"task": _task_payload(task, history_length=history_length)}
|
|
2479
|
-
if response_kind is ResponseKind.TASK:
|
|
2480
|
-
caller_assertion = _task_caller_assertion(request, config)
|
|
2481
|
-
creation = await _create_backend_task(
|
|
2482
|
-
client,
|
|
2483
|
-
message=message,
|
|
2484
|
-
task_id=_task_id(body),
|
|
2485
|
-
local_mode=config.local_mode,
|
|
2486
|
-
output_contract=output_contract,
|
|
2487
|
-
provenance=provenance,
|
|
2488
|
-
caller_assertion=caller_assertion,
|
|
2489
|
-
)
|
|
2490
|
-
task = creation.task
|
|
2491
|
-
if creation.created:
|
|
2530
|
+
with _naming_accepted_task(task):
|
|
2531
|
+
if config.local_mode:
|
|
2532
|
+
task = await _persist_local_recovery_contract(
|
|
2533
|
+
client,
|
|
2534
|
+
task,
|
|
2535
|
+
output_contract=output_contract,
|
|
2536
|
+
provenance=provenance,
|
|
2537
|
+
)
|
|
2492
2538
|
await _schedule_task_accelerator(
|
|
2493
2539
|
client,
|
|
2494
2540
|
manager,
|
|
@@ -2511,31 +2557,68 @@ async def _message_send(
|
|
|
2511
2557
|
)
|
|
2512
2558
|
task = await _task_with_history(client, task, history_length=history_length)
|
|
2513
2559
|
return {"task": _task_payload(task, history_length=history_length)}
|
|
2560
|
+
if response_kind is ResponseKind.TASK:
|
|
2561
|
+
caller_assertion = _task_caller_assertion(request, config)
|
|
2562
|
+
creation = await _create_backend_task(
|
|
2563
|
+
client,
|
|
2564
|
+
message=message,
|
|
2565
|
+
task_id=_task_id(body),
|
|
2566
|
+
local_mode=config.local_mode,
|
|
2567
|
+
output_contract=output_contract,
|
|
2568
|
+
provenance=provenance,
|
|
2569
|
+
caller_assertion=caller_assertion,
|
|
2570
|
+
)
|
|
2571
|
+
task = creation.task
|
|
2572
|
+
if creation.created:
|
|
2573
|
+
with _naming_accepted_task(task):
|
|
2574
|
+
await _schedule_task_accelerator(
|
|
2575
|
+
client,
|
|
2576
|
+
manager,
|
|
2577
|
+
task,
|
|
2578
|
+
prompt=prompt,
|
|
2579
|
+
output_contract=output_contract,
|
|
2580
|
+
max_output_bytes=config.max_turn_output_bytes,
|
|
2581
|
+
provenance=provenance,
|
|
2582
|
+
config=config,
|
|
2583
|
+
caller=_request_caller(caller_assertion),
|
|
2584
|
+
)
|
|
2585
|
+
if return_immediately:
|
|
2586
|
+
task = await _task_with_history(client, task, history_length=history_length)
|
|
2587
|
+
return {"task": _task_payload(task, history_length=history_length)}
|
|
2588
|
+
task = await _wait_for_task_return_state(
|
|
2589
|
+
client,
|
|
2590
|
+
task,
|
|
2591
|
+
poll_interval_seconds=config.a2a_task_event_poll_interval_seconds,
|
|
2592
|
+
wait_timeout_seconds=_task_wait_seconds(config, deadline),
|
|
2593
|
+
)
|
|
2594
|
+
task = await _task_with_history(client, task, history_length=history_length)
|
|
2595
|
+
return {"task": _task_payload(task, history_length=history_length)}
|
|
2514
2596
|
# An existing Task with this ID is answered only to a caller who may address its session.
|
|
2515
2597
|
await _require_task_session_access(client, task, checked=requested_context_id)
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
task
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2598
|
+
with _naming_accepted_task(task):
|
|
2599
|
+
if config.local_mode and task.status == "submitted":
|
|
2600
|
+
recovered_prompt, recovered_contract, recovered_provenance = (
|
|
2601
|
+
_recovery_execution_contract(task, config)
|
|
2602
|
+
)
|
|
2603
|
+
await _schedule_task_accelerator(
|
|
2604
|
+
client,
|
|
2605
|
+
manager,
|
|
2606
|
+
task,
|
|
2607
|
+
prompt=recovered_prompt,
|
|
2608
|
+
output_contract=recovered_contract,
|
|
2609
|
+
max_output_bytes=config.max_turn_output_bytes,
|
|
2610
|
+
provenance=recovered_provenance,
|
|
2611
|
+
config=config,
|
|
2612
|
+
)
|
|
2613
|
+
if not return_immediately and task.status not in TASK_RETURN_STATES:
|
|
2614
|
+
task = await _wait_for_task_return_state(
|
|
2615
|
+
client,
|
|
2616
|
+
task,
|
|
2617
|
+
poll_interval_seconds=config.a2a_task_event_poll_interval_seconds,
|
|
2618
|
+
wait_timeout_seconds=_task_wait_seconds(config, deadline),
|
|
2619
|
+
)
|
|
2620
|
+
task = await _task_with_history(client, task, history_length=history_length)
|
|
2621
|
+
return {"task": _task_payload(task, history_length=history_length)}
|
|
2539
2622
|
request_message_id = str(message["messageId"])
|
|
2540
2623
|
context_id = str(message["contextId"])
|
|
2541
2624
|
if config.local_mode:
|
|
@@ -2845,6 +2928,8 @@ async def json_rpc(
|
|
|
2845
2928
|
)
|
|
2846
2929
|
except _MessageLimitExceeded as error:
|
|
2847
2930
|
return _message_limit_json_rpc_error(request_id, error.limit_seconds)
|
|
2931
|
+
except _AcceptedTaskUnanswered as error:
|
|
2932
|
+
return _accepted_task_json_rpc_error(request_id, error)
|
|
2848
2933
|
elif method in {"SendStreamingMessage", "message/stream"}:
|
|
2849
2934
|
_response_kind(
|
|
2850
2935
|
params,
|
|
@@ -23,6 +23,7 @@ from ms_tau_sdk.errors import (
|
|
|
23
23
|
LocalModeUnsupportedError,
|
|
24
24
|
SessionNotFoundError,
|
|
25
25
|
)
|
|
26
|
+
from ms_tau_sdk.protocols.a2a_roles import platform_message_to_binding
|
|
26
27
|
from ms_tau_sdk.settings import TauSDKSettings
|
|
27
28
|
|
|
28
29
|
from .assertions import ASSERTION_HEADER
|
|
@@ -172,6 +173,30 @@ def _backend_rejection_log_fields(detail: object) -> dict[str, object]:
|
|
|
172
173
|
return fields
|
|
173
174
|
|
|
174
175
|
|
|
176
|
+
def _binding_message(task: AgentTask, record: Mapping[str, Any]) -> dict[str, Any]:
|
|
177
|
+
try:
|
|
178
|
+
return platform_message_to_binding(
|
|
179
|
+
record,
|
|
180
|
+
context_id=task.context_id,
|
|
181
|
+
task_id=task.task_id,
|
|
182
|
+
)
|
|
183
|
+
except ValueError as error:
|
|
184
|
+
raise BackendError(
|
|
185
|
+
f"Backend Task {task.task_id} has an invalid Message: {error}"
|
|
186
|
+
) from error
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _with_binding_messages(task: AgentTask) -> AgentTask:
|
|
190
|
+
"""Return ``task`` with the Messages the platform stores as Main Sequence binding Messages."""
|
|
191
|
+
|
|
192
|
+
update: dict[str, Any] = {}
|
|
193
|
+
if task.latest_message is not None:
|
|
194
|
+
update["latest_message"] = _binding_message(task, task.latest_message)
|
|
195
|
+
if task.history is not None:
|
|
196
|
+
update["history"] = [_binding_message(task, record) for record in task.history]
|
|
197
|
+
return task.model_copy(update=update) if update else task
|
|
198
|
+
|
|
199
|
+
|
|
175
200
|
class MainSequenceClient:
|
|
176
201
|
def __init__(
|
|
177
202
|
self,
|
|
@@ -970,7 +995,7 @@ class MainSequenceClient:
|
|
|
970
995
|
headers={ASSERTION_HEADER: caller_assertion} if caller_assertion else None,
|
|
971
996
|
)
|
|
972
997
|
return AgentTaskCreateResult(
|
|
973
|
-
task=AgentTask.model_validate(data),
|
|
998
|
+
task=_with_binding_messages(AgentTask.model_validate(data)),
|
|
974
999
|
created=status_code == 201,
|
|
975
1000
|
)
|
|
976
1001
|
|
|
@@ -979,7 +1004,10 @@ class MainSequenceClient:
|
|
|
979
1004
|
path = AGENT_TASKS + (f"?{query}" if query else "")
|
|
980
1005
|
data = await self._request("GET", path, idempotent=True)
|
|
981
1006
|
values = data.get("results", []) if isinstance(data, dict) else data
|
|
982
|
-
return
|
|
1007
|
+
return [
|
|
1008
|
+
_with_binding_messages(task)
|
|
1009
|
+
for task in TypeAdapter(list[AgentTask]).validate_python(values or [])
|
|
1010
|
+
]
|
|
983
1011
|
|
|
984
1012
|
async def get_task_by_protocol_id(
|
|
985
1013
|
self,
|
|
@@ -1008,25 +1036,26 @@ class MainSequenceClient:
|
|
|
1008
1036
|
f"{AGENT_TASKS}{task_uid}/{query}",
|
|
1009
1037
|
idempotent=True,
|
|
1010
1038
|
)
|
|
1011
|
-
return AgentTask.model_validate(data)
|
|
1039
|
+
return _with_binding_messages(AgentTask.model_validate(data))
|
|
1012
1040
|
|
|
1013
1041
|
async def list_task_messages(
|
|
1014
1042
|
self,
|
|
1015
|
-
|
|
1043
|
+
task: AgentTask,
|
|
1016
1044
|
*,
|
|
1017
|
-
|
|
1018
|
-
offset: int = 0,
|
|
1045
|
+
history_length: int,
|
|
1019
1046
|
) -> list[dict[str, Any]]:
|
|
1020
|
-
|
|
1047
|
+
"""Return the latest ``history_length`` Messages of ``task``, oldest first."""
|
|
1048
|
+
|
|
1049
|
+
query = urlencode({"history_length": max(0, min(int(history_length), 100))})
|
|
1021
1050
|
data = await self._request(
|
|
1022
1051
|
"GET",
|
|
1023
|
-
f"{agent_task_operation(
|
|
1052
|
+
f"{agent_task_operation(task.uid, 'messages')}?{query}",
|
|
1024
1053
|
idempotent=True,
|
|
1025
1054
|
)
|
|
1026
1055
|
values = data.get("results", []) if isinstance(data, dict) else data
|
|
1027
1056
|
if not isinstance(values, list) or any(not isinstance(item, dict) for item in values):
|
|
1028
1057
|
raise BackendError("Backend Task-message response is invalid")
|
|
1029
|
-
return [
|
|
1058
|
+
return [_binding_message(task, item) for item in values]
|
|
1030
1059
|
|
|
1031
1060
|
async def get_task_snapshot(self, task_uid: str) -> AgentTaskSnapshot:
|
|
1032
1061
|
data = await self._request(
|
|
@@ -1034,7 +1063,8 @@ class MainSequenceClient:
|
|
|
1034
1063
|
agent_task_operation(task_uid, "snapshot"),
|
|
1035
1064
|
idempotent=True,
|
|
1036
1065
|
)
|
|
1037
|
-
|
|
1066
|
+
snapshot = AgentTaskSnapshot.model_validate(data)
|
|
1067
|
+
return snapshot.model_copy(update={"task": _with_binding_messages(snapshot.task)})
|
|
1038
1068
|
|
|
1039
1069
|
async def get_task_snapshot_by_protocol_id(self, task_id: str) -> AgentTaskSnapshot:
|
|
1040
1070
|
task = await self.get_task_by_protocol_id(task_id)
|
|
@@ -1262,7 +1292,7 @@ class MainSequenceClient:
|
|
|
1262
1292
|
idempotent=True,
|
|
1263
1293
|
headers={ASSERTION_HEADER: caller_assertion} if caller_assertion else None,
|
|
1264
1294
|
)
|
|
1265
|
-
return AgentTask.model_validate(data)
|
|
1295
|
+
return _with_binding_messages(AgentTask.model_validate(data))
|
|
1266
1296
|
|
|
1267
1297
|
async def cancel_task(self, task_uid: str) -> AgentTask:
|
|
1268
1298
|
data = await self._request(
|
|
@@ -1271,4 +1301,4 @@ class MainSequenceClient:
|
|
|
1271
1301
|
json={},
|
|
1272
1302
|
idempotent=True,
|
|
1273
1303
|
)
|
|
1274
|
-
return AgentTask.model_validate(data)
|
|
1304
|
+
return _with_binding_messages(AgentTask.model_validate(data))
|
|
@@ -2590,20 +2590,14 @@ class LocalDevelopmentBackend(MainSequenceClient):
|
|
|
2590
2590
|
|
|
2591
2591
|
async def list_task_messages(
|
|
2592
2592
|
self,
|
|
2593
|
-
|
|
2593
|
+
task: AgentTask,
|
|
2594
2594
|
*,
|
|
2595
|
-
|
|
2596
|
-
offset: int = 0,
|
|
2595
|
+
history_length: int,
|
|
2597
2596
|
) -> list[dict[str, Any]]:
|
|
2598
2597
|
def operation() -> list[dict[str, Any]]:
|
|
2599
2598
|
with closing(self._connect()) as connection:
|
|
2600
|
-
self._task_row(connection,
|
|
2601
|
-
return self._task_messages(
|
|
2602
|
-
connection,
|
|
2603
|
-
task_uid,
|
|
2604
|
-
limit=limit,
|
|
2605
|
-
offset=offset,
|
|
2606
|
-
)
|
|
2599
|
+
self._task_row(connection, task.uid)
|
|
2600
|
+
return self._task_messages(connection, task.uid, limit=history_length)
|
|
2607
2601
|
|
|
2608
2602
|
return await self._run(operation)
|
|
2609
2603
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Role translation between A2A v1
|
|
1
|
+
"""Role translation between A2A v1, the Main Sequence Tau binding, and platform storage."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -19,11 +19,22 @@ class A2AProtocolRole(StrEnum):
|
|
|
19
19
|
AGENT = "ROLE_AGENT"
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
class PlatformMessageRole(StrEnum):
|
|
23
|
+
"""Direction-neutral roles of a Task Message the platform stores."""
|
|
24
|
+
|
|
25
|
+
USER = "user"
|
|
26
|
+
AGENT = "agent"
|
|
27
|
+
|
|
28
|
+
|
|
22
29
|
_TO_BINDING = {
|
|
23
30
|
A2AProtocolRole.USER.value: A2AMessageDirection.REQUESTER.value,
|
|
24
31
|
A2AProtocolRole.AGENT.value: A2AMessageDirection.RESPONDER.value,
|
|
25
32
|
}
|
|
26
33
|
_TO_PROTOCOL = {value: key for key, value in _TO_BINDING.items()}
|
|
34
|
+
_FROM_PLATFORM = {
|
|
35
|
+
PlatformMessageRole.USER.value: A2AMessageDirection.REQUESTER.value,
|
|
36
|
+
PlatformMessageRole.AGENT.value: A2AMessageDirection.RESPONDER.value,
|
|
37
|
+
}
|
|
27
38
|
|
|
28
39
|
|
|
29
40
|
def _validate_message_shape(message: Mapping[str, object]) -> None:
|
|
@@ -60,6 +71,36 @@ def message_to_protocol(message: Mapping[str, object]) -> dict[str, object]:
|
|
|
60
71
|
return {**message, "role": _TO_PROTOCOL[role]}
|
|
61
72
|
|
|
62
73
|
|
|
74
|
+
def platform_message_to_binding(
|
|
75
|
+
record: Mapping[str, object],
|
|
76
|
+
*,
|
|
77
|
+
context_id: str,
|
|
78
|
+
task_id: str,
|
|
79
|
+
) -> dict[str, object]:
|
|
80
|
+
"""Translate a Task Message the platform stores into a Main Sequence binding Message.
|
|
81
|
+
|
|
82
|
+
The platform stores the role ``user`` or ``agent`` and snake-case fields. The Task that owns
|
|
83
|
+
the Message supplies its context and Task IDs. Fields only the platform keeps, such as the
|
|
84
|
+
request hash and the requester, are left out.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
role = str(record.get("role") or "")
|
|
88
|
+
if role not in _FROM_PLATFORM:
|
|
89
|
+
raise ValueError("Platform Task Message role must be user or agent")
|
|
90
|
+
message: dict[str, object] = {
|
|
91
|
+
"messageId": record.get("message_id"),
|
|
92
|
+
"contextId": context_id,
|
|
93
|
+
"taskId": task_id,
|
|
94
|
+
"role": _FROM_PLATFORM[role],
|
|
95
|
+
"parts": record.get("parts"),
|
|
96
|
+
"metadata": record.get("metadata", {}),
|
|
97
|
+
"extensions": record.get("extensions", []),
|
|
98
|
+
"referenceTaskIds": record.get("reference_task_ids", []),
|
|
99
|
+
}
|
|
100
|
+
_validate_message_shape(message)
|
|
101
|
+
return message
|
|
102
|
+
|
|
103
|
+
|
|
63
104
|
def has_a2a_direction(
|
|
64
105
|
message: Mapping[str, object],
|
|
65
106
|
direction: A2AMessageDirection,
|
|
@@ -72,7 +113,9 @@ def has_a2a_direction(
|
|
|
72
113
|
__all__ = [
|
|
73
114
|
"A2AMessageDirection",
|
|
74
115
|
"A2AProtocolRole",
|
|
116
|
+
"PlatformMessageRole",
|
|
75
117
|
"has_a2a_direction",
|
|
76
118
|
"message_to_binding",
|
|
77
119
|
"message_to_protocol",
|
|
120
|
+
"platform_message_to_binding",
|
|
78
121
|
]
|
|
File without changes
|
|
File without changes
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/__init__.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/app.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/cli.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/config.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/env_file.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/logs.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/proxy.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/packages/tau-board/src/ms_tau_board/state.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
|
|
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.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/backend/team_memberships.py
RENAMED
|
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.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/protocols/assistant_ui.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/protocols/chat_history.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
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/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
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/tools/mainsequence_mcp.py
RENAMED
|
File without changes
|
{ms_tau_sdk-2.0.20.dev71 → ms_tau_sdk-2.0.21.dev72}/src/ms_tau_sdk/tools/mcp_applications.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|