plugin-agent-orchestrator 1.0.16 → 1.0.18

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.
Files changed (92) hide show
  1. package/dist/client/AgentRunsTab.d.ts +2 -0
  2. package/dist/client/HarnessProfilesTab.d.ts +2 -0
  3. package/dist/client/index.js +1 -1
  4. package/dist/client/skill-hub/components/LoopSettings.d.ts +2 -0
  5. package/dist/client/skill-hub/index.d.ts +2 -1
  6. package/dist/client/skill-hub/tools/InteractionSchemasProvider.d.ts +1 -14
  7. package/dist/client/skill-hub/tools/loopTemplates.d.ts +22 -0
  8. package/dist/client/skill-hub/tools/registerSkillLoopCards.d.ts +1 -0
  9. package/dist/client/tools/PlanApprovalCard.d.ts +3 -0
  10. package/dist/client/tools/registerOrchestratorCards.d.ts +1 -0
  11. package/dist/externalVersion.js +6 -6
  12. package/dist/server/collections/agent-harness-profiles.d.ts +2 -0
  13. package/dist/server/collections/agent-harness-profiles.js +89 -0
  14. package/dist/server/collections/agent-loop-events.d.ts +2 -0
  15. package/dist/server/collections/agent-loop-events.js +101 -0
  16. package/dist/server/collections/agent-loop-runs.d.ts +2 -0
  17. package/dist/server/collections/agent-loop-runs.js +188 -0
  18. package/dist/server/collections/agent-loop-steps.d.ts +2 -0
  19. package/dist/server/collections/agent-loop-steps.js +174 -0
  20. package/dist/server/collections/orchestrator-config.js +7 -0
  21. package/dist/server/collections/skill-executions.js +12 -0
  22. package/dist/server/collections/skill-loop-configs.d.ts +3 -0
  23. package/dist/server/collections/skill-loop-configs.js +94 -0
  24. package/dist/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.d.ts +7 -0
  25. package/dist/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.js +55 -0
  26. package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.d.ts +12 -0
  27. package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.js +162 -0
  28. package/dist/server/plugin.d.ts +2 -0
  29. package/dist/server/plugin.js +13 -0
  30. package/dist/server/resources/agent-loop.d.ts +3 -0
  31. package/dist/server/resources/agent-loop.js +205 -0
  32. package/dist/server/services/AgentHarness.d.ts +42 -0
  33. package/dist/server/services/AgentHarness.js +565 -0
  34. package/dist/server/services/AgentLoopController.d.ts +205 -0
  35. package/dist/server/services/AgentLoopController.js +940 -0
  36. package/dist/server/services/AgentLoopRepository.d.ts +20 -0
  37. package/dist/server/services/AgentLoopRepository.js +210 -0
  38. package/dist/server/services/AgentLoopService.d.ts +149 -0
  39. package/dist/server/services/AgentLoopService.js +133 -0
  40. package/dist/server/services/AgentPlanValidator.d.ts +4 -0
  41. package/dist/server/services/AgentPlanValidator.js +99 -0
  42. package/dist/server/services/AgentPlannerService.d.ts +8 -0
  43. package/dist/server/services/AgentPlannerService.js +119 -0
  44. package/dist/server/services/AgentRegistryService.d.ts +13 -0
  45. package/dist/server/services/AgentRegistryService.js +178 -0
  46. package/dist/server/services/ExecutionSpanService.d.ts +2 -0
  47. package/dist/server/skill-hub/plugin.d.ts +3 -0
  48. package/dist/server/skill-hub/plugin.js +137 -54
  49. package/dist/server/tools/agent-loop.d.ts +235 -0
  50. package/dist/server/tools/agent-loop.js +406 -0
  51. package/dist/server/tools/delegate-task.js +37 -350
  52. package/dist/server/tools/orchestrator-plan.d.ts +205 -0
  53. package/dist/server/tools/orchestrator-plan.js +291 -0
  54. package/dist/server/tools/skill-execute.js +2 -0
  55. package/package.json +2 -2
  56. package/src/client/AgentRunsTab.tsx +764 -0
  57. package/src/client/HarnessProfilesTab.tsx +247 -0
  58. package/src/client/OrchestratorSettings.tsx +40 -2
  59. package/src/client/RulesTab.tsx +103 -6
  60. package/src/client/plugin.tsx +27 -54
  61. package/src/client/skill-hub/components/LoopSettings.tsx +331 -0
  62. package/src/client/skill-hub/index.tsx +51 -75
  63. package/src/client/skill-hub/tools/InteractionSchemasProvider.tsx +56 -16
  64. package/src/client/skill-hub/tools/SkillHubCard.tsx +35 -4
  65. package/src/client/skill-hub/tools/loopTemplates.ts +52 -0
  66. package/src/client/skill-hub/tools/registerSkillLoopCards.ts +58 -0
  67. package/src/client/tools/PlanApprovalCard.tsx +175 -0
  68. package/src/client/tools/registerOrchestratorCards.ts +7 -0
  69. package/src/server/collections/agent-harness-profiles.ts +59 -0
  70. package/src/server/collections/agent-loop-events.ts +71 -0
  71. package/src/server/collections/agent-loop-runs.ts +158 -0
  72. package/src/server/collections/agent-loop-steps.ts +144 -0
  73. package/src/server/collections/orchestrator-config.ts +7 -0
  74. package/src/server/collections/skill-executions.ts +63 -51
  75. package/src/server/collections/skill-loop-configs.ts +65 -0
  76. package/src/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.ts +30 -0
  77. package/src/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.ts +142 -0
  78. package/src/server/plugin.ts +15 -0
  79. package/src/server/resources/agent-loop.ts +183 -0
  80. package/src/server/services/AgentHarness.ts +663 -0
  81. package/src/server/services/AgentLoopController.ts +1128 -0
  82. package/src/server/services/AgentLoopRepository.ts +194 -0
  83. package/src/server/services/AgentLoopService.ts +161 -0
  84. package/src/server/services/AgentPlanValidator.ts +73 -0
  85. package/src/server/services/AgentPlannerService.ts +93 -0
  86. package/src/server/services/AgentRegistryService.ts +169 -0
  87. package/src/server/services/ExecutionSpanService.ts +2 -0
  88. package/src/server/skill-hub/plugin.ts +881 -771
  89. package/src/server/tools/agent-loop.ts +399 -0
  90. package/src/server/tools/delegate-task.ts +48 -463
  91. package/src/server/tools/orchestrator-plan.ts +279 -0
  92. package/src/server/tools/skill-execute.ts +68 -64
