plugin-agent-orchestrator 1.0.17 → 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 (139) hide show
  1. package/dist/client/AIEmployeeSelect.d.ts +11 -0
  2. package/dist/client/AIEmployeesContext.d.ts +30 -0
  3. package/dist/client/AgentRunsTab.d.ts +2 -0
  4. package/dist/client/HarnessProfilesTab.d.ts +2 -0
  5. package/dist/client/OrchestratorSettings.d.ts +3 -0
  6. package/dist/client/RulesTab.d.ts +2 -0
  7. package/dist/client/TracingTab.d.ts +2 -0
  8. package/dist/client/index.d.ts +1 -0
  9. package/dist/client/index.js +1 -1
  10. package/dist/client/plugin.d.ts +6 -0
  11. package/dist/client/skill-hub/components/ExecutionHistory.d.ts +2 -0
  12. package/dist/client/skill-hub/components/ExecutionProgress.d.ts +20 -0
  13. package/dist/client/skill-hub/components/GitSkillImport.d.ts +7 -0
  14. package/dist/client/skill-hub/components/LoopSettings.d.ts +2 -0
  15. package/dist/client/skill-hub/components/SkillEditor.d.ts +7 -0
  16. package/dist/client/skill-hub/components/SkillManager.d.ts +2 -0
  17. package/dist/client/skill-hub/components/SkillMetrics.d.ts +2 -0
  18. package/dist/client/skill-hub/components/SkillTestPanel.d.ts +7 -0
  19. package/dist/client/skill-hub/index.d.ts +11 -0
  20. package/dist/client/skill-hub/locale.d.ts +3 -0
  21. package/dist/client/skill-hub/tools/InteractionSchemasProvider.d.ts +6 -0
  22. package/dist/client/skill-hub/tools/SkillHubCard.d.ts +3 -0
  23. package/dist/client/skill-hub/tools/loopTemplates.d.ts +22 -0
  24. package/dist/client/skill-hub/tools/registerSkillLoopCards.d.ts +1 -0
  25. package/dist/client/skill-hub/utils/jsonFields.d.ts +3 -0
  26. package/dist/client/tools/PlanApprovalCard.d.ts +3 -0
  27. package/dist/client/tools/registerOrchestratorCards.d.ts +1 -0
  28. package/dist/externalVersion.js +6 -6
  29. package/dist/index.d.ts +2 -0
  30. package/dist/server/collections/agent-execution-spans.d.ts +9 -0
  31. package/dist/server/collections/agent-harness-profiles.d.ts +2 -0
  32. package/dist/server/collections/agent-harness-profiles.js +89 -0
  33. package/dist/server/collections/agent-loop-events.d.ts +2 -0
  34. package/dist/server/collections/agent-loop-events.js +101 -0
  35. package/dist/server/collections/agent-loop-runs.d.ts +2 -0
  36. package/dist/server/collections/agent-loop-runs.js +188 -0
  37. package/dist/server/collections/agent-loop-steps.d.ts +2 -0
  38. package/dist/server/collections/agent-loop-steps.js +174 -0
  39. package/dist/server/collections/orchestrator-config.d.ts +2 -0
  40. package/dist/server/collections/orchestrator-config.js +7 -0
  41. package/dist/server/collections/orchestrator-logs.d.ts +8 -0
  42. package/dist/server/collections/skill-definitions.d.ts +3 -0
  43. package/dist/server/collections/skill-executions.d.ts +3 -0
  44. package/dist/server/collections/skill-executions.js +12 -0
  45. package/dist/server/collections/skill-loop-configs.d.ts +3 -0
  46. package/dist/server/collections/skill-loop-configs.js +94 -0
  47. package/dist/server/collections/skill-worker-configs.d.ts +3 -0
  48. package/dist/server/index.d.ts +1 -0
  49. package/dist/server/migrations/20260423000000-add-progress-fields.d.ts +4 -0
  50. package/dist/server/migrations/20260425000000-add-interaction-schema.d.ts +4 -0
  51. package/dist/server/migrations/20260427000000-add-tracing-detail-fields.d.ts +7 -0
  52. package/dist/server/migrations/20260427000000-change-packages-to-text.d.ts +4 -0
  53. package/dist/server/migrations/20260427000001-change-other-json-to-text.d.ts +4 -0
  54. package/dist/server/migrations/20260429000000-add-llm-fields.d.ts +7 -0
  55. package/dist/server/migrations/20260429000000-fix-inputargs-json-to-text.d.ts +16 -0
  56. package/dist/server/migrations/20260503000000-add-orchestrator-trace-fields.d.ts +7 -0
  57. package/dist/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.d.ts +7 -0
  58. package/dist/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.js +55 -0
  59. package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.d.ts +12 -0
  60. package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.js +162 -0
  61. package/dist/server/plugin.d.ts +16 -0
  62. package/dist/server/plugin.js +13 -0
  63. package/dist/server/resources/agent-loop.d.ts +3 -0
  64. package/dist/server/resources/agent-loop.js +205 -0
  65. package/dist/server/resources/tracing.d.ts +7 -0
  66. package/dist/server/services/AgentHarness.d.ts +42 -0
  67. package/dist/server/services/AgentHarness.js +565 -0
  68. package/dist/server/services/AgentLoopController.d.ts +205 -0
  69. package/dist/server/services/AgentLoopController.js +940 -0
  70. package/dist/server/services/AgentLoopRepository.d.ts +20 -0
  71. package/dist/server/services/AgentLoopRepository.js +210 -0
  72. package/dist/server/services/AgentLoopService.d.ts +149 -0
  73. package/dist/server/services/AgentLoopService.js +133 -0
  74. package/dist/server/services/AgentPlanValidator.d.ts +4 -0
  75. package/dist/server/services/AgentPlanValidator.js +99 -0
  76. package/dist/server/services/AgentPlannerService.d.ts +8 -0
  77. package/dist/server/services/AgentPlannerService.js +119 -0
  78. package/dist/server/services/AgentRegistryService.d.ts +13 -0
  79. package/dist/server/services/AgentRegistryService.js +178 -0
  80. package/dist/server/services/CodeValidator.d.ts +32 -0
  81. package/dist/server/services/ExecutionSpanService.d.ts +46 -0
  82. package/dist/server/services/FileManager.d.ts +28 -0
  83. package/dist/server/services/SandboxRunner.d.ts +41 -0
  84. package/dist/server/services/SkillManager.d.ts +6 -0
  85. package/dist/server/services/SkillRepositoryService.d.ts +22 -0
  86. package/dist/server/services/WorkerEnvManager.d.ts +26 -0
  87. package/dist/server/skill-hub/actions/git-import.d.ts +21 -0
  88. package/dist/server/skill-hub/mcp/McpController.d.ts +15 -0
  89. package/dist/server/skill-hub/plugin.d.ts +61 -0
  90. package/dist/server/skill-hub/plugin.js +137 -54
  91. package/dist/server/skill-hub/tasks/SkillExecutionTask.d.ts +16 -0
  92. package/dist/server/skill-hub/utils/json-fields.d.ts +7 -0
  93. package/dist/server/tools/agent-loop.d.ts +235 -0
  94. package/dist/server/tools/agent-loop.js +406 -0
  95. package/dist/server/tools/delegate-task.d.ts +19 -0
  96. package/dist/server/tools/delegate-task.js +19 -368
  97. package/dist/server/tools/external-rag-search.d.ts +42 -0
  98. package/dist/server/tools/orchestrator-plan.d.ts +205 -0
  99. package/dist/server/tools/orchestrator-plan.js +291 -0
  100. package/dist/server/tools/skill-execute.d.ts +36 -0
  101. package/dist/server/tools/skill-execute.js +2 -0
  102. package/package.json +1 -1
  103. package/src/client/AgentRunsTab.tsx +764 -0
  104. package/src/client/HarnessProfilesTab.tsx +247 -0
  105. package/src/client/OrchestratorSettings.tsx +40 -2
  106. package/src/client/RulesTab.tsx +103 -6
  107. package/src/client/plugin.tsx +27 -54
  108. package/src/client/skill-hub/components/LoopSettings.tsx +331 -0
  109. package/src/client/skill-hub/index.tsx +51 -75
  110. package/src/client/skill-hub/tools/InteractionSchemasProvider.tsx +56 -16
  111. package/src/client/skill-hub/tools/SkillHubCard.tsx +35 -4
  112. package/src/client/skill-hub/tools/loopTemplates.ts +52 -0
  113. package/src/client/skill-hub/tools/registerSkillLoopCards.ts +58 -0
  114. package/src/client/tools/PlanApprovalCard.tsx +175 -0
  115. package/src/client/tools/registerOrchestratorCards.ts +7 -0
  116. package/src/server/collections/agent-harness-profiles.ts +59 -0
  117. package/src/server/collections/agent-loop-events.ts +71 -0
  118. package/src/server/collections/agent-loop-runs.ts +158 -0
  119. package/src/server/collections/agent-loop-steps.ts +144 -0
  120. package/src/server/collections/orchestrator-config.ts +7 -0
  121. package/src/server/collections/skill-executions.ts +63 -51
  122. package/src/server/collections/skill-loop-configs.ts +65 -0
  123. package/src/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.ts +30 -0
  124. package/src/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.ts +142 -0
  125. package/src/server/plugin.ts +15 -0
  126. package/src/server/resources/agent-loop.ts +183 -0
  127. package/src/server/services/AgentHarness.ts +663 -0
  128. package/src/server/services/AgentLoopController.ts +1128 -0
  129. package/src/server/services/AgentLoopRepository.ts +194 -0
  130. package/src/server/services/AgentLoopService.ts +161 -0
  131. package/src/server/services/AgentPlanValidator.ts +73 -0
  132. package/src/server/services/AgentPlannerService.ts +93 -0
  133. package/src/server/services/AgentRegistryService.ts +169 -0
  134. package/src/server/services/ExecutionSpanService.ts +2 -0
  135. package/src/server/skill-hub/plugin.ts +881 -771
  136. package/src/server/tools/agent-loop.ts +399 -0
  137. package/src/server/tools/delegate-task.ts +23 -485
  138. package/src/server/tools/orchestrator-plan.ts +279 -0
  139. 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',