@lota-sdk/shared 0.1.23 → 0.1.24

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lota-sdk/shared",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -0,0 +1,15 @@
1
+ export const SILENT_EXECUTION_VISIBILITY = 'silent' as const
2
+
3
+ export const PROJECT_PLAN_ROUTING_PROMPT = `<project-plan-routing>
4
+ - Use createExecutionPlan for small inline work inside the current workstream.
5
+ - Use createProjectWithPlan when the work needs a dedicated project workstream, should stay visible in the sidebar or board, or needs 3 or more meaningful execution nodes.
6
+ - If createExecutionPlan rejects a larger draft, immediately retry with createProjectWithPlan instead of forcing the plan inline.
7
+ </project-plan-routing>`
8
+
9
+ export const EXECUTION_PLAN_SELF_START_PROMPT = `<execution-plan-self-start>
10
+ - When you create an execution plan with createExecutionPlan or createProjectWithPlan and the first node is assigned to you, begin executing that node immediately in the same turn. Do not wait for the user to ask.
11
+ - After completing a node, submit the result and check whether the next ready node is also yours. If so, continue working.
12
+ - When the user's message relates to an active plan where you own ready nodes, inspect the plan state and proactively work on your ready nodes.
13
+ - When you own a blocked or failed node, tell the user what is blocked and what resolution is needed.
14
+ - Briefly acknowledge what you are doing before you start work on a plan node.
15
+ </execution-plan-self-start>`
package/src/index.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  export * from './constants/attachments'
2
+ export * from './constants/execution-plan'
2
3
  export * from './constants/workstream'
3
4
  export * from './runtime/agent-types'
4
5
  export * from './runtime/chat-message-metadata'
5
6
  export * from './runtime/execution-plan-result'
7
+ export * from './schemas/agent-plan-draft'
6
8
  export * from './schemas/chat-api'
7
9
  export * from './schemas/chat-message'
8
10
  export * from './schemas/common'
@@ -14,6 +16,7 @@ export * from './schemas/execution-plan'
14
16
  export * from './schemas/graph-designer'
15
17
  export * from './schemas/organization'
16
18
  export * from './schemas/organization-api'
19
+ export * from './schemas/plan-board'
17
20
  export * from './schemas/playbook'
18
21
  export * from './schemas/plugin-coordination'
19
22
  export * from './schemas/queue-job'
