agentworkshop 0.7.61 → 0.7.63
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/.AgentWorkShop/prompts/host-tools.json +2488 -2526
- package/.output/.AgentWorkShop/prompts/host-tools.json +2488 -2526
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{DKHA3XxF.js → B5RD2ZST.js} +1 -1
- package/.output/public/_nuxt/{CeEzUIvN.js → DAfWhONg.js} +2 -2
- package/.output/public/_nuxt/{analysis.DfMg76el.css → analysis.BwhKdel9.css} +1 -1
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/3097fe87-dd0d-4037-b7bb-ead0620af56b.json +1 -0
- package/.output/server/chunks/_/nitro.mjs +2186 -2281
- package/.output/server/chunks/_/nitro.mjs.map +1 -1
- package/.output/server/chunks/build/{analysis-MVEnlO7A.mjs → analysis-CPIxT0FP.mjs} +5 -5
- package/.output/server/chunks/build/{analysis-MVEnlO7A.mjs.map → analysis-CPIxT0FP.mjs.map} +1 -1
- package/.output/server/chunks/routes/renderer.mjs +1 -1
- package/.output/server/chunks/virtual/entry.mjs +1 -1
- package/.output/server/chunks/virtual/precomputed.mjs +1 -1
- package/.output/server/package.json +1 -1
- package/README-zh.md +946 -945
- package/README.md +970 -969
- package/app/components/analysis/AnalysisEditModal.vue +192 -192
- package/config.yml +180 -180
- package/docs/cli.en.md +447 -447
- package/docs/cli.md +412 -412
- package/docs/full-test-plan.md +1 -1
- package/docs/plugins.en.md +1 -1
- package/docs/plugins.md +1 -1
- package/docs/sdk.en.md +1 -1
- package/docs/sdk.md +1 -1
- package/package.json +181 -181
- package/scripts/e2e-plc-plugin-closedloop.mjs +1 -1
- package/server/api/workshop/analysis/[id].patch.ts +100 -100
- package/server/plugins-builtin/diag-bridge/host/diagnosis.mjs +4 -2
- package/server/plugins-builtin/diag-bridge/host/plugin.mjs +2 -0
- package/server/services/workshop/agents/host-tool-bridge/dispatch.ts +241 -243
- package/server/services/workshop/agents/host-tool-bridge/tools/industrial.ts +96 -98
- package/server/services/workshop/agents/industrial/daq-tools.ts +16 -7
- package/server/services/workshop/agents/industrial/dcw-tools.ts +210 -255
- package/server/services/workshop/agents/industrial/index.ts +32 -32
- package/server/services/workshop/agents/industrial/param-tools.ts +0 -40
- package/server/services/workshop/prompts/loader.ts +15 -2
- package/.output/public/_nuxt/builds/meta/eba8574d-1991-47df-944c-18608bb58181.json +0 -1
|
@@ -1,98 +1,96 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 工业工具族(my_industrial_nodes / aml_* / dcw_* / param_* / daq_* / ops_log / recipe_* / line_context / analysis_*)。
|
|
3
|
-
*
|
|
4
|
-
* 原 dispatchHostTool 首个 switch 的 26 个转发分支按行搬运到本模块:每个分支都只是
|
|
5
|
-
* 「按 agentId 查绑定与节点后转交 industrial 模块的同名函数」,因此把闭包捕获的
|
|
6
|
-
* (identity.agentId, args) 收敛为显式参数,并整理成「工具名 → 处理器」一张表。
|
|
7
|
-
* 工具名集合与处理器表同源(INDUSTRIAL_TOOL_NAMES 由表键导出),不会出现有名字无处理器的分支。
|
|
8
|
-
*
|
|
9
|
-
* 该族**不依赖 workspace**,由 dispatch 在 workspace 门控之前分流(保持原分发顺序)。
|
|
10
|
-
*/
|
|
11
|
-
import type { HostToolResult } from '../types'
|
|
12
|
-
import { toolLineStart, toolLineStop, toolLineStatus, toolAmlDatasetBuild, toolAmlDatasetStats, toolAmlJobCancel, toolAmlJobLogs, toolAmlJobStatus, toolAmlJobSubmit, toolAmlLeaderboard, toolAmlModelFind, toolAmlModelPromote, toolAmlModelReference, toolAmlNodeCatalog, toolAmlTrainingPlanCreate, toolAmlTrainingPlanList, toolAmlTrainingPlanTrain, toolDaqExport, toolDaqFrames, toolDaqQuery, toolDcwControl, toolDcwJudge, toolDcwJournal,
|
|
13
|
-
|
|
14
|
-
import { toolExpCollect } from '../../industrial/exp-tools'
|
|
15
|
-
import { toolRecipePropose } from '../../industrial/recipe-propose-tools'
|
|
16
|
-
import { toolAmlActivity } from '../../industrial/aml-activity'
|
|
17
|
-
|
|
18
|
-
type IndustrialToolHandler = (agentId: string, args: Record<string, unknown>, channelId?: string) => Promise<HostToolResult>
|
|
19
|
-
|
|
20
|
-
/** 工具名 → 转发处理器(顺序与原 dispatch 首个 switch 的分支顺序一致) */
|
|
21
|
-
const INDUSTRIAL_HANDLERS = new Map<string, IndustrialToolHandler>([
|
|
22
|
-
['my_industrial_nodes', agentId => toolMyIndustrialNodes(agentId)],
|
|
23
|
-
['aml_node_catalog', agentId => toolAmlNodeCatalog(agentId)],
|
|
24
|
-
['aml_dataset_build', (agentId, args) => toolAmlDatasetBuild(agentId, args as Parameters<typeof toolAmlDatasetBuild>[1])],
|
|
25
|
-
['aml_dataset_stats', (agentId, args) => toolAmlDatasetStats(agentId, args as Parameters<typeof toolAmlDatasetStats>[1])],
|
|
26
|
-
['aml_job_submit', (agentId, args) => toolAmlJobSubmit(agentId, args as Parameters<typeof toolAmlJobSubmit>[1])],
|
|
27
|
-
['aml_job_status', (agentId, args) => toolAmlJobStatus(agentId, args as Parameters<typeof toolAmlJobStatus>[1])],
|
|
28
|
-
['aml_job_logs', (agentId, args) => toolAmlJobLogs(agentId, args as Parameters<typeof toolAmlJobLogs>[1])],
|
|
29
|
-
['aml_job_cancel', (agentId, args) => toolAmlJobCancel(agentId, args as Parameters<typeof toolAmlJobCancel>[1])],
|
|
30
|
-
['aml_leaderboard', (agentId, args) => toolAmlLeaderboard(agentId, args as Parameters<typeof toolAmlLeaderboard>[1])],
|
|
31
|
-
['aml_model_find', (agentId, args) => toolAmlModelFind(agentId, args as Parameters<typeof toolAmlModelFind>[1])],
|
|
32
|
-
['aml_model_promote', (agentId, args) => toolAmlModelPromote(agentId, args as Parameters<typeof toolAmlModelPromote>[1])],
|
|
33
|
-
['aml_model_reference', (agentId, args) => toolAmlModelReference(agentId, args as Parameters<typeof toolAmlModelReference>[1])],
|
|
34
|
-
['aml_training_plan_list', (agentId, args) => toolAmlTrainingPlanList(agentId, args)],
|
|
35
|
-
['aml_training_plan_create', (agentId, args) => toolAmlTrainingPlanCreate(agentId, args as Parameters<typeof toolAmlTrainingPlanCreate>[1])],
|
|
36
|
-
['aml_training_plan_train', (agentId, args) => toolAmlTrainingPlanTrain(agentId, args as Parameters<typeof toolAmlTrainingPlanTrain>[1])],
|
|
37
|
-
['twin_provider_catalog', (agentId, args) => toolTwinProviderCatalog(agentId, args)],
|
|
38
|
-
['twin_scene_discover', (agentId, args) => toolTwinSceneDiscover(agentId, args)],
|
|
39
|
-
['twin_scene_compile', (agentId, args) => toolTwinSceneCompile(agentId, args)],
|
|
40
|
-
['twin_scene_freeze', (agentId, args) => toolTwinSceneFreeze(agentId, args)],
|
|
41
|
-
['twin_physics_spec_draft', (agentId, args) => toolTwinPhysicsSpecDraft(agentId, args)],
|
|
42
|
-
['twin_physics_spec_validate', (agentId, args) => toolTwinPhysicsSpecValidate(agentId, args)],
|
|
43
|
-
['twin_physics_spec_compile', (agentId, args) => toolTwinPhysicsSpecCompile(agentId, args)],
|
|
44
|
-
['twin_scene_read', (agentId, args) => toolTwinSceneRead(agentId, args)],
|
|
45
|
-
['twin_snapshot_create', (agentId, args) => toolTwinSnapshotCreate(agentId, args)],
|
|
46
|
-
['twin_trial_run', (agentId, args) => toolTwinTrialRun(agentId, args)],
|
|
47
|
-
['mpc_optimize', (agentId, args) => toolMpcOptimize(agentId, args)],
|
|
48
|
-
['twin_gate_evaluate', (agentId, args) => toolTwinGateEvaluate(agentId, args)],
|
|
49
|
-
['twin_calibration_request', (agentId, args) => toolTwinCalibrationRequest(agentId, args)],
|
|
50
|
-
['optimization_explore', (agentId, args, channelId) => toolOptimizationExplore(agentId, args as Parameters<typeof toolOptimizationExplore>[1], channelId)],
|
|
51
|
-
['twin_bayes_optimize', (agentId, args) => toolTwinBayesOptimize(agentId, args)],
|
|
52
|
-
['dcw_control', (agentId, args, channelId) => toolDcwControl(agentId, args as { node_id?: string, value?: number | string, hypothesis?: string, task_id?: string }, channelId)],
|
|
53
|
-
['
|
|
54
|
-
['
|
|
55
|
-
['
|
|
56
|
-
['
|
|
57
|
-
['
|
|
58
|
-
['
|
|
59
|
-
['
|
|
60
|
-
['
|
|
61
|
-
['
|
|
62
|
-
['
|
|
63
|
-
['
|
|
64
|
-
['
|
|
65
|
-
['
|
|
66
|
-
['
|
|
67
|
-
['
|
|
68
|
-
['
|
|
69
|
-
['
|
|
70
|
-
['
|
|
71
|
-
['
|
|
72
|
-
['
|
|
73
|
-
|
|
74
|
-
['
|
|
75
|
-
|
|
76
|
-
['
|
|
77
|
-
['
|
|
78
|
-
['
|
|
79
|
-
|
|
80
|
-
['
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
*
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return handler(agentId, args, channelId)
|
|
98
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 工业工具族(my_industrial_nodes / aml_* / dcw_* / param_* / daq_* / ops_log / recipe_* / line_context / analysis_*)。
|
|
3
|
+
*
|
|
4
|
+
* 原 dispatchHostTool 首个 switch 的 26 个转发分支按行搬运到本模块:每个分支都只是
|
|
5
|
+
* 「按 agentId 查绑定与节点后转交 industrial 模块的同名函数」,因此把闭包捕获的
|
|
6
|
+
* (identity.agentId, args) 收敛为显式参数,并整理成「工具名 → 处理器」一张表。
|
|
7
|
+
* 工具名集合与处理器表同源(INDUSTRIAL_TOOL_NAMES 由表键导出),不会出现有名字无处理器的分支。
|
|
8
|
+
*
|
|
9
|
+
* 该族**不依赖 workspace**,由 dispatch 在 workspace 门控之前分流(保持原分发顺序)。
|
|
10
|
+
*/
|
|
11
|
+
import type { HostToolResult } from '../types'
|
|
12
|
+
import { toolLineStart, toolLineStop, toolLineStatus, toolAmlDatasetBuild, toolAmlDatasetStats, toolAmlJobCancel, toolAmlJobLogs, toolAmlJobStatus, toolAmlJobSubmit, toolAmlLeaderboard, toolAmlModelFind, toolAmlModelPromote, toolAmlModelReference, toolAmlNodeCatalog, toolAmlTrainingPlanCreate, toolAmlTrainingPlanList, toolAmlTrainingPlanTrain, toolDaqExport, toolDaqFrames, toolDaqQuery, toolDcwControl, toolDcwJudge, toolDcwJournal, toolDcwRollback, toolLineContext, toolMesCatalog, toolMesDatasetRead, toolMesDatasets, toolMesFetch, toolMyIndustrialNodes, toolOpsLog, toolParamControl, toolRecipeApply, toolRecipeLog, toolRecipeRollback, toolRecipeTrial, toolRecipeUpdate, toolRecipeVersions, toolOptimizationExplore, toolTwinProviderCatalog, toolTwinSceneDiscover, toolTwinSceneCompile, toolTwinSceneFreeze, toolTwinSceneRead, toolTwinPhysicsSpecDraft, toolTwinPhysicsSpecValidate, toolTwinPhysicsSpecCompile, toolTwinSnapshotCreate, toolTwinTrialRun, toolMpcOptimize, toolTwinGateEvaluate, toolTwinBayesOptimize, toolTwinCalibrationRequest, toolAnalysisSave, toolAnalysisQuery } from '../../industrial'
|
|
13
|
+
|
|
14
|
+
import { toolExpCollect } from '../../industrial/exp-tools'
|
|
15
|
+
import { toolRecipePropose } from '../../industrial/recipe-propose-tools'
|
|
16
|
+
import { toolAmlActivity } from '../../industrial/aml-activity'
|
|
17
|
+
|
|
18
|
+
type IndustrialToolHandler = (agentId: string, args: Record<string, unknown>, channelId?: string) => Promise<HostToolResult>
|
|
19
|
+
|
|
20
|
+
/** 工具名 → 转发处理器(顺序与原 dispatch 首个 switch 的分支顺序一致) */
|
|
21
|
+
const INDUSTRIAL_HANDLERS = new Map<string, IndustrialToolHandler>([
|
|
22
|
+
['my_industrial_nodes', agentId => toolMyIndustrialNodes(agentId)],
|
|
23
|
+
['aml_node_catalog', agentId => toolAmlNodeCatalog(agentId)],
|
|
24
|
+
['aml_dataset_build', (agentId, args) => toolAmlDatasetBuild(agentId, args as Parameters<typeof toolAmlDatasetBuild>[1])],
|
|
25
|
+
['aml_dataset_stats', (agentId, args) => toolAmlDatasetStats(agentId, args as Parameters<typeof toolAmlDatasetStats>[1])],
|
|
26
|
+
['aml_job_submit', (agentId, args) => toolAmlJobSubmit(agentId, args as Parameters<typeof toolAmlJobSubmit>[1])],
|
|
27
|
+
['aml_job_status', (agentId, args) => toolAmlJobStatus(agentId, args as Parameters<typeof toolAmlJobStatus>[1])],
|
|
28
|
+
['aml_job_logs', (agentId, args) => toolAmlJobLogs(agentId, args as Parameters<typeof toolAmlJobLogs>[1])],
|
|
29
|
+
['aml_job_cancel', (agentId, args) => toolAmlJobCancel(agentId, args as Parameters<typeof toolAmlJobCancel>[1])],
|
|
30
|
+
['aml_leaderboard', (agentId, args) => toolAmlLeaderboard(agentId, args as Parameters<typeof toolAmlLeaderboard>[1])],
|
|
31
|
+
['aml_model_find', (agentId, args) => toolAmlModelFind(agentId, args as Parameters<typeof toolAmlModelFind>[1])],
|
|
32
|
+
['aml_model_promote', (agentId, args) => toolAmlModelPromote(agentId, args as Parameters<typeof toolAmlModelPromote>[1])],
|
|
33
|
+
['aml_model_reference', (agentId, args) => toolAmlModelReference(agentId, args as Parameters<typeof toolAmlModelReference>[1])],
|
|
34
|
+
['aml_training_plan_list', (agentId, args) => toolAmlTrainingPlanList(agentId, args)],
|
|
35
|
+
['aml_training_plan_create', (agentId, args) => toolAmlTrainingPlanCreate(agentId, args as Parameters<typeof toolAmlTrainingPlanCreate>[1])],
|
|
36
|
+
['aml_training_plan_train', (agentId, args) => toolAmlTrainingPlanTrain(agentId, args as Parameters<typeof toolAmlTrainingPlanTrain>[1])],
|
|
37
|
+
['twin_provider_catalog', (agentId, args) => toolTwinProviderCatalog(agentId, args)],
|
|
38
|
+
['twin_scene_discover', (agentId, args) => toolTwinSceneDiscover(agentId, args)],
|
|
39
|
+
['twin_scene_compile', (agentId, args) => toolTwinSceneCompile(agentId, args)],
|
|
40
|
+
['twin_scene_freeze', (agentId, args) => toolTwinSceneFreeze(agentId, args)],
|
|
41
|
+
['twin_physics_spec_draft', (agentId, args) => toolTwinPhysicsSpecDraft(agentId, args)],
|
|
42
|
+
['twin_physics_spec_validate', (agentId, args) => toolTwinPhysicsSpecValidate(agentId, args)],
|
|
43
|
+
['twin_physics_spec_compile', (agentId, args) => toolTwinPhysicsSpecCompile(agentId, args)],
|
|
44
|
+
['twin_scene_read', (agentId, args) => toolTwinSceneRead(agentId, args)],
|
|
45
|
+
['twin_snapshot_create', (agentId, args) => toolTwinSnapshotCreate(agentId, args)],
|
|
46
|
+
['twin_trial_run', (agentId, args) => toolTwinTrialRun(agentId, args)],
|
|
47
|
+
['mpc_optimize', (agentId, args) => toolMpcOptimize(agentId, args)],
|
|
48
|
+
['twin_gate_evaluate', (agentId, args) => toolTwinGateEvaluate(agentId, args)],
|
|
49
|
+
['twin_calibration_request', (agentId, args) => toolTwinCalibrationRequest(agentId, args)],
|
|
50
|
+
['optimization_explore', (agentId, args, channelId) => toolOptimizationExplore(agentId, args as Parameters<typeof toolOptimizationExplore>[1], channelId)],
|
|
51
|
+
['twin_bayes_optimize', (agentId, args) => toolTwinBayesOptimize(agentId, args)],
|
|
52
|
+
['dcw_control', (agentId, args, channelId) => toolDcwControl(agentId, args as { node_id?: string, value?: number | string, hypothesis?: string, task_id?: string }, channelId)],
|
|
53
|
+
['param_control', (agentId, args, channelId) => toolParamControl(agentId, args as { param?: string, value?: number | string, hypothesis?: string, task_id?: string, line_id?: string }, channelId)],
|
|
54
|
+
['daq_query', (agentId, args) => toolDaqQuery(agentId, args as Parameters<typeof toolDaqQuery>[1])],
|
|
55
|
+
['daq_export', (agentId, args) => toolDaqExport(agentId, args as Parameters<typeof toolDaqExport>[1])],
|
|
56
|
+
['daq_frames', (agentId, args) => toolDaqFrames(agentId, args as Parameters<typeof toolDaqFrames>[1])],
|
|
57
|
+
['dcw_judge', (agentId, args) => toolDcwJudge(agentId, args as { record_id?: string, verdict?: string, reason?: string })],
|
|
58
|
+
['dcw_rollback', (agentId, args) => toolDcwRollback(agentId, args as { record_id?: string, node_id?: string, to?: string })],
|
|
59
|
+
['dcw_journal', (agentId, args) => toolDcwJournal(agentId, args as { node_id?: string, recipe_id?: string, limit?: number | string })],
|
|
60
|
+
['ops_log', (agentId, args) => toolOpsLog(agentId, args as Parameters<typeof toolOpsLog>[1])],
|
|
61
|
+
['recipe_log', (agentId, args) => toolRecipeLog(agentId, args as Parameters<typeof toolRecipeLog>[1])],
|
|
62
|
+
['line_context', (agentId, args) => toolLineContext(agentId, args as { line_id?: string })],
|
|
63
|
+
['recipe_versions', (agentId, args) => toolRecipeVersions(agentId, args as { recipe_id?: string, limit?: number | string })],
|
|
64
|
+
['recipe_update', (agentId, args) => toolRecipeUpdate(agentId, args as Parameters<typeof toolRecipeUpdate>[1])],
|
|
65
|
+
['recipe_rollback', (agentId, args) => toolRecipeRollback(agentId, args as Parameters<typeof toolRecipeRollback>[1])],
|
|
66
|
+
['recipe_trial', (agentId, args) => toolRecipeTrial(agentId, args as Parameters<typeof toolRecipeTrial>[1])],
|
|
67
|
+
['recipe_apply', (agentId, args) => toolRecipeApply(agentId, args as Parameters<typeof toolRecipeApply>[1])],
|
|
68
|
+
['mes_catalog', (agentId, args) => toolMesCatalog(agentId, args as Parameters<typeof toolMesCatalog>[1])],
|
|
69
|
+
['mes_fetch', (agentId, args) => toolMesFetch(agentId, args as Parameters<typeof toolMesFetch>[1])],
|
|
70
|
+
['mes_dataset_read', (agentId, args) => toolMesDatasetRead(agentId, args as Parameters<typeof toolMesDatasetRead>[1])],
|
|
71
|
+
['mes_datasets', (agentId, args) => toolMesDatasets(agentId, args as Parameters<typeof toolMesDatasets>[1])],
|
|
72
|
+
['exp_collect', (agentId, args) => toolExpCollect(agentId, args as { line_id?: string, lineId?: string })],
|
|
73
|
+
// 产线 Co-Pilot P2(诊断工程师下发面):整包方案审批 + AML 活动硬闸自查
|
|
74
|
+
['recipe_propose', (agentId, args) => toolRecipePropose(agentId, args as Parameters<typeof toolRecipePropose>[1])],
|
|
75
|
+
['line_start', (agentId, args, channelId) => toolLineStart(agentId, args as Parameters<typeof toolLineStart>[1], channelId)],
|
|
76
|
+
['line_stop', (agentId, args, channelId) => toolLineStop(agentId, args as Parameters<typeof toolLineStop>[1], channelId)],
|
|
77
|
+
['line_status', (agentId, args, channelId) => toolLineStatus(agentId, args as Parameters<typeof toolLineStatus>[1], channelId)],
|
|
78
|
+
['aml_activity', (agentId, args) => toolAmlActivity(agentId, args as { line_id?: string })],
|
|
79
|
+
// 数据分析系统:分析结果留痕台账(save 可写台账(非产线写);query 查历史留痕)
|
|
80
|
+
['analysis_save', (agentId, args, channelId) => toolAnalysisSave(agentId, args as Parameters<typeof toolAnalysisSave>[1], channelId)],
|
|
81
|
+
['analysis_query', (agentId, args) => toolAnalysisQuery(agentId, args as Parameters<typeof toolAnalysisQuery>[1])],
|
|
82
|
+
])
|
|
83
|
+
|
|
84
|
+
/** 工业工具名集合(与 INDUSTRIAL_HANDLERS 同源;dispatch 据此在 workspace 门控前分流) */
|
|
85
|
+
export const INDUSTRIAL_TOOL_NAMES: ReadonlySet<string> = new Set(INDUSTRIAL_HANDLERS.keys())
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* 工业工具族分发:按工具名转交 industrial 模块(调用参数与该族原分支逐字一致)。
|
|
89
|
+
* 调用方先经 INDUSTRIAL_TOOL_NAMES 判断,故「未登记的工具名」不可达 —— 仍然显式拒绝,
|
|
90
|
+
* 避免静默返回与未知工具混淆。
|
|
91
|
+
*/
|
|
92
|
+
export function dispatchIndustrialTool(agentId: string, toolName: string, args: Record<string, unknown>, channelId?: string): Promise<HostToolResult> {
|
|
93
|
+
const handler = INDUSTRIAL_HANDLERS.get(toolName)
|
|
94
|
+
if (!handler) return Promise.reject(new Error(`未知工业工具: ${toolName}`))
|
|
95
|
+
return handler(agentId, args, channelId)
|
|
96
|
+
}
|
|
@@ -8,9 +8,12 @@ import { getActiveLineRun } from '../../dcw/line-run'
|
|
|
8
8
|
import { getAgentNodeBindingRepo } from '../node-bindings.repo'
|
|
9
9
|
import { getDaqNodeRepo } from '../../daq/daq-node.repo'
|
|
10
10
|
import { getDcwController } from '../../dcw/dcw-controller'
|
|
11
|
+
import { channelBoundLineId } from './ops-tools'
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
|
-
* 数采目标集解析(工具共用鉴权面):
|
|
14
|
+
* 数采目标集解析(工具共用鉴权面):
|
|
15
|
+
* ① Agent 绑定(kind=daq);② v28 频道绑线只读扩权 —— 频道绑定产线下的数采节点
|
|
16
|
+
* 并入读取集(与 ops_log/line_context 的绑线只读扩权同族;本函数仅服务只读查询面)。
|
|
14
17
|
* node_id/line_id 只能缩小范围,不能放大(越权节点一律拒绝)。
|
|
15
18
|
*/
|
|
16
19
|
export function daqTargetsOf(agentId: string, nodeIdArg: unknown, lineIdArg: unknown):
|
|
@@ -18,23 +21,29 @@ export function daqTargetsOf(agentId: string, nodeIdArg: unknown, lineIdArg: unk
|
|
|
18
21
|
| { error: { text: string, isError: true } } {
|
|
19
22
|
const repo = getAgentNodeBindingRepo()
|
|
20
23
|
const daqBindings = repo.byAgent(agentId).filter(b => b.kind === 'daq')
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
// v28:频道绑线的数采节点并入可见集(只读)
|
|
25
|
+
const boundLine = channelBoundLineId(agentId)
|
|
26
|
+
const boundLineNodes = boundLine
|
|
27
|
+
? getDaqNodeRepo().all().filter(n => n.lineId === boundLine).map(n => n.id)
|
|
28
|
+
: []
|
|
29
|
+
const readable = new Set([...daqBindings.map(b => b.nodeId), ...boundLineNodes])
|
|
30
|
+
if (readable.size === 0) {
|
|
31
|
+
return { error: { text: '你尚未绑定任何数采节点,频道也未绑定产线,无权查询采集数据。请在数字孪生界面绑定数采节点,或将频道绑定到目标产线(绑线后可只读查询该线数采数据)。', isError: true } }
|
|
23
32
|
}
|
|
24
33
|
const wanted = nodeIdArg ? String(nodeIdArg) : ''
|
|
25
|
-
if (wanted && !
|
|
26
|
-
return { error: { text: `无权查询节点 ${wanted}。你有权访问的数采节点:${
|
|
34
|
+
if (wanted && !readable.has(wanted)) {
|
|
35
|
+
return { error: { text: `无权查询节点 ${wanted}。你有权访问的数采节点:${[...readable].join(', ')}`, isError: true } }
|
|
27
36
|
}
|
|
28
37
|
const lineFilter = lineIdArg ? String(lineIdArg).trim() : ''
|
|
29
38
|
const lineOf = (id: string): string => getDaqNodeRepo().byId(id)?.lineId ?? ''
|
|
30
39
|
if (lineFilter && wanted && lineOf(wanted) !== lineFilter) {
|
|
31
40
|
return { error: { text: `节点 ${wanted} 不属于产线 ${lineFilter}(实际归属:${lineOf(wanted) || '未分配'}),line_id 与 node_id 过滤冲突。`, isError: true } }
|
|
32
41
|
}
|
|
33
|
-
let targets = wanted ? [wanted] :
|
|
42
|
+
let targets = wanted ? [wanted] : [...readable]
|
|
34
43
|
if (lineFilter && !wanted) {
|
|
35
44
|
const onLine = targets.filter(id => lineOf(id) === lineFilter)
|
|
36
45
|
if (onLine.length === 0) {
|
|
37
|
-
return { error: { text:
|
|
46
|
+
return { error: { text: `你有权访问的数采节点中没有归属产线 ${lineFilter} 的(各节点归属:${[...readable].map(id => `${id}=${lineOf(id) || '未分配'}`).join('; ')})。`, isError: true } }
|
|
38
47
|
}
|
|
39
48
|
targets = onLine
|
|
40
49
|
}
|