ms-tau-sdk 1.2.14.dev25__tar.gz → 1.3.0.dev26__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.
Files changed (80) hide show
  1. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/CHANGELOG.md +14 -0
  2. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/PKG-INFO +1 -1
  3. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/pyproject.toml +1 -1
  4. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/agent_skills/tau_project_customization/SKILL.md +8 -5
  5. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/extensions.py +6 -0
  6. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/manager.py +10 -1
  7. ms_tau_sdk-1.3.0.dev26/src/ms_tau_sdk/tools/skill_read.py +52 -0
  8. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/.gitignore +0 -0
  9. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/README.md +0 -0
  10. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/__init__.py +0 -0
  11. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/app.py +0 -0
  12. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/cli.py +0 -0
  13. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/config.py +0 -0
  14. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/env_file.py +0 -0
  15. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/logs.py +0 -0
  16. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/proxy.py +0 -0
  17. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/state.py +0 -0
  18. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/static/BULMA-LICENSE.txt +0 -0
  19. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/static/app.js +0 -0
  20. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/static/board.css +0 -0
  21. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/static/bulma.min.css +0 -0
  22. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/packages/tau-board/src/ms_tau_board/static/index.html +0 -0
  23. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/__init__.py +0 -0
  24. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/agent_skills/tau_a2a_runtime_adapter/SKILL.md +0 -0
  25. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/agent_skills/tau_local_development/SKILL.md +0 -0
  26. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/agent_skills/tau_repository_integration/SKILL.md +0 -0
  27. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/api/__init__.py +0 -0
  28. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/api/a2a.py +0 -0
  29. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/api/chat.py +0 -0
  30. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/api/conversations.py +0 -0
  31. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/api/dependencies.py +0 -0
  32. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/api/health.py +0 -0
  33. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/api/inspection.py +0 -0
  34. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/api/local_chat.py +0 -0
  35. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/api/models.py +0 -0
  36. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/api/sessions.py +0 -0
  37. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/app.py +0 -0
  38. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/application.py +0 -0
  39. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/backend/__init__.py +0 -0
  40. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/backend/auth.py +0 -0
  41. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/backend/client.py +0 -0
  42. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/backend/local.py +0 -0
  43. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/backend/mcp.py +0 -0
  44. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/backend/models.py +0 -0
  45. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/backend/routes.py +0 -0
  46. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/cli.py +0 -0
  47. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/errors.py +0 -0
  48. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/logging.py +0 -0
  49. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/protocols/__init__.py +0 -0
  50. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/protocols/a2a_failure.py +0 -0
  51. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/protocols/a2a_message.py +0 -0
  52. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/protocols/a2a_roles.py +0 -0
  53. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/protocols/assistant_ui.py +0 -0
  54. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/protocols/chat_history.py +0 -0
  55. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/protocols/strict_json.py +0 -0
  56. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/providers/__init__.py +0 -0
  57. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/providers/definitions.py +0 -0
  58. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/providers/factory.py +0 -0
  59. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/providers/tau_compat.py +0 -0
  60. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/resources/SYSTEM.md +0 -0
  61. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/resources/__init__.py +0 -0
  62. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/resources/loader.py +0 -0
  63. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/resources/prompts/review-code-repository.md +0 -0
  64. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/__init__.py +0 -0
  65. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/deployment_health.py +0 -0
  66. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/events.py +0 -0
  67. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/failures.py +0 -0
  68. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/live_turns.py +0 -0
  69. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/observability.py +0 -0
  70. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/provenance.py +0 -0
  71. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/session.py +0 -0
  72. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/snapshots.py +0 -0
  73. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/runtime/task_context.py +0 -0
  74. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/sessions/__init__.py +0 -0
  75. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/sessions/storage.py +0 -0
  76. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/settings.py +0 -0
  77. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/skills.py +0 -0
  78. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/tools/__init__.py +0 -0
  79. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/tools/mainsequence_mcp.py +0 -0
  80. {ms_tau_sdk-1.2.14.dev25 → ms_tau_sdk-1.3.0.dev26}/src/ms_tau_sdk/tools/task_control.py +0 -0
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ - Project skills stay available with `TAU_EXCLUDE_BASE_TOOLS=true`. Tau lists skills in the system
6
+ prompt only when a tool named `read` exists, so excluding the four coding tools also removed
7
+ every skill in `.tau/skills/`. The SDK now registers a `read` tool in their place that opens only
8
+ the files of the skills Tau discovered for the session: a skill's `SKILL.md` and the files in its
9
+ directory, such as `references/*.md`. It rejects every other path, including other workspace
10
+ files, system paths, `..` escapes, and symlinks that resolve outside the skill, so the process
11
+ environment and its credentials stay out of reach. It keeps Tau's `offset`, `limit`, and output
12
+ limits. With both exclusions set, the catalog is project tools, this `read`, and the two Task
13
+ controls. In this mode a project extension that registers `read` fails on session load and on
14
+ reload. With base tools included nothing changes. See the 2026-10-05 amendment of ADR 0011
15
+ ([#54](https://github.com/mainsequence-sdk/ms-tau-sdk/issues/54)).
16
+
3
17
  ## 1.2.14 — 2026-10-01
4
18
 
5
19
  - The repository structure reference now shows Tau Board: the tree lists `packages/tau-board/` and
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ms-tau-sdk
3
- Version: 1.2.14.dev25
3
+ Version: 1.3.0.dev26
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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ms-tau-sdk"
7
- version = "1.2.14.dev25"
7
+ version = "1.3.0.dev26"
8
8
  description = "Workspace-bound Tau application primitives for Main Sequence projects"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -52,7 +52,7 @@ Two independent process settings select the host-provided tools. Both default to
52
52
 
53
53
  | Setting | Effect when `true` |
54
54
  | --- | --- |
55
- | `TAU_EXCLUDE_BASE_TOOLS` | Omit Tau's `read`, `write`, `edit`, and `bash`. |
55
+ | `TAU_EXCLUDE_BASE_TOOLS` | Replace Tau's `read`, `write`, `edit`, and `bash` with a skill-scoped `read`. |
56
56
  | `TAU_EXCLUDE_MAINSEQUENCE_MCP` | Skip Main Sequence MCP connection, tools, resources, and resource prompt. |
57
57
 
58
58
  Set them in `harness_agent.spec.env_vars` in a managed repository workflow, in the process
@@ -67,15 +67,18 @@ Task controls requires an actual Task context and is specified by ADR 0015.
67
67
  | Exclude base tools | Exclude Main Sequence MCP | Model-facing sources |
68
68
  | --- | --- | --- |
69
69
  | `false` | `false` | Coding tools, Main Sequence MCP, project extension tools, A2A Task controls. |
70
- | `true` | `false` | Main Sequence MCP, project extension tools, A2A Task controls. |
70
+ | `true` | `false` | Skill-scoped `read`, Main Sequence MCP, project extension tools, A2A Task controls. |
71
71
  | `false` | `true` | Coding tools, project extension tools, A2A Task controls. |
72
- | `true` | `true` | Project extension tools and A2A Task controls. |
72
+ | `true` | `true` | Skill-scoped `read`, project extension tools, and A2A Task controls. |
73
73
 
74
74
  The A2A Task controls are `task_request_input` and `task_request_authorization`. They remain
75
75
  available in every mode for the agent's own Task; extensions must not register those names.
76
76
  Register project tools under `.tau/extensions/` and verify the effective catalog after loading.
77
- With `read` excluded, Tau 0.4.2 does not insert discovered skills into the system prompt. Put
78
- needed guidance in the effective `.tau/SYSTEM.md` or expose it through a declared retrieval tool.
77
+ With base tools excluded, the skill-scoped `read` keeps `.tau/skills/` available: it opens a
78
+ discovered skill's `SKILL.md` and the files in its directory, such as `references/*.md`, and
79
+ rejects every other path, including symlinks that resolve outside the skill. Tau lists the skills
80
+ in the system prompt because a tool named `read` exists. Extensions must not register `read` in
81
+ this mode.
79
82
  Excluding coding tools does not sandbox extension Python code.
80
83
 
81
84
  ## Invariants extensions must not replace
@@ -18,6 +18,7 @@ def validate_tool_catalog(
18
18
  *,
19
19
  sdk_tool_names: frozenset[str],
20
20
  require_complete_project_catalog: bool,
21
+ reserved_sdk_tool_names: frozenset[str] = frozenset(),
21
22
  ) -> None:
22
23
  """Reject extension overrides and catalog drift before a model can use tools."""
23
24
  sources = session.extension_tool_sources
@@ -26,6 +27,11 @@ def validate_tool_catalog(
26
27
  raise ConfigurationError(
27
28
  "Project extensions cannot replace A2A Task controls: " + ", ".join(sorted(reserved))
28
29
  )
30
+ replaced = reserved_sdk_tool_names & sources.keys()
31
+ if replaced:
32
+ raise ConfigurationError(
33
+ "Project extensions cannot replace reserved SDK tools: " + ", ".join(sorted(replaced))
34
+ )
29
35
  names = [tool.name for tool in session.tools]
30
36
  expected = sdk_tool_names | sources.keys()
31
37
  if len(names) != len(set(names)) or set(names) != expected:
@@ -77,6 +77,7 @@ from ms_tau_sdk.tools.mainsequence_mcp import (
77
77
  create_mainsequence_mcp_tools,
78
78
  mainsequence_mcp_resource_prompt,
79
79
  )
80
+ from ms_tau_sdk.tools.skill_read import create_skill_read_tool
80
81
  from ms_tau_sdk.tools.task_control import create_task_control_tools
81
82
 
82
83
  from .session import ActiveSessionRuntime, PlatformEvent
@@ -1123,7 +1124,11 @@ class SessionRuntimeManager:
1123
1124
  "lease_token": lease.lease_token,
1124
1125
  }
1125
1126
  tools = []
1126
- if not self.settings.exclude_base_tools:
1127
+ if self.settings.exclude_base_tools:
1128
+ # Tau lists skills only when a tool named `read` exists. The tool runs only in
1129
+ # this session's turns, after `coding_session` is bound below.
1130
+ tools.append(create_skill_read_tool(cwd=cwd, skills=lambda: coding_session.skills))
1131
+ else:
1127
1132
  tools.extend(create_coding_tools(cwd=cwd))
1128
1133
  if mcp_client is not None:
1129
1134
  tools.extend(
@@ -1140,12 +1145,16 @@ class SessionRuntimeManager:
1140
1145
  require_complete_project_catalog = (
1141
1146
  self.settings.exclude_base_tools and self.settings.exclude_mainsequence_mcp
1142
1147
  )
1148
+ reserved_sdk_tool_names = (
1149
+ frozenset({"read"}) if self.settings.exclude_base_tools else frozenset()
1150
+ )
1143
1151
 
1144
1152
  def check_catalog(session: CodingSession) -> None:
1145
1153
  validate_tool_catalog(
1146
1154
  session,
1147
1155
  sdk_tool_names=sdk_tool_names,
1148
1156
  require_complete_project_catalog=require_complete_project_catalog,
1157
+ reserved_sdk_tool_names=reserved_sdk_tool_names,
1149
1158
  )
1150
1159
 
1151
1160
  coding_session = await CodingSession.load(
@@ -0,0 +1,52 @@
1
+ """Tau's `read` tool limited to the files of discovered skills."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import dataclasses
6
+ from collections.abc import Callable, Iterable
7
+ from pathlib import Path
8
+
9
+ from tau_agent.tools import AgentTool
10
+ from tau_coding.skills import Skill
11
+ from tau_coding.tools import (
12
+ DEFAULT_MAX_OUTPUT_BYTES,
13
+ DEFAULT_MAX_OUTPUT_LINES,
14
+ DEFAULT_READ_OPERATIONS,
15
+ ToolInputError,
16
+ create_read_tool_definition,
17
+ )
18
+
19
+
20
+ def create_skill_read_tool(*, cwd: Path, skills: Callable[[], Iterable[Skill]]) -> AgentTool:
21
+ """Create a `read` tool that serves only the files of the session's discovered skills.
22
+
23
+ Tau lists skills in the system prompt only when a tool named `read` exists. With the coding
24
+ tools excluded, this tool keeps project skills available without exposing any other file.
25
+ `skills` is called on every read, so a Tau reload changes what the tool serves.
26
+ """
27
+
28
+ def validate_path(path: Path) -> None:
29
+ resolved = path.resolve()
30
+ if not any(
31
+ resolved == skill.path.resolve() or resolved.is_relative_to(skill.path.parent.resolve())
32
+ for skill in skills()
33
+ ):
34
+ raise ToolInputError(f"Path is outside the available skills: {path}")
35
+ DEFAULT_READ_OPERATIONS.validate_path(path)
36
+
37
+ definition = create_read_tool_definition(
38
+ cwd=cwd,
39
+ operations=dataclasses.replace(DEFAULT_READ_OPERATIONS, validate_path=validate_path),
40
+ )
41
+ return dataclasses.replace(
42
+ definition,
43
+ description=(
44
+ "Read a file of one of the available skills: its SKILL.md or another file in its "
45
+ "skill directory, such as a referenced document. Every other path is rejected. "
46
+ f"Output is truncated to {DEFAULT_MAX_OUTPUT_LINES} lines or "
47
+ f"{DEFAULT_MAX_OUTPUT_BYTES // 1024}KB (whichever is hit first). Use offset/limit "
48
+ "for large files. When you need the full file, continue with offset until complete."
49
+ ),
50
+ prompt_snippet="Read the files of the available skills",
51
+ prompt_guidelines=(),
52
+ ).to_agent_tool()