@@ -0,0 +1,232 @@
1
+ import { z } from 'zod'
2
+
3
+ import { SILENT_EXECUTION_VISIBILITY } from '../constants/execution-plan'
4
+ import type { PlanArtifactSpec, PlanCompletionCheck, PlanDraft, PlanNodeOwner, PlanNodeType } from './execution-plan'
5
+ import {
6
+ ExecutionModeSchema,
7
+ PlanArtifactSpecSchema,
8
+ PlanCompletionCheckSchema,
9
+ PlanCompletionCheckTypeSchema,
10
+ PlanContextPolicySchema,
11
+ PlanEdgeSpecSchema,
12
+ PlanExecutionVisibilitySchema,
13
+ PlanNodeOwnerSchema,
14
+ PlanNodeTypeSchema,
15
+ PlanRetryPolicySchema,
16
+ PlanToolPolicySchema,
17
+ } from './execution-plan'
18
+
19
+ const STRUCTURAL_NODE_TYPES = new Set<PlanNodeType>(['switch', 'join', 'deliberation-fork'])
20
+
21
+ const agentPlanOwnerStringSchema = z.string().trim().min(1).max(200)
22
+
23
+ const AgentPlanDeliverableDraftSchema = z.union([z.string().trim().min(1).max(1000), PlanArtifactSpecSchema])
24
+
25
+ const SimplifiedCompletionCheckSchema = z.object({
26
+ type: PlanCompletionCheckTypeSchema,
27
+ description: z.string().trim().min(1).max(1000),
28
+ blocking: z.boolean().optional(),
29
+ config: z.record(z.string(), z.unknown()).optional(),
30
+ })
31
+
32
+ const AgentPlanCompletionCheckDraftSchema = z.union([PlanCompletionCheckSchema, SimplifiedCompletionCheckSchema])
33
+
34
+ export const AgentPlanNodeDraftSchema = z.object({
35
+ id: z.string().trim().min(1).max(200),
36
+ type: PlanNodeTypeSchema,
37
+ label: z.string().trim().min(1).max(300),
38
+ owner: z.union([PlanNodeOwnerSchema, agentPlanOwnerStringSchema]),
39
+ objective: z.string().trim().min(1).max(2000),
40
+ instructions: z.string().trim().min(1).max(4000),
41
+ successCriteria: z.array(z.string().trim().min(1).max(1000)).min(1),
42
+ deliverables: z.array(AgentPlanDeliverableDraftSchema).min(1).optional(),
43
+ completionChecks: z.array(AgentPlanCompletionCheckDraftSchema).min(1).optional(),
44
+ })
45
+ export type AgentPlanNodeDraft = z.infer<typeof AgentPlanNodeDraftSchema>
46
+
47
+ export const AgentPlanEdgeDraftSchema = z.object({
48
+ id: z.string().trim().min(1).max(200),
49
+ source: z.string().trim().min(1).max(200),
50
+ target: z.string().trim().min(1).max(200),
51
+ when: z.string().trim().min(1).max(500).optional(),
52
+ })
53
+ export type AgentPlanEdgeDraft = z.infer<typeof AgentPlanEdgeDraftSchema>
54
+
55
+ export const AgentPlanDraftSchema = z.object({
56
+ title: z.string().trim().min(1).max(200),
57
+ objective: z.string().trim().min(1).max(2000),
58
+ nodes: z.array(AgentPlanNodeDraftSchema).min(1).max(32),
59
+ edges: z.array(AgentPlanEdgeDraftSchema).default([]),
60
+ entryNodeIds: z.array(z.string().trim().min(1).max(200)).min(1).optional(),
61
+ executionMode: ExecutionModeSchema.optional(),
62
+ })
63
+ export type AgentPlanDraft = z.infer<typeof AgentPlanDraftSchema>
64
+
65
+ export function normalizeOwner(owner: string | PlanNodeOwner): PlanNodeOwner {
66
+ if (typeof owner !== 'string') {
67
+ return owner
68
+ }
69
+
70
+ const normalized = owner.trim()
71
+ if (normalized.toLowerCase() === 'user') {
72
+ return { executorType: 'user', ref: 'user' }
73
+ }
74
+
75
+ return { executorType: 'agent', ref: normalized }
76
+ }
77
+
78
+ function toDeliverableName(value: string, fallback: string): string {
79
+ const normalized = value
80
+ .trim()
81
+ .toLowerCase()
82
+ .replace(/[^a-z0-9]+/g, '-')
83
+ .replace(/^-+|-+$/g, '')
84
+
85
+ return normalized.length > 0 ? normalized.slice(0, 200) : fallback
86
+ }
87
+
88
+ function isStructuralNodeType(type: PlanNodeType): boolean {
89
+ return STRUCTURAL_NODE_TYPES.has(type)
90
+ }
91
+
92
+ function buildDefaultDeliverables(node: AgentPlanNodeDraft): PlanArtifactSpec[] {
93
+ if (isStructuralNodeType(node.type)) {
94
+ return []
95
+ }
96
+
97
+ if (node.type === 'human-approval') {
98
+ return [
99
+ { name: `${node.id}-approval`, kind: 'json', required: false, description: `Approval record from ${node.label}` },
100
+ ]
101
+ }
102
+
103
+ if (node.type === 'human-input' || node.type === 'human-review-edit' || node.type === 'human-decision') {
104
+ return [{ name: `${node.id}-response`, kind: 'json', required: false, description: `Response from ${node.label}` }]
105
+ }
106
+
107
+ return [{ name: `${node.id}-output`, kind: 'markdown', required: false, description: `Output from ${node.label}` }]
108
+ }
109
+
110
+ function expandDeliverables(node: AgentPlanNodeDraft): PlanArtifactSpec[] {
111
+ const deliverables = node.deliverables
112
+ if (!deliverables || deliverables.length === 0) {
113
+ return buildDefaultDeliverables(node)
114
+ }
115
+
116
+ return deliverables.map((deliverable, index) => {
117
+ if (typeof deliverable !== 'string') {
118
+ return deliverable
119
+ }
120
+
121
+ const description = deliverable.trim()
122
+ const fallbackName = `${node.id}-output-${index + 1}`
123
+ return { name: toDeliverableName(description, fallbackName), kind: 'markdown', required: false, description }
124
+ })
125
+ }
126
+
127
+ function buildDefaultCompletionChecks(
128
+ node: AgentPlanNodeDraft,
129
+ deliverables: PlanArtifactSpec[],
130
+ ): PlanCompletionCheck[] {
131
+ if (isStructuralNodeType(node.type)) {
132
+ return []
133
+ }
134
+
135
+ if (node.type === 'human-approval') {
136
+ return [
137
+ {
138
+ type: 'human-approval',
139
+ config: { approvedField: 'approved' },
140
+ blocking: true,
141
+ description: 'Approval recorded',
142
+ },
143
+ ]
144
+ }
145
+
146
+ if (node.type === 'human-input' || node.type === 'human-review-edit') {
147
+ return [
148
+ {
149
+ type: 'assertion',
150
+ config: { truthyPaths: ['responseText'] },
151
+ blocking: true,
152
+ description: 'Response captured',
153
+ },
154
+ ]
155
+ }
156
+
157
+ if (node.type === 'human-decision') {
158
+ return [
159
+ { type: 'assertion', config: { truthyPaths: ['approved'] }, blocking: true, description: 'Decision captured' },
160
+ ]
161
+ }
162
+
163
+ const primaryDeliverable = deliverables.at(0)
164
+ return [
165
+ {
166
+ type: 'tool-check',
167
+ config: primaryDeliverable ? { artifact: primaryDeliverable.name, mode: 'artifact-present' } : {},
168
+ blocking: true,
169
+ description: primaryDeliverable ? `Artifact "${primaryDeliverable.name}" exists` : 'Required output is present',
170
+ },
171
+ ]
172
+ }
173
+
174
+ function expandCompletionChecks(node: AgentPlanNodeDraft, deliverables: PlanArtifactSpec[]): PlanCompletionCheck[] {
175
+ const completionChecks = node.completionChecks
176
+ if (!completionChecks || completionChecks.length === 0) {
177
+ return buildDefaultCompletionChecks(node, deliverables)
178
+ }
179
+
180
+ const primaryDeliverable = deliverables.at(0)
181
+ return completionChecks.map((check) => {
182
+ const blocking = check.blocking ?? true
183
+ const config =
184
+ check.config ??
185
+ (check.type === 'human-approval'
186
+ ? { approvedField: 'approved' }
187
+ : check.type === 'tool-check' && primaryDeliverable
188
+ ? { artifact: primaryDeliverable.name, mode: 'artifact-present' }
189
+ : {})
190
+
191
+ return { type: check.type, description: check.description, blocking, config }
192
+ })
193
+ }
194
+
195
+ export function expandAgentPlanDraft(draft: AgentPlanDraft): PlanDraft {
196
+ const expandedNodes = draft.nodes.map((node) => {
197
+ const deliverables = expandDeliverables(node)
198
+ const completionChecks = expandCompletionChecks(node, deliverables)
199
+
200
+ return {
201
+ id: node.id,
202
+ type: node.type,
203
+ label: node.label,
204
+ owner: normalizeOwner(node.owner),
205
+ objective: node.objective,
206
+ instructions: node.instructions,
207
+ deliverables,
208
+ successCriteria: [...node.successCriteria],
209
+ completionChecks,
210
+ retryPolicy: PlanRetryPolicySchema.parse({ maxAttempts: 0, retryOn: [] }),
211
+ failurePolicy: [],
212
+ toolPolicy: PlanToolPolicySchema.parse({ allow: [], deny: [] }),
213
+ contextPolicy: PlanContextPolicySchema.parse({
214
+ retrievalScopes: [],
215
+ attachmentPolicy: 'referenced-only',
216
+ webPolicy: 'allowed',
217
+ }),
218
+ executionVisibility: PlanExecutionVisibilitySchema.parse('auto'),
219
+ }
220
+ })
221
+
222
+ return {
223
+ title: draft.title,
224
+ objective: draft.objective,
225
+ schemas: {},
226
+ defaultExecutionVisibility: SILENT_EXECUTION_VISIBILITY,
227
+ nodes: expandedNodes,
228
+ edges: draft.edges.map((edge) => PlanEdgeSpecSchema.parse({ ...edge, map: {} })),
229
+ entryNodeIds: draft.entryNodeIds ? [...draft.entryNodeIds] : undefined,
230
+ executionMode: draft.executionMode,
231
+ }
232
+ }
@@ -549,7 +549,7 @@ export const PlanNodeSpecSchema = z
549
549
  outputSchemaRef: z.string().trim().min(1).max(200).optional(),
