muse-code-sdk 1.4.13__tar.gz → 1.4.14__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 (71) hide show
  1. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/PKG-INFO +2 -2
  2. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/pyproject.toml +2 -2
  3. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/__init__.py +2 -2
  4. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/facade/approval.py +5 -0
  5. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/facade/client.py +14 -4
  6. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code_sdk.egg-info/PKG-INFO +2 -2
  7. muse_code_sdk-1.4.14/src/muse_code_sdk.egg-info/requires.txt +2 -0
  8. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_facade_approval.py +32 -0
  9. muse_code_sdk-1.4.13/src/muse_code_sdk.egg-info/requires.txt +0 -2
  10. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/LICENSE +0 -0
  11. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/README.md +0 -0
  12. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/setup.cfg +0 -0
  13. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/connection/__init__.py +0 -0
  14. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/connection/connection.py +0 -0
  15. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/connection/discovery.py +0 -0
  16. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/connection/spawn.py +0 -0
  17. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/connection/validation.py +0 -0
  18. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/errors.py +0 -0
  19. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/facade/__init__.py +0 -0
  20. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/facade/discarded.py +0 -0
  21. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/facade/gap_fill.py +0 -0
  22. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/facade/host_death.py +0 -0
  23. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/facade/host_start.py +0 -0
  24. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/facade/session.py +0 -0
  25. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/facade/turn_handle.py +0 -0
  26. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/facade/turn_submit.py +0 -0
  27. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/fold/__init__.py +0 -0
  28. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/fold/item_store.py +0 -0
  29. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/fold/session_fold.py +0 -0
  30. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/fold/state_store.py +0 -0
  31. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/pending/__init__.py +0 -0
  32. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/pending/pending_command_set.py +0 -0
  33. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/py.typed +0 -0
  34. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/replay.py +0 -0
  35. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code/sync_facade.py +0 -0
  36. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code_sdk.egg-info/SOURCES.txt +0 -0
  37. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code_sdk.egg-info/dependency_links.txt +0 -0
  38. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/src/muse_code_sdk.egg-info/top_level.txt +0 -0
  39. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_asyncio_cancellation.py +0 -0
  40. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_compatibility_row.py +0 -0
  41. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_connection.py +0 -0
  42. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_connection_error_arms.py +0 -0
  43. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_docs_generation.py +0 -0
  44. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_external_audience.py +0 -0
  45. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_facade_approval_resend.py +0 -0
  46. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_facade_gap_fill.py +0 -0
  47. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_facade_open_same_chunk.py +0 -0
  48. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_facade_persistent_approval.py +0 -0
  49. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_facade_required_selection.py +0 -0
  50. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_facade_turn.py +0 -0
  51. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_facade_user_input_resend.py +0 -0
  52. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_host_discovery.py +0 -0
  53. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_item_store.py +0 -0
  54. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_manifests.py +0 -0
  55. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_muse_serve_child.py +0 -0
  56. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_pending_command_corpus.py +0 -0
  57. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_pending_command_set.py +0 -0
  58. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_pending_command_wire_binding.py +0 -0
  59. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_permission_state_wire_types.py +0 -0
  60. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_public_mirror_text.py +0 -0
  61. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_publish_shape.py +0 -0
  62. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_recovery_observation.py +0 -0
  63. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_session_fold.py +0 -0
  64. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_source_closure.py +0 -0
  65. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_spawn_handshake.py +0 -0
  66. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_spawn_host_lost.py +0 -0
  67. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_state_store.py +0 -0
  68. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_sync_facade.py +0 -0
  69. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_tolerance_corpus.py +0 -0
  70. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_transcript_replay.py +0 -0
  71. {muse_code_sdk-1.4.13 → muse_code_sdk-1.4.14}/tests/test_typing_gates.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: muse-code-sdk
3
- Version: 1.4.13
3
+ Version: 1.4.14
4
4
  Summary: Muse Code SDK for MSP: asyncio-first facade over the generated wire types (muse-code-msp), with a thin sync wrapper.
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/meta-models/muse-code-sdk
@@ -15,7 +15,7 @@ Requires-Python: >=3.10
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: pydantic==2.13.5
18
- Requires-Dist: muse-code-msp==1.4.13
18
+ Requires-Dist: muse-code-msp==1.4.14
19
19
  Dynamic: license-file
20
20
 
21
21
  # `muse-code-sdk`
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "muse-code-sdk"
8
- version = "1.4.13"
8
+ version = "1.4.14"
9
9
  description = "Muse Code SDK for MSP: asyncio-first facade over the generated wire types (muse-code-msp), with a thin sync wrapper."
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -18,7 +18,7 @@ license-files = ["LICENSE"]
18
18
  # `pip install muse-code-sdk` must import, and the release bump moves this
