shotgun-sh 0.1.0.dev20__py3-none-any.whl → 0.1.0.dev23__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 shotgun-sh might be problematic. Click here for more details.
- shotgun/agents/agent_manager.py +100 -16
- shotgun/agents/common.py +142 -28
- shotgun/agents/conversation_history.py +56 -0
- shotgun/agents/conversation_manager.py +105 -0
- shotgun/agents/export.py +5 -2
- shotgun/agents/models.py +21 -7
- shotgun/agents/plan.py +2 -1
- shotgun/agents/research.py +2 -1
- shotgun/agents/specify.py +2 -1
- shotgun/agents/tasks.py +5 -2
- shotgun/agents/tools/codebase/codebase_shell.py +2 -2
- shotgun/agents/tools/codebase/directory_lister.py +1 -1
- shotgun/agents/tools/codebase/file_read.py +1 -1
- shotgun/agents/tools/codebase/query_graph.py +1 -1
- shotgun/agents/tools/codebase/retrieve_code.py +1 -1
- shotgun/agents/tools/file_management.py +67 -2
- shotgun/main.py +9 -1
- shotgun/prompts/agents/export.j2 +14 -11
- shotgun/prompts/agents/partials/codebase_understanding.j2 +9 -0
- shotgun/prompts/agents/partials/common_agent_system_prompt.j2 +6 -9
- shotgun/prompts/agents/plan.j2 +9 -13
- shotgun/prompts/agents/research.j2 +11 -14
- shotgun/prompts/agents/specify.j2 +9 -12
- shotgun/prompts/agents/state/codebase/codebase_graphs_available.j2 +5 -1
- shotgun/prompts/agents/state/system_state.j2 +27 -5
- shotgun/prompts/agents/tasks.j2 +12 -12
- shotgun/sdk/models.py +1 -1
- shotgun/sdk/services.py +0 -14
- shotgun/tui/app.py +9 -4
- shotgun/tui/screens/chat.py +92 -30
- shotgun/tui/screens/chat_screen/command_providers.py +1 -1
- shotgun/tui/screens/chat_screen/history.py +6 -0
- shotgun/tui/utils/__init__.py +5 -0
- shotgun/tui/utils/mode_progress.py +257 -0
- {shotgun_sh-0.1.0.dev20.dist-info → shotgun_sh-0.1.0.dev23.dist-info}/METADATA +8 -9
- {shotgun_sh-0.1.0.dev20.dist-info → shotgun_sh-0.1.0.dev23.dist-info}/RECORD +39 -56
- shotgun/agents/artifact_state.py +0 -58
- shotgun/agents/tools/artifact_management.py +0 -481
- shotgun/artifacts/__init__.py +0 -17
- shotgun/artifacts/exceptions.py +0 -89
- shotgun/artifacts/manager.py +0 -530
- shotgun/artifacts/models.py +0 -334
- shotgun/artifacts/service.py +0 -463
- shotgun/artifacts/templates/__init__.py +0 -10
- shotgun/artifacts/templates/loader.py +0 -252
- shotgun/artifacts/templates/models.py +0 -136
- shotgun/artifacts/templates/plan/delivery_and_release_plan.yaml +0 -66
- shotgun/artifacts/templates/research/market_research.yaml +0 -585
- shotgun/artifacts/templates/research/sdk_comparison.yaml +0 -257
- shotgun/artifacts/templates/specify/prd.yaml +0 -331
- shotgun/artifacts/templates/specify/product_spec.yaml +0 -301
- shotgun/artifacts/utils.py +0 -76
- shotgun/prompts/agents/partials/artifact_system.j2 +0 -32
- shotgun/prompts/agents/state/artifact_templates_available.j2 +0 -20
- shotgun/prompts/agents/state/existing_artifacts_available.j2 +0 -25
- shotgun/sdk/artifact_models.py +0 -186
- shotgun/sdk/artifacts.py +0 -448
- {shotgun_sh-0.1.0.dev20.dist-info → shotgun_sh-0.1.0.dev23.dist-info}/WHEEL +0 -0
- {shotgun_sh-0.1.0.dev20.dist-info → shotgun_sh-0.1.0.dev23.dist-info}/entry_points.txt +0 -0
- {shotgun_sh-0.1.0.dev20.dist-info → shotgun_sh-0.1.0.dev23.dist-info}/licenses/LICENSE +0 -0
shotgun/sdk/artifacts.py
DELETED
|
@@ -1,448 +0,0 @@
|
|
|
1
|
-
"""Artifact SDK for framework-agnostic business logic."""
|
|
2
|
-
|
|
3
|
-
from collections.abc import Callable
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Any
|
|
6
|
-
|
|
7
|
-
from shotgun.artifacts.exceptions import (
|
|
8
|
-
ArtifactAlreadyExistsError,
|
|
9
|
-
ArtifactError,
|
|
10
|
-
ArtifactNotFoundError,
|
|
11
|
-
SectionAlreadyExistsError,
|
|
12
|
-
SectionNotFoundError,
|
|
13
|
-
)
|
|
14
|
-
from shotgun.artifacts.models import AgentMode, ArtifactSection
|
|
15
|
-
from shotgun.artifacts.service import ArtifactService
|
|
16
|
-
from shotgun.artifacts.utils import generate_artifact_name
|
|
17
|
-
|
|
18
|
-
from .artifact_models import (
|
|
19
|
-
ArtifactCreateResult,
|
|
20
|
-
ArtifactDeleteResult,
|
|
21
|
-
ArtifactErrorResult,
|
|
22
|
-
ArtifactInfoResult,
|
|
23
|
-
ArtifactListResult,
|
|
24
|
-
SectionContentResult,
|
|
25
|
-
SectionCreateResult,
|
|
26
|
-
SectionDeleteResult,
|
|
27
|
-
SectionUpdateResult,
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class ArtifactSDK:
|
|
32
|
-
"""Framework-agnostic SDK for artifact operations.
|
|
33
|
-
|
|
34
|
-
This SDK provides business logic for artifact management that can be
|
|
35
|
-
used by both CLI and TUI implementations without framework dependencies.
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
def __init__(self, base_path: Path | None = None):
|
|
39
|
-
"""Initialize SDK with optional base path.
|
|
40
|
-
|
|
41
|
-
Args:
|
|
42
|
-
base_path: Optional custom base path for artifacts.
|
|
43
|
-
Defaults to .shotgun in current directory.
|
|
44
|
-
"""
|
|
45
|
-
self.service = ArtifactService(base_path)
|
|
46
|
-
|
|
47
|
-
# Artifact operations
|
|
48
|
-
|
|
49
|
-
def list_artifacts(
|
|
50
|
-
self, agent_mode: AgentMode | None = None
|
|
51
|
-
) -> ArtifactListResult | ArtifactErrorResult:
|
|
52
|
-
"""List all artifacts, optionally filtered by agent mode.
|
|
53
|
-
|
|
54
|
-
Args:
|
|
55
|
-
agent_mode: Optional agent mode filter
|
|
56
|
-
|
|
57
|
-
Returns:
|
|
58
|
-
ArtifactListResult containing list of artifacts or ArtifactErrorResult
|
|
59
|
-
"""
|
|
60
|
-
try:
|
|
61
|
-
artifacts = self.service.list_artifacts(agent_mode)
|
|
62
|
-
return ArtifactListResult(artifacts=artifacts, agent_mode=agent_mode)
|
|
63
|
-
except ArtifactError as e:
|
|
64
|
-
return ArtifactErrorResult(error_message=str(e), agent_mode=agent_mode)
|
|
65
|
-
|
|
66
|
-
def create_artifact(
|
|
67
|
-
self,
|
|
68
|
-
artifact_id: str,
|
|
69
|
-
agent_mode: AgentMode,
|
|
70
|
-
name: str,
|
|
71
|
-
template_id: str | None = None,
|
|
72
|
-
) -> ArtifactCreateResult | ArtifactErrorResult:
|
|
73
|
-
"""Create a new artifact.
|
|
74
|
-
|
|
75
|
-
Args:
|
|
76
|
-
artifact_id: Unique identifier for the artifact
|
|
77
|
-
agent_mode: Agent mode this artifact belongs to
|
|
78
|
-
name: Human-readable name for the artifact
|
|
79
|
-
template_id: Optional template ID to use for creating the artifact
|
|
80
|
-
|
|
81
|
-
Returns:
|
|
82
|
-
ArtifactCreateResult or ArtifactErrorResult
|
|
83
|
-
"""
|
|
84
|
-
try:
|
|
85
|
-
self.service.create_artifact(artifact_id, agent_mode, name, template_id)
|
|
86
|
-
return ArtifactCreateResult(
|
|
87
|
-
artifact_id=artifact_id,
|
|
88
|
-
agent_mode=agent_mode,
|
|
89
|
-
name=name,
|
|
90
|
-
)
|
|
91
|
-
except ArtifactAlreadyExistsError as e:
|
|
92
|
-
return ArtifactErrorResult(
|
|
93
|
-
error_message="Artifact already exists",
|
|
94
|
-
artifact_id=artifact_id,
|
|
95
|
-
agent_mode=agent_mode,
|
|
96
|
-
details=str(e),
|
|
97
|
-
)
|
|
98
|
-
except ArtifactError as e:
|
|
99
|
-
return ArtifactErrorResult(
|
|
100
|
-
error_message=str(e),
|
|
101
|
-
artifact_id=artifact_id,
|
|
102
|
-
agent_mode=agent_mode,
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
def delete_artifact(
|
|
106
|
-
self,
|
|
107
|
-
artifact_id: str,
|
|
108
|
-
agent_mode: AgentMode,
|
|
109
|
-
confirm_callback: Callable[[str, AgentMode], bool] | None = None,
|
|
110
|
-
) -> ArtifactDeleteResult | ArtifactErrorResult:
|
|
111
|
-
"""Delete an artifact with optional confirmation.
|
|
112
|
-
|
|
113
|
-
Args:
|
|
114
|
-
artifact_id: ID of the artifact to delete
|
|
115
|
-
agent_mode: Agent mode
|
|
116
|
-
confirm_callback: Optional callback for confirmation that receives
|
|
117
|
-
artifact_id and agent_mode and returns boolean.
|
|
118
|
-
|
|
119
|
-
Returns:
|
|
120
|
-
ArtifactDeleteResult or ArtifactErrorResult
|
|
121
|
-
"""
|
|
122
|
-
try:
|
|
123
|
-
# Handle confirmation callback if provided
|
|
124
|
-
if confirm_callback and not confirm_callback(artifact_id, agent_mode):
|
|
125
|
-
return ArtifactDeleteResult(
|
|
126
|
-
artifact_id=artifact_id,
|
|
127
|
-
agent_mode=agent_mode,
|
|
128
|
-
deleted=False,
|
|
129
|
-
cancelled=True,
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
self.service.delete_artifact(artifact_id, agent_mode)
|
|
133
|
-
return ArtifactDeleteResult(
|
|
134
|
-
artifact_id=artifact_id,
|
|
135
|
-
agent_mode=agent_mode,
|
|
136
|
-
deleted=True,
|
|
137
|
-
)
|
|
138
|
-
except ArtifactNotFoundError as e:
|
|
139
|
-
return ArtifactErrorResult(
|
|
140
|
-
error_message="Artifact not found",
|
|
141
|
-
artifact_id=artifact_id,
|
|
142
|
-
agent_mode=agent_mode,
|
|
143
|
-
details=str(e),
|
|
144
|
-
)
|
|
145
|
-
except ArtifactError as e:
|
|
146
|
-
return ArtifactErrorResult(
|
|
147
|
-
error_message=str(e),
|
|
148
|
-
artifact_id=artifact_id,
|
|
149
|
-
agent_mode=agent_mode,
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
def get_artifact_info(
|
|
153
|
-
self, artifact_id: str, agent_mode: AgentMode
|
|
154
|
-
) -> ArtifactInfoResult | ArtifactErrorResult:
|
|
155
|
-
"""Get detailed information about an artifact.
|
|
156
|
-
|
|
157
|
-
Args:
|
|
158
|
-
artifact_id: ID of the artifact to get info for
|
|
159
|
-
agent_mode: Agent mode
|
|
160
|
-
|
|
161
|
-
Returns:
|
|
162
|
-
ArtifactInfoResult or ArtifactErrorResult
|
|
163
|
-
"""
|
|
164
|
-
try:
|
|
165
|
-
artifact = self.service.get_artifact(artifact_id, agent_mode, "")
|
|
166
|
-
return ArtifactInfoResult(artifact=artifact)
|
|
167
|
-
except ArtifactNotFoundError as e:
|
|
168
|
-
return ArtifactErrorResult(
|
|
169
|
-
error_message="Artifact not found",
|
|
170
|
-
artifact_id=artifact_id,
|
|
171
|
-
agent_mode=agent_mode,
|
|
172
|
-
details=str(e),
|
|
173
|
-
)
|
|
174
|
-
except ArtifactError as e:
|
|
175
|
-
return ArtifactErrorResult(
|
|
176
|
-
error_message=str(e),
|
|
177
|
-
artifact_id=artifact_id,
|
|
178
|
-
agent_mode=agent_mode,
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
# Section operations
|
|
182
|
-
|
|
183
|
-
def create_section(
|
|
184
|
-
self,
|
|
185
|
-
artifact_id: str,
|
|
186
|
-
agent_mode: AgentMode,
|
|
187
|
-
section_number: int,
|
|
188
|
-
section_slug: str,
|
|
189
|
-
section_title: str,
|
|
190
|
-
content: str = "",
|
|
191
|
-
) -> SectionCreateResult | ArtifactErrorResult:
|
|
192
|
-
"""Create a new section in an artifact.
|
|
193
|
-
|
|
194
|
-
Args:
|
|
195
|
-
artifact_id: Artifact identifier
|
|
196
|
-
agent_mode: Agent mode
|
|
197
|
-
section_number: Section number
|
|
198
|
-
section_slug: Section slug
|
|
199
|
-
section_title: Section title
|
|
200
|
-
content: Section content
|
|
201
|
-
|
|
202
|
-
Returns:
|
|
203
|
-
SectionCreateResult or ArtifactErrorResult
|
|
204
|
-
"""
|
|
205
|
-
try:
|
|
206
|
-
section = ArtifactSection(
|
|
207
|
-
number=section_number,
|
|
208
|
-
slug=section_slug,
|
|
209
|
-
title=section_title,
|
|
210
|
-
content=content,
|
|
211
|
-
)
|
|
212
|
-
self.service.add_section(artifact_id, agent_mode, section)
|
|
213
|
-
return SectionCreateResult(
|
|
214
|
-
artifact_id=artifact_id,
|
|
215
|
-
agent_mode=agent_mode,
|
|
216
|
-
section_number=section_number,
|
|
217
|
-
section_title=section_title,
|
|
218
|
-
)
|
|
219
|
-
except (SectionAlreadyExistsError, ArtifactNotFoundError) as e:
|
|
220
|
-
return ArtifactErrorResult(
|
|
221
|
-
error_message=str(e),
|
|
222
|
-
artifact_id=artifact_id,
|
|
223
|
-
agent_mode=agent_mode,
|
|
224
|
-
section_number=section_number,
|
|
225
|
-
)
|
|
226
|
-
except ArtifactError as e:
|
|
227
|
-
return ArtifactErrorResult(
|
|
228
|
-
error_message=str(e),
|
|
229
|
-
artifact_id=artifact_id,
|
|
230
|
-
agent_mode=agent_mode,
|
|
231
|
-
section_number=section_number,
|
|
232
|
-
)
|
|
233
|
-
|
|
234
|
-
def update_section(
|
|
235
|
-
self,
|
|
236
|
-
artifact_id: str,
|
|
237
|
-
agent_mode: AgentMode,
|
|
238
|
-
section_number: int,
|
|
239
|
-
**kwargs: Any,
|
|
240
|
-
) -> SectionUpdateResult | ArtifactErrorResult:
|
|
241
|
-
"""Update a section in an artifact.
|
|
242
|
-
|
|
243
|
-
Args:
|
|
244
|
-
artifact_id: Artifact identifier
|
|
245
|
-
agent_mode: Agent mode
|
|
246
|
-
section_number: Section number to update
|
|
247
|
-
**kwargs: Fields to update
|
|
248
|
-
|
|
249
|
-
Returns:
|
|
250
|
-
SectionUpdateResult or ArtifactErrorResult
|
|
251
|
-
"""
|
|
252
|
-
try:
|
|
253
|
-
self.service.update_section(
|
|
254
|
-
artifact_id, agent_mode, section_number, **kwargs
|
|
255
|
-
)
|
|
256
|
-
return SectionUpdateResult(
|
|
257
|
-
artifact_id=artifact_id,
|
|
258
|
-
agent_mode=agent_mode,
|
|
259
|
-
section_number=section_number,
|
|
260
|
-
updated_fields=list(kwargs.keys()),
|
|
261
|
-
)
|
|
262
|
-
except (SectionNotFoundError, ArtifactNotFoundError) as e:
|
|
263
|
-
return ArtifactErrorResult(
|
|
264
|
-
error_message=str(e),
|
|
265
|
-
artifact_id=artifact_id,
|
|
266
|
-
agent_mode=agent_mode,
|
|
267
|
-
section_number=section_number,
|
|
268
|
-
)
|
|
269
|
-
except ArtifactError as e:
|
|
270
|
-
return ArtifactErrorResult(
|
|
271
|
-
error_message=str(e),
|
|
272
|
-
artifact_id=artifact_id,
|
|
273
|
-
agent_mode=agent_mode,
|
|
274
|
-
section_number=section_number,
|
|
275
|
-
)
|
|
276
|
-
|
|
277
|
-
def delete_section(
|
|
278
|
-
self,
|
|
279
|
-
artifact_id: str,
|
|
280
|
-
agent_mode: AgentMode,
|
|
281
|
-
section_number: int,
|
|
282
|
-
) -> SectionDeleteResult | ArtifactErrorResult:
|
|
283
|
-
"""Delete a section from an artifact.
|
|
284
|
-
|
|
285
|
-
Args:
|
|
286
|
-
artifact_id: Artifact identifier
|
|
287
|
-
agent_mode: Agent mode
|
|
288
|
-
section_number: Section number to delete
|
|
289
|
-
|
|
290
|
-
Returns:
|
|
291
|
-
SectionDeleteResult or ArtifactErrorResult
|
|
292
|
-
"""
|
|
293
|
-
try:
|
|
294
|
-
self.service.delete_section(artifact_id, agent_mode, section_number)
|
|
295
|
-
return SectionDeleteResult(
|
|
296
|
-
artifact_id=artifact_id,
|
|
297
|
-
agent_mode=agent_mode,
|
|
298
|
-
section_number=section_number,
|
|
299
|
-
)
|
|
300
|
-
except (SectionNotFoundError, ArtifactNotFoundError) as e:
|
|
301
|
-
return ArtifactErrorResult(
|
|
302
|
-
error_message=str(e),
|
|
303
|
-
artifact_id=artifact_id,
|
|
304
|
-
agent_mode=agent_mode,
|
|
305
|
-
section_number=section_number,
|
|
306
|
-
)
|
|
307
|
-
except ArtifactError as e:
|
|
308
|
-
return ArtifactErrorResult(
|
|
309
|
-
error_message=str(e),
|
|
310
|
-
artifact_id=artifact_id,
|
|
311
|
-
agent_mode=agent_mode,
|
|
312
|
-
section_number=section_number,
|
|
313
|
-
)
|
|
314
|
-
|
|
315
|
-
def get_section_content(
|
|
316
|
-
self,
|
|
317
|
-
artifact_id: str,
|
|
318
|
-
agent_mode: AgentMode,
|
|
319
|
-
section_number: int,
|
|
320
|
-
) -> SectionContentResult | ArtifactErrorResult:
|
|
321
|
-
"""Get the content of a section.
|
|
322
|
-
|
|
323
|
-
Args:
|
|
324
|
-
artifact_id: Artifact identifier
|
|
325
|
-
agent_mode: Agent mode
|
|
326
|
-
section_number: Section number
|
|
327
|
-
|
|
328
|
-
Returns:
|
|
329
|
-
SectionContentResult or ArtifactErrorResult
|
|
330
|
-
"""
|
|
331
|
-
try:
|
|
332
|
-
content = self.service.get_section_content(
|
|
333
|
-
artifact_id, agent_mode, section_number
|
|
334
|
-
)
|
|
335
|
-
return SectionContentResult(
|
|
336
|
-
artifact_id=artifact_id,
|
|
337
|
-
agent_mode=agent_mode,
|
|
338
|
-
section_number=section_number,
|
|
339
|
-
content=content,
|
|
340
|
-
)
|
|
341
|
-
except (SectionNotFoundError, ArtifactNotFoundError) as e:
|
|
342
|
-
return ArtifactErrorResult(
|
|
343
|
-
error_message=str(e),
|
|
344
|
-
artifact_id=artifact_id,
|
|
345
|
-
agent_mode=agent_mode,
|
|
346
|
-
section_number=section_number,
|
|
347
|
-
)
|
|
348
|
-
except ArtifactError as e:
|
|
349
|
-
return ArtifactErrorResult(
|
|
350
|
-
error_message=str(e),
|
|
351
|
-
artifact_id=artifact_id,
|
|
352
|
-
agent_mode=agent_mode,
|
|
353
|
-
section_number=section_number,
|
|
354
|
-
)
|
|
355
|
-
|
|
356
|
-
# Template operations
|
|
357
|
-
|
|
358
|
-
def list_templates(
|
|
359
|
-
self, agent_mode: AgentMode | None = None
|
|
360
|
-
) -> list[Any] | ArtifactErrorResult:
|
|
361
|
-
"""List available artifact templates.
|
|
362
|
-
|
|
363
|
-
Args:
|
|
364
|
-
agent_mode: Optional agent mode filter
|
|
365
|
-
|
|
366
|
-
Returns:
|
|
367
|
-
List of template summaries or ArtifactErrorResult
|
|
368
|
-
"""
|
|
369
|
-
try:
|
|
370
|
-
return self.service.list_templates(agent_mode)
|
|
371
|
-
except Exception as e:
|
|
372
|
-
return ArtifactErrorResult(
|
|
373
|
-
error_message=f"Failed to list templates: {str(e)}",
|
|
374
|
-
agent_mode=agent_mode,
|
|
375
|
-
)
|
|
376
|
-
|
|
377
|
-
# Convenience methods
|
|
378
|
-
|
|
379
|
-
def ensure_artifact_exists(
|
|
380
|
-
self,
|
|
381
|
-
artifact_id: str,
|
|
382
|
-
agent_mode: AgentMode,
|
|
383
|
-
name: str | None = None,
|
|
384
|
-
) -> ArtifactCreateResult | ArtifactInfoResult | ArtifactErrorResult:
|
|
385
|
-
"""Ensure an artifact exists, creating it if necessary.
|
|
386
|
-
|
|
387
|
-
Args:
|
|
388
|
-
artifact_id: Artifact identifier
|
|
389
|
-
agent_mode: Agent mode
|
|
390
|
-
name: Optional name (defaults to formatted artifact_id)
|
|
391
|
-
|
|
392
|
-
Returns:
|
|
393
|
-
ArtifactCreateResult if created, ArtifactInfoResult if already existed, ArtifactErrorResult on error
|
|
394
|
-
"""
|
|
395
|
-
if name is None:
|
|
396
|
-
name = generate_artifact_name(artifact_id)
|
|
397
|
-
|
|
398
|
-
# Try to get existing artifact
|
|
399
|
-
info_result = self.get_artifact_info(artifact_id, agent_mode)
|
|
400
|
-
if isinstance(info_result, ArtifactInfoResult):
|
|
401
|
-
return info_result
|
|
402
|
-
|
|
403
|
-
# Create new artifact
|
|
404
|
-
create_result = self.create_artifact(artifact_id, agent_mode, name)
|
|
405
|
-
return create_result
|
|
406
|
-
|
|
407
|
-
def ensure_section_exists(
|
|
408
|
-
self,
|
|
409
|
-
artifact_id: str,
|
|
410
|
-
agent_mode: AgentMode,
|
|
411
|
-
section_number: int,
|
|
412
|
-
section_slug: str,
|
|
413
|
-
section_title: str,
|
|
414
|
-
initial_content: str = "",
|
|
415
|
-
) -> SectionCreateResult | SectionContentResult | ArtifactErrorResult:
|
|
416
|
-
"""Ensure a section exists, creating it if necessary.
|
|
417
|
-
|
|
418
|
-
Args:
|
|
419
|
-
artifact_id: Artifact identifier
|
|
420
|
-
agent_mode: Agent mode
|
|
421
|
-
section_number: Section number
|
|
422
|
-
section_slug: Section slug
|
|
423
|
-
section_title: Section title
|
|
424
|
-
initial_content: Initial content for new sections
|
|
425
|
-
|
|
426
|
-
Returns:
|
|
427
|
-
SectionCreateResult if created, SectionContentResult if already existed, ArtifactErrorResult on error
|
|
428
|
-
"""
|
|
429
|
-
# Try to get existing section
|
|
430
|
-
content_result = self.get_section_content(
|
|
431
|
-
artifact_id, agent_mode, section_number
|
|
432
|
-
)
|
|
433
|
-
if isinstance(content_result, SectionContentResult):
|
|
434
|
-
return content_result
|
|
435
|
-
|
|
436
|
-
# Ensure artifact exists first
|
|
437
|
-
self.ensure_artifact_exists(artifact_id, agent_mode)
|
|
438
|
-
|
|
439
|
-
# Create new section
|
|
440
|
-
create_result = self.create_section(
|
|
441
|
-
artifact_id,
|
|
442
|
-
agent_mode,
|
|
443
|
-
section_number,
|
|
444
|
-
section_slug,
|
|
445
|
-
section_title,
|
|
446
|
-
initial_content,
|
|
447
|
-
)
|
|
448
|
-
return create_result
|
|
File without changes
|
|
File without changes
|
|
File without changes
|