550
550
  deliverables: z.array(PlanArtifactSpecSchema).default([]),
551
551
  successCriteria: z.array(z.string().trim().min(1).max(1000)).default([]),
552
- completionChecks: z.array(PlanCompletionCheckSchema).default([]),
552
+ completionChecks: z.array(PlanCompletionCheckSchema).min(1),
553
553
  retryPolicy: PlanRetryPolicySchema.default({ maxAttempts: 0, retryOn: [] }),
554
554
  failurePolicy: z.array(PlanFailureRuleSchema).default([]),
555
555
  timeoutMs: z.number().int().positive().optional(),
@@ -0,0 +1,129 @@
1
+ import { z } from 'zod'
2
+
3
+ export const PlanNodeCardSchema = z
4
+ .object({
5
+ nodeId: z.string().trim().min(1),
6
+ label: z.string().trim().min(1),
7
+ objective: z.string(),
8
+ status: z.string().trim().min(1),
9
+ ownerType: z.string().trim().min(1),
10
+ ownerRef: z.string().trim().min(1),
11
+ planRunId: z.string().trim().min(1),
12
+ planTitle: z.string().trim().min(1),
13
+ workstreamId: z.string().trim().min(1),
14
+ workstreamTitle: z.string().trim().min(1),
15
+ nodeType: z.string().trim().min(1),
16
+ artifactCount: z.number().int().nonnegative(),
17
+ hasApproval: z.boolean(),
18
+ approvalId: z.string().trim().min(1).nullable(),
19
+ approvalStatus: z.string().trim().min(1).nullable(),
20
+ blockedReason: z.string().nullable(),
21
+ latestNotes: z.string().nullable(),
22
+ startedAt: z.iso.datetime().nullable(),
23
+ completedAt: z.iso.datetime().nullable(),
24
+ readyAt: z.iso.datetime().nullable(),
25
+ })
26
+ .strict()
27
+ export type PlanNodeCard = z.infer<typeof PlanNodeCardSchema>
28
+
29
+ export const PlanBoardColumnSchema = z
30
+ .object({ status: z.string().trim().min(1), label: z.string().trim().min(1), nodes: z.array(PlanNodeCardSchema) })
31
+ .strict()
32
+ export type PlanBoardColumn = z.infer<typeof PlanBoardColumnSchema>
33
+
34
+ export const PlanBoardResponseSchema = z
35
+ .object({
36
+ columns: z.array(PlanBoardColumnSchema),
37
+ summary: z
38
+ .object({
39
+ totalNodes: z.number().int().nonnegative(),
40
+ completedNodes: z.number().int().nonnegative(),
41
+ activePlanCount: z.number().int().nonnegative(),
42
+ pendingApprovalCount: z.number().int().nonnegative(),
43
+ })
44
+ .strict(),
45
+ })
46
+ .strict()
47
+ export type PlanBoardResponse = z.infer<typeof PlanBoardResponseSchema>
48
+
49
+ export const PlanViewNodeSchema = PlanNodeCardSchema.extend({
50
+ deliverableNames: z.array(z.string()),
51
+ upstreamNodeIds: z.array(z.string()),
52
+ downstreamNodeIds: z.array(z.string()),
53
+ }).strict()
54
+ export type PlanViewNode = z.infer<typeof PlanViewNodeSchema>
55
+
56
+ export const PlanViewResponseSchema = z
57
+ .object({
58
+ planRunId: z.string().trim().min(1),
59
+ title: z.string().trim().min(1),
60
+ objective: z.string().trim().min(1),
61
+ status: z.string().trim().min(1),
62
+ leadAgentId: z.string().trim().min(1),
63
+ progress: z.object({ completed: z.number().int().nonnegative(), total: z.number().int().nonnegative() }).strict(),
64
+ nodes: z.array(PlanViewNodeSchema),
65
+ edges: z.array(z.object({ from: z.string().trim().min(1), to: z.string().trim().min(1) }).strict()),
66
+ })
67
+ .strict()
68
+ export type PlanViewResponse = z.infer<typeof PlanViewResponseSchema>
69
+
70
+ export const MyTasksResponseSchema = z
71
+ .object({ tasks: z.array(PlanNodeCardSchema), pendingApprovalCount: z.number().int().nonnegative() })
72
+ .strict()
73
+ export type MyTasksResponse = z.infer<typeof MyTasksResponseSchema>
74
+
75
+ export const AgentProjectEntrySchema = z
76
+ .object({
77
+ workstreamId: z.string().trim().min(1),
78
+ workstreamTitle: z.string().trim().min(1),
79
+ planRunId: z.string().trim().min(1),
80
+ planTitle: z.string().trim().min(1),
81
+ status: z.string().trim().min(1),
82
+ })
83
+ .strict()
84
+ export type AgentProjectEntry = z.infer<typeof AgentProjectEntrySchema>
85
+
86
+ export const AgentActivityCountsSchema = z
87
+ .object({
88
+ running: z.number().int().nonnegative(),
89
+ ready: z.number().int().nonnegative(),
90
+ pending: z.number().int().nonnegative(),
91
+ awaitingHuman: z.number().int().nonnegative(),
92
+ blocked: z.number().int().nonnegative(),
93
+ completed: z.number().int().nonnegative(),
94
+ failed: z.number().int().nonnegative(),
95
+ })
96
+ .strict()
97
+ export type AgentActivityCounts = z.infer<typeof AgentActivityCountsSchema>
98
+
99
+ export const UserActivitySummarySchema = z
100
+ .object({
101
+ taskCount: z.number().int().nonnegative(),
102
+ pendingApprovalCount: z.number().int().nonnegative(),
103
+ awaitingHumanCount: z.number().int().nonnegative(),
104
+ lastActiveAt: z.iso.datetime().nullable(),
105
+ })
106
+ .strict()
107
+ export type UserActivitySummary = z.infer<typeof UserActivitySummarySchema>
108
+
109
+ export const AgentActivityEntrySchema = z
110
+ .object({
111
+ agentId: z.string().trim().min(1),
112
+ counts: AgentActivityCountsSchema,
113
+ tasks: z.array(PlanNodeCardSchema),
114
+ projects: z.array(AgentProjectEntrySchema),
115
+ isLeadingActivePlan: z.boolean(),
116
+ isRunning: z.boolean(),
117
+ lastActiveAt: z.iso.datetime().nullable(),
118
+ })
119
+ .strict()
120
+ export type AgentActivityEntry = z.infer<typeof AgentActivityEntrySchema>
121
+
122
+ export const AgentActivityResponseSchema = z
123
+ .object({
124
+ agents: z.array(AgentActivityEntrySchema),
125
+ userActivity: UserActivitySummarySchema,
126
+ totalActivePlans: z.number().int().nonnegative(),
127
+ })
128
+ .strict()
129
+ export type AgentActivityResponse = z.infer<typeof AgentActivityResponseSchema>
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod'
2
2
 
