cartesia-line 0.2.0.dev0__tar.gz → 0.2.0.dev2__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.
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/PKG-INFO +3 -10
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/cartesia_line.egg-info/PKG-INFO +3 -10
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/cartesia_line.egg-info/SOURCES.txt +0 -9
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/cartesia_line.egg-info/requires.txt +2 -14
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/__init__.py +2 -28
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/events.py +27 -88
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/llm_agent.py +26 -28
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/scripts/test_provider.py +2 -3
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/voice_agent_app.py +84 -76
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/pyproject.toml +3 -15
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/tests/test_llm_agent_llm_agent.py +139 -142
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/tests/test_voice_agent_app.py +50 -45
- cartesia_line-0.2.0.dev0/line/v02/example_integrations/browserbase/main.py +0 -122
- cartesia_line-0.2.0.dev0/line/v02/example_integrations/browserbase/stagehand_form_filler.py +0 -371
- cartesia_line-0.2.0.dev0/line/v02/example_integrations/exa/main.py +0 -106
- cartesia_line-0.2.0.dev0/line/v02/examples/basic_chat/main.py +0 -30
- cartesia_line-0.2.0.dev0/line/v02/examples/echo/main.py +0 -29
- cartesia_line-0.2.0.dev0/line/v02/examples/echo/tools.py +0 -21
- cartesia_line-0.2.0.dev0/line/v02/examples/form_filler/form_filler.py +0 -252
- cartesia_line-0.2.0.dev0/line/v02/examples/form_filler/main.py +0 -53
- cartesia_line-0.2.0.dev0/line/v02/examples/transfer_phone_call/main.py +0 -55
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/LICENSE +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/README.md +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/cartesia_line.egg-info/dependency_links.txt +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/cartesia_line.egg-info/top_level.txt +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/agent.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/harness_types.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/__init__.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/config.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/provider.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/schema_converter.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/tools/__init__.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/tools/decorators.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/tools/system.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/tools/utils.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/setup.cfg +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/tests/test_llm_agent_config.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/tests/test_llm_agent_tools_decorators.py +0 -0
- {cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/tests/test_llm_agent_tools_system.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cartesia-line
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev2
|
|
4
4
|
Summary: Cartesia Voice Agents SDK
|
|
5
5
|
Author-email: "Cartesia AI, Inc." <support@cartesia.ai>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -29,8 +29,8 @@ Requires-Dist: fastapi>=0.115.0
|
|
|
29
29
|
Requires-Dist: aiohttp>=3.8.0
|
|
30
30
|
Requires-Dist: pydantic<3,>=2.0.0
|
|
31
31
|
Requires-Dist: uvicorn<1,>=0.35.0
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist:
|
|
32
|
+
Requires-Dist: websockets>=13.0.0
|
|
33
|
+
Requires-Dist: litellm>=1.81.6
|
|
34
34
|
Requires-Dist: ddgs>=9.8.0
|
|
35
35
|
Requires-Dist: phonenumbers>=9.0.22
|
|
36
36
|
Requires-Dist: build>=1.4.0
|
|
@@ -43,13 +43,6 @@ Requires-Dist: pytest-repeat==0.9.4; extra == "dev"
|
|
|
43
43
|
Requires-Dist: pre-commit; extra == "dev"
|
|
44
44
|
Requires-Dist: ruff==0.12.8; extra == "dev"
|
|
45
45
|
Requires-Dist: google-genai<2,>=1.26.0; extra == "dev"
|
|
46
|
-
Provides-Extra: gemini
|
|
47
|
-
Requires-Dist: google-genai<2,>=1.26.0; python_version >= "3.9" and extra == "gemini"
|
|
48
|
-
Requires-Dist: aiohttp>=3.12.0; extra == "gemini"
|
|
49
|
-
Provides-Extra: openai
|
|
50
|
-
Requires-Dist: openai>=1.70.0; extra == "openai"
|
|
51
|
-
Provides-Extra: llm
|
|
52
|
-
Requires-Dist: litellm>=1.56.0; extra == "llm"
|
|
53
46
|
Dynamic: license-file
|
|
54
47
|
|
|
55
48
|
# Cartesia Line SDK
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cartesia-line
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev2
|
|
4
4
|
Summary: Cartesia Voice Agents SDK
|
|
5
5
|
Author-email: "Cartesia AI, Inc." <support@cartesia.ai>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -29,8 +29,8 @@ Requires-Dist: fastapi>=0.115.0
|
|
|
29
29
|
Requires-Dist: aiohttp>=3.8.0
|
|
30
30
|
Requires-Dist: pydantic<3,>=2.0.0
|
|
31
31
|
Requires-Dist: uvicorn<1,>=0.35.0
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist:
|
|
32
|
+
Requires-Dist: websockets>=13.0.0
|
|
33
|
+
Requires-Dist: litellm>=1.81.6
|
|
34
34
|
Requires-Dist: ddgs>=9.8.0
|
|
35
35
|
Requires-Dist: phonenumbers>=9.0.22
|
|
36
36
|
Requires-Dist: build>=1.4.0
|
|
@@ -43,13 +43,6 @@ Requires-Dist: pytest-repeat==0.9.4; extra == "dev"
|
|
|
43
43
|
Requires-Dist: pre-commit; extra == "dev"
|
|
44
44
|
Requires-Dist: ruff==0.12.8; extra == "dev"
|
|
45
45
|
Requires-Dist: google-genai<2,>=1.26.0; extra == "dev"
|
|
46
|
-
Provides-Extra: gemini
|
|
47
|
-
Requires-Dist: google-genai<2,>=1.26.0; python_version >= "3.9" and extra == "gemini"
|
|
48
|
-
Requires-Dist: aiohttp>=3.12.0; extra == "gemini"
|
|
49
|
-
Provides-Extra: openai
|
|
50
|
-
Requires-Dist: openai>=1.70.0; extra == "openai"
|
|
51
|
-
Provides-Extra: llm
|
|
52
|
-
Requires-Dist: litellm>=1.56.0; extra == "llm"
|
|
53
46
|
Dynamic: license-file
|
|
54
47
|
|
|
55
48
|
# Cartesia Line SDK
|
|
@@ -21,15 +21,6 @@ line/llm_agent/tools/__init__.py
|
|
|
21
21
|
line/llm_agent/tools/decorators.py
|
|
22
22
|
line/llm_agent/tools/system.py
|
|
23
23
|
line/llm_agent/tools/utils.py
|
|
24
|
-
line/v02/example_integrations/browserbase/main.py
|
|
25
|
-
line/v02/example_integrations/browserbase/stagehand_form_filler.py
|
|
26
|
-
line/v02/example_integrations/exa/main.py
|
|
27
|
-
line/v02/examples/basic_chat/main.py
|
|
28
|
-
line/v02/examples/echo/main.py
|
|
29
|
-
line/v02/examples/echo/tools.py
|
|
30
|
-
line/v02/examples/form_filler/form_filler.py
|
|
31
|
-
line/v02/examples/form_filler/main.py
|
|
32
|
-
line/v02/examples/transfer_phone_call/main.py
|
|
33
24
|
tests/test_llm_agent_config.py
|
|
34
25
|
tests/test_llm_agent_llm_agent.py
|
|
35
26
|
tests/test_llm_agent_tools_decorators.py
|
|
@@ -4,8 +4,8 @@ fastapi>=0.115.0
|
|
|
4
4
|
aiohttp>=3.8.0
|
|
5
5
|
pydantic<3,>=2.0.0
|
|
6
6
|
uvicorn<1,>=0.35.0
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
websockets>=13.0.0
|
|
8
|
+
litellm>=1.81.6
|
|
9
9
|
ddgs>=9.8.0
|
|
10
10
|
phonenumbers>=9.0.22
|
|
11
11
|
build>=1.4.0
|
|
@@ -19,15 +19,3 @@ pytest-repeat==0.9.4
|
|
|
19
19
|
pre-commit
|
|
20
20
|
ruff==0.12.8
|
|
21
21
|
google-genai<2,>=1.26.0
|
|
22
|
-
|
|
23
|
-
[gemini]
|
|
24
|
-
aiohttp>=3.12.0
|
|
25
|
-
|
|
26
|
-
[gemini:python_version >= "3.9"]
|
|
27
|
-
google-genai<2,>=1.26.0
|
|
28
|
-
|
|
29
|
-
[llm]
|
|
30
|
-
litellm>=1.56.0
|
|
31
|
-
|
|
32
|
-
[openai]
|
|
33
|
-
openai>=1.70.0
|
|
@@ -24,25 +24,12 @@ from line.events import (
|
|
|
24
24
|
AgentTurnEnded,
|
|
25
25
|
AgentTurnStarted,
|
|
26
26
|
CallEnded,
|
|
27
|
-
# Input events
|
|
27
|
+
# Input events
|
|
28
28
|
CallStarted,
|
|
29
29
|
InputEvent,
|
|
30
30
|
LogMessage,
|
|
31
31
|
LogMetric,
|
|
32
32
|
OutputEvent,
|
|
33
|
-
SpecificAgentDtmfSent,
|
|
34
|
-
SpecificAgentHandedOff,
|
|
35
|
-
SpecificAgentTextSent,
|
|
36
|
-
SpecificAgentTurnEnded,
|
|
37
|
-
SpecificAgentTurnStarted,
|
|
38
|
-
SpecificCallEnded,
|
|
39
|
-
# Specific input events (without history)
|
|
40
|
-
SpecificCallStarted,
|
|
41
|
-
SpecificInputEvent,
|
|
42
|
-
SpecificUserDtmfSent,
|
|
43
|
-
SpecificUserTextSent,
|
|
44
|
-
SpecificUserTurnEnded,
|
|
45
|
-
SpecificUserTurnStarted,
|
|
46
33
|
UserDtmfSent,
|
|
47
34
|
UserTextSent,
|
|
48
35
|
UserTurnEnded,
|
|
@@ -101,7 +88,7 @@ __all__ = [
|
|
|
101
88
|
"LogMetric",
|
|
102
89
|
"LogMessage",
|
|
103
90
|
"OutputEvent",
|
|
104
|
-
# Input events
|
|
91
|
+
# Input events
|
|
105
92
|
"CallStarted",
|
|
106
93
|
"CallEnded",
|
|
107
94
|
"UserTurnStarted",
|
|
@@ -114,19 +101,6 @@ __all__ = [
|
|
|
114
101
|
"AgentTurnEnded",
|
|
115
102
|
"AgentHandedOff",
|
|
116
103
|
"InputEvent",
|
|
117
|
-
# Specific input events
|
|
118
|
-
"SpecificCallStarted",
|
|
119
|
-
"SpecificCallEnded",
|
|
120
|
-
"SpecificUserTurnStarted",
|
|
121
|
-
"SpecificUserDtmfSent",
|
|
122
|
-
"SpecificUserTextSent",
|
|
123
|
-
"SpecificUserTurnEnded",
|
|
124
|
-
"SpecificAgentTurnStarted",
|
|
125
|
-
"SpecificAgentTextSent",
|
|
126
|
-
"SpecificAgentDtmfSent",
|
|
127
|
-
"SpecificAgentTurnEnded",
|
|
128
|
-
"SpecificAgentHandedOff",
|
|
129
|
-
"SpecificInputEvent",
|
|
130
104
|
# Harness types
|
|
131
105
|
"InputMessage",
|
|
132
106
|
"OutputMessage",
|
|
@@ -81,135 +81,87 @@ OutputEvent = Union[
|
|
|
81
81
|
# -------------------------
|
|
82
82
|
# Input Events (harness -> agent)
|
|
83
83
|
# -------------------------
|
|
84
|
-
# Specific* events do NOT include history and are used within the history list.
|
|
85
84
|
# Each event has a stable event_id (UUID) for tracking which events trigger responses.
|
|
85
|
+
# history=None indicates the event is used within a history list (no nested history).
|
|
86
86
|
|
|
87
87
|
|
|
88
|
-
class
|
|
88
|
+
class CallStarted(BaseModel):
|
|
89
89
|
type: Literal["call_started"] = "call_started"
|
|
90
90
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
91
|
+
history: Optional[List["InputEvent"]] = None
|
|
91
92
|
|
|
92
93
|
|
|
93
|
-
class
|
|
94
|
+
class CallEnded(BaseModel):
|
|
94
95
|
type: Literal["call_ended"] = "call_ended"
|
|
95
96
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
97
|
+
history: Optional[List["InputEvent"]] = None
|
|
96
98
|
|
|
97
99
|
|
|
98
|
-
class
|
|
100
|
+
class AgentHandedOff(BaseModel):
|
|
99
101
|
"""Event emitted when control is transferred to the tool target."""
|
|
100
102
|
|
|
101
103
|
type: Literal["agent_handed_off"] = "agent_handed_off"
|
|
102
104
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
105
|
+
history: Optional[List["InputEvent"]] = None
|
|
103
106
|
|
|
104
107
|
|
|
105
|
-
class
|
|
108
|
+
class UserTurnStarted(BaseModel):
|
|
106
109
|
type: Literal["user_turn_started"] = "user_turn_started"
|
|
107
110
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
111
|
+
history: Optional[List["InputEvent"]] = None
|
|
108
112
|
|
|
109
113
|
|
|
110
|
-
class
|
|
114
|
+
class UserDtmfSent(BaseModel):
|
|
111
115
|
type: Literal["user_dtmf_sent"] = "user_dtmf_sent"
|
|
112
116
|
button: str
|
|
113
117
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
118
|
+
history: Optional[List["InputEvent"]] = None
|
|
114
119
|
|
|
115
120
|
|
|
116
|
-
class
|
|
121
|
+
class UserTextSent(BaseModel):
|
|
117
122
|
type: Literal["user_text_sent"] = "user_text_sent"
|
|
118
123
|
content: str
|
|
119
124
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
125
|
+
history: Optional[List["InputEvent"]] = None
|
|
120
126
|
|
|
121
127
|
|
|
122
|
-
class
|
|
128
|
+
class UserTurnEnded(BaseModel):
|
|
123
129
|
type: Literal["user_turn_ended"] = "user_turn_ended"
|
|
124
|
-
content: List[Union[
|
|
130
|
+
content: List[Union[UserDtmfSent, UserTextSent]] = Field(default_factory=list)
|
|
125
131
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
132
|
+
history: Optional[List["InputEvent"]] = None
|
|
126
133
|
|
|
127
134
|
|
|
128
|
-
class
|
|
135
|
+
class AgentTurnStarted(BaseModel):
|
|
129
136
|
type: Literal["agent_turn_started"] = "agent_turn_started"
|
|
130
137
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
138
|
+
history: Optional[List["InputEvent"]] = None
|
|
131
139
|
|
|
132
140
|
|
|
133
|
-
class
|
|
141
|
+
class AgentTextSent(BaseModel):
|
|
134
142
|
type: Literal["agent_text_sent"] = "agent_text_sent"
|
|
135
143
|
content: str
|
|
136
144
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
145
|
+
history: Optional[List["InputEvent"]] = None
|
|
137
146
|
|
|
138
147
|
|
|
139
|
-
class
|
|
148
|
+
class AgentDtmfSent(BaseModel):
|
|
140
149
|
type: Literal["agent_dtmf_sent"] = "agent_dtmf_sent"
|
|
141
150
|
button: str
|
|
142
151
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
152
|
+
history: Optional[List["InputEvent"]] = None
|
|
143
153
|
|
|
144
154
|
|
|
145
|
-
class
|
|
155
|
+
class AgentTurnEnded(BaseModel):
|
|
146
156
|
type: Literal["agent_turn_ended"] = "agent_turn_ended"
|
|
147
157
|
content: List[
|
|
148
158
|
Union[
|
|
149
|
-
|
|
150
|
-
|
|
159
|
+
AgentTextSent,
|
|
160
|
+
AgentDtmfSent,
|
|
151
161
|
]
|
|
152
162
|
] = Field(default_factory=list)
|
|
153
163
|
event_id: str = Field(default_factory=_generate_event_id)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
SpecificInputEvent = Union[
|
|
157
|
-
SpecificCallStarted,
|
|
158
|
-
SpecificAgentHandedOff,
|
|
159
|
-
SpecificUserTurnStarted,
|
|
160
|
-
SpecificUserDtmfSent,
|
|
161
|
-
SpecificUserTextSent,
|
|
162
|
-
SpecificUserTurnEnded,
|
|
163
|
-
SpecificAgentTurnStarted,
|
|
164
|
-
SpecificAgentTextSent,
|
|
165
|
-
SpecificAgentDtmfSent,
|
|
166
|
-
SpecificAgentTurnEnded,
|
|
167
|
-
SpecificCallEnded,
|
|
168
|
-
]
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
class CallStarted(SpecificCallStarted):
|
|
172
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
class CallEnded(SpecificCallEnded):
|
|
176
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
class UserTurnStarted(SpecificUserTurnStarted):
|
|
180
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
class UserDtmfSent(SpecificUserDtmfSent):
|
|
184
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
class UserTextSent(SpecificUserTextSent):
|
|
188
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
class UserTurnEnded(SpecificUserTurnEnded):
|
|
192
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
class AgentTurnStarted(SpecificAgentTurnStarted):
|
|
196
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
class AgentTextSent(SpecificAgentTextSent):
|
|
200
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
class AgentDtmfSent(SpecificAgentDtmfSent):
|
|
204
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
class AgentTurnEnded(SpecificAgentTurnEnded):
|
|
208
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
class AgentHandedOff(SpecificAgentHandedOff):
|
|
212
|
-
history: List[SpecificInputEvent] = Field(default_factory=list)
|
|
164
|
+
history: Optional[List["InputEvent"]] = None
|
|
213
165
|
|
|
214
166
|
|
|
215
167
|
InputEvent = Union[
|
|
@@ -239,19 +191,7 @@ __all__ = [
|
|
|
239
191
|
"LogMetric",
|
|
240
192
|
"LogMessage",
|
|
241
193
|
"OutputEvent",
|
|
242
|
-
# Input
|
|
243
|
-
"SpecificCallStarted",
|
|
244
|
-
"SpecificCallEnded",
|
|
245
|
-
"SpecificUserTurnStarted",
|
|
246
|
-
"SpecificUserDtmfSent",
|
|
247
|
-
"SpecificUserTextSent",
|
|
248
|
-
"SpecificUserTurnEnded",
|
|
249
|
-
"SpecificAgentTurnStarted",
|
|
250
|
-
"SpecificAgentTextSent",
|
|
251
|
-
"SpecificAgentDtmfSent",
|
|
252
|
-
"SpecificAgentTurnEnded",
|
|
253
|
-
"SpecificInputEvent",
|
|
254
|
-
# Input with history
|
|
194
|
+
# Input
|
|
255
195
|
"CallStarted",
|
|
256
196
|
"CallEnded",
|
|
257
197
|
"UserTurnStarted",
|
|
@@ -262,6 +202,5 @@ __all__ = [
|
|
|
262
202
|
"AgentTextSent",
|
|
263
203
|
"AgentDtmfSent",
|
|
264
204
|
"AgentTurnEnded",
|
|
265
|
-
"AgentHandedOff",
|
|
266
205
|
"InputEvent",
|
|
267
206
|
]
|
|
@@ -23,22 +23,19 @@ from loguru import logger
|
|
|
23
23
|
|
|
24
24
|
from line.agent import AgentCallable, TurnEnv
|
|
25
25
|
from line.events import (
|
|
26
|
+
AgentDtmfSent,
|
|
26
27
|
AgentEndCall,
|
|
27
28
|
AgentHandedOff,
|
|
28
29
|
AgentSendDtmf,
|
|
29
30
|
AgentSendText,
|
|
31
|
+
AgentTextSent,
|
|
30
32
|
AgentToolCalled,
|
|
31
33
|
AgentToolReturned,
|
|
32
34
|
CallEnded,
|
|
33
35
|
CallStarted,
|
|
34
36
|
InputEvent,
|
|
35
37
|
OutputEvent,
|
|
36
|
-
|
|
37
|
-
SpecificAgentHandedOff,
|
|
38
|
-
SpecificAgentTextSent,
|
|
39
|
-
SpecificCallEnded,
|
|
40
|
-
SpecificInputEvent,
|
|
41
|
-
SpecificUserTextSent,
|
|
38
|
+
UserTextSent,
|
|
42
39
|
)
|
|
43
40
|
from line.llm_agent.config import LlmConfig
|
|
44
41
|
from line.llm_agent.provider import LLMProvider, Message, ToolCall
|
|
@@ -406,9 +403,10 @@ class LlmAgent:
|
|
|
406
403
|
yield tool_returned_output
|
|
407
404
|
|
|
408
405
|
# AgentHandedOff input event is passed to the handoff target to execute the tool
|
|
409
|
-
|
|
406
|
+
handed_off_event = AgentHandedOff()
|
|
410
407
|
event = AgentHandedOff(
|
|
411
|
-
history=event.history + [
|
|
408
|
+
history=event.history + [handed_off_event],
|
|
409
|
+
**{k: v for k, v in handed_off_event.model_dump().items() if k != "history"},
|
|
412
410
|
)
|
|
413
411
|
self._append_to_local_history(event)
|
|
414
412
|
try:
|
|
@@ -442,7 +440,7 @@ class LlmAgent:
|
|
|
442
440
|
|
|
443
441
|
def _build_messages(
|
|
444
442
|
self,
|
|
445
|
-
input_history: List[
|
|
443
|
+
input_history: List[InputEvent],
|
|
446
444
|
local_history: List[tuple[str, OutputEvent]],
|
|
447
445
|
current_event_id: str,
|
|
448
446
|
) -> List[Message]:
|
|
@@ -455,17 +453,17 @@ class LlmAgent:
|
|
|
455
453
|
4. Unobservable events (tool calls) are interpolated relative to observables
|
|
456
454
|
|
|
457
455
|
The full_history contains:
|
|
458
|
-
-
|
|
456
|
+
- InputEvent (with history=None) for events from input_history
|
|
459
457
|
- OutputEvent for unobservable/current events from local_history
|
|
460
458
|
"""
|
|
461
459
|
full_history = _build_full_history(input_history, local_history, current_event_id)
|
|
462
460
|
|
|
463
461
|
messages = []
|
|
464
462
|
for event in full_history:
|
|
465
|
-
# Handle
|
|
466
|
-
if isinstance(event,
|
|
463
|
+
# Handle InputEvent types (from input_history)
|
|
464
|
+
if isinstance(event, UserTextSent):
|
|
467
465
|
messages.append(Message(role="user", content=event.content))
|
|
468
|
-
elif isinstance(event,
|
|
466
|
+
elif isinstance(event, AgentTextSent):
|
|
469
467
|
messages.append(Message(role="assistant", content=event.content))
|
|
470
468
|
# Handle OutputEvent types (unobservable events from local_history)
|
|
471
469
|
elif isinstance(event, AgentSendText):
|
|
@@ -603,10 +601,10 @@ class LlmAgent:
|
|
|
603
601
|
|
|
604
602
|
|
|
605
603
|
def _build_full_history(
|
|
606
|
-
input_history: List[
|
|
604
|
+
input_history: List[InputEvent],
|
|
607
605
|
local_history: List[tuple[str, OutputEvent]],
|
|
608
606
|
current_event_id: str,
|
|
609
|
-
) -> List[Union[
|
|
607
|
+
) -> List[Union[InputEvent, OutputEvent]]:
|
|
610
608
|
"""
|
|
611
609
|
Build full history by merging input_history (canonical) with local_history.
|
|
612
610
|
|
|
@@ -645,7 +643,7 @@ def _build_full_history(
|
|
|
645
643
|
trigger_event_ids = set(local_by_event_id.keys())
|
|
646
644
|
|
|
647
645
|
# Process input in slices
|
|
648
|
-
result: List[Union[
|
|
646
|
+
result: List[Union[InputEvent, OutputEvent]] = []
|
|
649
647
|
i = 0
|
|
650
648
|
|
|
651
649
|
while i < len(input_history):
|
|
@@ -693,9 +691,9 @@ def _concat_contiguous_agent_send_text(local_history: List[OutputEvent]) -> List
|
|
|
693
691
|
|
|
694
692
|
|
|
695
693
|
def _build_history_rec(
|
|
696
|
-
input_history: List[
|
|
694
|
+
input_history: List[InputEvent],
|
|
697
695
|
local_history: List[OutputEvent],
|
|
698
|
-
) -> List[Union[
|
|
696
|
+
) -> List[Union[InputEvent, OutputEvent]]:
|
|
699
697
|
"""
|
|
700
698
|
Recursive implementation of history merging.
|
|
701
699
|
|
|
@@ -793,20 +791,20 @@ def _is_local_observable(event: OutputEvent) -> bool:
|
|
|
793
791
|
|
|
794
792
|
|
|
795
793
|
OBSERVABLE_INPUT_EVENT_TYPES = (
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
794
|
+
AgentDtmfSent,
|
|
795
|
+
AgentTextSent,
|
|
796
|
+
CallEnded,
|
|
799
797
|
)
|
|
800
798
|
|
|
801
799
|
|
|
802
|
-
def _is_input_observable(event:
|
|
803
|
-
"""Check if
|
|
800
|
+
def _is_input_observable(event: InputEvent) -> bool:
|
|
801
|
+
"""Check if an InputEvent is observable (can be matched to local history)."""
|
|
804
802
|
return isinstance(event, OBSERVABLE_INPUT_EVENT_TYPES)
|
|
805
803
|
|
|
806
804
|
|
|
807
805
|
def _try_match_events(
|
|
808
|
-
local: OutputEvent, input_evt:
|
|
809
|
-
) -> Optional[tuple[
|
|
806
|
+
local: OutputEvent, input_evt: InputEvent
|
|
807
|
+
) -> Optional[tuple[InputEvent, Optional[OutputEvent]]]:
|
|
810
808
|
"""Try to match a local observable event to an input observable event.
|
|
811
809
|
|
|
812
810
|
Returns:
|
|
@@ -817,16 +815,16 @@ def _try_match_events(
|
|
|
817
815
|
For text events, supports prefix matching (input is prefix of local).
|
|
818
816
|
For DTMF and EndCall events, only exact matching is supported.
|
|
819
817
|
"""
|
|
820
|
-
if isinstance(local, AgentSendText) and isinstance(input_evt,
|
|
818
|
+
if isinstance(local, AgentSendText) and isinstance(input_evt, AgentTextSent):
|
|
821
819
|
if local.text == input_evt.content:
|
|
822
820
|
return (input_evt, None)
|
|
823
821
|
if local.text.startswith(input_evt.content):
|
|
824
822
|
suffix = local.text[len(input_evt.content) :]
|
|
825
823
|
return (input_evt, AgentSendText(text=suffix))
|
|
826
|
-
elif isinstance(local, AgentSendDtmf) and isinstance(input_evt,
|
|
824
|
+
elif isinstance(local, AgentSendDtmf) and isinstance(input_evt, AgentDtmfSent):
|
|
827
825
|
if local.button == input_evt.button:
|
|
828
826
|
return (input_evt, None)
|
|
829
|
-
elif isinstance(local, AgentEndCall) and isinstance(input_evt,
|
|
827
|
+
elif isinstance(local, AgentEndCall) and isinstance(input_evt, CallEnded):
|
|
830
828
|
return (input_evt, None)
|
|
831
829
|
return None
|
|
832
830
|
|
{cartesia_line-0.2.0.dev0 → cartesia_line-0.2.0.dev2}/line/llm_agent/scripts/test_provider.py
RENAMED
|
@@ -29,7 +29,6 @@ from line.events import (
|
|
|
29
29
|
AgentToolCalled,
|
|
30
30
|
AgentToolReturned,
|
|
31
31
|
CallStarted,
|
|
32
|
-
SpecificUserTextSent,
|
|
33
32
|
UserTextSent,
|
|
34
33
|
)
|
|
35
34
|
from line.llm_agent import (
|
|
@@ -137,7 +136,7 @@ async def test_tool_calling(model: str):
|
|
|
137
136
|
user_message = "What's the weather in Tokyo? Also, what's 25 * 4?"
|
|
138
137
|
event = UserTextSent(
|
|
139
138
|
content=user_message,
|
|
140
|
-
history=[
|
|
139
|
+
history=[UserTextSent(content=user_message)],
|
|
141
140
|
)
|
|
142
141
|
|
|
143
142
|
print("User: What's the weather in Tokyo? Also, what's 25 * 4?")
|
|
@@ -209,7 +208,7 @@ async def test_web_search(model: str, search_context_size: str = "medium"):
|
|
|
209
208
|
user_message = "What is the current weather in New York City? Search the web for this information."
|
|
210
209
|
event = UserTextSent(
|
|
211
210
|
content=user_message,
|
|
212
|
-
history=[
|
|
211
|
+
history=[UserTextSent(content=user_message)],
|
|
213
212
|
)
|
|
214
213
|
|
|
215
214
|
print(f"User: {user_message}")
|