plugin-agent-orchestrator 1.0.23 → 1.0.26

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.
@@ -11,8 +11,9 @@ module.exports = {
11
11
  "react": "18.2.0",
12
12
  "antd": "5.24.2",
13
13
  "@ant-design/icons": "5.6.1",
14
- "@nocobase/client": "2.1.6",
14
+ "ahooks": "3.7.8",
15
15
  "@nocobase/client-v2": "2.1.6",
16
+ "@nocobase/client": "2.1.6",
16
17
  "@nocobase/server": "2.1.6",
17
18
  "@nocobase/database": "2.1.6",
18
19
  "@langchain/langgraph": "0.2.74",
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName.zh-CN": "代理协调器",
5
5
  "displayName.vi-VN": "Điều phối Agent",
6
6
  "description": "Hierarchical Multi-Agent orchestration for NocoBase AI Employees. Enables Leader agents to delegate tasks to Sub-Agent employees without modifying core plugin-ai.",
7
- "version": "1.0.23",
7
+ "version": "1.0.26",
8
8
  "license": "Apache-2.0",
9
9
  "main": "dist/server/index.js",
10
10
  "keywords": [
@@ -1,5 +1,6 @@
1
1
  import React, { createContext, useContext } from 'react';
2
- import { useRequest } from '@nocobase/client';
2
+ import { useRequest } from 'ahooks';
3
+ import { useApp } from '@nocobase/client-v2';
3
4
 
4
5
  interface AIEmployeeInfo {
5
6
  username: string;
@@ -74,10 +75,13 @@ function extractToolNames(skillSettings: any) {
74
75
  * delegate_<leader>_to_<sub> tool to its skillSettings.tools.
75
76
  */
76
77
  export const AIEmployeesProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
77
- const { data, loading, refresh } = useRequest({
78
- url: 'aiEmployees:list',
79
- params: { pageSize: 200 },
80
- });
78
+ const api = useApp().apiClient;
79
+ const { data, loading, refresh } = useRequest(() =>
80
+ api.request({
81
+ url: 'aiEmployees:list',
82
+ params: { pageSize: 200 },
83
+ }),
84
+ );
81
85
 
82
86
  const value = React.useMemo(() => {
83
87
  const rawEmployees = (data as any)?.data || [];
@@ -30,7 +30,8 @@ import {
30
30
  ReloadOutlined,
31
31
  StopOutlined,
32
32
  } from '@ant-design/icons';
33
- import { useAPIClient, useRequest } from '@nocobase/client';
33
+ import { useRequest } from 'ahooks';
34
+ import { useApp } from '@nocobase/client-v2';
34
35
  import { useAIEmployees } from './AIEmployeesContext';
35
36
  import { parseJsonText } from './skill-hub/utils/jsonFields';
36
37
 
@@ -174,7 +175,7 @@ function TextBlock({ value, rows = 10 }: { value: any; rows?: number }) {
174
175
  }
175
176
 
176
177
  export const AgentRunsTab: React.FC = () => {
177
- const api = useAPIClient();
178
+ const api = useApp().apiClient;
178
179
  const { employees, employeeMap } = useAIEmployees();
179
180
  const [filters, setFilters] = useState<FilterState>({});
180
181
  const [page, setPage] = useState(1);
@@ -197,10 +198,11 @@ export const AgentRunsTab: React.FC = () => {
197
198
  }, [filters, page, pageSize]);
198
199
 
199
200
  const { data, loading, refresh } = useRequest(
200
- {
201
- url: 'agentLoops:list',
202
- params: requestParams,
203
- },
201
+ () =>
202
+ api.request({
203
+ url: 'agentLoops:list',
204
+ params: requestParams,
205
+ }),
204
206
  {
205
207
  refreshDeps: [requestParams],
206
208
  },
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import { Button, Card, Drawer, Form, Input, Popconfirm, Space, Switch, Table, Tag, Typography, message } from 'antd';
3
3
  import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons';
4
- import { useAPIClient, useRequest } from '@nocobase/client';
4
+ import { useRequest } from 'ahooks';
5
+ import { useApp } from '@nocobase/client-v2';
5
6
 
6
7
  const { Text } = Typography;
7
8
 
@@ -12,18 +13,20 @@ const parseSettings = (value: string) => {
12
13
  };
13
14
 
14
15
  export const HarnessProfilesTab: React.FC = () => {
15
- const api = useAPIClient();
16
+ const api = useApp().apiClient;
16
17
  const [open, setOpen] = React.useState(false);
17
18
  const [editingRecord, setEditingRecord] = React.useState<any>(null);
18
19
  const [form] = Form.useForm();
19
20
 
20
- const { data, loading, refresh } = useRequest({
21
- url: 'agentHarnessProfiles:list',
22
- params: {
23
- sort: ['tag'],
24
- pageSize: 100,
25
- },
26
- });
21
+ const { data, loading, refresh } = useRequest(() =>
22
+ api.request({
23
+ url: 'agentHarnessProfiles:list',
24
+ params: {
25
+ sort: ['tag'],
26
+ pageSize: 100,
27
+ },
28
+ }),
29
+ );
27
30
 
28
31
  const rows = React.useMemo(() => {
29
32
  const raw = (data as any)?.data;
@@ -25,7 +25,8 @@ import {
25
25
  WarningOutlined,
26
26
  ThunderboltOutlined,
27
27
  } from '@ant-design/icons';
28
- import { useAPIClient, useRequest } from '@nocobase/client';
28
+ import { useRequest } from 'ahooks';
29
+ import { useApp } from '@nocobase/client-v2';
29
30
  import { AIEmployeeSelect } from './AIEmployeeSelect';
30
31
  import { useAIEmployees } from './AIEmployeesContext';
31
32
 
@@ -104,30 +105,36 @@ const normalizeSkillSettingsForTools = (skillSettings: any) => {
104
105
  };
105
106
 
106
107
  export const RulesTab: React.FC = () => {
107
- const api = useAPIClient();
108
+ const api = useApp().apiClient;
108
109
  const [visible, setVisible] = useState(false);
109
110
  const [editingRecord, setEditingRecord] = useState<any>(null);
110
111
  const [form] = Form.useForm();
111
112
 
112
- const { data, loading, refresh } = useRequest({
113
- url: 'orchestratorConfig:list',
114
- params: {
115
- sort: ['-createdAt'],
116
- },
117
- });
118
-
119
- const { data: llmServicesData, loading: llmLoading } = useRequest({
120
- url: 'ai:listAllEnabledModels',
121
- });
122
-
123
- const { data: harnessProfilesData, loading: harnessLoading } = useRequest({
124
- url: 'agentHarnessProfiles:list',
125
- params: {
126
- filter: { enabled: true },
127
- sort: ['tag'],
128
- pageSize: 100,
129
- },
130
- });
113
+ const { data, loading, refresh } = useRequest(() =>
114
+ api.request({
115
+ url: 'orchestratorConfig:list',
116
+ params: {
117
+ sort: ['-createdAt'],
118
+ },
119
+ }),
120
+ );
121
+
122
+ const { data: llmServicesData, loading: llmLoading } = useRequest(() =>
123
+ api.request({
124
+ url: 'ai:listAllEnabledModels',
125
+ }),
126
+ );
127
+
128
+ const { data: harnessProfilesData, loading: harnessLoading } = useRequest(() =>
129
+ api.request({
130
+ url: 'agentHarnessProfiles:list',
131
+ params: {
132
+ filter: { enabled: true },
133
+ sort: ['tag'],
134
+ pageSize: 100,
135
+ },
136
+ }),
137
+ );
131
138
 
132
139
  const llmServices = React.useMemo(() => {
133
140
  const raw = (llmServicesData as any)?.data ?? llmServicesData;
@@ -18,7 +18,8 @@ import {
18
18
  Form,
19
19
  } from 'antd';
20
20
  import { EyeOutlined, CheckCircleOutlined, CloseCircleOutlined, ReloadOutlined } from '@ant-design/icons';
21
- import { useAPIClient, useRequest } from '@nocobase/client';
21
+ import { useRequest } from 'ahooks';
22
+ import { useApp } from '@nocobase/client-v2';
22
23
  import { useAIEmployees } from './AIEmployeesContext';
23
24
 
24
25
  const { Text, Paragraph } = Typography;
@@ -32,7 +33,7 @@ type FilterState = {
32
33
  };
33
34
 
34
35
  export const TracingTab: React.FC = () => {
35
- const api = useAPIClient();
36
+ const api = useApp().apiClient;
36
37
  const [selectedLog, setSelectedLog] = useState<any>(null);
37
38
  const [detailLoading, setDetailLoading] = useState(false);
38
39
 
@@ -61,10 +62,11 @@ export const TracingTab: React.FC = () => {
61
62
  }, [page, pageSize, filters]);
62
63
 
63
64
  const { data, loading, refresh } = useRequest(
64
- {
65
- url: 'orchestratorTracing:list',
66
- params: requestParams,
67
- },
65
+ () =>
66
+ api.request({
67
+ url: 'orchestratorTracing:list',
68
+ params: requestParams,
69
+ }),
68
70
  {
69
71
  refreshDeps: [requestParams],
70
72
  },
@@ -1,9 +1,10 @@
1
1
  import React, { useState, useEffect, useCallback } from 'react';
2
2
  import { Card, Table, Tag, Button, Typography, Space, Tooltip, Popconfirm, message } from 'antd';
3
3
  import { ReloadOutlined, DownloadOutlined, DeleteOutlined } from '@ant-design/icons';
4
- import { useAPIClient, Upload } from '@nocobase/client';
5
- import { useT } from '../locale';
6
- import { parseJsonText } from '../utils/jsonFields';
4
+ import { Upload } from '@nocobase/client';
5
+ import { useApp } from '@nocobase/client-v2';
6
+ import { useT } from '../locale';
7
+ import { parseJsonText } from '../utils/jsonFields';
7
8
 
8
9
  const STATUS_COLORS: Record<string, string> = {
9
10
  pending: 'default',
@@ -15,7 +16,7 @@ const STATUS_COLORS: Record<string, string> = {
15
16
  };
16
17
 
17
18
  export const ExecutionHistory: React.FC = () => {
18
- const api = useAPIClient();
19
+ const api = useApp().apiClient;
19
20
  const t = useT();
20
21
  const [executions, setExecutions] = useState<any[]>([]);
21
22
  const [loading, setLoading] = useState(false);
@@ -96,12 +97,12 @@ export const ExecutionHistory: React.FC = () => {
96
97
  },
97
98
  {
98
99
  title: t('Files'),
99
- dataIndex: 'outputFiles',
100
+ dataIndex: 'outputFiles',
100
101
  key: 'files',
101
102
  width: 250,
102
- render: (files: any[], record: any) => {
103
- files = parseJsonText(files, []);
104
- if (!Array.isArray(files) || !files.length) return '-';
103
+ render: (files: any[], record: any) => {
104
+ files = parseJsonText(files, []);
105
+ if (!Array.isArray(files) || !files.length) return '-';
105
106
  const formattedFiles = files.map((f, i) => ({
106
107
  id: `${record.id}-${f.name}-${i}`,
107
108
  title: f.name,
@@ -25,7 +25,7 @@ import {
25
25
  DatabaseOutlined,
26
26
  SearchOutlined,
27
27
  } from '@ant-design/icons';
28
- import { useAPIClient } from '@nocobase/client';
28
+ import { useApp } from '@nocobase/client-v2';
29
29
  import { useT } from '../locale';
30
30
 
31
31
  const { Text } = Typography;
@@ -39,7 +39,7 @@ interface GitSkillImportProps {
39
39
  export const GitSkillImport: React.FC<GitSkillImportProps> = ({ open, onClose }) => {
40
40
  const t = useT();
41
41
  const { token } = useToken();
42
- const api = useAPIClient();
42
+ const api = useApp().apiClient;
43
43
 
44
44
  const [step, setStep] = useState(0);
45
45
 
@@ -16,7 +16,7 @@ import {
16
16
  Typography,
17
17
  } from 'antd';
18
18
  import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons';
19
- import { useAPIClient, useApp } from '@nocobase/client';
19
+ import { useApp } from '@nocobase/client-v2';
20
20
  import { useT } from '../locale';
21
21
  import { formatJsonText, parseJsonText, stringifyJsonText } from '../utils/jsonFields';
22
22
  import { getLoopTemplate, LOOP_TEMPLATES } from '../tools/loopTemplates';
@@ -30,8 +30,8 @@ const extractList = (data: any) => {
30
30
  };
31
31
 
32
32
  export const LoopSettings: React.FC = () => {
33
- const api = useAPIClient();
34
33
  const app = useApp();
34
+ const api = app.apiClient;
35
35
  const t = useT();
36
36
  const [form] = Form.useForm();
37
37
  const [skills, setSkills] = useState<any[]>([]);
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
  import { Modal, Form, Input, Select, InputNumber, Switch, message, Upload, Radio, Button, Space, theme } from 'antd';
3
3
  import { InboxOutlined, CloseOutlined, SaveOutlined } from '@ant-design/icons';
4
- import { useAPIClient } from '@nocobase/client';
4
+ import { useApp } from '@nocobase/client-v2';
5
5
  import { useT } from '../locale';
6
6
  import { formatJsonText, stringifyJsonText, parseJsonText } from '../utils/jsonFields';
7
7
 
@@ -14,7 +14,7 @@ interface SkillEditorProps {
14
14
  }
15
15
 
16
16
  export const SkillEditor: React.FC<SkillEditorProps> = ({ skill, onClose }) => {
17
- const api = useAPIClient();
17
+ const api = useApp().apiClient;
18
18
  const t = useT();
19
19
  const { token } = useToken();
20
20
  const [form] = Form.useForm();
@@ -17,7 +17,7 @@ import {
17
17
  Tooltip,
18
18
  } from 'antd';
19
19
  import { PlusOutlined, EditOutlined, DeleteOutlined, PlayCircleOutlined, BranchesOutlined } from '@ant-design/icons';
20
- import { useAPIClient } from '@nocobase/client';
20
+ import { useApp } from '@nocobase/client-v2';
21
21
  import { useT } from '../locale';
22
22
  import { SkillEditor } from './SkillEditor';
23
23
  import { SkillTestPanel } from './SkillTestPanel';
@@ -26,7 +26,7 @@ import { GitSkillImport } from './GitSkillImport';
26
26
  const { TextArea } = Input;
27
27
 
28
28
  export const SkillManager: React.FC = () => {
29
- const api = useAPIClient();
29
+ const api = useApp().apiClient;
30
30
  const t = useT();
31
31
  const [skills, setSkills] = useState<any[]>([]);
32
32
  const [loading, setLoading] = useState(false);
@@ -1,13 +1,13 @@
1
1
  import React, { useState, useEffect, useCallback, useMemo } from 'react';
2
2
  import { Card, Table, Typography, Space, Row, Col, Statistic, Progress } from 'antd';
3
3
  import { SyncOutlined, CheckCircleOutlined, CloseCircleOutlined, ClockCircleOutlined } from '@ant-design/icons';
4
- import { useAPIClient } from '@nocobase/client';
4
+ import { useApp } from '@nocobase/client-v2';
5
5
  import { useT } from '../locale';
6
6
 
7
7
  const { Title, Text } = Typography;
8
8
 
9
9
  export const SkillMetrics: React.FC = () => {
10
- const api = useAPIClient();
10
+ const api = useApp().apiClient;
11
11
  const t = useT();
12
12
  const [executions, setExecutions] = useState<any[]>([]);
13
13
  const [loading, setLoading] = useState(false);
@@ -1,8 +1,9 @@
1
1
  import React, { useState } from 'react';
2
2
  import { Modal, Input, Button, Alert, Typography, Space, Spin } from 'antd';
3
- import { useAPIClient, Upload } from '@nocobase/client';
4
- import { useT } from '../locale';
5
- import { parseJsonText } from '../utils/jsonFields';
3
+ import { Upload } from '@nocobase/client';
4
+ import { useApp } from '@nocobase/client-v2';
5
+ import { useT } from '../locale';
6
+ import { parseJsonText } from '../utils/jsonFields';
6
7
 
7
8
  const { TextArea } = Input;
8
9
 
@@ -11,16 +12,16 @@ interface SkillTestPanelProps {
11
12
  onClose: () => void;
12
13
  }
13
14
 
14
- export const SkillTestPanel: React.FC<SkillTestPanelProps> = ({ skill, onClose }) => {
15
- const api = useAPIClient();
16
- const t = useT();
17
- const inputSchema = parseJsonText(skill.inputSchema, null);
18
- const [input, setInput] = useState(
19
- inputSchema?.properties
20
- ? JSON.stringify(
21
- Object.fromEntries(
22
- Object.keys(inputSchema.properties).map((k) => [k, '']),
23
- ),
15
+ export const SkillTestPanel: React.FC<SkillTestPanelProps> = ({ skill, onClose }) => {
16
+ const api = useApp().apiClient;
17
+ const t = useT();
18
+ const inputSchema = parseJsonText(skill.inputSchema, null);
19
+ const [input, setInput] = useState(
20
+ inputSchema?.properties
21
+ ? JSON.stringify(
22
+ Object.fromEntries(
23
+ Object.keys(inputSchema.properties).map((k) => [k, '']),
24
+ ),
24
25
  null,
25
26
  2,
26
27
  )
@@ -1,4 +1,4 @@
1
- import { useApp } from '@nocobase/client';
1
+ import { useApp } from '@nocobase/client-v2';
2
2
  import { useCallback } from 'react';
3
3
  export const namespace = 'plugin-agent-orchestrator';
4
4
 
@@ -1,5 +1,5 @@
1
1
  import React, { createContext, useContext, useEffect, useState } from 'react';
2
- import { useAPIClient } from '@nocobase/client';
2
+ import { useApp } from '@nocobase/client-v2';
3
3
  import { parseJsonText } from '../utils/jsonFields';
4
4
  import { InteractionSchema } from './loopTemplates';
5
5
 
@@ -7,7 +7,7 @@ const Ctx = createContext<Map<string, InteractionSchema>>(new Map());
7
7
 
8
8
  export const useInteractionSchemas = () => useContext(Ctx);
9
9
 
10
- type ApiClientWithAuth = ReturnType<typeof useAPIClient> & {
10
+ type ApiClientWithAuth = ReturnType<typeof useApp>['apiClient'] & {
11
11
  auth?: {
12
12
  getToken?: () => string | null | undefined;
13
13
  token?: string | null;
@@ -28,7 +28,7 @@ const sanitize = (name: string) =>
28
28
  .replace(/^_|_$/g, '');
29
29
 
30
30
  export const InteractionSchemasProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) => {
31
- const api = useAPIClient() as ApiClientWithAuth;
31
+ const api = useApp().apiClient as ApiClientWithAuth;
32
32
  const authToken = api.auth?.getToken?.() || api.auth?.token || '';
33
33
  const [map, setMap] = useState<Map<string, InteractionSchema>>(new Map());
34
34
  const [version, setVersion] = useState(0);
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Alert, Button, Card, Input, List, Space, Tag, Typography, message } from 'antd';
3
- import { ToolsUIProperties, useAPIClient } from '@nocobase/client';
3
+ import { ToolsUIProperties } from '@nocobase/client';
4
+ import { useApp } from '@nocobase/client-v2';
4
5
 
5
6
  const { Paragraph, Text } = Typography;
6
7
 
@@ -18,7 +19,7 @@ const summarizeArgsPlan = (plan: any[]) =>
18
19
  }));
19
20
 
20
21
  export const PlanApprovalCard: React.FC<ToolsUIProperties> = ({ toolCall, decisions }) => {
21
- const api = useAPIClient();
22
+ const api = useApp().apiClient;
22
23
  const rawArgs = (toolCall.args as Record<string, any>) || {};
23
24
  const runId = rawArgs.runId;
24
25
  const [detail, setDetail] = React.useState<any>(null);