3
+ import { AgentPlanDraftSchema } from './agent-plan-draft'
3
4
  import { baseChatMessageSchema } from './chat-api'
4
5
  import type { AnyChatMessage } from './chat-message'
5
6
  import {
@@ -13,6 +14,7 @@ export const USER_QUESTIONS_TOOL_NAME = 'userQuestions' as const
13
14
  export const CONSULT_SPECIALIST_TOOL_NAME = 'consultSpecialist' as const
14
15
  export const CONSULT_TEAM_TOOL_NAME = 'consultTeam' as const
15
16
  export const CREATE_EXECUTION_PLAN_TOOL_NAME = 'createExecutionPlan' as const
17
+ export const CREATE_PROJECT_WITH_PLAN_TOOL_NAME = 'createProjectWithPlan' as const
16
18
  export const REPLACE_EXECUTION_PLAN_TOOL_NAME = 'replaceExecutionPlan' as const
17
19
  export const SUBMIT_EXECUTION_NODE_RESULT_TOOL_NAME = 'submitExecutionNodeResult' as const
18
20
  export const SUBMIT_PLAN_TURN_RESULT_TOOL_NAME = 'submitPlanTurnResult' as const
@@ -60,7 +62,17 @@ const ExecutionPlanToolActionSchema = z.enum([
60
62
  'none',
61
63
  ])
62
64
 
63
- export const CreateExecutionPlanArgsSchema = PlanDraftSchema
65
+ export const CreateExecutionPlanArgsSchema = PlanDraftSchema.extend({
66
+ targetWorkstreamId: z.string().trim().min(1).optional(),
67
+ }).strict()
68
+
69
+ export const CreateProjectWithPlanArgsSchema = AgentPlanDraftSchema.extend({
70
+ projectTitle: z.string().trim().min(1).max(200).optional(),
71
+ targetWorkstreamId: z.string().trim().min(1).optional(),
72
+ }).refine((value) => Boolean(value.projectTitle) !== Boolean(value.targetWorkstreamId), {
73
+ message: 'Provide exactly one of projectTitle or targetWorkstreamId.',
74
+ path: ['projectTitle'],
75
+ })
64
76
 
65
77
  export const ReplaceExecutionPlanArgsSchema = PlanDraftSchema.extend({
66
78
  runId: z.string().trim().min(1),
@@ -121,6 +133,12 @@ export const ExecutionPlanToolResultDataSchema = z
121
133
  })
122
134
  .strict()
123
135
 
136
+ export const CreateProjectWithPlanResultDataSchema = ExecutionPlanToolResultDataSchema.extend({
137
+ workstreamId: z.string().trim().min(1),
138
+ workstreamTitle: z.string().trim().min(1),
139
+ createdWorkstream: z.boolean(),
140
+ }).strict()
141
+
124
142
  export const ConsultTeamResultDataSchema = z.object({ responses: z.array(ConsultTeamResponseSchema) }).strict()
125
143
 
126
144
  export type UserQuestionItem = z.infer<typeof UserQuestionItemSchema>
@@ -133,6 +151,7 @@ export type ConsultTeamResponseData = Omit<z.infer<typeof ConsultTeamResponseSch
133
151
  }