@@ -0,0 +1,58 @@
1
+ import { SkillHubCard } from './SkillHubCard';
2
+ import { parseJsonText } from '../utils/jsonFields';
3
+
4
+ const sanitize = (name: string) =>
5
+ name
6
+ .toLowerCase()
7
+ .replace(/[^a-z0-9_]/g, '_')
8
+ .replace(/_+/g, '_')
9
+ .replace(/^_|_$/g, '');
10
+
11
+ const extractList = (data: any) => {
12
+ const value = data?.data?.data ?? data?.data ?? data ?? [];
13
+ return Array.isArray(value) ? value : [];
14
+ };
15
+
16
+ export async function registerSkillLoopCards(app: any) {
17
+ const toolsManager = app.aiManager?.toolsManager;
18
+ if (!toolsManager) return;
19
+
20
+ try {
21
+ const skillsResponse = await app.apiClient.request({
22
+ url: 'skillDefinitions:list',
23
+ params: {
24
+ filter: { enabled: true },
25
+ fields: ['id', 'name', 'autoCall', 'interactionSchema'],
26
+ pageSize: 500,
27
+ },
28
+ });
29
+
30
+ let loopSkillIds = new Set<string>();
31
+ try {
32
+ const loopConfigsResponse = await app.apiClient.request({
33
+ url: 'skillLoopConfigs:list',
34
+ params: {
35
+ filter: { enabled: true },
36
+ fields: ['skillId'],
37
+ pageSize: 500,
38
+ },
39
+ });
40
+ loopSkillIds = new Set(extractList(loopConfigsResponse.data).map((config: any) => String(config.skillId)));
41
+ if (loopSkillIds.size > 0) {
42
+ toolsManager.registerTools('skill_hub_execute', { ui: { card: SkillHubCard } });
43
+ }
44
+ } catch {
45
+ // Older deployments may not have the collection before migration/sync.
46
+ }
47
+
48
+ const skills = extractList(skillsResponse.data);
49
+ for (const skill of skills) {
50
+ const hasLoopConfig = loopSkillIds.has(String(skill.id));
51
+ const hasLegacySchema = !skill.autoCall && !!parseJsonText(skill.interactionSchema, null);
52
+ if (!hasLoopConfig && !hasLegacySchema) continue;
53
+ toolsManager.registerTools(`skill_hub_${sanitize(skill.name)}`, { ui: { card: SkillHubCard } });
54
+ }
55
+ } catch {
56
+ // user without ACL or backend unavailable - skip silently
57
+ }
58
+ }
@@ -0,0 +1,175 @@
1
+ import React from 'react';
2
+ import { Alert, Button, Card, Input, List, Space, Tag, Typography, message } from 'antd';
3
+ import { ToolsUIProperties, useAPIClient } from '@nocobase/client';
4
+
5
+ const { Paragraph, Text } = Typography;
6
+
7
+ const extractData = (response: any) => response?.data?.data ?? response?.data ?? response;
8
+
9
+ const summarizeArgsPlan = (plan: any[]) =>
10
+ (Array.isArray(plan) ? plan : []).map((step, index) => ({
11
+ id: step.id || step.planKey || index,
12
+ planKey: step.planKey || step.key || step.id || `step_${index + 1}`,
13
+ title: step.title || `Step ${index + 1}`,
14
+ description: step.description || '',
15
+ type: step.type || 'tool',
16
+ target: step.target || '',
17
+ dependsOn: step.dependsOn || [],
18
+ }));
19
+
20
+ export const PlanApprovalCard: React.FC<ToolsUIProperties> = ({ toolCall, decisions }) => {
21
+ const api = useAPIClient();
22
+ const rawArgs = (toolCall.args as Record<string, any>) || {};
23
+ const runId = rawArgs.runId;
24
+ const [detail, setDetail] = React.useState<any>(null);
25
+ const [loading, setLoading] = React.useState(false);
26
+ const [submitting, setSubmitting] = React.useState(false);
27
+ const [feedback, setFeedback] = React.useState('');
28
+
29
+ const interrupted = toolCall.invokeStatus === 'init' || toolCall.invokeStatus === 'interrupted';
30
+
31
+ React.useEffect(() => {
32
+ if (!interrupted || !runId) return;
33
+ let mounted = true;
34
+ setLoading(true);
35
+ api
36
+ .request({
37
+ url: 'agentLoops:get',
38
+ params: { filterByTk: runId },
39
+ })
40
+ .then((response) => {
41
+ if (mounted) setDetail(extractData(response));
42
+ })
43
+ .catch(() => {
44
+ if (mounted) setDetail(null);
45
+ })
46
+ .finally(() => {
47
+ if (mounted) setLoading(false);
48
+ });
49
+ return () => {
50
+ mounted = false;
51
+ };
52
+ }, [api, interrupted, runId]);
53
+
54
+ if (!interrupted) {
55
+ return null;
56
+ }
57
+
58
+ const run = detail?.run || {};
59
+ const steps = summarizeArgsPlan(detail?.steps || rawArgs.plan || []);
60
+ const goal = run.goal || rawArgs.goal || '';
61
+
62
+ const rejectPlan = async () => {
63
+ if (!runId) {
64
+ await decisions.reject('missing_run_id');
65
+ return;
66
+ }
67
+ setSubmitting(true);
68
+ try {
69
+ await api.request({
70
+ url: 'agentLoops:rejectPlan',
71
+ method: 'post',
72
+ data: { runId, reason: feedback || 'Plan rejected by user.' },
73
+ });
74
+ await decisions.reject(JSON.stringify({ reason: 'plan_rejected', runId, feedback }));
75
+ } catch (error: any) {
76
+ message.error(error?.message || 'Failed to reject plan');
77
+ } finally {
78
+ setSubmitting(false);
79
+ }
80
+ };
81
+
82
+ const requestChanges = async () => {
83
+ if (!feedback.trim()) {
84
+ message.warning('Add feedback before requesting changes.');
85
+ return;
86
+ }
87
+ setSubmitting(true);
88
+ try {
89
+ await api.request({
90
+ url: 'agentLoops:requestPlanChanges',
91
+ method: 'post',
92
+ data: { runId, feedback },
93
+ });
94
+ await decisions.reject(JSON.stringify({ reason: 'changes_requested', runId, feedback }));
95
+ } catch (error: any) {
96
+ message.error(error?.message || 'Failed to request plan changes');
97
+ } finally {
98
+ setSubmitting(false);
99
+ }
100
+ };
101
+
102
+ return (
103
+ <Card size="small" style={{ marginTop: 8 }}>
104
+ <Space direction="vertical" size={12} style={{ width: '100%' }}>
105
+ <Alert
106
+ type="info"
107
+ showIcon
108
+ message="Review orchestrator plan"
109
+ description="Execution starts only after you approve this plan."
110
+ />
111
+
112
+ <Space size={8} wrap>
113
+ {runId && <Tag color="blue">Run #{runId}</Tag>}
114
+ <Tag color="purple">Plan v{run.planVersion || rawArgs.planVersion || 1}</Tag>
115
+ <Tag color={run.approvalStatus === 'pending' ? 'gold' : 'default'}>
116
+ {run.approvalStatus || 'pending'}
117
+ </Tag>
118
+ {run.metadata?.harnessTag && <Tag>{run.metadata.harnessTag}</Tag>}
119
+ </Space>
120
+
121
+ {goal && (
122
+ <Paragraph style={{ marginBottom: 0 }}>
123
+ <Text strong>Goal: </Text>
124
+ {goal}
125
+ </Paragraph>
126
+ )}
127
+
128
+ <List
129
+ size="small"
130
+ loading={loading}
131
+ dataSource={steps}
132
+ locale={{ emptyText: 'No plan steps found.' }}
133
+ renderItem={(step: any, index) => (
134
+ <List.Item>
135
+ <Space direction="vertical" size={2} style={{ width: '100%' }}>
136
+ <Space size={8} wrap>
137
+ <Text strong>
138
+ {index + 1}. {step.title}
139
+ </Text>
140
+ <Tag>{step.type}</Tag>
141
+ {step.target && <Tag color="green">{step.target}</Tag>}
142
+ </Space>
143
+ {step.description && <Text type="secondary">{step.description}</Text>}
144
+ {step.dependsOn?.length > 0 && (
145
+ <Text type="secondary" style={{ fontSize: 12 }}>
146
+ Depends on: {step.dependsOn.join(', ')}
147
+ </Text>
148
+ )}
149
+ </Space>
150
+ </List.Item>
151
+ )}
152
+ />
153
+
154
+ <Input.TextArea
155
+ rows={3}
156
+ value={feedback}
157
+ onChange={(event) => setFeedback(event.target.value)}
158
+ placeholder="Optional rejection reason or requested changes"
159
+ />
160
+
161
+ <Space wrap>
162
+ <Button type="primary" loading={submitting} onClick={() => decisions.approve()}>
163
+ Accept & Run
164
+ </Button>
165
+ <Button loading={submitting} onClick={requestChanges}>
166
+ Request changes
167
+ </Button>
168
+ <Button danger loading={submitting} onClick={rejectPlan}>
169
+ Reject
170
+ </Button>
171
+ </Space>
172
+ </Space>
173
+ </Card>
174
+ );
175
+ };
@@ -0,0 +1,7 @@
1
+ import { PlanApprovalCard } from './PlanApprovalCard';
2
+
3
+ export async function registerOrchestratorCards(app: any) {
4
+ const toolsManager = app.aiManager?.toolsManager;
5
+ if (!toolsManager) return;
6
+ toolsManager.registerTools('orchestrator_execute_plan', { ui: { card: PlanApprovalCard } });
7
+ }
@@ -0,0 +1,59 @@
1
+ import { defineCollection } from '@nocobase/database';
2
+
3
+ export default defineCollection({
4
+ name: 'agentHarnessProfiles',
5
+ title: 'Agent Harness Profiles',
6
+ fields: [
7
+ {
8
+ name: 'id',
9
+ type: 'bigInt',
10
+ autoIncrement: true,
11
+ primaryKey: true,
12
+ },
13
+ {
14
+ name: 'tag',
15
+ type: 'string',
16
+ length: 100,
17
+ allowNull: false,
18
+ unique: true,
19
+ comment: 'Stable harness profile tag used by orchestration rules and agent loop runs.',
20
+ },
21
+ {
22
+ name: 'title',
23
+ type: 'string',
24
+ length: 200,
25
+ },
26
+ {
27
+ name: 'description',
28
+ type: 'text',
29
+ },
30
+ {
31
+ name: 'enabled',
32
+ type: 'boolean',
33
+ defaultValue: true,
34
+ },
35
+ {
36
+ name: 'settings',
37
+ type: 'json',
38
+ defaultValue: {},
39
+ comment: 'Harness limits and behavior settings such as max parallel sub-agents, approval mode, and tool policy.',
40
+ },
41
+ {
42
+ name: 'createdAt',
43
+ type: 'date',
44
+ },
45
+ {
46
+ name: 'updatedAt',
47
+ type: 'date',
48
+ },
49
+ ],
50
+ indexes: [
51
+ {
52
+ unique: true,
53
+ fields: ['tag'],
54
+ },
55
+ {
56
+ fields: ['enabled'],
57
+ },
58
+ ],
59
+ });
@@ -0,0 +1,71 @@
1
+ import { defineCollection } from '@nocobase/database';
2
+
3
+ export default defineCollection({
4
+ name: 'agentLoopEvents',
5
+ title: 'Agent Loop Events',
6
+ fields: [
7
+ {
8
+ name: 'id',
9
+ type: 'bigInt',
10
+ autoIncrement: true,
11
+ primaryKey: true,
12
+ },
13
+ {
14
+ name: 'run',
15
+ type: 'belongsTo',
16
+ target: 'agentLoopRuns',
17
+ foreignKey: 'runId',
18
+ },
19
+ {
20
+ name: 'step',
21
+ type: 'belongsTo',
22
+ target: 'agentLoopSteps',
23
+ foreignKey: 'stepId',
24
+ },
25
+ {
26
+ name: 'type',
27
+ type: 'string',
28
+ length: 80,
29
+ },
30
+ {
31
+ name: 'title',
32
+ type: 'string',
33
+ length: 500,
34
+ },
35
+ {
36
+ name: 'content',
37
+ type: 'text',
38
+ },
39
+ {
40
+ name: 'status',
41
+ type: 'string',
42
+ length: 30,
43
+ },
44
+ {
45
+ name: 'payload',
46
+ type: 'json',
47
+ defaultValue: {},
48
+ },
49
+ {
50
+ name: 'user',
51
+ type: 'belongsTo',
52
+ target: 'users',
53
+ foreignKey: 'userId',
54
+ },
55
+ {
56
+ name: 'createdAt',
57
+ type: 'date',
58
+ },
59
+ ],
60
+ indexes: [
61
+ {
62
+ fields: ['runId'],
63
+ },
64
+ {
65
+ fields: ['stepId'],
66
+ },
67
+ {
68
+ fields: ['type'],
69
+ },
70
+ ],
71
+ });
@@ -0,0 +1,158 @@
1
+ import { defineCollection } from '@nocobase/database';
2
+
3
+ export default defineCollection({
4
+ name: 'agentLoopRuns',
5
+ title: 'Agent Loop Runs',
6
+ fields: [
7
+ {
8
+ name: 'id',
9
+ type: 'bigInt',
10
+ autoIncrement: true,
11
+ primaryKey: true,
12
+ },
13
+ {
14
+ name: 'rootRunId',
15
+ type: 'string',
16
+ length: 100,
17
+ allowNull: false,
18
+ },
19
+ {
20
+ name: 'sessionId',
21
+ type: 'string',
22
+ length: 100,
23
+ },
24
+ {
25
+ name: 'messageId',
26
+ type: 'string',
27
+ length: 100,
28
+ },
29
+ {
30
+ name: 'leaderUsername',
31
+ type: 'string',
32
+ length: 100,
33
+ },
34
+ {
35
+ name: 'goal',
36
+ type: 'text',
37
+ },
38
+ {
39
+ name: 'status',
40
+ type: 'string',
41
+ length: 30,
42
+ defaultValue: 'planning',
43
+ comment: 'planning, waiting_plan_approval, approved, running, waiting_user, needs_replan, succeeded, failed, rejected, canceled',
44
+ },
45
+ {
46
+ name: 'currentStepId',
47
+ type: 'bigInt',
48
+ },
49
+ {
50
+ name: 'policy',
51
+ type: 'json',
52
+ defaultValue: {},
53
+ },
54
+ {
55
+ name: 'iterationCount',
56
+ type: 'integer',
57
+ defaultValue: 0,
58
+ },
59
+ {
60
+ name: 'approvalStatus',
61
+ type: 'string',
62
+ length: 30,
63
+ defaultValue: 'none',
64
+ comment: 'none, pending, approved, rejected, changes_requested',
65
+ },
66
+ {
67
+ name: 'approvedBy',
68
+ type: 'belongsTo',
69
+ target: 'users',
70
+ foreignKey: 'approvedById',
71
+ },
72
+ {
73
+ name: 'approvedAt',
74
+ type: 'date',
75
+ },
76
+ {
77
+ name: 'rejectionReason',
78
+ type: 'text',
79
+ },
80
+ {
81
+ name: 'changeRequest',
82
+ type: 'text',
83
+ },
84
+ {
85
+ name: 'planVersion',
86
+ type: 'integer',
87
+ defaultValue: 1,
88
+ },
89
+ {
90
+ name: 'planSource',
91
+ type: 'string',
92
+ length: 50,
93
+ },
94
+ {
95
+ name: 'plannerModel',
96
+ type: 'string',
97
+ length: 100,
98
+ },
99
+ {
100
+ name: 'lockedBy',
101
+ type: 'string',
102
+ length: 100,
103
+ },
104
+ {
105
+ name: 'lockedUntil',
106
+ type: 'date',
107
+ },
108
+ {
109
+ name: 'finalAnswer',
110
+ type: 'text',
111
+ },
112
+ {
113
+ name: 'summary',
114
+ type: 'text',
115
+ },
116
+ {
117
+ name: 'metadata',
118
+ type: 'json',
119
+ defaultValue: {},
120
+ },
121
+ {
122
+ name: 'user',
123
+ type: 'belongsTo',
124
+ target: 'users',
125
+ foreignKey: 'userId',
126
+ },
127
+ {
128
+ name: 'startedAt',
129
+ type: 'date',
130
+ },
131
+ {
132
+ name: 'endedAt',
133
+ type: 'date',
134
+ },
135
+ {
136
+ name: 'createdAt',
137
+ type: 'date',
138
+ },
139
+ {
140
+ name: 'updatedAt',
141
+ type: 'date',
142
+ },
143
+ ],
144
+ indexes: [
145
+ {
146
+ fields: ['rootRunId'],
147
+ },
148
+ {
149
+ fields: ['status'],
150
+ },
151
+ {
152
+ fields: ['leaderUsername'],
153
+ },
154
+ {
155
+ fields: ['sessionId'],
156
+ },
157
+ ],
158
+ });
@@ -0,0 +1,144 @@
1
+ import { defineCollection } from '@nocobase/database';
2
+
3
+ export default defineCollection({
4
+ name: 'agentLoopSteps',
5
+ title: 'Agent Loop Steps',
6
+ fields: [
7
+ {
8
+ name: 'id',
9
+ type: 'bigInt',
10
+ autoIncrement: true,
11
+ primaryKey: true,
12
+ },
13
+ {
14
+ name: 'run',
15
+ type: 'belongsTo',
16
+ target: 'agentLoopRuns',
17
+ foreignKey: 'runId',
18
+ },
19
+ {
20
+ name: 'parentStep',
21
+ type: 'belongsTo',
22
+ target: 'agentLoopSteps',
23
+ foreignKey: 'parentStepId',
24
+ },
25
+ {
26
+ name: 'planKey',
27
+ type: 'string',
28
+ length: 100,
29
+ },
30
+ {
31
+ name: 'index',
32
+ type: 'integer',
33
+ defaultValue: 0,
34
+ },
35
+ {
36
+ name: 'title',
37
+ type: 'string',
38
+ length: 500,
39
+ },
40
+ {
41
+ name: 'description',
42
+ type: 'text',
43
+ },
44
+ {
45
+ name: 'type',
46
+ type: 'string',
47
+ length: 30,
48
+ comment: 'reasoning, skill, tool, sub_agent, verification',
49
+ },
50
+ {
51
+ name: 'target',
52
+ type: 'string',
53
+ length: 200,
54
+ },
55
+ {
56
+ name: 'input',
57
+ type: 'json',
58
+ defaultValue: {},
59
+ },
60
+ {
61
+ name: 'output',
62
+ type: 'json',
63
+ defaultValue: {},
64
+ },
65
+ {
66
+ name: 'status',
67
+ type: 'string',
68
+ length: 30,
69
+ defaultValue: 'pending',
70
+ comment: 'pending, running, waiting_user, succeeded, failed, skipped',
71
+ },
72
+ {
73
+ name: 'attempt',
74
+ type: 'integer',
75
+ defaultValue: 0,
76
+ },
77
+ {
78
+ name: 'maxAttempts',
79
+ type: 'integer',
80
+ defaultValue: 2,
81
+ },
82
+ {
83
+ name: 'dependsOn',
84
+ type: 'json',
85
+ defaultValue: [],
86
+ },
87
+ {
88
+ name: 'dependencyPolicy',
89
+ type: 'string',
90
+ length: 30,
91
+ defaultValue: 'require_success',
92
+ comment: 'require_success or allow_skipped',
93
+ },
94
+ {
95
+ name: 'approval',
96
+ type: 'json',
97
+ defaultValue: {},
98
+ },
99
+ {
100
+ name: 'error',
101
+ type: 'text',
102
+ },
103
+ {
104
+ name: 'agentExecutionSpanId',
105
+ type: 'bigInt',
106
+ },
107
+ {
108
+ name: 'skillExecutionId',
109
+ type: 'bigInt',
110
+ },
111
+ {
112
+ name: 'metadata',
113
+ type: 'json',
114
+ defaultValue: {},
115
+ },
116
+ {
117
+ name: 'startedAt',
118
+ type: 'date',
119
+ },
120
+ {
121
+ name: 'endedAt',
122
+ type: 'date',
123
+ },
124
+ {
125
+ name: 'createdAt',
126
+ type: 'date',
127
+ },
128
+ {
129
+ name: 'updatedAt',
130
+ type: 'date',
131
+ },
132
+ ],
133
+ indexes: [
134
+ {
135
+ fields: ['runId'],
136
+ },
137
+ {
138
+ fields: ['status'],
139
+ },
140
+ {
141
+ fields: ['planKey'],
142
+ },
143
+ ],
144
+ });
@@ -46,6 +46,13 @@ export default defineCollection({
46
46
  comment:
47
47
  'Max LangGraph reasoning steps (tool-call + LLM-step iterations) per delegation. Lower = safer; higher = more complex multi-step tasks. Default 50.',
48
48
  },
49
+ {
50
+ name: 'harnessTag',
51
+ type: 'string',
52
+ length: 100,
53
+ defaultValue: 'default',
54
+ comment: 'Harness profile tag used by the orchestrator controller and approval flow.',
55
+ },
49
56
  {
50
57
  name: 'llmService',
51
58
  type: 'string',