harness-sdk-python 0.31.2__py3-none-any.whl → 0.32.0__py3-none-any.whl
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.
harness_sdk/voice.py
CHANGED
|
@@ -7,9 +7,10 @@ lives in its own ephemeral tray, minted by ``voice/start`` and deleted when
|
|
|
7
7
|
the session ends. The host implements ``VoiceManager.Host``: the seed read
|
|
8
8
|
and the turn commit both stay host-owned.
|
|
9
9
|
|
|
10
|
-
``voice/start {offer
|
|
11
|
-
transcript (at most 128 messages, tail taken), hands the
|
|
12
|
-
function tool definitions
|
|
10
|
+
``voice/start {offer}`` seeds the provider from the thread
|
|
11
|
+
transcript (at most 128 messages, tail taken), hands the caller's frontend
|
|
12
|
+
function tool definitions (the ``tools`` map the client's synced model
|
|
13
|
+
context stores at ``ctx.caller.context``) to the provider, and projects ``state["voice"] =
|
|
13
14
|
{clientId, status, toolCalls, activeTask}`` — the SDP answer rides only the command's
|
|
14
15
|
result payload ``{answer}``. A named call matching a client-declared tool
|
|
15
16
|
projects into ``toolCalls`` as ``{callId, name, arguments}``; the owning
|
|
@@ -74,28 +75,32 @@ def _reject(reason: str, message: str) -> StatewireReject:
|
|
|
74
75
|
return StatewireReject(message, payload={"reason": reason})
|
|
75
76
|
|
|
76
77
|
|
|
77
|
-
def
|
|
78
|
+
def _context_tools(context: Any) -> "list[VoiceManager.ToolDef]":
|
|
79
|
+
tools = context.get("tools") if isinstance(context, dict) else None
|
|
78
80
|
if tools is None:
|
|
79
81
|
return []
|
|
80
|
-
if not isinstance(tools,
|
|
81
|
-
raise _reject("invalid-message", "tools must be a
|
|
82
|
-
|
|
83
|
-
for
|
|
82
|
+
if not isinstance(tools, dict):
|
|
83
|
+
raise _reject("invalid-message", "context tools must be a name-keyed object")
|
|
84
|
+
defs: "list[VoiceManager.ToolDef]" = []
|
|
85
|
+
for name, spec in tools.items():
|
|
84
86
|
if (
|
|
85
|
-
|
|
86
|
-
or not isinstance(
|
|
87
|
-
or
|
|
88
|
-
or not isinstance(
|
|
89
|
-
or not isinstance(tool.get("parameters"), dict)
|
|
87
|
+
name == ""
|
|
88
|
+
or not isinstance(spec, dict)
|
|
89
|
+
or not isinstance(spec.get("description", ""), str)
|
|
90
|
+
or not isinstance(spec.get("parameters"), dict)
|
|
90
91
|
):
|
|
91
92
|
raise _reject(
|
|
92
93
|
"invalid-message",
|
|
93
|
-
f"tools entries must be {{
|
|
94
|
+
f"context tools entries must be name -> {{description?, parameters}}, got {name!r}: {spec!r}",
|
|
94
95
|
)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
defs.append(
|
|
97
|
+
{
|
|
98
|
+
"name": name,
|
|
99
|
+
"description": spec.get("description", ""),
|
|
100
|
+
"parameters": spec["parameters"],
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
return defs
|
|
99
104
|
|
|
100
105
|
|
|
101
106
|
def _capped_seed(seed: Any) -> "list[VoiceManager.SeedMessage]":
|
|
@@ -156,7 +161,7 @@ class VoiceManager(Tray):
|
|
|
156
161
|
text: str
|
|
157
162
|
|
|
158
163
|
class ToolDef(TypedDict):
|
|
159
|
-
"""One frontend function tool the
|
|
164
|
+
"""One frontend function tool from the caller's synced model context."""
|
|
160
165
|
|
|
161
166
|
name: str
|
|
162
167
|
description: str
|
|
@@ -593,7 +598,7 @@ class VoiceManagerNamespace(TrayMapNamespace):
|
|
|
593
598
|
offer = params.get("offer")
|
|
594
599
|
if not isinstance(offer, str) or offer == "":
|
|
595
600
|
raise _reject("invalid-message", "offer must be a non-empty SDP string")
|
|
596
|
-
tools =
|
|
601
|
+
tools = _context_tools(ctx.caller.context)
|
|
597
602
|
if self._starting:
|
|
598
603
|
raise _reject("voice-active", "a voice session is already live")
|
|
599
604
|
session = self.live()
|
|
@@ -4,7 +4,7 @@ harness_sdk/deepagents.py,sha256=cMipZ9ndZ3zUR3-VqOMf5CiPVMmym74ytIeguQAjYZo,122
|
|
|
4
4
|
harness_sdk/fenced_postgres.py,sha256=hbbrMR1WaqrHTNgd4wFrXfRrzQFGnyim-c8nZXgwWp4,13235
|
|
5
5
|
harness_sdk/linear_thread.py,sha256=laDRXKLFsMlyWS4snqNAM6t38wO26gevLWXRNivhHSM,1810
|
|
6
6
|
harness_sdk/run_manager.py,sha256=CbY_4dpFeqGx3kJNI1ffsu3uIvzVc-Tc1UB6Nr9SiHY,77654
|
|
7
|
-
harness_sdk/voice.py,sha256=
|
|
8
|
-
harness_sdk_python-0.
|
|
9
|
-
harness_sdk_python-0.
|
|
10
|
-
harness_sdk_python-0.
|
|
7
|
+
harness_sdk/voice.py,sha256=KtUHmwfZQCwEvJaIolc-XgjAhxvltfMYEI5ycWcw53M,28590
|
|
8
|
+
harness_sdk_python-0.32.0.dist-info/METADATA,sha256=aiPtfiHYq8Lij70AkH4QVyGWxYhhJJKt6RXaaSk518Y,2200
|
|
9
|
+
harness_sdk_python-0.32.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
10
|
+
harness_sdk_python-0.32.0.dist-info/RECORD,,
|
|
File without changes
|