19
19
  # package's version and its muse-code-msp pin together; pydantic bumps stay
20
20
  # reviewed PRs (test_publish_shape pins the pairing).
21
- dependencies = ["pydantic==2.13.5", "muse-code-msp==1.4.13"]
21
+ dependencies = ["pydantic==2.13.5", "muse-code-msp==1.4.14"]
22
22
  classifiers = [
23
23
  # Alpha states the withheld promise: publication is permitted, but the
24
24
  # stability promise and conformance claim stay withheld — experimental
@@ -80,7 +80,7 @@ __all__ = [
80
80
  ]
81
81
 
82
82
  EXPECTED_SCHEMA_FINGERPRINT: Final[str] = (
83
- "sha256:7fddaf646dbc317e5fcac0785e135eb04df14fbb0db1863089dfd6da21730e5b"
83
+ "sha256:c94c3d1f2f51e6424074b9ec43eac3eedcf532d3dcd77351ec1383a87d3049c6"
84
84
  )
85
85
  """The stable schema-bundle fingerprint this SDK was built against.
86
86
 
@@ -92,7 +92,7 @@ Python SDK reds this lane instead of drifting silently.
92
92
  # The lockstep rule: the release train bumps pyproject.toml, the
93
93
  # distribution-metadata authority; this constant is aligned at publication
94
94
  # time.
95
- __version__: Final[str] = "1.4.13"
95
+ __version__: Final[str] = "1.4.14"
96
96
 
97
97
  # The facade is imported last so the constants above are already bound: the
98
98
  # spawn path reads ``EXPECTED_SCHEMA_FINGERPRINT`` (lazily, at initialize
@@ -66,6 +66,7 @@ _REFRESH_FROM_REQUEST = frozenset(
66
66
  "judgeEscalated",
67
67
  "protectedWrite",
68
68
  "rawArgs",
69
+ "reviewerReason",
69
70
  "taskId",
70
71
  "toolCallId",
71
72
  "toolName",
@@ -302,6 +303,10 @@ class ApprovalRouter:
302
303
  # the retained request across stages.
303
304
  if "cuaCardFacts" in requested:
304
305
  refreshed["cuaCardFacts"] = requested["cuaCardFacts"]
306
+ # The escalation reason belongs to the call, so it stays with the
307
+ # retained request across stages.
308
+ if "reviewerReason" in requested:
309
+ refreshed["reviewerReason"] = requested["reviewerReason"]
305
310
  acked = self._in_flight.get(requested["approvalId"])
306
311
  if acked is not None:
307
312
  return self._after_ack(acked, refreshed)
@@ -80,7 +80,8 @@ class StartSessionOptions:
80
80
  """Caller-facing options for ``session/start``.
81
81
 
82
82
  Composed from the generated ``SessionStartParams``. ``config`` is excluded as well as ``commandId`` until the facade
83
- implements the required ``sessionMcp`` grant check and forwarding.
83
+ implements the required ``sessionMcp`` grant check and forwarding; ``previousSessionId`` is excluded because the
84
+ facade starts root sessions, and ``spawnedBy`` because the facade does not expose a spawner yet.
84
85
 
85
86
  Attributes:
86
87
  approval_mode: The approval enforcement mode to start under; omitted
@@ -139,6 +140,9 @@ class ResumeSessionOptions:
139
140
  wire's ``permissionProfile`` member: the host restores the
140
141
  retained authority first, then applies the pick. Omitted means
141
142
  no override.
143
+ model_id: The model override forwarded as the wire's ``modelId``
144
+ member: the host applies it after the warm pick, before
145
+ enrichments. Omitted means no override.
142
146
  recovery_mode: Optional recovery selection (wire ``recoveryMode``);
143
147
  omitted means no selection is sent.
144
148
  on_approval: Answers this session's approvals from its first frame,
@@ -158,6 +162,7 @@ class ResumeSessionOptions:
158
162
  exclude_items: bool | None = None
159
163
  history: Mapping[str, Any] | None = None
160
164
  permission_profile: str | None = None
165
+ model_id: str | None = None
161
166
  recovery_mode: RecoveryMode | None = None
162
167
  on_approval: ApprovalHandler | None = None
163
168
  on_approval_error: ApprovalFailureHandler | None = None
@@ -168,12 +173,15 @@ class ResumeSessionOptions:
168
173
  # generated params but not to the options dataclass reds THIS import (and thus
169
174
  # every test), so a regenerated member cannot silently fail to reach the wire.
170
175
  # The excluded members are the ones the facade owns rather than forwards:
171
- # `commandId` (the connection is the single minter) and `config`
172
- # (temporarily withheld until capability-checked forwarding lands). The owned
176
+ # `commandId` (the connection is the single minter), `config`
177
+ # (temporarily withheld until capability-checked forwarding lands) and
178
+ # `previousSessionId` (the facade starts root sessions; the predecessor link
179
+ # belongs to a client that switches sessions) and `spawnedBy` (the facade
180
+ # does not expose a spawner yet). The owned
173
181
  # members are options-only posture the wire never carries (client-local
174
182
  # `requirePermissionProfile`, the required-selection check): subtracted from
175
183
  # the options side, so a regen that adds a same-named wire member reds here.
176
- _START_EXCLUDED = {"commandId", "config"}
184
+ _START_EXCLUDED = {"commandId", "config", "previousSessionId", "spawnedBy"}
177
185
  _START_OWNED = {"requirePermissionProfile"}
178
186
  assert (
179
187
  {_camel(f.name) for f in fields(StartSessionOptions)} - _START_OWNED
@@ -521,6 +529,8 @@ class MuseClient(Generic[_I]):
521
529
  params["excludeItems"] = options.exclude_items
522
530
  if options.history is not None:
523
531
  params["history"] = options.history
532
+ if options.model_id is not None:
533
+ params["modelId"] = options.model_id
524
534
  if options.recovery_mode is not None:
525
535
  params["recoveryMode"] = options.recovery_mode
526
536
  if options.permission_profile is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: muse-code-sdk
3
- Version: 1.4.13
3
+ Version: 1.4.14
4
4
  Summary: Muse Code SDK for MSP: asyncio-first facade over the generated wire types (muse-code-msp), with a thin sync wrapper.
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/meta-models/muse-code-sdk
@@ -15,7 +15,7 @@ Requires-Python: >=3.10
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: pydantic==2.13.5
18
- Requires-Dist: muse-code-msp==1.4.13
18
+ Requires-Dist: muse-code-msp==1.4.14
19
19
  Dynamic: license-file
20
20
 
21
21
  # `muse-code-sdk`
@@ -0,0 +1,2 @@
1
+ pydantic==2.13.5
2
+ muse-code-msp==1.4.14
@@ -734,6 +734,38 @@ async def test_a_stage_advance_keeps_the_requests_cua_card_facts(facts: Any) ->
734
734
  await settled_io(updated.io)
735
735
 
736
736
 
737
+ @pytest.mark.asyncio
738
+ @pytest.mark.parametrize("reason", ["pipes a downloaded script into sh", None])
739
+ async def test_a_stage_advance_keeps_the_requests_reviewer_reason(reason: Any) -> None:
740
+ # `reviewerReason` belongs to the call and `approval/updated` doesn't
741
+ # carry it, so the refreshed stage-2 request keeps the original request's
742
+ # reason, and a request without one stays without the key.
743
+ transport, session, minted = wired()
744
+ seen: List[Params] = []
745
+
746
+ def handler(request: Any) -> ApprovalDecisionInput:
747
+ seen.append(dict(request))
748
+ return ApprovalDecisionInput(choice_id="allow_once")
749
+
750
+ session.on_approval(handler)
751
+ overrides: Params = {} if reason is None else {"reviewerReason": reason}
752
+ first = session.apply(approval_requested(**overrides))
753
+ await wait_for_writes(transport, 1)
754
+ answer(transport, 0, {**decide_result("mint-0"), "terminal": False})
755
+ await settled_io(first.io)
756
+
757
+ updated = session.apply(stage_resolved(2, CHOICES))
758
+ await wait_for_writes(transport, 2)
759
+ assert minted == ["mint-0", "mint-1"]
760
+ assert len(seen) == 2
761
+ if reason is None:
762
+ assert "reviewerReason" not in seen[1]
763
+ else:
764
+ assert seen[1]["reviewerReason"] == reason
765
+ answer(transport, 1, decide_result("mint-1"))
766
+ await settled_io(updated.io)
767
+
768
+
737
769
  @pytest.mark.asyncio
738
770
  async def test_an_approval_updated_naming_the_decided_stage_asks_nothing() -> None:
739
771
  # The per-stage latch: an update that still names the stage this client
@@ -1,2 +0,0 @@
1
- pydantic==2.13.5
2
- muse-code-msp==1.4.13
File without changes
File without changes
File without changes