134
152
  export type ConsultTeamResultData = { responses: ConsultTeamResponseData[] }
135
153
  export type CreateExecutionPlanArgs = z.infer<typeof CreateExecutionPlanArgsSchema>
154
+ export type CreateProjectWithPlanArgs = z.infer<typeof CreateProjectWithPlanArgsSchema>
136
155
  export type ReplaceExecutionPlanArgs = z.infer<typeof ReplaceExecutionPlanArgsSchema>
137
156
  export type SubmitExecutionNodeResultArgs = z.infer<typeof SubmitExecutionNodeResultArgsSchema>
138
157
  export type SubmitPlanTurnResultArgs = z.infer<typeof SubmitPlanTurnResultArgsSchema>
@@ -142,11 +161,13 @@ export type ListExecutionPlansToolResultData = z.infer<typeof ListExecutionPlans
142
161
  export type GetActiveExecutionPlanArgs = z.infer<typeof GetActiveExecutionPlanArgsSchema>
143
162
  export type ResumeExecutionPlanRunArgs = z.infer<typeof ResumeExecutionPlanRunArgsSchema>
144
163
  export type ExecutionPlanToolResultData = z.infer<typeof ExecutionPlanToolResultDataSchema>
164
+ export type CreateProjectWithPlanResultData = z.infer<typeof CreateProjectWithPlanResultDataSchema>
145
165
  export type CoreChatTools = {
146
166
  userQuestions: { input: UserQuestionsArgs; output: unknown }
147
167
  consultSpecialist: { input: ConsultSpecialistArgs; output: ConsultSpecialistResultData }
148
168
  consultTeam: { input: ConsultTeamArgs; output: ConsultTeamResultData }
149
169
  createExecutionPlan: { input: CreateExecutionPlanArgs; output: ExecutionPlanToolResultData }
170
+ createProjectWithPlan: { input: CreateProjectWithPlanArgs; output: CreateProjectWithPlanResultData }
150
171
  replaceExecutionPlan: { input: ReplaceExecutionPlanArgs; output: ExecutionPlanToolResultData }
151
172
  submitExecutionNodeResult: { input: SubmitExecutionNodeResultArgs; output: ExecutionPlanToolResultData }
152
173
  submitPlanTurnResult: { input: SubmitPlanTurnResultArgs; output: ExecutionPlanToolResultData }