meshagent-agents 0.0.36__py3-none-any.whl → 0.0.38__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.
Potentially problematic release.
This version of meshagent-agents might be problematic. Click here for more details.
- meshagent/agents/__init__.py +27 -2
- meshagent/agents/adapter.py +18 -9
- meshagent/agents/agent.py +317 -214
- meshagent/agents/chat.py +390 -267
- meshagent/agents/context.py +58 -30
- meshagent/agents/development.py +11 -13
- meshagent/agents/hosting.py +109 -46
- meshagent/agents/indexer.py +241 -224
- meshagent/agents/listener.py +55 -52
- meshagent/agents/mail.py +145 -109
- meshagent/agents/planning.py +294 -199
- meshagent/agents/prompt.py +14 -12
- meshagent/agents/pydantic.py +98 -61
- meshagent/agents/schemas/__init__.py +11 -0
- meshagent/agents/schemas/document.py +32 -21
- meshagent/agents/schemas/gallery.py +23 -14
- meshagent/agents/schemas/presentation.py +33 -17
- meshagent/agents/schemas/schema.py +99 -45
- meshagent/agents/schemas/super_editor_document.py +52 -46
- meshagent/agents/single_shot_writer.py +37 -31
- meshagent/agents/thread_schema.py +74 -32
- meshagent/agents/utils.py +20 -12
- meshagent/agents/version.py +1 -1
- meshagent/agents/worker.py +48 -28
- meshagent/agents/writer.py +36 -23
- meshagent_agents-0.0.38.dist-info/METADATA +64 -0
- meshagent_agents-0.0.38.dist-info/RECORD +30 -0
- meshagent_agents-0.0.36.dist-info/METADATA +0 -36
- meshagent_agents-0.0.36.dist-info/RECORD +0 -30
- {meshagent_agents-0.0.36.dist-info → meshagent_agents-0.0.38.dist-info}/WHEEL +0 -0
- {meshagent_agents-0.0.36.dist-info → meshagent_agents-0.0.38.dist-info}/licenses/LICENSE +0 -0
- {meshagent_agents-0.0.36.dist-info → meshagent_agents-0.0.38.dist-info}/top_level.txt +0 -0
meshagent/agents/prompt.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
from .adapter import LLMAdapter, Toolkit, ToolResponseAdapter
|
|
3
2
|
from meshagent.api.schema_util import prompt_schema
|
|
4
3
|
from .agent import AgentCallContext
|
|
@@ -6,9 +5,11 @@ from typing import Optional
|
|
|
6
5
|
from meshagent.agents import TaskRunner
|
|
7
6
|
from meshagent.api import RequiredToolkit
|
|
8
7
|
|
|
8
|
+
|
|
9
9
|
# An agent that takes a simple prompt and gets the result
|
|
10
10
|
class PromptAgent(TaskRunner):
|
|
11
|
-
def __init__(
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
12
13
|
*,
|
|
13
14
|
name: str,
|
|
14
15
|
output_schema: dict,
|
|
@@ -20,19 +21,17 @@ class PromptAgent(TaskRunner):
|
|
|
20
21
|
description: Optional[str] = None,
|
|
21
22
|
requires: Optional[list[RequiredToolkit]] = None,
|
|
22
23
|
supports_tools: Optional[bool] = None,
|
|
23
|
-
labels: Optional[list[str]] = None
|
|
24
|
+
labels: Optional[list[str]] = None,
|
|
24
25
|
):
|
|
25
26
|
super().__init__(
|
|
26
27
|
name=name,
|
|
27
28
|
description=description,
|
|
28
29
|
title=title,
|
|
29
|
-
input_schema=prompt_schema(
|
|
30
|
-
description=description
|
|
31
|
-
),
|
|
30
|
+
input_schema=prompt_schema(description=description),
|
|
32
31
|
output_schema=output_schema,
|
|
33
32
|
requires=requires,
|
|
34
33
|
supports_tools=supports_tools,
|
|
35
|
-
labels=labels
|
|
34
|
+
labels=labels,
|
|
36
35
|
)
|
|
37
36
|
self.rules = rules
|
|
38
37
|
self.tools = tools
|
|
@@ -47,9 +46,12 @@ class PromptAgent(TaskRunner):
|
|
|
47
46
|
async def ask(self, *, context: AgentCallContext, arguments: dict):
|
|
48
47
|
context.chat.append_user_message(arguments["prompt"])
|
|
49
48
|
|
|
50
|
-
toolkits = [
|
|
51
|
-
*self.toolkits,
|
|
52
|
-
*context.toolkits
|
|
53
|
-
]
|
|
49
|
+
toolkits = [*self.toolkits, *context.toolkits]
|
|
54
50
|
|
|
55
|
-
return await self.llm_adapter.next(
|
|
51
|
+
return await self.llm_adapter.next(
|
|
52
|
+
context=context.chat,
|
|
53
|
+
room=context.room,
|
|
54
|
+
toolkits=toolkits,
|
|
55
|
+
tool_adapter=self.tool_adapter,
|
|
56
|
+
output_schema=self.output_schema,
|
|
57
|
+
)
|
meshagent/agents/pydantic.py
CHANGED
|
@@ -8,10 +8,10 @@ import logging
|
|
|
8
8
|
from typing import Optional
|
|
9
9
|
from meshagent.api import RoomClient
|
|
10
10
|
|
|
11
|
-
from .agent import TaskRunner,
|
|
11
|
+
from .agent import TaskRunner, Requirement
|
|
12
12
|
|
|
13
|
-
from .adapter import
|
|
14
|
-
from meshagent.tools.toolkit import Tool,
|
|
13
|
+
from .adapter import ToolResponseAdapter
|
|
14
|
+
from meshagent.tools.toolkit import Tool, ToolContext
|
|
15
15
|
from meshagent.tools.pydantic import get_pydantic_ai_tool_definition
|
|
16
16
|
|
|
17
17
|
from typing import Sequence
|
|
@@ -20,37 +20,48 @@ import pydantic_ai
|
|
|
20
20
|
logger = logging.getLogger("pydantic_agent")
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
def get_pydantic_ai_tool(
|
|
24
|
+
*, room: RoomClient, tool: Tool, response_adapter: ToolResponseAdapter
|
|
25
|
+
) -> pydantic_ai.tools.Tool:
|
|
26
|
+
async def prepare(
|
|
27
|
+
ctx: pydantic_ai.RunContext, tool_def: pydantic_ai.tools.ToolDefinition
|
|
28
|
+
):
|
|
29
|
+
return get_pydantic_ai_tool_definition(tool=tool)
|
|
23
30
|
|
|
24
|
-
def
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
response = await tool.execute(context=ToolContext(room=room, caller=room.local_participant), **kwargs)
|
|
30
|
-
return await response_adapter.to_plain_text(room=room, response=response)
|
|
31
|
+
async def execute(**kwargs):
|
|
32
|
+
response = await tool.execute(
|
|
33
|
+
context=ToolContext(room=room, caller=room.local_participant), **kwargs
|
|
34
|
+
)
|
|
35
|
+
return await response_adapter.to_plain_text(room=room, response=response)
|
|
31
36
|
|
|
32
|
-
|
|
37
|
+
return pydantic_ai.Tool(
|
|
33
38
|
name=tool.name,
|
|
34
39
|
takes_ctx=False,
|
|
35
40
|
description=tool.description,
|
|
36
41
|
prepare=prepare,
|
|
37
|
-
function=execute
|
|
42
|
+
function=execute,
|
|
38
43
|
)
|
|
39
44
|
|
|
40
|
-
def get_pydantic_ai_tools_from_context(*, context: AgentCallContext, response_adapter: ToolResponseAdapter) -> list[pydantic_ai.tools.Tool]:
|
|
41
45
|
|
|
46
|
+
def get_pydantic_ai_tools_from_context(
|
|
47
|
+
*, context: AgentCallContext, response_adapter: ToolResponseAdapter
|
|
48
|
+
) -> list[pydantic_ai.tools.Tool]:
|
|
42
49
|
tools = list[pydantic_ai.tools.Tool]()
|
|
43
50
|
|
|
44
51
|
for toolkit in context.toolkits:
|
|
45
|
-
|
|
46
52
|
for tool in toolkit.tools:
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
tools.append(
|
|
54
|
+
get_pydantic_ai_tool(
|
|
55
|
+
room=context.room, tool=tool, response_adapter=response_adapter
|
|
56
|
+
)
|
|
57
|
+
)
|
|
49
58
|
|
|
50
59
|
return tools
|
|
51
60
|
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
|
|
62
|
+
class PydanticAgent[TInput: BaseModel, TOutput: BaseModel](TaskRunner):
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
54
65
|
*,
|
|
55
66
|
name: str,
|
|
56
67
|
input_model: TInput,
|
|
@@ -58,26 +69,26 @@ class PydanticAgent[TInput:BaseModel, TOutput:BaseModel](TaskRunner):
|
|
|
58
69
|
title: Optional[str] = None,
|
|
59
70
|
description: Optional[str] = None,
|
|
60
71
|
requires: Optional[list[Requirement]] = None,
|
|
61
|
-
supports_tools
|
|
72
|
+
supports_tools: Optional[bool] = None,
|
|
62
73
|
):
|
|
63
74
|
self.input_model = input_model
|
|
64
75
|
self.output_model = output_model
|
|
65
|
-
|
|
76
|
+
|
|
66
77
|
super().__init__(
|
|
67
|
-
name
|
|
68
|
-
description
|
|
69
|
-
title
|
|
78
|
+
name=name,
|
|
79
|
+
description=description,
|
|
80
|
+
title=title,
|
|
70
81
|
input_schema=input_model.model_json_schema(),
|
|
71
|
-
output_schema=output_model.model_json_schema(),
|
|
82
|
+
output_schema=output_model.model_json_schema(),
|
|
72
83
|
requires=requires,
|
|
73
|
-
supports_tools=supports_tools
|
|
84
|
+
supports_tools=supports_tools,
|
|
74
85
|
)
|
|
75
|
-
|
|
86
|
+
|
|
76
87
|
async def ask(self, *, context: AgentCallContext, arguments: dict):
|
|
77
88
|
try:
|
|
78
89
|
input = self.input_model.model_validate(arguments)
|
|
79
90
|
output = await self.ask_model(context=context, arguments=input)
|
|
80
|
-
return output.model_dump(mode=
|
|
91
|
+
return output.model_dump(mode="json")
|
|
81
92
|
except Exception as e:
|
|
82
93
|
logger.error("Unhandled exception in ask agent call", exc_info=e)
|
|
83
94
|
raise
|
|
@@ -86,22 +97,23 @@ class PydanticAgent[TInput:BaseModel, TOutput:BaseModel](TaskRunner):
|
|
|
86
97
|
async def ask_model(self, context: AgentCallContext, arguments: TInput) -> TOutput:
|
|
87
98
|
pass
|
|
88
99
|
|
|
89
|
-
|
|
90
|
-
|
|
100
|
+
|
|
101
|
+
class PydanticWriter[TInput: BaseModel, TOutput: BaseModel](Writer):
|
|
102
|
+
def __init__(
|
|
103
|
+
self,
|
|
91
104
|
name: str,
|
|
92
105
|
input_model: TInput,
|
|
93
106
|
output_model: TOutput,
|
|
94
107
|
title: Optional[str] = None,
|
|
95
|
-
description: Optional[str] = None
|
|
108
|
+
description: Optional[str] = None,
|
|
96
109
|
):
|
|
97
|
-
|
|
98
110
|
self.input_model = input_model
|
|
99
111
|
self.output_model = output_model
|
|
100
112
|
|
|
101
|
-
super().__init__(
|
|
113
|
+
super().__init__(
|
|
102
114
|
name=name,
|
|
103
115
|
description=description,
|
|
104
|
-
title=title,
|
|
116
|
+
title=title,
|
|
105
117
|
input_schema=input_model.model_json_schema(),
|
|
106
118
|
output_schema=output_model.model_json_schema(),
|
|
107
119
|
)
|
|
@@ -109,59 +121,84 @@ class PydanticWriter[TInput:BaseModel, TOutput:BaseModel](Writer):
|
|
|
109
121
|
async def write(self, writer_context: WriterContext, arguments: dict):
|
|
110
122
|
try:
|
|
111
123
|
input = self.input_model.model_validate(arguments)
|
|
112
|
-
output = await self.write_model(
|
|
113
|
-
|
|
124
|
+
output = await self.write_model(
|
|
125
|
+
writer_context=writer_context, arguments=input
|
|
126
|
+
)
|
|
127
|
+
return output.model_dump(mode="json")
|
|
114
128
|
except Exception as e:
|
|
115
129
|
logger.error("Unhandled exception in write call", exc_info=e)
|
|
116
130
|
raise
|
|
117
|
-
|
|
131
|
+
|
|
118
132
|
@abstractmethod
|
|
119
|
-
async def write_model(
|
|
133
|
+
async def write_model(
|
|
134
|
+
self, writer_context: WriterContext, arguments: TInput
|
|
135
|
+
) -> TOutput:
|
|
120
136
|
pass
|
|
121
137
|
|
|
122
138
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def __init__(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
139
|
+
class PydanicAgentHost[TInput: BaseModel, TOutput: BaseModel](
|
|
140
|
+
PydanticAgent[TInput, TOutput]
|
|
141
|
+
):
|
|
142
|
+
def __init__(
|
|
143
|
+
self,
|
|
144
|
+
*,
|
|
145
|
+
model: pydantic_ai.models.KnownModelName,
|
|
146
|
+
system_prompt: str | Sequence[str],
|
|
147
|
+
response_adapter: ToolResponseAdapter,
|
|
148
|
+
tools: Optional[list[pydantic_ai.Tool]] = None,
|
|
149
|
+
name,
|
|
150
|
+
input_model,
|
|
151
|
+
output_model,
|
|
152
|
+
title=None,
|
|
153
|
+
description=None,
|
|
154
|
+
requires=None,
|
|
155
|
+
supports_tools=None,
|
|
156
|
+
):
|
|
132
157
|
super().__init__(
|
|
133
|
-
name=name,
|
|
134
|
-
|
|
158
|
+
name=name,
|
|
159
|
+
input_model=input_model,
|
|
160
|
+
output_model=output_model,
|
|
161
|
+
title=title,
|
|
162
|
+
description=description,
|
|
163
|
+
requires=requires,
|
|
164
|
+
supports_tools=supports_tools,
|
|
135
165
|
)
|
|
136
166
|
self._model = model
|
|
137
167
|
self._system_prompt = system_prompt
|
|
138
168
|
self._response_adapter = response_adapter
|
|
139
|
-
if tools
|
|
169
|
+
if tools is None:
|
|
140
170
|
tools = []
|
|
141
|
-
|
|
171
|
+
|
|
142
172
|
self._tools = tools
|
|
143
173
|
|
|
144
174
|
def message_history(self, context: AgentCallContext) -> None | list:
|
|
145
175
|
return None
|
|
146
|
-
|
|
176
|
+
|
|
147
177
|
def to_prompt(self, *, arguments: TInput) -> str:
|
|
148
178
|
return str(arguments)
|
|
149
179
|
|
|
150
|
-
def create_agent(
|
|
151
|
-
|
|
180
|
+
def create_agent(
|
|
181
|
+
self, *, tools: list[pydantic_ai.Tool]
|
|
182
|
+
) -> pydantic_ai.Agent[TInput, TOutput]:
|
|
183
|
+
return pydantic_ai.Agent(
|
|
152
184
|
model=self._model,
|
|
153
185
|
system_prompt=self._system_prompt,
|
|
154
186
|
deps_type=self.input_model,
|
|
155
187
|
result_type=self.output_model,
|
|
156
|
-
tools=[
|
|
157
|
-
*self._tools,
|
|
158
|
-
*tools
|
|
159
|
-
]
|
|
188
|
+
tools=[*self._tools, *tools],
|
|
160
189
|
)
|
|
161
190
|
|
|
162
191
|
@abstractmethod
|
|
163
192
|
async def ask_model(self, context: AgentCallContext, arguments: TInput) -> TOutput:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
193
|
+
agent = self.create_agent(
|
|
194
|
+
tools=get_pydantic_ai_tools_from_context(
|
|
195
|
+
context=context, response_adapter=self._response_adapter
|
|
196
|
+
)
|
|
197
|
+
)
|
|
198
|
+
result = await agent.run(
|
|
199
|
+
self.to_prompt(arguments=arguments),
|
|
200
|
+
message_history=self.message_history(context),
|
|
201
|
+
result_type=self.output_model,
|
|
202
|
+
deps=arguments,
|
|
203
|
+
)
|
|
204
|
+
return result.data
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from document import document_schema
|
|
2
|
+
from gallery import gallery_schema
|
|
3
|
+
from presentation import presentation_schema
|
|
4
|
+
from super_editor_document import super_editor_document_schema
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
document_schema,
|
|
8
|
+
gallery_schema,
|
|
9
|
+
presentation_schema,
|
|
10
|
+
super_editor_document_schema,
|
|
11
|
+
]
|
|
@@ -1,38 +1,49 @@
|
|
|
1
|
-
from meshagent.api.schema import MeshSchema, ElementType,
|
|
1
|
+
from meshagent.api.schema import MeshSchema, ElementType, ChildProperty, ValueProperty
|
|
2
2
|
|
|
3
3
|
document_schema = MeshSchema(
|
|
4
4
|
root_tag_name="document",
|
|
5
|
-
elements=[
|
|
5
|
+
elements=[
|
|
6
6
|
ElementType(
|
|
7
|
-
tag_name="document",
|
|
7
|
+
tag_name="document",
|
|
8
8
|
description="a document",
|
|
9
9
|
properties=[
|
|
10
|
-
ChildProperty(
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
ChildProperty(
|
|
11
|
+
name="content",
|
|
12
|
+
description="the content in the document",
|
|
13
|
+
child_tag_names=["heading", "body", "file"],
|
|
14
|
+
),
|
|
15
|
+
],
|
|
16
|
+
),
|
|
15
17
|
ElementType(
|
|
16
|
-
tag_name="heading",
|
|
18
|
+
tag_name="heading",
|
|
17
19
|
description="heading",
|
|
18
20
|
properties=[
|
|
19
|
-
ValueProperty(
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
ValueProperty(
|
|
22
|
+
name="text", description="the text of the heading", type="string"
|
|
23
|
+
),
|
|
24
|
+
],
|
|
25
|
+
),
|
|
22
26
|
ElementType(
|
|
23
|
-
tag_name="body",
|
|
27
|
+
tag_name="body",
|
|
24
28
|
description="text",
|
|
25
|
-
properties=[
|
|
26
|
-
ValueProperty(
|
|
27
|
-
|
|
29
|
+
properties=[
|
|
30
|
+
ValueProperty(
|
|
31
|
+
name="text",
|
|
32
|
+
description="body content in markdown format",
|
|
33
|
+
type="string",
|
|
34
|
+
),
|
|
35
|
+
],
|
|
28
36
|
),
|
|
29
37
|
ElementType(
|
|
30
|
-
tag_name="file",
|
|
38
|
+
tag_name="file",
|
|
31
39
|
description="an image",
|
|
32
40
|
properties=[
|
|
33
|
-
ValueProperty(
|
|
34
|
-
|
|
41
|
+
ValueProperty(
|
|
42
|
+
name="name",
|
|
43
|
+
description="reference a file that was output from one of the steps. use to display the content of a file or image.",
|
|
44
|
+
type="string",
|
|
45
|
+
),
|
|
46
|
+
],
|
|
35
47
|
),
|
|
36
|
-
]
|
|
48
|
+
],
|
|
37
49
|
)
|
|
38
|
-
|
|
@@ -1,25 +1,34 @@
|
|
|
1
|
-
from meshagent.api.schema import MeshSchema, ElementType,
|
|
1
|
+
from meshagent.api.schema import MeshSchema, ElementType, ChildProperty, ValueProperty
|
|
2
2
|
|
|
3
3
|
gallery_schema = MeshSchema(
|
|
4
4
|
root_tag_name="gallery",
|
|
5
|
-
elements=[
|
|
5
|
+
elements=[
|
|
6
6
|
ElementType(
|
|
7
|
-
tag_name="gallery",
|
|
7
|
+
tag_name="gallery",
|
|
8
8
|
description="a media gallery",
|
|
9
9
|
properties=[
|
|
10
|
-
ChildProperty(
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
ChildProperty(
|
|
11
|
+
name="content",
|
|
12
|
+
description="the content in the gallery",
|
|
13
|
+
child_tag_names=["file"],
|
|
14
|
+
),
|
|
15
|
+
],
|
|
16
|
+
),
|
|
15
17
|
ElementType(
|
|
16
|
-
tag_name="file",
|
|
18
|
+
tag_name="file",
|
|
17
19
|
description="an image",
|
|
18
20
|
properties=[
|
|
19
|
-
ValueProperty(
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
ValueProperty(
|
|
22
|
+
name="path",
|
|
23
|
+
description="reference a file that was output from one of the steps. use to display the content of a file or image.",
|
|
24
|
+
type="string",
|
|
25
|
+
),
|
|
26
|
+
ValueProperty(
|
|
27
|
+
name="description",
|
|
28
|
+
description="a description of the image",
|
|
29
|
+
type="string",
|
|
30
|
+
),
|
|
31
|
+
],
|
|
22
32
|
),
|
|
23
|
-
]
|
|
33
|
+
],
|
|
24
34
|
)
|
|
25
|
-
|
|
@@ -2,31 +2,47 @@ from meshagent.api.schema import MeshSchema, ElementType, ChildProperty, ValuePr
|
|
|
2
2
|
|
|
3
3
|
presentation_schema = MeshSchema(
|
|
4
4
|
root_tag_name="presentation",
|
|
5
|
-
elements=[
|
|
5
|
+
elements=[
|
|
6
6
|
ElementType(
|
|
7
|
-
tag_name="presentation",
|
|
7
|
+
tag_name="presentation",
|
|
8
8
|
description="a presentation",
|
|
9
9
|
properties=[
|
|
10
|
-
ChildProperty(
|
|
11
|
-
|
|
10
|
+
ChildProperty(
|
|
11
|
+
name="slides",
|
|
12
|
+
description="the slides for the presentation",
|
|
13
|
+
child_tag_names=["slide"],
|
|
14
|
+
),
|
|
15
|
+
],
|
|
12
16
|
),
|
|
13
17
|
ElementType(
|
|
14
|
-
tag_name="slide",
|
|
18
|
+
tag_name="slide",
|
|
15
19
|
description="a slide",
|
|
16
20
|
properties=[
|
|
17
|
-
ValueProperty(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
ValueProperty(
|
|
22
|
+
name="title", description="a title for the slide", type="string"
|
|
23
|
+
),
|
|
24
|
+
ValueProperty(
|
|
25
|
+
name="background",
|
|
26
|
+
description="an file to use for an background of the slide, must be a filename output from a previous step",
|
|
27
|
+
type="string",
|
|
28
|
+
),
|
|
29
|
+
ChildProperty(
|
|
30
|
+
name="lines",
|
|
31
|
+
description="the slides for the presentation",
|
|
32
|
+
child_tag_names=["line"],
|
|
33
|
+
),
|
|
34
|
+
],
|
|
21
35
|
),
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
tag_name="line",
|
|
36
|
+
ElementType(
|
|
37
|
+
tag_name="line",
|
|
25
38
|
description="a line of text",
|
|
26
39
|
properties=[
|
|
27
|
-
ValueProperty(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
ValueProperty(
|
|
41
|
+
name="line",
|
|
42
|
+
description="the text of a bullet point for the slide",
|
|
43
|
+
type="string",
|
|
44
|
+
),
|
|
45
|
+
],
|
|
46
|
+
),
|
|
47
|
+
],
|
|
32
48
|
)
|