@memberjunction/ng-record-process-studio 6.2.0-edge.0 → 6.2.0-edge.2
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/dist/lib/feature-pipeline-builder/feature-pipeline-builder.component.d.ts +211 -11
- package/dist/lib/feature-pipeline-builder/feature-pipeline-builder.component.d.ts.map +1 -1
- package/dist/lib/feature-pipeline-builder/feature-pipeline-builder.component.js +1639 -400
- package/dist/lib/feature-pipeline-builder/feature-pipeline-builder.component.js.map +1 -1
- package/dist/lib/record-process-editor/record-process-editor.component.d.ts +10 -0
- package/dist/lib/record-process-editor/record-process-editor.component.d.ts.map +1 -1
- package/dist/lib/record-process-editor/record-process-editor.component.js +25 -5
- package/dist/lib/record-process-editor/record-process-editor.component.js.map +1 -1
- package/dist/lib/record-process-history/record-process-history.component.d.ts +10 -0
- package/dist/lib/record-process-history/record-process-history.component.d.ts.map +1 -1
- package/dist/lib/record-process-history/record-process-history.component.js +30 -10
- package/dist/lib/record-process-history/record-process-history.component.js.map +1 -1
- package/dist/lib/record-process-studio/record-process-studio.component.d.ts +12 -0
- package/dist/lib/record-process-studio/record-process-studio.component.d.ts.map +1 -1
- package/dist/lib/record-process-studio/record-process-studio.component.js +31 -7
- package/dist/lib/record-process-studio/record-process-studio.component.js.map +1 -1
- package/dist/lib/run-detail.d.ts +4 -0
- package/dist/lib/run-detail.d.ts.map +1 -1
- package/dist/lib/run-detail.js +10 -2
- package/dist/lib/run-detail.js.map +1 -1
- package/package.json +10 -10
|
@@ -10,70 +10,103 @@ import { CommonModule } from '@angular/common';
|
|
|
10
10
|
import { FormsModule } from '@angular/forms';
|
|
11
11
|
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
12
12
|
import { LogError, RunView } from '@memberjunction/core';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
13
|
+
import { KnowledgeHubMetadataEngine, } from '@memberjunction/core-entities';
|
|
14
|
+
import { renderConstraintBlock, validateSpec, GetFeaturePipelineCapabilities, ValidateOutputsAgainstCapabilities, FindEscalationTargetRowProblem, FindEscalationTargetSpecProblem, } from '@memberjunction/feature-pipelines';
|
|
15
|
+
import { EscapeSQLString, SafeJSONParse, UUIDsEqual } from '@memberjunction/global';
|
|
16
|
+
import { MJButtonDirective, MJConfirmDialogComponent } from '@memberjunction/ng-ui-components';
|
|
16
17
|
import * as i0 from "@angular/core";
|
|
17
18
|
import * as i1 from "@angular/forms";
|
|
18
|
-
const _forTrack0 = ($index, $item) => $item.
|
|
19
|
-
const _forTrack1 = ($index, $item) => $item.
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
const _forTrack0 = ($index, $item) => $item.Name;
|
|
20
|
+
const _forTrack1 = ($index, $item) => $item.ID;
|
|
21
|
+
const _forTrack2 = ($index, $item) => $item.Value;
|
|
22
|
+
function FeaturePipelineBuilderComponent_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
23
|
+
i0.ɵɵelementStart(0, "option", 5);
|
|
22
24
|
i0.ɵɵtext(1);
|
|
23
25
|
i0.ɵɵelementEnd();
|
|
24
26
|
} if (rf & 2) {
|
|
25
|
-
const
|
|
26
|
-
i0.ɵɵ
|
|
27
|
+
const t_r1 = ctx.$implicit;
|
|
28
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
29
|
+
i0.ɵɵproperty("value", t_r1.Name)("selected", ctx_r1.IsCurrentPipelineType(t_r1.Name));
|
|
30
|
+
i0.ɵɵadvance();
|
|
31
|
+
i0.ɵɵtextInterpolate(t_r1.DisplayName || t_r1.Name);
|
|
32
|
+
} }
|
|
33
|
+
function FeaturePipelineBuilderComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
34
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
35
|
+
i0.ɵɵelementStart(0, "div", 7)(1, "div", 3)(2, "label");
|
|
36
|
+
i0.ɵɵtext(3, "Capture Reasoning");
|
|
37
|
+
i0.ɵɵelementEnd();
|
|
38
|
+
i0.ɵɵelementStart(4, "select", 36);
|
|
39
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_14_Template_select_change_4_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.UpdateCaptureReasoning($event)); });
|
|
40
|
+
i0.ɵɵelementStart(5, "option", 30);
|
|
41
|
+
i0.ɵɵtext(6, "Yes \u2014 Keep the model's rationale with each Feature Value");
|
|
42
|
+
i0.ɵɵelementEnd();
|
|
43
|
+
i0.ɵɵelementStart(7, "option", 31);
|
|
44
|
+
i0.ɵɵtext(8, "No");
|
|
45
|
+
i0.ɵɵelementEnd()()()();
|
|
46
|
+
} if (rf & 2) {
|
|
47
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
48
|
+
i0.ɵɵadvance(4);
|
|
49
|
+
i0.ɵɵproperty("value", ctx_r1.spec.CaptureReasoning ? "true" : "false");
|
|
50
|
+
} }
|
|
51
|
+
function FeaturePipelineBuilderComponent_Conditional_34_For_7_Template(rf, ctx) { if (rf & 1) {
|
|
52
|
+
i0.ɵɵelementStart(0, "option", 5);
|
|
53
|
+
i0.ɵɵtext(1);
|
|
54
|
+
i0.ɵɵelementEnd();
|
|
55
|
+
} if (rf & 2) {
|
|
56
|
+
const doc_r5 = ctx.$implicit;
|
|
57
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
58
|
+
i0.ɵɵproperty("value", doc_r5.ID)("selected", ctx_r1.IsSavedEntityDoc(doc_r5));
|
|
27
59
|
i0.ɵɵadvance();
|
|
28
|
-
i0.ɵɵtextInterpolate(
|
|
60
|
+
i0.ɵɵtextInterpolate(doc_r5.Name);
|
|
29
61
|
} }
|
|
30
|
-
function
|
|
31
|
-
const
|
|
32
|
-
i0.ɵɵelementStart(0, "div",
|
|
62
|
+
function FeaturePipelineBuilderComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
|
|
63
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
64
|
+
i0.ɵɵelementStart(0, "div", 3)(1, "label");
|
|
33
65
|
i0.ɵɵtext(2, "Entity Document");
|
|
34
66
|
i0.ɵɵelementEnd();
|
|
35
|
-
i0.ɵɵelementStart(3, "select",
|
|
36
|
-
i0.ɵɵlistener("change", function
|
|
37
|
-
i0.ɵɵelementStart(4, "option",
|
|
67
|
+
i0.ɵɵelementStart(3, "select", 4);
|
|
68
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_34_Template_select_change_3_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onEntityDocChange($event)); });
|
|
69
|
+
i0.ɵɵelementStart(4, "option", 18);
|
|
38
70
|
i0.ɵɵtext(5, "\u2014 Select Entity Document \u2014");
|
|
39
71
|
i0.ɵɵelementEnd();
|
|
40
|
-
i0.ɵɵrepeaterCreate(6,
|
|
72
|
+
i0.ɵɵrepeaterCreate(6, FeaturePipelineBuilderComponent_Conditional_34_For_7_Template, 2, 3, "option", 5, _forTrack1);
|
|
41
73
|
i0.ɵɵelementEnd()();
|
|
42
74
|
} if (rf & 2) {
|
|
43
75
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
44
|
-
i0.ɵɵadvance(
|
|
45
|
-
i0.ɵɵproperty("
|
|
46
|
-
i0.ɵɵadvance(
|
|
76
|
+
i0.ɵɵadvance(4);
|
|
77
|
+
i0.ɵɵproperty("selected", !ctx_r1.SavedEntityDocListed);
|
|
78
|
+
i0.ɵɵadvance(2);
|
|
47
79
|
i0.ɵɵrepeater(ctx_r1.availableDocs);
|
|
48
80
|
} }
|
|
49
|
-
function
|
|
50
|
-
const
|
|
51
|
-
i0.ɵɵelementStart(0, "div",
|
|
81
|
+
function FeaturePipelineBuilderComponent_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
82
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
83
|
+
i0.ɵɵelementStart(0, "div", 3)(1, "label");
|
|
52
84
|
i0.ɵɵtext(2, "Query ID");
|
|
53
85
|
i0.ɵɵelementEnd();
|
|
54
|
-
i0.ɵɵelementStart(3, "input",
|
|
55
|
-
i0.ɵɵlistener("input", function
|
|
86
|
+
i0.ɵɵelementStart(3, "input", 37);
|
|
87
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_35_Template_input_input_3_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onQueryIDChange($event)); });
|
|
56
88
|
i0.ɵɵelementEnd()();
|
|
57
89
|
} if (rf & 2) {
|
|
58
90
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
59
91
|
i0.ɵɵadvance(3);
|
|
60
92
|
i0.ɵɵproperty("value", ctx_r1.spec.Context.QueryID || "");
|
|
61
93
|
} }
|
|
62
|
-
function
|
|
63
|
-
i0.ɵɵelementStart(0, "option",
|
|
94
|
+
function FeaturePipelineBuilderComponent_For_54_Template(rf, ctx) { if (rf & 1) {
|
|
95
|
+
i0.ɵɵelementStart(0, "option", 5);
|
|
64
96
|
i0.ɵɵtext(1);
|
|
65
97
|
i0.ɵɵelementEnd();
|
|
66
98
|
} if (rf & 2) {
|
|
67
|
-
const
|
|
68
|
-
i0.ɵɵ
|
|
99
|
+
const p_r7 = ctx.$implicit;
|
|
100
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
101
|
+
i0.ɵɵproperty("value", p_r7.ID)("selected", ctx_r1.IsSavedPrompt(p_r7));
|
|
69
102
|
i0.ɵɵadvance();
|
|
70
|
-
i0.ɵɵtextInterpolate(
|
|
103
|
+
i0.ɵɵtextInterpolate(p_r7.Name);
|
|
71
104
|
} }
|
|
72
|
-
function
|
|
73
|
-
i0.ɵɵelementStart(0, "div",
|
|
105
|
+
function FeaturePipelineBuilderComponent_Conditional_55_Template(rf, ctx) { if (rf & 1) {
|
|
106
|
+
i0.ɵɵelementStart(0, "div", 3)(1, "label");
|
|
74
107
|
i0.ɵɵtext(2, "Prompt Description");
|
|
75
108
|
i0.ɵɵelementEnd();
|
|
76
|
-
i0.ɵɵelementStart(3, "div",
|
|
109
|
+
i0.ɵɵelementStart(3, "div", 6);
|
|
77
110
|
i0.ɵɵtext(4);
|
|
78
111
|
i0.ɵɵelementEnd()();
|
|
79
112
|
} if (rf & 2) {
|
|
@@ -81,13 +114,13 @@ function FeaturePipelineBuilderComponent_Conditional_41_Template(rf, ctx) { if (
|
|
|
81
114
|
i0.ɵɵadvance(4);
|
|
82
115
|
i0.ɵɵtextInterpolate(ctx_r1.selectedPrompt.Description || "No description provided");
|
|
83
116
|
} }
|
|
84
|
-
function
|
|
85
|
-
i0.ɵɵelementStart(0, "div",
|
|
117
|
+
function FeaturePipelineBuilderComponent_Conditional_56_Template(rf, ctx) { if (rf & 1) {
|
|
118
|
+
i0.ɵɵelementStart(0, "div", 19)(1, "label");
|
|
86
119
|
i0.ɵɵtext(2, "Injected Constraint Block ");
|
|
87
|
-
i0.ɵɵelementStart(3, "span",
|
|
120
|
+
i0.ɵɵelementStart(3, "span", 38);
|
|
88
121
|
i0.ɵɵtext(4, "\u2014 automatically appended to prompt instructions");
|
|
89
122
|
i0.ɵɵelementEnd()();
|
|
90
|
-
i0.ɵɵelementStart(5, "pre",
|
|
123
|
+
i0.ɵɵelementStart(5, "pre", 39);
|
|
91
124
|
i0.ɵɵtext(6);
|
|
92
125
|
i0.ɵɵelementEnd()();
|
|
93
126
|
} if (rf & 2) {
|
|
@@ -95,9 +128,9 @@ function FeaturePipelineBuilderComponent_Conditional_42_Template(rf, ctx) { if (
|
|
|
95
128
|
i0.ɵɵadvance(6);
|
|
96
129
|
i0.ɵɵtextInterpolate(ctx_r1.renderedConstraintPreview);
|
|
97
130
|
} }
|
|
98
|
-
function
|
|
99
|
-
i0.ɵɵelementStart(0, "div",
|
|
100
|
-
i0.ɵɵelement(1, "i",
|
|
131
|
+
function FeaturePipelineBuilderComponent_Conditional_69_Template(rf, ctx) { if (rf & 1) {
|
|
132
|
+
i0.ɵɵelementStart(0, "div", 24);
|
|
133
|
+
i0.ɵɵelement(1, "i", 40);
|
|
101
134
|
i0.ɵɵelementStart(2, "span");
|
|
102
135
|
i0.ɵɵtext(3, "No outputs defined. Click ");
|
|
103
136
|
i0.ɵɵelementStart(4, "strong");
|
|
@@ -106,243 +139,454 @@ function FeaturePipelineBuilderComponent_Conditional_55_Template(rf, ctx) { if (
|
|
|
106
139
|
i0.ɵɵtext(6, " to configure at least one output attribute.");
|
|
107
140
|
i0.ɵɵelementEnd()();
|
|
108
141
|
} }
|
|
109
|
-
function
|
|
110
|
-
i0.ɵɵelementStart(0, "option",
|
|
142
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
143
|
+
i0.ɵɵelementStart(0, "option", 18);
|
|
144
|
+
i0.ɵɵtext(1, "\u2014 Select Target Mode \u2014");
|
|
145
|
+
i0.ɵɵelementEnd();
|
|
146
|
+
} if (rf & 2) {
|
|
147
|
+
i0.ɵɵproperty("selected", true);
|
|
148
|
+
} }
|
|
149
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_For_22_Template(rf, ctx) { if (rf & 1) {
|
|
150
|
+
i0.ɵɵelementStart(0, "option", 5);
|
|
111
151
|
i0.ɵɵtext(1);
|
|
112
152
|
i0.ɵɵelementEnd();
|
|
113
153
|
} if (rf & 2) {
|
|
114
|
-
const
|
|
115
|
-
i0.ɵɵ
|
|
154
|
+
const m_r10 = ctx.$implicit;
|
|
155
|
+
const output_r11 = i0.ɵɵnextContext().$implicit;
|
|
156
|
+
i0.ɵɵproperty("value", m_r10.Value)("selected", m_r10.Value === output_r11.Target.Mode);
|
|
116
157
|
i0.ɵɵadvance();
|
|
117
|
-
i0.ɵɵ
|
|
158
|
+
i0.ɵɵtextInterpolate(m_r10.Label);
|
|
118
159
|
} }
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
-
i0.ɵɵ
|
|
160
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_24_For_7_Template(rf, ctx) { if (rf & 1) {
|
|
161
|
+
i0.ɵɵelementStart(0, "option", 5);
|
|
162
|
+
i0.ɵɵtext(1);
|
|
163
|
+
i0.ɵɵelementEnd();
|
|
164
|
+
} if (rf & 2) {
|
|
165
|
+
const f_r13 = ctx.$implicit;
|
|
166
|
+
const output_r11 = i0.ɵɵnextContext(2).$implicit;
|
|
167
|
+
i0.ɵɵproperty("value", f_r13.Name)("selected", f_r13.Name === output_r11.Target.EntityFieldName);
|
|
168
|
+
i0.ɵɵadvance();
|
|
169
|
+
i0.ɵɵtextInterpolate2("", f_r13.DisplayName || f_r13.Name, " (", f_r13.TSType, ")");
|
|
170
|
+
} }
|
|
171
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_24_Template(rf, ctx) { if (rf & 1) {
|
|
172
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
173
|
+
i0.ɵɵelementStart(0, "div", 3)(1, "label");
|
|
122
174
|
i0.ɵɵtext(2, "Target Field");
|
|
123
175
|
i0.ɵɵelementEnd();
|
|
124
|
-
i0.ɵɵelementStart(3, "select",
|
|
125
|
-
i0.ɵɵlistener("change", function
|
|
126
|
-
i0.ɵɵelementStart(4, "option",
|
|
176
|
+
i0.ɵɵelementStart(3, "select", 4);
|
|
177
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_24_Template_select_change_3_listener($event) { i0.ɵɵrestoreView(_r12); const ɵ$index_185_r9 = i0.ɵɵnextContext().$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateFieldTarget(ɵ$index_185_r9, $event)); });
|
|
178
|
+
i0.ɵɵelementStart(4, "option", 18);
|
|
127
179
|
i0.ɵɵtext(5, "\u2014 Select Column \u2014");
|
|
128
180
|
i0.ɵɵelementEnd();
|
|
129
|
-
i0.ɵɵrepeaterCreate(6,
|
|
181
|
+
i0.ɵɵrepeaterCreate(6, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_24_For_7_Template, 2, 4, "option", 5, _forTrack0);
|
|
130
182
|
i0.ɵɵelementEnd()();
|
|
131
183
|
} if (rf & 2) {
|
|
132
|
-
const
|
|
184
|
+
const output_r11 = i0.ɵɵnextContext().$implicit;
|
|
133
185
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
134
|
-
i0.ɵɵadvance(
|
|
135
|
-
i0.ɵɵproperty("
|
|
136
|
-
i0.ɵɵadvance(
|
|
186
|
+
i0.ɵɵadvance(4);
|
|
187
|
+
i0.ɵɵproperty("selected", !ctx_r1.IsEntityFieldListed(output_r11.Target.EntityFieldName));
|
|
188
|
+
i0.ɵɵadvance(2);
|
|
137
189
|
i0.ɵɵrepeater(ctx_r1.entityFields);
|
|
138
190
|
} }
|
|
139
|
-
function
|
|
140
|
-
i0.ɵɵelementStart(0, "option",
|
|
191
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_25_For_7_Template(rf, ctx) { if (rf & 1) {
|
|
192
|
+
i0.ɵɵelementStart(0, "option", 5);
|
|
141
193
|
i0.ɵɵtext(1);
|
|
142
194
|
i0.ɵɵelementEnd();
|
|
143
195
|
} if (rf & 2) {
|
|
144
|
-
const
|
|
145
|
-
i0.ɵɵ
|
|
196
|
+
const e_r15 = ctx.$implicit;
|
|
197
|
+
const output_r11 = i0.ɵɵnextContext(2).$implicit;
|
|
198
|
+
i0.ɵɵproperty("value", e_r15.Name)("selected", e_r15.Name === output_r11.Target.EntityName);
|
|
146
199
|
i0.ɵɵadvance();
|
|
147
|
-
i0.ɵɵtextInterpolate(
|
|
200
|
+
i0.ɵɵtextInterpolate(e_r15.DisplayName || e_r15.Name);
|
|
148
201
|
} }
|
|
149
|
-
function
|
|
150
|
-
const
|
|
151
|
-
i0.ɵɵelementStart(0, "div",
|
|
202
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_25_Template(rf, ctx) { if (rf & 1) {
|
|
203
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
204
|
+
i0.ɵɵelementStart(0, "div", 3)(1, "label");
|
|
152
205
|
i0.ɵɵtext(2, "Child Entity");
|
|
153
206
|
i0.ɵɵelementEnd();
|
|
154
|
-
i0.ɵɵelementStart(3, "select",
|
|
155
|
-
i0.ɵɵlistener("change", function
|
|
156
|
-
i0.ɵɵelementStart(4, "option",
|
|
207
|
+
i0.ɵɵelementStart(3, "select", 4);
|
|
208
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_25_Template_select_change_3_listener($event) { i0.ɵɵrestoreView(_r14); const ɵ$index_185_r9 = i0.ɵɵnextContext().$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateChildTargetEntity(ɵ$index_185_r9, $event)); });
|
|
209
|
+
i0.ɵɵelementStart(4, "option", 18);
|
|
157
210
|
i0.ɵɵtext(5, "\u2014 Select Entity \u2014");
|
|
158
211
|
i0.ɵɵelementEnd();
|
|
159
|
-
i0.ɵɵrepeaterCreate(6,
|
|
212
|
+
i0.ɵɵrepeaterCreate(6, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_25_For_7_Template, 2, 3, "option", 5, _forTrack1);
|
|
160
213
|
i0.ɵɵelementEnd()();
|
|
161
214
|
} if (rf & 2) {
|
|
162
|
-
const
|
|
215
|
+
const output_r11 = i0.ɵɵnextContext().$implicit;
|
|
163
216
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
164
|
-
i0.ɵɵadvance(
|
|
165
|
-
i0.ɵɵproperty("
|
|
166
|
-
i0.ɵɵadvance(
|
|
217
|
+
i0.ɵɵadvance(4);
|
|
218
|
+
i0.ɵɵproperty("selected", !ctx_r1.IsEntityListed(output_r11.Target.EntityName));
|
|
219
|
+
i0.ɵɵadvance(2);
|
|
167
220
|
i0.ɵɵrepeater(ctx_r1.availableEntities);
|
|
168
221
|
} }
|
|
169
|
-
function
|
|
170
|
-
|
|
171
|
-
i0.ɵɵ
|
|
222
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_30_Template(rf, ctx) { if (rf & 1) {
|
|
223
|
+
i0.ɵɵelementStart(0, "option", 47);
|
|
224
|
+
i0.ɵɵtext(1, "\u2014 Select Constraint \u2014");
|
|
225
|
+
i0.ɵɵelementEnd();
|
|
226
|
+
} if (rf & 2) {
|
|
227
|
+
i0.ɵɵproperty("selected", true);
|
|
228
|
+
} }
|
|
229
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_For_32_Template(rf, ctx) { if (rf & 1) {
|
|
230
|
+
i0.ɵɵelementStart(0, "option", 5);
|
|
231
|
+
i0.ɵɵtext(1);
|
|
232
|
+
i0.ɵɵelementEnd();
|
|
233
|
+
} if (rf & 2) {
|
|
234
|
+
const t_r16 = ctx.$implicit;
|
|
235
|
+
const output_r11 = i0.ɵɵnextContext().$implicit;
|
|
236
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
237
|
+
i0.ɵɵproperty("value", t_r16.Value)("selected", t_r16.Value === ctx_r1.SavedConstraintType(output_r11));
|
|
238
|
+
i0.ɵɵadvance();
|
|
239
|
+
i0.ɵɵtextInterpolate(t_r16.Label);
|
|
240
|
+
} }
|
|
241
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_33_Template(rf, ctx) { if (rf & 1) {
|
|
242
|
+
const _r17 = i0.ɵɵgetCurrentView();
|
|
243
|
+
i0.ɵɵelementStart(0, "div", 3)(1, "label");
|
|
172
244
|
i0.ɵɵtext(2, "Violation Policy");
|
|
173
245
|
i0.ɵɵelementEnd();
|
|
174
|
-
i0.ɵɵelementStart(3, "select",
|
|
175
|
-
i0.ɵɵlistener("change", function
|
|
176
|
-
i0.ɵɵelementStart(4, "option",
|
|
246
|
+
i0.ɵɵelementStart(3, "select", 13);
|
|
247
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_33_Template_select_change_3_listener($event) { i0.ɵɵrestoreView(_r17); const ɵ$index_185_r9 = i0.ɵɵnextContext().$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateViolationPolicy(ɵ$index_185_r9, $event)); });
|
|
248
|
+
i0.ɵɵelementStart(4, "option", 48);
|
|
177
249
|
i0.ɵɵtext(5, "Fail Row");
|
|
178
250
|
i0.ɵɵelementEnd();
|
|
179
|
-
i0.ɵɵelementStart(6, "option",
|
|
251
|
+
i0.ɵɵelementStart(6, "option", 49);
|
|
180
252
|
i0.ɵɵtext(7, "Set Output to Null");
|
|
181
253
|
i0.ɵɵelementEnd();
|
|
182
|
-
i0.ɵɵelementStart(8, "option",
|
|
254
|
+
i0.ɵɵelementStart(8, "option", 50);
|
|
183
255
|
i0.ɵɵtext(9, "Coerce / Fallback");
|
|
184
256
|
i0.ɵɵelementEnd()()();
|
|
185
257
|
} if (rf & 2) {
|
|
186
|
-
const
|
|
258
|
+
const output_r11 = i0.ɵɵnextContext().$implicit;
|
|
187
259
|
i0.ɵɵadvance(3);
|
|
188
|
-
i0.ɵɵproperty("value",
|
|
260
|
+
i0.ɵɵproperty("value", output_r11.Constraint.OnViolation || "fail");
|
|
189
261
|
} }
|
|
190
|
-
function
|
|
191
|
-
const
|
|
192
|
-
i0.ɵɵelementStart(0, "div",
|
|
262
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_34_Conditional_4_For_7_Template(rf, ctx) { if (rf & 1) {
|
|
263
|
+
const _r19 = i0.ɵɵgetCurrentView();
|
|
264
|
+
i0.ɵɵelementStart(0, "div", 53)(1, "span", 54);
|
|
265
|
+
i0.ɵɵtext(2);
|
|
266
|
+
i0.ɵɵelementEnd();
|
|
267
|
+
i0.ɵɵelementStart(3, "input", 55);
|
|
268
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_34_Conditional_4_For_7_Template_input_input_3_listener($event) { const val_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ɵ$index_185_r9 = i0.ɵɵnextContext(3).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.UpdateEnumValueDescription(ɵ$index_185_r9, val_r20, $event)); });
|
|
269
|
+
i0.ɵɵelementEnd()();
|
|
270
|
+
} if (rf & 2) {
|
|
271
|
+
const val_r20 = ctx.$implicit;
|
|
272
|
+
const output_r11 = i0.ɵɵnextContext(3).$implicit;
|
|
273
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
274
|
+
i0.ɵɵadvance(2);
|
|
275
|
+
i0.ɵɵtextInterpolate(val_r20);
|
|
276
|
+
i0.ɵɵadvance();
|
|
277
|
+
i0.ɵɵproperty("value", ctx_r1.GetEnumValueDescription(output_r11, val_r20))("placeholder", "Description for " + val_r20);
|
|
278
|
+
} }
|
|
279
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_34_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
280
|
+
i0.ɵɵelementStart(0, "div", 19)(1, "label");
|
|
281
|
+
i0.ɵɵtext(2, "Value Descriptions ");
|
|
282
|
+
i0.ɵɵelementStart(3, "span", 38);
|
|
283
|
+
i0.ɵɵtext(4, "\u2014 Decision models require a description for every choice option");
|
|
284
|
+
i0.ɵɵelementEnd()();
|
|
285
|
+
i0.ɵɵelementStart(5, "div", 52);
|
|
286
|
+
i0.ɵɵrepeaterCreate(6, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_34_Conditional_4_For_7_Template, 4, 3, "div", 53, i0.ɵɵrepeaterTrackByIdentity);
|
|
287
|
+
i0.ɵɵelementEnd()();
|
|
288
|
+
} if (rf & 2) {
|
|
289
|
+
const output_r11 = i0.ɵɵnextContext(2).$implicit;
|
|
290
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
291
|
+
i0.ɵɵadvance(6);
|
|
292
|
+
i0.ɵɵrepeater(ctx_r1.GetEnumValues(output_r11));
|
|
293
|
+
} }
|
|
294
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_34_Template(rf, ctx) { if (rf & 1) {
|
|
295
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
296
|
+
i0.ɵɵelementStart(0, "div", 19)(1, "label");
|
|
193
297
|
i0.ɵɵtext(2, "Allowed Values (comma separated)");
|
|
194
298
|
i0.ɵɵelementEnd();
|
|
195
|
-
i0.ɵɵelementStart(3, "input",
|
|
196
|
-
i0.ɵɵlistener("input", function
|
|
299
|
+
i0.ɵɵelementStart(3, "input", 51);
|
|
300
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_34_Template_input_input_3_listener($event) { i0.ɵɵrestoreView(_r18); const ɵ$index_185_r9 = i0.ɵɵnextContext().$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateEnumValues(ɵ$index_185_r9, $event)); });
|
|
197
301
|
i0.ɵɵelementEnd()();
|
|
302
|
+
i0.ɵɵconditionalCreate(4, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_34_Conditional_4_Template, 8, 0, "div", 19);
|
|
198
303
|
} if (rf & 2) {
|
|
199
|
-
const
|
|
304
|
+
const output_r11 = i0.ɵɵnextContext().$implicit;
|
|
200
305
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
201
306
|
i0.ɵɵadvance(3);
|
|
202
|
-
i0.ɵɵproperty("value", ctx_r1.getEnumValuesCsv(
|
|
307
|
+
i0.ɵɵproperty("value", ctx_r1.getEnumValuesCsv(output_r11.Constraint));
|
|
308
|
+
i0.ɵɵadvance();
|
|
309
|
+
i0.ɵɵconditional(ctx_r1.IsDecisionPipeline && ctx_r1.GetEnumValues(output_r11).length > 0 ? 4 : -1);
|
|
203
310
|
} }
|
|
204
|
-
function
|
|
205
|
-
const
|
|
206
|
-
i0.ɵɵelementStart(0, "div",
|
|
311
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_0_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
312
|
+
const _r22 = i0.ɵɵgetCurrentView();
|
|
313
|
+
i0.ɵɵelementStart(0, "div", 59)(1, "span", 60);
|
|
314
|
+
i0.ɵɵtext(2);
|
|
315
|
+
i0.ɵɵelementEnd();
|
|
316
|
+
i0.ɵɵelementStart(3, "input", 61);
|
|
317
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_0_For_11_Template_input_input_3_listener($event) { const ɵ$index_339_r23 = i0.ɵɵrestoreView(_r22).$index; const ɵ$index_185_r9 = i0.ɵɵnextContext(3).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.UpdateNumericLevel(ɵ$index_185_r9, ɵ$index_339_r23, $event)); });
|
|
318
|
+
i0.ɵɵelementEnd();
|
|
319
|
+
i0.ɵɵelementStart(4, "button", 62);
|
|
320
|
+
i0.ɵɵlistener("click", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_0_For_11_Template_button_click_4_listener() { const ɵ$index_339_r23 = i0.ɵɵrestoreView(_r22).$index; const ɵ$index_185_r9 = i0.ɵɵnextContext(3).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.MoveNumericLevel(ɵ$index_185_r9, ɵ$index_339_r23, "up")); });
|
|
321
|
+
i0.ɵɵelement(5, "i", 63);
|
|
322
|
+
i0.ɵɵelementEnd();
|
|
323
|
+
i0.ɵɵelementStart(6, "button", 64);
|
|
324
|
+
i0.ɵɵlistener("click", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_0_For_11_Template_button_click_6_listener() { const ɵ$index_339_r23 = i0.ɵɵrestoreView(_r22).$index; const ɵ$index_185_r9 = i0.ɵɵnextContext(3).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.MoveNumericLevel(ɵ$index_185_r9, ɵ$index_339_r23, "down")); });
|
|
325
|
+
i0.ɵɵelement(7, "i", 65);
|
|
326
|
+
i0.ɵɵelementEnd();
|
|
327
|
+
i0.ɵɵelementStart(8, "button", 66);
|
|
328
|
+
i0.ɵɵlistener("click", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_0_For_11_Template_button_click_8_listener() { const ɵ$index_339_r23 = i0.ɵɵrestoreView(_r22).$index; const ɵ$index_185_r9 = i0.ɵɵnextContext(3).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.RemoveNumericLevel(ɵ$index_185_r9, ɵ$index_339_r23)); });
|
|
329
|
+
i0.ɵɵelement(9, "i", 44);
|
|
330
|
+
i0.ɵɵelementEnd()();
|
|
331
|
+
} if (rf & 2) {
|
|
332
|
+
const lvl_r24 = ctx.$implicit;
|
|
333
|
+
const ɵ$index_339_r23 = ctx.$index;
|
|
334
|
+
const ɵ$count_339_r25 = ctx.$count;
|
|
335
|
+
const output_r11 = i0.ɵɵnextContext(3).$implicit;
|
|
336
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
337
|
+
i0.ɵɵadvance(2);
|
|
338
|
+
i0.ɵɵtextInterpolate(ɵ$index_339_r23 + 1);
|
|
339
|
+
i0.ɵɵadvance();
|
|
340
|
+
i0.ɵɵproperty("value", lvl_r24);
|
|
341
|
+
i0.ɵɵadvance();
|
|
342
|
+
i0.ɵɵproperty("disabled", ɵ$index_339_r23 === 0);
|
|
343
|
+
i0.ɵɵadvance(2);
|
|
344
|
+
i0.ɵɵproperty("disabled", ɵ$index_339_r23 === ɵ$count_339_r25 - 1);
|
|
345
|
+
i0.ɵɵadvance(2);
|
|
346
|
+
i0.ɵɵproperty("disabled", ctx_r1.GetNumericLevels(output_r11).length <= 2);
|
|
347
|
+
} }
|
|
348
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
349
|
+
const _r21 = i0.ɵɵgetCurrentView();
|
|
350
|
+
i0.ɵɵelementStart(0, "div", 19)(1, "div", 56)(2, "label");
|
|
351
|
+
i0.ɵɵtext(3, "Numeric Levels ");
|
|
352
|
+
i0.ɵɵelementStart(4, "span", 38);
|
|
353
|
+
i0.ɵɵtext(5, "(Ordered: lowest to highest, 2 to 10 levels)");
|
|
354
|
+
i0.ɵɵelementEnd()();
|
|
355
|
+
i0.ɵɵelementStart(6, "button", 57);
|
|
356
|
+
i0.ɵɵlistener("click", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r21); const ɵ$index_185_r9 = i0.ɵɵnextContext(2).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.AddNumericLevel(ɵ$index_185_r9)); });
|
|
357
|
+
i0.ɵɵelement(7, "i", 23);
|
|
358
|
+
i0.ɵɵtext(8, " Add Level ");
|
|
359
|
+
i0.ɵɵelementEnd()();
|
|
360
|
+
i0.ɵɵelementStart(9, "div", 58);
|
|
361
|
+
i0.ɵɵrepeaterCreate(10, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_0_For_11_Template, 10, 5, "div", 59, i0.ɵɵrepeaterTrackByIndex);
|
|
362
|
+
i0.ɵɵelementEnd()();
|
|
363
|
+
} if (rf & 2) {
|
|
364
|
+
const output_r11 = i0.ɵɵnextContext(2).$implicit;
|
|
365
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
366
|
+
i0.ɵɵadvance(6);
|
|
367
|
+
i0.ɵɵproperty("disabled", ctx_r1.GetNumericLevels(output_r11).length >= 10);
|
|
368
|
+
i0.ɵɵadvance(4);
|
|
369
|
+
i0.ɵɵrepeater(ctx_r1.GetNumericLevels(output_r11));
|
|
370
|
+
} }
|
|
371
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
372
|
+
const _r26 = i0.ɵɵgetCurrentView();
|
|
373
|
+
i0.ɵɵelementStart(0, "div", 7)(1, "div", 3)(2, "label");
|
|
207
374
|
i0.ɵɵtext(3, "Min Value");
|
|
208
375
|
i0.ɵɵelementEnd();
|
|
209
|
-
i0.ɵɵelementStart(4, "input",
|
|
210
|
-
i0.ɵɵlistener("input", function
|
|
376
|
+
i0.ɵɵelementStart(4, "input", 67);
|
|
377
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_1_Template_input_input_4_listener($event) { i0.ɵɵrestoreView(_r26); const ɵ$index_185_r9 = i0.ɵɵnextContext(2).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateNumericMin(ɵ$index_185_r9, $event)); });
|
|
211
378
|
i0.ɵɵelementEnd()();
|
|
212
|
-
i0.ɵɵelementStart(5, "div",
|
|
379
|
+
i0.ɵɵelementStart(5, "div", 3)(6, "label");
|
|
213
380
|
i0.ɵɵtext(7, "Max Value");
|
|
214
381
|
i0.ɵɵelementEnd();
|
|
215
|
-
i0.ɵɵelementStart(8, "input",
|
|
216
|
-
i0.ɵɵlistener("input", function
|
|
382
|
+
i0.ɵɵelementStart(8, "input", 67);
|
|
383
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_1_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(_r26); const ɵ$index_185_r9 = i0.ɵɵnextContext(2).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateNumericMax(ɵ$index_185_r9, $event)); });
|
|
217
384
|
i0.ɵɵelementEnd()()();
|
|
218
385
|
} if (rf & 2) {
|
|
219
|
-
const
|
|
386
|
+
const output_r11 = i0.ɵɵnextContext(2).$implicit;
|
|
220
387
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
221
388
|
i0.ɵɵadvance(4);
|
|
222
|
-
i0.ɵɵproperty("value", ctx_r1.getNumericMin(
|
|
389
|
+
i0.ɵɵproperty("value", ctx_r1.getNumericMin(output_r11.Constraint));
|
|
223
390
|
i0.ɵɵadvance(4);
|
|
224
|
-
i0.ɵɵproperty("value", ctx_r1.getNumericMax(
|
|
391
|
+
i0.ɵɵproperty("value", ctx_r1.getNumericMax(output_r11.Constraint));
|
|
225
392
|
} }
|
|
226
|
-
function
|
|
227
|
-
|
|
228
|
-
|
|
393
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
394
|
+
i0.ɵɵconditionalCreate(0, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_0_Template, 12, 1, "div", 19)(1, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Conditional_1_Template, 9, 2, "div", 7);
|
|
395
|
+
} if (rf & 2) {
|
|
396
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
397
|
+
i0.ɵɵconditional(ctx_r1.IsDecisionPipeline ? 0 : 1);
|
|
398
|
+
} }
|
|
399
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_36_Template(rf, ctx) { if (rf & 1) {
|
|
400
|
+
const _r27 = i0.ɵɵgetCurrentView();
|
|
401
|
+
i0.ɵɵelementStart(0, "div", 19)(1, "label");
|
|
402
|
+
i0.ɵɵtext(2, "Decision Threshold (0.0 to 1.0) ");
|
|
403
|
+
i0.ɵɵelementStart(3, "span", 38);
|
|
404
|
+
i0.ɵɵtext(4, "\u2014 calibrated probability threshold for true");
|
|
405
|
+
i0.ɵɵelementEnd()();
|
|
406
|
+
i0.ɵɵelementStart(5, "input", 68);
|
|
407
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_36_Template_input_input_5_listener($event) { i0.ɵɵrestoreView(_r27); const ɵ$index_185_r9 = i0.ɵɵnextContext().$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.UpdateBooleanThreshold(ɵ$index_185_r9, $event)); });
|
|
408
|
+
i0.ɵɵelementEnd()();
|
|
409
|
+
} if (rf & 2) {
|
|
410
|
+
const output_r11 = i0.ɵɵnextContext().$implicit;
|
|
411
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
412
|
+
i0.ɵɵadvance(5);
|
|
413
|
+
i0.ɵɵproperty("value", ctx_r1.GetBooleanThreshold(output_r11) ?? "");
|
|
414
|
+
} }
|
|
415
|
+
function FeaturePipelineBuilderComponent_Conditional_70_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
416
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
417
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "div", 42)(2, "h4");
|
|
229
418
|
i0.ɵɵtext(3);
|
|
230
419
|
i0.ɵɵelementEnd();
|
|
231
|
-
i0.ɵɵelementStart(4, "button",
|
|
232
|
-
i0.ɵɵlistener("click", function
|
|
233
|
-
i0.ɵɵelement(5, "i",
|
|
420
|
+
i0.ɵɵelementStart(4, "button", 43);
|
|
421
|
+
i0.ɵɵlistener("click", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Template_button_click_4_listener() { const ɵ$index_185_r9 = i0.ɵɵrestoreView(_r8).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.removeOutput(ɵ$index_185_r9)); });
|
|
422
|
+
i0.ɵɵelement(5, "i", 44);
|
|
234
423
|
i0.ɵɵtext(6, " Remove ");
|
|
235
424
|
i0.ɵɵelementEnd()();
|
|
236
|
-
i0.ɵɵelementStart(7, "div",
|
|
425
|
+
i0.ɵɵelementStart(7, "div", 12)(8, "div", 3)(9, "label");
|
|
237
426
|
i0.ɵɵtext(10, "Output Name");
|
|
238
427
|
i0.ɵɵelementEnd();
|
|
239
|
-
i0.ɵɵelementStart(11, "input",
|
|
240
|
-
i0.ɵɵlistener("input", function
|
|
428
|
+
i0.ɵɵelementStart(11, "input", 45);
|
|
429
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Template_input_input_11_listener($event) { const ɵ$index_185_r9 = i0.ɵɵrestoreView(_r8).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateOutputProp(ɵ$index_185_r9, "Name", $event)); });
|
|
241
430
|
i0.ɵɵelementEnd()();
|
|
242
|
-
i0.ɵɵelementStart(12, "div",
|
|
431
|
+
i0.ɵɵelementStart(12, "div", 3)(13, "label");
|
|
243
432
|
i0.ɵɵtext(14, "JSON Path / Ref");
|
|
244
433
|
i0.ɵɵelementEnd();
|
|
245
|
-
i0.ɵɵelementStart(15, "input",
|
|
246
|
-
i0.ɵɵlistener("input", function
|
|
434
|
+
i0.ɵɵelementStart(15, "input", 46);
|
|
435
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Template_input_input_15_listener($event) { const ɵ$index_185_r9 = i0.ɵɵrestoreView(_r8).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateOutputProp(ɵ$index_185_r9, "Ref", $event)); });
|
|
247
436
|
i0.ɵɵelementEnd()();
|
|
248
|
-
i0.ɵɵelementStart(16, "div",
|
|
437
|
+
i0.ɵɵelementStart(16, "div", 3)(17, "label");
|
|
249
438
|
i0.ɵɵtext(18, "Target Mode");
|
|
250
439
|
i0.ɵɵelementEnd();
|
|
251
|
-
i0.ɵɵelementStart(19, "select",
|
|
252
|
-
i0.ɵɵlistener("change", function
|
|
253
|
-
i0.ɵɵ
|
|
254
|
-
i0.ɵɵ
|
|
255
|
-
i0.ɵɵelementEnd();
|
|
256
|
-
i0.ɵɵelementStart(22, "option", 41);
|
|
257
|
-
i0.ɵɵtext(23, "Child Rows (child)");
|
|
258
|
-
i0.ɵɵelementEnd();
|
|
259
|
-
i0.ɵɵelementStart(24, "option", 42);
|
|
260
|
-
i0.ɵɵtext(25, "Taxonomy Tags (tags)");
|
|
261
|
-
i0.ɵɵelementEnd()()()();
|
|
262
|
-
i0.ɵɵelementStart(26, "div", 27);
|
|
263
|
-
i0.ɵɵconditionalCreate(27, FeaturePipelineBuilderComponent_Conditional_56_For_2_Conditional_27_Template, 8, 1, "div", 6);
|
|
264
|
-
i0.ɵɵconditionalCreate(28, FeaturePipelineBuilderComponent_Conditional_56_For_2_Conditional_28_Template, 8, 1, "div", 6);
|
|
265
|
-
i0.ɵɵelementStart(29, "div", 6)(30, "label");
|
|
266
|
-
i0.ɵɵtext(31, "Constraint Type");
|
|
267
|
-
i0.ɵɵelementEnd();
|
|
268
|
-
i0.ɵɵelementStart(32, "select", 7);
|
|
269
|
-
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_56_For_2_Template_select_change_32_listener($event) { const $index_r7 = i0.ɵɵrestoreView(_r6).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateConstraintType($index_r7, $event)); });
|
|
270
|
-
i0.ɵɵelementStart(33, "option", 43);
|
|
271
|
-
i0.ɵɵtext(34, "None / Unconstrained");
|
|
272
|
-
i0.ɵɵelementEnd();
|
|
273
|
-
i0.ɵɵelementStart(35, "option", 44);
|
|
274
|
-
i0.ɵɵtext(36, "Enum (Allowed Values)");
|
|
275
|
-
i0.ɵɵelementEnd();
|
|
276
|
-
i0.ɵɵelementStart(37, "option", 45);
|
|
277
|
-
i0.ɵɵtext(38, "Numeric (Min/Max)");
|
|
278
|
-
i0.ɵɵelementEnd();
|
|
279
|
-
i0.ɵɵelementStart(39, "option", 46);
|
|
280
|
-
i0.ɵɵtext(40, "Boolean");
|
|
281
|
-
i0.ɵɵelementEnd();
|
|
282
|
-
i0.ɵɵelementStart(41, "option", 47);
|
|
283
|
-
i0.ɵɵtext(42, "Free Text");
|
|
440
|
+
i0.ɵɵelementStart(19, "select", 4);
|
|
441
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Template_select_change_19_listener($event) { const ɵ$index_185_r9 = i0.ɵɵrestoreView(_r8).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateTargetMode(ɵ$index_185_r9, $event)); });
|
|
442
|
+
i0.ɵɵconditionalCreate(20, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_20_Template, 2, 1, "option", 18);
|
|
443
|
+
i0.ɵɵrepeaterCreate(21, FeaturePipelineBuilderComponent_Conditional_70_For_2_For_22_Template, 2, 3, "option", 5, _forTrack2);
|
|
284
444
|
i0.ɵɵelementEnd()()();
|
|
285
|
-
i0.ɵɵ
|
|
445
|
+
i0.ɵɵelementStart(23, "div", 32);
|
|
446
|
+
i0.ɵɵconditionalCreate(24, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_24_Template, 8, 1, "div", 3);
|
|
447
|
+
i0.ɵɵconditionalCreate(25, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_25_Template, 8, 1, "div", 3);
|
|
448
|
+
i0.ɵɵelementStart(26, "div", 3)(27, "label");
|
|
449
|
+
i0.ɵɵtext(28, "Constraint Type");
|
|
286
450
|
i0.ɵɵelementEnd();
|
|
287
|
-
i0.ɵɵ
|
|
288
|
-
i0.ɵɵ
|
|
451
|
+
i0.ɵɵelementStart(29, "select", 4);
|
|
452
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_70_For_2_Template_select_change_29_listener($event) { const ɵ$index_185_r9 = i0.ɵɵrestoreView(_r8).$index; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.updateConstraintType(ɵ$index_185_r9, $event)); });
|
|
453
|
+
i0.ɵɵconditionalCreate(30, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_30_Template, 2, 1, "option", 47);
|
|
454
|
+
i0.ɵɵrepeaterCreate(31, FeaturePipelineBuilderComponent_Conditional_70_For_2_For_32_Template, 2, 3, "option", 5, _forTrack2);
|
|
455
|
+
i0.ɵɵelementEnd()();
|
|
456
|
+
i0.ɵɵconditionalCreate(33, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_33_Template, 10, 1, "div", 3);
|
|
457
|
+
i0.ɵɵelementEnd();
|
|
458
|
+
i0.ɵɵconditionalCreate(34, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_34_Template, 5, 2);
|
|
459
|
+
i0.ɵɵconditionalCreate(35, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_35_Template, 2, 1);
|
|
460
|
+
i0.ɵɵconditionalCreate(36, FeaturePipelineBuilderComponent_Conditional_70_For_2_Conditional_36_Template, 6, 1, "div", 19);
|
|
289
461
|
i0.ɵɵelementEnd();
|
|
290
462
|
} if (rf & 2) {
|
|
291
|
-
const
|
|
292
|
-
const
|
|
463
|
+
const output_r11 = ctx.$implicit;
|
|
464
|
+
const ɵ$index_185_r9 = ctx.$index;
|
|
465
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
293
466
|
i0.ɵɵadvance(3);
|
|
294
|
-
i0.ɵɵtextInterpolate2("Output #",
|
|
467
|
+
i0.ɵɵtextInterpolate2("Output #", ɵ$index_185_r9 + 1, ": ", output_r11.Name || "(unnamed)");
|
|
295
468
|
i0.ɵɵadvance(8);
|
|
296
|
-
i0.ɵɵproperty("value",
|
|
469
|
+
i0.ɵɵproperty("value", output_r11.Name);
|
|
297
470
|
i0.ɵɵadvance(4);
|
|
298
|
-
i0.ɵɵproperty("value",
|
|
299
|
-
i0.ɵɵadvance(
|
|
300
|
-
i0.ɵɵ
|
|
301
|
-
i0.ɵɵadvance(8);
|
|
302
|
-
i0.ɵɵconditional(output_r10.Target.Mode === "field" ? 27 : -1);
|
|
471
|
+
i0.ɵɵproperty("value", output_r11.Ref);
|
|
472
|
+
i0.ɵɵadvance(5);
|
|
473
|
+
i0.ɵɵconditional(!ctx_r1.IsTargetModeOffered(output_r11) ? 20 : -1);
|
|
303
474
|
i0.ɵɵadvance();
|
|
304
|
-
i0.ɵɵ
|
|
305
|
-
i0.ɵɵadvance(
|
|
306
|
-
i0.ɵɵ
|
|
307
|
-
i0.ɵɵadvance(11);
|
|
308
|
-
i0.ɵɵconditional(output_r10.Constraint ? 43 : -1);
|
|
475
|
+
i0.ɵɵrepeater(ctx_r1.AvailableTargetModes);
|
|
476
|
+
i0.ɵɵadvance(3);
|
|
477
|
+
i0.ɵɵconditional(output_r11.Target.Mode === "field" ? 24 : -1);
|
|
309
478
|
i0.ɵɵadvance();
|
|
310
|
-
i0.ɵɵconditional(
|
|
479
|
+
i0.ɵɵconditional(output_r11.Target.Mode === "child" ? 25 : -1);
|
|
480
|
+
i0.ɵɵadvance(5);
|
|
481
|
+
i0.ɵɵconditional(!ctx_r1.IsConstraintTypeOffered(output_r11) ? 30 : -1);
|
|
311
482
|
i0.ɵɵadvance();
|
|
312
|
-
i0.ɵɵ
|
|
483
|
+
i0.ɵɵrepeater(ctx_r1.AvailableConstraintTypes);
|
|
484
|
+
i0.ɵɵadvance(2);
|
|
485
|
+
i0.ɵɵconditional(output_r11.Constraint ? 33 : -1);
|
|
486
|
+
i0.ɵɵadvance();
|
|
487
|
+
i0.ɵɵconditional((output_r11.Constraint == null ? null : output_r11.Constraint.Type) === "enum" ? 34 : -1);
|
|
488
|
+
i0.ɵɵadvance();
|
|
489
|
+
i0.ɵɵconditional((output_r11.Constraint == null ? null : output_r11.Constraint.Type) === "numeric" ? 35 : -1);
|
|
490
|
+
i0.ɵɵadvance();
|
|
491
|
+
i0.ɵɵconditional((output_r11.Constraint == null ? null : output_r11.Constraint.Type) === "boolean" && ctx_r1.IsDecisionPipeline ? 36 : -1);
|
|
313
492
|
} }
|
|
314
|
-
function
|
|
315
|
-
i0.ɵɵelementStart(0, "div",
|
|
316
|
-
i0.ɵɵrepeaterCreate(1,
|
|
493
|
+
function FeaturePipelineBuilderComponent_Conditional_70_Template(rf, ctx) { if (rf & 1) {
|
|
494
|
+
i0.ɵɵelementStart(0, "div", 25);
|
|
495
|
+
i0.ɵɵrepeaterCreate(1, FeaturePipelineBuilderComponent_Conditional_70_For_2_Template, 37, 12, "div", 41, i0.ɵɵrepeaterTrackByIndex);
|
|
317
496
|
i0.ɵɵelementEnd();
|
|
318
497
|
} if (rf & 2) {
|
|
319
498
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
320
499
|
i0.ɵɵadvance();
|
|
321
500
|
i0.ɵɵrepeater(ctx_r1.spec.Outputs);
|
|
322
501
|
} }
|
|
323
|
-
function
|
|
324
|
-
|
|
325
|
-
i0.ɵɵ
|
|
502
|
+
function FeaturePipelineBuilderComponent_Conditional_71_Conditional_12_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
503
|
+
i0.ɵɵelementStart(0, "option", 73);
|
|
504
|
+
i0.ɵɵtext(1);
|
|
505
|
+
i0.ɵɵelementEnd();
|
|
506
|
+
} if (rf & 2) {
|
|
507
|
+
const target_r30 = ctx.$implicit;
|
|
508
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
509
|
+
i0.ɵɵproperty("value", target_r30.ID)("disabled", !!ctx_r1.GetTargetProblem(target_r30))("selected", ctx_r1.IsSavedEscalationTarget(target_r30));
|
|
510
|
+
i0.ɵɵadvance();
|
|
511
|
+
i0.ɵɵtextInterpolate2(" ", target_r30.Name, "", ctx_r1.GetTargetProblem(target_r30) ? " (" + ctx_r1.GetTargetProblem(target_r30) + ")" : "", " ");
|
|
512
|
+
} }
|
|
513
|
+
function FeaturePipelineBuilderComponent_Conditional_71_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
514
|
+
const _r29 = i0.ɵɵgetCurrentView();
|
|
515
|
+
i0.ɵɵelementStart(0, "div", 7)(1, "div", 3)(2, "label");
|
|
516
|
+
i0.ɵɵtext(3, "Target LLM Pipeline");
|
|
517
|
+
i0.ɵɵelementEnd();
|
|
518
|
+
i0.ɵɵelementStart(4, "select", 4);
|
|
519
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_71_Conditional_12_Template_select_change_4_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnEscalationTargetChange($event)); });
|
|
520
|
+
i0.ɵɵelementStart(5, "option", 18);
|
|
521
|
+
i0.ɵɵtext(6);
|
|
522
|
+
i0.ɵɵelementEnd();
|
|
523
|
+
i0.ɵɵrepeaterCreate(7, FeaturePipelineBuilderComponent_Conditional_71_Conditional_12_For_8_Template, 2, 5, "option", 73, _forTrack1);
|
|
524
|
+
i0.ɵɵelementEnd()();
|
|
525
|
+
i0.ɵɵelementStart(9, "div", 3)(10, "label");
|
|
526
|
+
i0.ɵɵtext(11, "Confidence Floor (0.0 to 1.0)");
|
|
527
|
+
i0.ɵɵelementEnd();
|
|
528
|
+
i0.ɵɵelementStart(12, "input", 74);
|
|
529
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_71_Conditional_12_Template_input_input_12_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnEscalationFloorChange($event)); });
|
|
530
|
+
i0.ɵɵelementEnd()()();
|
|
531
|
+
} if (rf & 2) {
|
|
532
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
533
|
+
i0.ɵɵadvance(5);
|
|
534
|
+
i0.ɵɵproperty("selected", !ctx_r1.SavedEscalationTargetListed);
|
|
535
|
+
i0.ɵɵadvance();
|
|
536
|
+
i0.ɵɵtextInterpolate(ctx_r1.EscalationTargetsPlaceholder);
|
|
537
|
+
i0.ɵɵadvance();
|
|
538
|
+
i0.ɵɵrepeater(ctx_r1.AvailableEscalationTargets);
|
|
539
|
+
i0.ɵɵadvance(5);
|
|
540
|
+
i0.ɵɵproperty("value", (ctx_r1.spec.Escalation == null ? null : ctx_r1.spec.Escalation.BelowConfidence) ?? "");
|
|
541
|
+
} }
|
|
542
|
+
function FeaturePipelineBuilderComponent_Conditional_71_Template(rf, ctx) { if (rf & 1) {
|
|
543
|
+
const _r28 = i0.ɵɵgetCurrentView();
|
|
544
|
+
i0.ɵɵelementStart(0, "section", 26)(1, "div", 9);
|
|
545
|
+
i0.ɵɵelement(2, "i", 69);
|
|
546
|
+
i0.ɵɵelementStart(3, "h3");
|
|
547
|
+
i0.ɵɵtext(4, "Borderline Escalation");
|
|
548
|
+
i0.ɵɵelementEnd()();
|
|
549
|
+
i0.ɵɵelementStart(5, "p", 11);
|
|
550
|
+
i0.ɵɵtext(6, "Records any output of which the decision model answers below this confidence are re-run through the chosen LLM pipeline. Only those records are re-run.");
|
|
551
|
+
i0.ɵɵelementEnd();
|
|
552
|
+
i0.ɵɵelementStart(7, "div", 70)(8, "label", 71)(9, "input", 72);
|
|
553
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_71_Template_input_change_9_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnEscalationToggle($event)); });
|
|
554
|
+
i0.ɵɵelementEnd();
|
|
555
|
+
i0.ɵɵelementStart(10, "span");
|
|
556
|
+
i0.ɵɵtext(11, "Escalate borderline records to an LLM pipeline");
|
|
557
|
+
i0.ɵɵelementEnd()()();
|
|
558
|
+
i0.ɵɵconditionalCreate(12, FeaturePipelineBuilderComponent_Conditional_71_Conditional_12_Template, 13, 3, "div", 7);
|
|
559
|
+
i0.ɵɵelementEnd();
|
|
560
|
+
} if (rf & 2) {
|
|
561
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
562
|
+
i0.ɵɵadvance(9);
|
|
563
|
+
i0.ɵɵproperty("checked", ctx_r1.IsEscalationEnabled);
|
|
564
|
+
i0.ɵɵadvance(3);
|
|
565
|
+
i0.ɵɵconditional(ctx_r1.IsEscalationEnabled ? 12 : -1);
|
|
566
|
+
} }
|
|
567
|
+
function FeaturePipelineBuilderComponent_Conditional_105_Template(rf, ctx) { if (rf & 1) {
|
|
568
|
+
const _r31 = i0.ɵɵgetCurrentView();
|
|
569
|
+
i0.ɵɵelementStart(0, "div", 32)(1, "div", 3)(2, "label");
|
|
326
570
|
i0.ɵɵtext(3, "Cache Key Fields (comma separated)");
|
|
327
571
|
i0.ɵɵelementEnd();
|
|
328
|
-
i0.ɵɵelementStart(4, "input",
|
|
329
|
-
i0.ɵɵlistener("input", function
|
|
572
|
+
i0.ɵɵelementStart(4, "input", 75);
|
|
573
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_105_Template_input_input_4_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.updateCacheKeyFields($event)); });
|
|
330
574
|
i0.ɵɵelementEnd()();
|
|
331
|
-
i0.ɵɵelementStart(5, "div",
|
|
575
|
+
i0.ɵɵelementStart(5, "div", 3)(6, "label");
|
|
332
576
|
i0.ɵɵtext(7, "Cache TTL (Seconds)");
|
|
333
577
|
i0.ɵɵelementEnd();
|
|
334
|
-
i0.ɵɵelementStart(8, "input",
|
|
335
|
-
i0.ɵɵlistener("input", function
|
|
578
|
+
i0.ɵɵelementStart(8, "input", 67);
|
|
579
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Conditional_105_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.updateCacheTTL($event)); });
|
|
336
580
|
i0.ɵɵelementEnd()();
|
|
337
|
-
i0.ɵɵelementStart(9, "div",
|
|
581
|
+
i0.ɵɵelementStart(9, "div", 3)(10, "label");
|
|
338
582
|
i0.ɵɵtext(11, "Cache Scope");
|
|
339
583
|
i0.ɵɵelementEnd();
|
|
340
|
-
i0.ɵɵelementStart(12, "select",
|
|
341
|
-
i0.ɵɵlistener("change", function
|
|
342
|
-
i0.ɵɵelementStart(13, "option",
|
|
584
|
+
i0.ɵɵelementStart(12, "select", 13);
|
|
585
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Conditional_105_Template_select_change_12_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.updateCacheScope($event)); });
|
|
586
|
+
i0.ɵɵelementStart(13, "option", 76);
|
|
343
587
|
i0.ɵɵtext(14, "Pipeline (Isolated to this process)");
|
|
344
588
|
i0.ɵɵelementEnd();
|
|
345
|
-
i0.ɵɵelementStart(15, "option",
|
|
589
|
+
i0.ɵɵelementStart(15, "option", 77);
|
|
346
590
|
i0.ɵɵtext(16, "Prompt (Shared across processes with same prompt)");
|
|
347
591
|
i0.ɵɵelementEnd()()()();
|
|
348
592
|
} if (rf & 2) {
|
|
@@ -354,44 +598,62 @@ function FeaturePipelineBuilderComponent_Conditional_90_Template(rf, ctx) { if (
|
|
|
354
598
|
i0.ɵɵadvance(4);
|
|
355
599
|
i0.ɵɵproperty("value", ctx_r1.spec.Caching.Scope || "pipeline");
|
|
356
600
|
} }
|
|
357
|
-
function
|
|
358
|
-
i0.ɵɵelementStart(0, "span",
|
|
601
|
+
function FeaturePipelineBuilderComponent_Conditional_106_For_6_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
602
|
+
i0.ɵɵelementStart(0, "span", 38);
|
|
359
603
|
i0.ɵɵtext(1);
|
|
360
604
|
i0.ɵɵelementEnd();
|
|
361
605
|
} if (rf & 2) {
|
|
362
|
-
const
|
|
606
|
+
const issue_r32 = i0.ɵɵnextContext().$implicit;
|
|
363
607
|
i0.ɵɵadvance();
|
|
364
|
-
i0.ɵɵtextInterpolate1("(Fix: ",
|
|
608
|
+
i0.ɵɵtextInterpolate1("(Fix: ", issue_r32.FixRecommendation, ")");
|
|
365
609
|
} }
|
|
366
|
-
function
|
|
610
|
+
function FeaturePipelineBuilderComponent_Conditional_106_For_6_Template(rf, ctx) { if (rf & 1) {
|
|
367
611
|
i0.ɵɵelementStart(0, "li")(1, "strong");
|
|
368
612
|
i0.ɵɵtext(2);
|
|
369
613
|
i0.ɵɵelementEnd();
|
|
370
614
|
i0.ɵɵtext(3);
|
|
371
|
-
i0.ɵɵconditionalCreate(4,
|
|
615
|
+
i0.ɵɵconditionalCreate(4, FeaturePipelineBuilderComponent_Conditional_106_For_6_Conditional_4_Template, 2, 1, "span", 38);
|
|
372
616
|
i0.ɵɵelementEnd();
|
|
373
617
|
} if (rf & 2) {
|
|
374
|
-
const
|
|
618
|
+
const issue_r32 = ctx.$implicit;
|
|
375
619
|
i0.ɵɵadvance(2);
|
|
376
|
-
i0.ɵɵtextInterpolate(
|
|
620
|
+
i0.ɵɵtextInterpolate(issue_r32.Field ? issue_r32.Field + ": " : "");
|
|
377
621
|
i0.ɵɵadvance();
|
|
378
|
-
i0.ɵɵtextInterpolate1("",
|
|
622
|
+
i0.ɵɵtextInterpolate1("", issue_r32.Message, " ");
|
|
379
623
|
i0.ɵɵadvance();
|
|
380
|
-
i0.ɵɵconditional(
|
|
624
|
+
i0.ɵɵconditional(issue_r32.FixRecommendation ? 4 : -1);
|
|
381
625
|
} }
|
|
382
|
-
function
|
|
383
|
-
i0.ɵɵelementStart(0, "div",
|
|
384
|
-
i0.ɵɵelement(2, "i",
|
|
626
|
+
function FeaturePipelineBuilderComponent_Conditional_106_Template(rf, ctx) { if (rf & 1) {
|
|
627
|
+
i0.ɵɵelementStart(0, "div", 33)(1, "h4");
|
|
628
|
+
i0.ɵɵelement(2, "i", 78);
|
|
385
629
|
i0.ɵɵtext(3, " Specification Issues");
|
|
386
630
|
i0.ɵɵelementEnd();
|
|
387
631
|
i0.ɵɵelementStart(4, "ul");
|
|
388
|
-
i0.ɵɵrepeaterCreate(5,
|
|
632
|
+
i0.ɵɵrepeaterCreate(5, FeaturePipelineBuilderComponent_Conditional_106_For_6_Template, 5, 3, "li", null, i0.ɵɵrepeaterTrackByIndex);
|
|
389
633
|
i0.ɵɵelementEnd()();
|
|
390
634
|
} if (rf & 2) {
|
|
391
635
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
392
636
|
i0.ɵɵadvance(5);
|
|
393
637
|
i0.ɵɵrepeater(ctx_r1.validationErrors);
|
|
394
638
|
} }
|
|
639
|
+
function FeaturePipelineBuilderComponent_For_110_Template(rf, ctx) { if (rf & 1) {
|
|
640
|
+
i0.ɵɵelementStart(0, "li");
|
|
641
|
+
i0.ɵɵtext(1);
|
|
642
|
+
i0.ɵɵelementEnd();
|
|
643
|
+
} if (rf & 2) {
|
|
644
|
+
const issue_r33 = ctx.$implicit;
|
|
645
|
+
i0.ɵɵadvance();
|
|
646
|
+
i0.ɵɵtextInterpolate(issue_r33);
|
|
647
|
+
} }
|
|
648
|
+
/**
|
|
649
|
+
* The confidence floor typed into the builder, as a number. A blank or non-numeric entry is NaN, so the spec
|
|
650
|
+
* check reports it ("must be a number greater than 0 and less than 1, but is NaN") instead of the builder
|
|
651
|
+
* guessing a value; an out-of-range number is kept as typed, for the same check to report.
|
|
652
|
+
*/
|
|
653
|
+
export function ParseConfidenceFloor(raw) {
|
|
654
|
+
const text = raw.trim();
|
|
655
|
+
return text.length === 0 ? Number.NaN : Number(text);
|
|
656
|
+
}
|
|
395
657
|
export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
396
658
|
cdr = inject(ChangeDetectorRef);
|
|
397
659
|
Record = null;
|
|
@@ -406,28 +668,241 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
406
668
|
Outputs: [],
|
|
407
669
|
Caching: { Cacheable: false },
|
|
408
670
|
};
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
671
|
+
AvailablePipelineTypes = [
|
|
672
|
+
{ Name: 'LLM', Description: null },
|
|
673
|
+
];
|
|
674
|
+
ShowTypeSwitchConfirm = false;
|
|
675
|
+
PendingPipelineType = null;
|
|
676
|
+
TypeSwitchIssues = [];
|
|
677
|
+
get CurrentPipelineTypeName() {
|
|
678
|
+
return this.spec.PipelineType?.trim() || 'LLM';
|
|
679
|
+
}
|
|
680
|
+
get CurrentCapabilities() {
|
|
681
|
+
return GetFeaturePipelineCapabilities(this.CurrentPipelineTypeName);
|
|
682
|
+
}
|
|
683
|
+
get IsDecisionPipeline() {
|
|
684
|
+
return this.CurrentPipelineTypeName.toLowerCase() === 'decision';
|
|
685
|
+
}
|
|
686
|
+
AvailableEscalationTargets = [];
|
|
687
|
+
/** Whether the escalation targets were loaded. False until a load succeeds, and after one fails. */
|
|
688
|
+
EscalationTargetsLoaded = false;
|
|
689
|
+
/** Why the last load of escalation targets failed, or null when it did not. */
|
|
690
|
+
EscalationTargetsLoadError = null;
|
|
691
|
+
/** Numbers each target load, so a slower earlier load cannot overwrite a later one. */
|
|
692
|
+
escalationTargetsLoadSeq = 0;
|
|
693
|
+
get IsEscalationEnabled() {
|
|
694
|
+
return this.spec.Escalation !== undefined && this.spec.Escalation !== null;
|
|
695
|
+
}
|
|
696
|
+
/** The target picker's empty option: what to pick, or why there is nothing to pick. */
|
|
697
|
+
get EscalationTargetsPlaceholder() {
|
|
698
|
+
if (this.EscalationTargetsLoadError) {
|
|
699
|
+
return '— Pipelines could not be loaded —';
|
|
700
|
+
}
|
|
701
|
+
return this.AvailableEscalationTargets.length > 0 ? '— Select LLM Pipeline —' : '— No other Infer pipelines on this entity —';
|
|
702
|
+
}
|
|
703
|
+
/** Whether `target` is the spec's escalation target. IDs compare through UUIDsEqual, as the target check does. */
|
|
704
|
+
IsSavedEscalationTarget(target) {
|
|
705
|
+
return UUIDsEqual(target.ID, this.spec.Escalation?.PipelineID);
|
|
706
|
+
}
|
|
707
|
+
/** Whether the target picker lists the spec's escalation target. Until the targets load, or when it is not among them, the placeholder shows. */
|
|
708
|
+
get SavedEscalationTargetListed() {
|
|
709
|
+
return this.AvailableEscalationTargets.some((t) => this.IsSavedEscalationTarget(t));
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Whether to offer the Capture Reasoning setting: for a type that produces reasoning, and for any spec
|
|
713
|
+
* that already asks for it, so a pipeline switched to a type without reasoning can turn it off.
|
|
714
|
+
*/
|
|
715
|
+
get ShowCaptureReasoning() {
|
|
716
|
+
return this.CurrentCapabilities.ProducesReasoning || this.spec.CaptureReasoning === true;
|
|
717
|
+
}
|
|
718
|
+
get SelectedPipelineTypeDescription() {
|
|
719
|
+
const cur = this.CurrentPipelineTypeName.toLowerCase();
|
|
720
|
+
const opt = this.AvailablePipelineTypes.find((t) => t.Name.toLowerCase() === cur);
|
|
721
|
+
return opt?.Description ?? '';
|
|
722
|
+
}
|
|
723
|
+
get AvailableTargetModes() {
|
|
724
|
+
const all = [
|
|
725
|
+
{ Value: 'field', Label: 'Entity Column (field)' },
|
|
726
|
+
{ Value: 'child', Label: 'Child Rows (child)' },
|
|
727
|
+
{ Value: 'tags', Label: 'Taxonomy Tags (tags)' },
|
|
728
|
+
];
|
|
729
|
+
const supported = this.CurrentCapabilities.TargetModes;
|
|
730
|
+
return all.filter((m) => supported.includes(m.Value));
|
|
731
|
+
}
|
|
732
|
+
get AvailableConstraintTypes() {
|
|
733
|
+
const options = [];
|
|
734
|
+
if (!this.IsDecisionPipeline) {
|
|
735
|
+
options.push({ Value: 'none', Label: 'None / Unconstrained' });
|
|
736
|
+
}
|
|
737
|
+
if (this.CurrentCapabilities.ConstraintTypes.includes('boolean')) {
|
|
738
|
+
options.push({ Value: 'boolean', Label: 'Boolean' });
|
|
739
|
+
}
|
|
740
|
+
if (this.CurrentCapabilities.ConstraintTypes.includes('enum')) {
|
|
741
|
+
options.push({ Value: 'enum', Label: 'Enum (Allowed Values)' });
|
|
742
|
+
}
|
|
743
|
+
if (this.CurrentCapabilities.ConstraintTypes.includes('numeric')) {
|
|
744
|
+
options.push({ Value: 'numeric', Label: this.IsDecisionPipeline ? 'Numeric (Levels)' : 'Numeric (Min/Max)' });
|
|
745
|
+
}
|
|
746
|
+
if (this.CurrentCapabilities.ConstraintTypes.includes('freetext')) {
|
|
747
|
+
options.push({ Value: 'freetext', Label: 'Free Text' });
|
|
748
|
+
}
|
|
749
|
+
return options;
|
|
750
|
+
}
|
|
751
|
+
// The pickers mark the saved option with [selected] on each <option>, not [value] on the <select>. A [value]
|
|
752
|
+
// binding runs before @for creates the options, matches nothing, and does not run again, so the browser shows
|
|
753
|
+
// the first option. When the saved value is not listed, the placeholder is selected. A placeholder inside @if
|
|
754
|
+
// binds [selected] instead of carrying the attribute, because on a live type switch the attribute loses to the
|
|
755
|
+
// option still selected, which is then removed.
|
|
756
|
+
/** Whether `name` is the spec's pipeline type. Names compare case-insensitively, as {@link IsDecisionPipeline} does. */
|
|
757
|
+
IsCurrentPipelineType(name) {
|
|
758
|
+
return name.toLowerCase() === this.CurrentPipelineTypeName.toLowerCase();
|
|
759
|
+
}
|
|
760
|
+
/** The output's saved constraint type as the constraint picker names it: `'none'` when it has none. */
|
|
761
|
+
SavedConstraintType(output) {
|
|
762
|
+
return output.Constraint?.Type || 'none';
|
|
763
|
+
}
|
|
764
|
+
/** Whether the constraint picker lists the output's saved type. A Decision output with no constraint, or one this type cannot produce, is not listed. */
|
|
765
|
+
IsConstraintTypeOffered(output) {
|
|
766
|
+
const saved = this.SavedConstraintType(output);
|
|
767
|
+
return this.AvailableConstraintTypes.some((t) => t.Value === saved);
|
|
768
|
+
}
|
|
769
|
+
/** Whether the target mode picker lists the output's saved mode. */
|
|
770
|
+
IsTargetModeOffered(output) {
|
|
771
|
+
return this.AvailableTargetModes.some((m) => m.Value === output.Target.Mode);
|
|
772
|
+
}
|
|
773
|
+
/** Whether the target field picker lists a field named `name`. */
|
|
774
|
+
IsEntityFieldListed(name) {
|
|
775
|
+
return !!name && this.EntityFields.some((f) => f.Name === name);
|
|
776
|
+
}
|
|
777
|
+
/** Whether the child entity picker lists an entity named `name`. */
|
|
778
|
+
IsEntityListed(name) {
|
|
779
|
+
return !!name && this.AvailableEntities.some((e) => e.Name === name);
|
|
780
|
+
}
|
|
781
|
+
/** Whether `prompt` is the pipeline's saved prompt. */
|
|
782
|
+
IsSavedPrompt(prompt) {
|
|
783
|
+
return UUIDsEqual(prompt.ID, this.Record ? this.Record.PromptID : this.spec.PromptID);
|
|
784
|
+
}
|
|
785
|
+
/** Whether the prompt picker lists the pipeline's saved prompt. */
|
|
786
|
+
get SavedPromptListed() {
|
|
787
|
+
return this.AvailablePrompts.some((p) => this.IsSavedPrompt(p));
|
|
788
|
+
}
|
|
789
|
+
/** Whether `doc` is the spec's saved entity document. */
|
|
790
|
+
IsSavedEntityDoc(doc) {
|
|
791
|
+
return UUIDsEqual(doc.ID, this.spec.Context.EntityDocumentID);
|
|
792
|
+
}
|
|
793
|
+
/** Whether the entity document picker lists the spec's saved document. */
|
|
794
|
+
get SavedEntityDocListed() {
|
|
795
|
+
return this.AvailableDocs.some((d) => this.IsSavedEntityDoc(d));
|
|
796
|
+
}
|
|
797
|
+
AvailablePrompts = [];
|
|
798
|
+
/** @deprecated Use {@link AvailablePrompts}. */
|
|
799
|
+
get availablePrompts() {
|
|
800
|
+
return this.AvailablePrompts;
|
|
801
|
+
}
|
|
802
|
+
/** @deprecated Use {@link AvailablePrompts}. */
|
|
803
|
+
set availablePrompts(value) {
|
|
804
|
+
this.AvailablePrompts = value;
|
|
805
|
+
}
|
|
806
|
+
AvailableDocs = [];
|
|
807
|
+
/** @deprecated Use {@link AvailableDocs}. */
|
|
808
|
+
get availableDocs() {
|
|
809
|
+
return this.AvailableDocs;
|
|
810
|
+
}
|
|
811
|
+
/** @deprecated Use {@link AvailableDocs}. */
|
|
812
|
+
set availableDocs(value) {
|
|
813
|
+
this.AvailableDocs = value;
|
|
814
|
+
}
|
|
815
|
+
AvailableEntities = [];
|
|
816
|
+
/** @deprecated Use {@link AvailableEntities}. */
|
|
817
|
+
get availableEntities() {
|
|
818
|
+
return this.AvailableEntities;
|
|
819
|
+
}
|
|
820
|
+
/** @deprecated Use {@link AvailableEntities}. */
|
|
821
|
+
set availableEntities(value) {
|
|
822
|
+
this.AvailableEntities = value;
|
|
823
|
+
}
|
|
824
|
+
EntityFields = [];
|
|
825
|
+
/** @deprecated Use {@link EntityFields}. */
|
|
826
|
+
get entityFields() {
|
|
827
|
+
return this.EntityFields;
|
|
828
|
+
}
|
|
829
|
+
/** @deprecated Use {@link EntityFields}. */
|
|
830
|
+
set entityFields(value) {
|
|
831
|
+
this.EntityFields = value;
|
|
832
|
+
}
|
|
833
|
+
SelectedPrompt = null;
|
|
834
|
+
/** @deprecated Use {@link SelectedPrompt}. */
|
|
835
|
+
get selectedPrompt() {
|
|
836
|
+
return this.SelectedPrompt;
|
|
837
|
+
}
|
|
838
|
+
/** @deprecated Use {@link SelectedPrompt}. */
|
|
839
|
+
set selectedPrompt(value) {
|
|
840
|
+
this.SelectedPrompt = value;
|
|
841
|
+
}
|
|
842
|
+
ContextMode = 'fields';
|
|
843
|
+
/** @deprecated Use {@link ContextMode}. */
|
|
844
|
+
get contextMode() {
|
|
845
|
+
return this.ContextMode;
|
|
846
|
+
}
|
|
847
|
+
/** @deprecated Use {@link ContextMode}. */
|
|
848
|
+
set contextMode(value) {
|
|
849
|
+
this.ContextMode = value;
|
|
850
|
+
}
|
|
851
|
+
FieldsCsv = '';
|
|
852
|
+
/** @deprecated Use {@link FieldsCsv}. */
|
|
853
|
+
get fieldsCsv() {
|
|
854
|
+
return this.FieldsCsv;
|
|
855
|
+
}
|
|
856
|
+
/** @deprecated Use {@link FieldsCsv}. */
|
|
857
|
+
set fieldsCsv(value) {
|
|
858
|
+
this.FieldsCsv = value;
|
|
859
|
+
}
|
|
860
|
+
CacheKeyFieldsCsv = '';
|
|
861
|
+
/** @deprecated Use {@link CacheKeyFieldsCsv}. */
|
|
862
|
+
get cacheKeyFieldsCsv() {
|
|
863
|
+
return this.CacheKeyFieldsCsv;
|
|
864
|
+
}
|
|
865
|
+
/** @deprecated Use {@link CacheKeyFieldsCsv}. */
|
|
866
|
+
set cacheKeyFieldsCsv(value) {
|
|
867
|
+
this.CacheKeyFieldsCsv = value;
|
|
868
|
+
}
|
|
869
|
+
ValidationErrors = [];
|
|
870
|
+
/** @deprecated Use {@link ValidationErrors}. */
|
|
871
|
+
get validationErrors() {
|
|
872
|
+
return this.ValidationErrors;
|
|
873
|
+
}
|
|
874
|
+
/** @deprecated Use {@link ValidationErrors}. */
|
|
875
|
+
set validationErrors(value) {
|
|
876
|
+
this.ValidationErrors = value;
|
|
877
|
+
}
|
|
878
|
+
RenderedConstraintPreview = '';
|
|
879
|
+
/** @deprecated Use {@link RenderedConstraintPreview}. */
|
|
880
|
+
get renderedConstraintPreview() {
|
|
881
|
+
return this.RenderedConstraintPreview;
|
|
882
|
+
}
|
|
883
|
+
/** @deprecated Use {@link RenderedConstraintPreview}. */
|
|
884
|
+
set renderedConstraintPreview(value) {
|
|
885
|
+
this.RenderedConstraintPreview = value;
|
|
886
|
+
}
|
|
419
887
|
async ngOnInit() {
|
|
420
|
-
this.
|
|
888
|
+
this.AvailableEntities = [...this.ProviderToUse.Entities].sort((a, b) => (a.DisplayName || a.Name).localeCompare(b.DisplayName || b.Name));
|
|
889
|
+
await this.loadPipelineTypes();
|
|
421
890
|
await this.loadPrompts();
|
|
422
891
|
await this.loadEntityDocs();
|
|
423
|
-
this.
|
|
892
|
+
await this.LoadEscalationTargets();
|
|
893
|
+
this.SyncFromRecord();
|
|
424
894
|
}
|
|
425
895
|
ngOnChanges(changes) {
|
|
426
896
|
if (changes['Record'] || changes['EntityID']) {
|
|
427
|
-
this.
|
|
897
|
+
this.SyncFromRecord();
|
|
898
|
+
// ngOnInit loads the targets for the first binding; reload only when the pipeline or entity changes after it
|
|
899
|
+
const firstBinding = Object.values(changes).every((change) => change.firstChange);
|
|
900
|
+
if (!firstBinding) {
|
|
901
|
+
void this.LoadEscalationTargets();
|
|
902
|
+
}
|
|
428
903
|
}
|
|
429
904
|
}
|
|
430
|
-
|
|
905
|
+
SyncFromRecord() {
|
|
431
906
|
if (this.Record) {
|
|
432
907
|
this.spec.Name = this.Record.Name || '';
|
|
433
908
|
this.spec.Description = this.Record.Description || '';
|
|
@@ -439,6 +914,16 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
439
914
|
this.spec.Context = parsed.Context ?? {};
|
|
440
915
|
this.spec.Caching = parsed.Caching ?? { Cacheable: false };
|
|
441
916
|
this.spec.ProcessorExtensionKey = parsed.ProcessorExtensionKey;
|
|
917
|
+
this.spec.PipelineType = parsed.PipelineType;
|
|
918
|
+
if (parsed.Escalation) {
|
|
919
|
+
this.spec.Escalation = { ...parsed.Escalation };
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
delete this.spec.Escalation;
|
|
923
|
+
}
|
|
924
|
+
// Carried so the capability check sees what the runtime sees, and the next edit keeps them
|
|
925
|
+
this.spec.CaptureReasoning = parsed.CaptureReasoning;
|
|
926
|
+
this.spec.Watermark = parsed.Watermark;
|
|
442
927
|
}
|
|
443
928
|
}
|
|
444
929
|
}
|
|
@@ -449,30 +934,100 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
449
934
|
this.spec.Context = {};
|
|
450
935
|
}
|
|
451
936
|
if (this.spec.Context.EntityDocumentID) {
|
|
452
|
-
this.
|
|
937
|
+
this.ContextMode = 'document';
|
|
453
938
|
}
|
|
454
939
|
else if (this.spec.Context.QueryID) {
|
|
455
|
-
this.
|
|
940
|
+
this.ContextMode = 'query';
|
|
456
941
|
}
|
|
457
942
|
else {
|
|
458
|
-
this.
|
|
943
|
+
this.ContextMode = 'fields';
|
|
459
944
|
}
|
|
460
|
-
this.
|
|
461
|
-
this.
|
|
945
|
+
this.FieldsCsv = (this.spec.Context.Fields ?? []).join(', ');
|
|
946
|
+
this.CacheKeyFieldsCsv = (this.spec.Caching.KeyFields ?? []).join(', ');
|
|
462
947
|
const targetEntityID = this.Record?.EntityID || this.EntityID;
|
|
463
948
|
if (targetEntityID) {
|
|
464
949
|
const entity = this.ProviderToUse.EntityByID(targetEntityID);
|
|
465
|
-
this.
|
|
950
|
+
this.EntityFields = entity?.Fields ? [...entity.Fields].sort((a, b) => a.Name.localeCompare(b.Name)) : [];
|
|
466
951
|
}
|
|
467
952
|
else {
|
|
468
|
-
this.
|
|
953
|
+
this.EntityFields = [];
|
|
469
954
|
}
|
|
470
955
|
if (this.Record?.PromptID) {
|
|
471
|
-
this.
|
|
956
|
+
this.SelectedPrompt = this.AvailablePrompts.find((p) => UUIDsEqual(p.ID, this.Record?.PromptID)) ?? null;
|
|
472
957
|
}
|
|
958
|
+
this.ensureLoadedTypeIncluded();
|
|
473
959
|
this.recomputeValidation();
|
|
474
960
|
this.cdr.detectChanges();
|
|
475
961
|
}
|
|
962
|
+
/** @deprecated Use {@link SyncFromRecord}. */
|
|
963
|
+
syncFromRecord() {
|
|
964
|
+
return this.SyncFromRecord();
|
|
965
|
+
}
|
|
966
|
+
async loadPipelineTypes() {
|
|
967
|
+
let activeRows = [];
|
|
968
|
+
try {
|
|
969
|
+
await KnowledgeHubMetadataEngine.Instance.Config(false, this.ProviderToUse.CurrentUser, this.ProviderToUse);
|
|
970
|
+
const engineTypes = KnowledgeHubMetadataEngine.Instance.FeaturePipelineTypes;
|
|
971
|
+
if (Array.isArray(engineTypes)) {
|
|
972
|
+
activeRows = engineTypes.filter((t) => t.Status === 'Active');
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
catch (error) {
|
|
976
|
+
LogError('Error loading Feature Pipeline Types from KnowledgeHubMetadataEngine', undefined, error);
|
|
977
|
+
}
|
|
978
|
+
if (activeRows.length > 0) {
|
|
979
|
+
this.AvailablePipelineTypes = activeRows.map((t) => ({
|
|
980
|
+
Name: t.Name,
|
|
981
|
+
Description: t.Description || null,
|
|
982
|
+
}));
|
|
983
|
+
if (!this.AvailablePipelineTypes.some((t) => t.Name.toLowerCase() === 'llm')) {
|
|
984
|
+
this.AvailablePipelineTypes.unshift({
|
|
985
|
+
Name: 'LLM',
|
|
986
|
+
Description: null,
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
else {
|
|
991
|
+
this.AvailablePipelineTypes = [
|
|
992
|
+
{
|
|
993
|
+
Name: 'LLM',
|
|
994
|
+
Description: null,
|
|
995
|
+
},
|
|
996
|
+
];
|
|
997
|
+
}
|
|
998
|
+
this.ensureLoadedTypeIncluded();
|
|
999
|
+
}
|
|
1000
|
+
ensureLoadedTypeIncluded() {
|
|
1001
|
+
const typeName = this.spec.PipelineType?.trim();
|
|
1002
|
+
if (!typeName || typeName.toLowerCase() === 'llm') {
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
const exists = this.AvailablePipelineTypes.some((t) => t.Name.toLowerCase() === typeName.toLowerCase());
|
|
1006
|
+
if (exists) {
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
let isInactive = false;
|
|
1010
|
+
let desc = null;
|
|
1011
|
+
try {
|
|
1012
|
+
const engineTypes = KnowledgeHubMetadataEngine.Instance.FeaturePipelineTypes;
|
|
1013
|
+
if (Array.isArray(engineTypes)) {
|
|
1014
|
+
const match = engineTypes.find((t) => t.Name?.trim().toLowerCase() === typeName.toLowerCase());
|
|
1015
|
+
if (match) {
|
|
1016
|
+
isInactive = match.Status !== 'Active';
|
|
1017
|
+
desc = match.Description || null;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
catch {
|
|
1022
|
+
// Ignore
|
|
1023
|
+
}
|
|
1024
|
+
const label = isInactive ? `${typeName} (inactive)` : `${typeName} (unrecognized)`;
|
|
1025
|
+
this.AvailablePipelineTypes.push({
|
|
1026
|
+
Name: typeName,
|
|
1027
|
+
DisplayName: label,
|
|
1028
|
+
Description: desc,
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
476
1031
|
async loadPrompts() {
|
|
477
1032
|
try {
|
|
478
1033
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
@@ -482,15 +1037,15 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
482
1037
|
ResultType: 'simple',
|
|
483
1038
|
});
|
|
484
1039
|
if (res.Success && Array.isArray(res.Results)) {
|
|
485
|
-
this.
|
|
1040
|
+
this.AvailablePrompts = res.Results;
|
|
486
1041
|
}
|
|
487
1042
|
else {
|
|
488
|
-
this.
|
|
1043
|
+
this.AvailablePrompts = [];
|
|
489
1044
|
LogError(`Failed to load AI Prompts: ${res.ErrorMessage || 'unknown error'}`);
|
|
490
1045
|
}
|
|
491
1046
|
}
|
|
492
1047
|
catch (error) {
|
|
493
|
-
this.
|
|
1048
|
+
this.AvailablePrompts = [];
|
|
494
1049
|
LogError('Error loading AI Prompts', undefined, error);
|
|
495
1050
|
}
|
|
496
1051
|
}
|
|
@@ -503,49 +1058,161 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
503
1058
|
ResultType: 'simple',
|
|
504
1059
|
});
|
|
505
1060
|
if (res.Success && Array.isArray(res.Results)) {
|
|
506
|
-
this.
|
|
1061
|
+
this.AvailableDocs = res.Results;
|
|
507
1062
|
}
|
|
508
1063
|
else {
|
|
509
|
-
this.
|
|
1064
|
+
this.AvailableDocs = [];
|
|
510
1065
|
LogError(`Failed to load Entity Documents: ${res.ErrorMessage || 'unknown error'}`);
|
|
511
1066
|
}
|
|
512
1067
|
}
|
|
513
1068
|
catch (error) {
|
|
514
|
-
this.
|
|
1069
|
+
this.AvailableDocs = [];
|
|
515
1070
|
LogError('Error loading Entity Documents', undefined, error);
|
|
516
1071
|
}
|
|
517
1072
|
}
|
|
518
|
-
|
|
519
|
-
|
|
1073
|
+
/**
|
|
1074
|
+
* Loads the Infer pipelines on this pipeline's entity that it could escalate to. With no entity there is
|
|
1075
|
+
* nothing to offer, so nothing is loaded. A failed load is recorded in {@link EscalationTargetsLoadError},
|
|
1076
|
+
* not taken to mean there are no targets. Only the latest load's result is kept.
|
|
1077
|
+
*/
|
|
1078
|
+
async LoadEscalationTargets() {
|
|
1079
|
+
const seq = ++this.escalationTargetsLoadSeq;
|
|
1080
|
+
const targetEntityID = this.Record?.EntityID || this.EntityID;
|
|
1081
|
+
const outcome = targetEntityID
|
|
1082
|
+
? await this.fetchEscalationTargets(targetEntityID)
|
|
1083
|
+
: { Targets: [], Error: null };
|
|
1084
|
+
if (seq !== this.escalationTargetsLoadSeq) {
|
|
1085
|
+
return; // a later load, for a later Record or entity, has superseded this one
|
|
1086
|
+
}
|
|
1087
|
+
this.AvailableEscalationTargets = outcome.Targets;
|
|
1088
|
+
this.EscalationTargetsLoadError = outcome.Error;
|
|
1089
|
+
this.EscalationTargetsLoaded = outcome.Error === null;
|
|
1090
|
+
this.recomputeValidation();
|
|
1091
|
+
this.cdr.detectChanges();
|
|
1092
|
+
}
|
|
1093
|
+
/** The Infer pipelines on the entity, other than this one, each with its parsed spec; or why they could not be read. */
|
|
1094
|
+
async fetchEscalationTargets(entityID) {
|
|
1095
|
+
try {
|
|
1096
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
1097
|
+
const res = await rv.RunView({
|
|
1098
|
+
EntityName: 'MJ: Record Processes',
|
|
1099
|
+
Fields: ['ID', 'Name', 'Description', 'Entity', 'EntityID', 'WorkType', 'Status', 'PromptID', 'Configuration'],
|
|
1100
|
+
ExtraFilter: `WorkType='Infer' AND EntityID='${EscapeSQLString(entityID)}'`,
|
|
1101
|
+
OrderBy: 'Name',
|
|
1102
|
+
ResultType: 'simple',
|
|
1103
|
+
});
|
|
1104
|
+
if (!res.Success) {
|
|
1105
|
+
const reason = res.ErrorMessage || 'unknown error';
|
|
1106
|
+
LogError(`Failed to load Escalation Targets: ${reason}`);
|
|
1107
|
+
return { Targets: [], Error: reason };
|
|
1108
|
+
}
|
|
1109
|
+
const currentID = this.Record?.ID;
|
|
1110
|
+
const targets = (res.Results ?? [])
|
|
1111
|
+
.filter((r) => !currentID || !UUIDsEqual(r.ID, currentID))
|
|
1112
|
+
.map((r) => ({ ...r, ParsedSpec: this.parseTargetSpec(r.Configuration) }));
|
|
1113
|
+
return { Targets: targets, Error: null };
|
|
1114
|
+
}
|
|
1115
|
+
catch (error) {
|
|
1116
|
+
LogError('Error loading Escalation Targets', undefined, error);
|
|
1117
|
+
return { Targets: [], Error: error instanceof Error ? error.message : String(error) };
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
/** A target's Configuration as a spec, or undefined when it is empty or not a JSON object. */
|
|
1121
|
+
parseTargetSpec(configuration) {
|
|
1122
|
+
const parsed = configuration ? SafeJSONParse(configuration) : null;
|
|
1123
|
+
return parsed && typeof parsed === 'object' ? parsed : undefined;
|
|
1124
|
+
}
|
|
1125
|
+
/**
|
|
1126
|
+
* Why a pipeline cannot be this pipeline's escalation target, or null when it can. Beyond the shared row and
|
|
1127
|
+
* output checks, its own spec must pass `ValidateSpec`, as the engine requires before it builds the target.
|
|
1128
|
+
*/
|
|
1129
|
+
GetTargetProblem(target) {
|
|
1130
|
+
const targetEntityID = this.Record?.EntityID || this.EntityID || '';
|
|
1131
|
+
const rowProblem = FindEscalationTargetRowProblem(target, targetEntityID);
|
|
1132
|
+
if (rowProblem) {
|
|
1133
|
+
return rowProblem;
|
|
1134
|
+
}
|
|
1135
|
+
const specError = target.ParsedSpec ? validateSpec(target.ParsedSpec).find((issue) => issue.Severity === 'error') : undefined;
|
|
1136
|
+
if (specError) {
|
|
1137
|
+
return `has an invalid spec: ${specError.Message}`;
|
|
1138
|
+
}
|
|
1139
|
+
return FindEscalationTargetSpecProblem(target.ParsedSpec, this.spec.Outputs ?? []);
|
|
1140
|
+
}
|
|
1141
|
+
OnEscalationToggle(event) {
|
|
1142
|
+
const checked = event.target.checked;
|
|
1143
|
+
if (checked) {
|
|
1144
|
+
this.spec.Escalation = {
|
|
1145
|
+
PipelineID: this.spec.Escalation?.PipelineID || '',
|
|
1146
|
+
BelowConfidence: this.spec.Escalation?.BelowConfidence ?? 0.7,
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
else {
|
|
1150
|
+
delete this.spec.Escalation;
|
|
1151
|
+
}
|
|
1152
|
+
this.emitChanges();
|
|
1153
|
+
}
|
|
1154
|
+
OnEscalationTargetChange(event) {
|
|
1155
|
+
const val = event.target.value;
|
|
1156
|
+
if (!this.spec.Escalation) {
|
|
1157
|
+
this.spec.Escalation = {
|
|
1158
|
+
PipelineID: val,
|
|
1159
|
+
BelowConfidence: 0.7,
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
else {
|
|
1163
|
+
this.spec.Escalation.PipelineID = val;
|
|
1164
|
+
}
|
|
1165
|
+
this.emitChanges();
|
|
1166
|
+
}
|
|
1167
|
+
/** Sets the confidence floor from its input, as a number; a blank or invalid entry is NaN, which the spec check reports. */
|
|
1168
|
+
OnEscalationFloorChange(event) {
|
|
1169
|
+
const floor = ParseConfidenceFloor(event.target.value);
|
|
1170
|
+
this.spec.Escalation = { PipelineID: this.spec.Escalation?.PipelineID ?? '', BelowConfidence: floor };
|
|
1171
|
+
this.emitChanges();
|
|
1172
|
+
}
|
|
1173
|
+
OnContextModeChange(event) {
|
|
1174
|
+
this.ContextMode = event.target.value;
|
|
520
1175
|
if (!this.spec.Context)
|
|
521
1176
|
this.spec.Context = {};
|
|
522
|
-
if (this.
|
|
1177
|
+
if (this.ContextMode === 'fields') {
|
|
523
1178
|
this.spec.Context.EntityDocumentID = undefined;
|
|
524
1179
|
this.spec.Context.QueryID = undefined;
|
|
525
1180
|
}
|
|
526
|
-
else if (this.
|
|
1181
|
+
else if (this.ContextMode === 'document') {
|
|
527
1182
|
this.spec.Context.QueryID = undefined;
|
|
528
1183
|
}
|
|
529
|
-
else if (this.
|
|
1184
|
+
else if (this.ContextMode === 'query') {
|
|
530
1185
|
this.spec.Context.EntityDocumentID = undefined;
|
|
531
1186
|
}
|
|
532
1187
|
this.emitChanges();
|
|
533
1188
|
}
|
|
534
|
-
|
|
1189
|
+
/** @deprecated Use {@link OnContextModeChange}. */
|
|
1190
|
+
onContextModeChange(event) {
|
|
1191
|
+
return this.OnContextModeChange(event);
|
|
1192
|
+
}
|
|
1193
|
+
OnEntityDocChange(event) {
|
|
535
1194
|
if (!this.spec.Context)
|
|
536
1195
|
this.spec.Context = {};
|
|
537
1196
|
this.spec.Context.EntityDocumentID = event.target.value;
|
|
538
1197
|
this.emitChanges();
|
|
539
1198
|
}
|
|
540
|
-
|
|
1199
|
+
/** @deprecated Use {@link OnEntityDocChange}. */
|
|
1200
|
+
onEntityDocChange(event) {
|
|
1201
|
+
return this.OnEntityDocChange(event);
|
|
1202
|
+
}
|
|
1203
|
+
OnQueryIDChange(event) {
|
|
541
1204
|
if (!this.spec.Context)
|
|
542
1205
|
this.spec.Context = {};
|
|
543
1206
|
this.spec.Context.QueryID = event.target.value;
|
|
544
1207
|
this.emitChanges();
|
|
545
1208
|
}
|
|
546
|
-
|
|
1209
|
+
/** @deprecated Use {@link OnQueryIDChange}. */
|
|
1210
|
+
onQueryIDChange(event) {
|
|
1211
|
+
return this.OnQueryIDChange(event);
|
|
1212
|
+
}
|
|
1213
|
+
OnFieldsCsvChange(event) {
|
|
547
1214
|
const val = event.target.value;
|
|
548
|
-
this.
|
|
1215
|
+
this.FieldsCsv = val;
|
|
549
1216
|
if (!this.spec.Context)
|
|
550
1217
|
this.spec.Context = {};
|
|
551
1218
|
this.spec.Context.Fields = val
|
|
@@ -554,49 +1221,71 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
554
1221
|
.filter((s) => s.length > 0);
|
|
555
1222
|
this.emitChanges();
|
|
556
1223
|
}
|
|
557
|
-
|
|
1224
|
+
/** @deprecated Use {@link OnFieldsCsvChange}. */
|
|
1225
|
+
onFieldsCsvChange(event) {
|
|
1226
|
+
return this.OnFieldsCsvChange(event);
|
|
1227
|
+
}
|
|
1228
|
+
OnPromptChange(event) {
|
|
558
1229
|
const promptID = event.target.value;
|
|
559
1230
|
if (this.Record) {
|
|
560
1231
|
this.Record.PromptID = promptID;
|
|
561
1232
|
}
|
|
562
1233
|
this.spec.PromptID = promptID;
|
|
563
|
-
this.
|
|
1234
|
+
this.SelectedPrompt = this.AvailablePrompts.find((p) => UUIDsEqual(p.ID, promptID)) ?? null;
|
|
564
1235
|
this.emitChanges();
|
|
565
1236
|
}
|
|
1237
|
+
/** @deprecated Use {@link OnPromptChange}. */
|
|
1238
|
+
onPromptChange(event) {
|
|
1239
|
+
return this.OnPromptChange(event);
|
|
1240
|
+
}
|
|
566
1241
|
addOutput() {
|
|
567
1242
|
const newOutput = {
|
|
568
1243
|
Name: `Output_${this.spec.Outputs.length + 1}`,
|
|
569
1244
|
Ref: '$',
|
|
570
1245
|
Target: {
|
|
571
1246
|
Mode: 'field',
|
|
572
|
-
EntityFieldName: this.
|
|
1247
|
+
EntityFieldName: this.EntityFields.length > 0 ? this.EntityFields[0].Name : '',
|
|
573
1248
|
},
|
|
574
1249
|
};
|
|
1250
|
+
if (this.IsDecisionPipeline) {
|
|
1251
|
+
newOutput.Constraint = {
|
|
1252
|
+
Type: 'boolean',
|
|
1253
|
+
OnViolation: 'fail',
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
575
1256
|
this.spec.Outputs.push(newOutput);
|
|
576
1257
|
this.emitChanges();
|
|
577
1258
|
}
|
|
578
|
-
|
|
1259
|
+
RemoveOutput(index) {
|
|
579
1260
|
this.spec.Outputs.splice(index, 1);
|
|
580
1261
|
this.emitChanges();
|
|
581
1262
|
}
|
|
582
|
-
|
|
1263
|
+
/** @deprecated Use {@link RemoveOutput}. */
|
|
1264
|
+
removeOutput(index) {
|
|
1265
|
+
return this.RemoveOutput(index);
|
|
1266
|
+
}
|
|
1267
|
+
UpdateOutputProp(index, prop, event) {
|
|
583
1268
|
const val = event.target.value;
|
|
584
1269
|
this.spec.Outputs[index][prop] = val;
|
|
585
1270
|
this.emitChanges();
|
|
586
1271
|
}
|
|
587
|
-
|
|
1272
|
+
/** @deprecated Use {@link UpdateOutputProp}. */
|
|
1273
|
+
updateOutputProp(index, prop, event) {
|
|
1274
|
+
return this.UpdateOutputProp(index, prop, event);
|
|
1275
|
+
}
|
|
1276
|
+
UpdateTargetMode(index, event) {
|
|
588
1277
|
const mode = event.target.value;
|
|
589
1278
|
const current = this.spec.Outputs[index];
|
|
590
1279
|
if (mode === 'field') {
|
|
591
1280
|
current.Target = {
|
|
592
1281
|
Mode: 'field',
|
|
593
|
-
EntityFieldName: this.
|
|
1282
|
+
EntityFieldName: this.EntityFields.length > 0 ? this.EntityFields[0].Name : '',
|
|
594
1283
|
};
|
|
595
1284
|
}
|
|
596
1285
|
else if (mode === 'child') {
|
|
597
1286
|
current.Target = {
|
|
598
1287
|
Mode: 'child',
|
|
599
|
-
EntityName: this.
|
|
1288
|
+
EntityName: this.AvailableEntities.length > 0 ? this.AvailableEntities[0].Name : '',
|
|
600
1289
|
ParentField: 'ParentID',
|
|
601
1290
|
Map: {},
|
|
602
1291
|
};
|
|
@@ -609,15 +1298,26 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
609
1298
|
}
|
|
610
1299
|
this.emitChanges();
|
|
611
1300
|
}
|
|
612
|
-
|
|
1301
|
+
/** @deprecated Use {@link UpdateTargetMode}. */
|
|
1302
|
+
updateTargetMode(index, event) {
|
|
1303
|
+
return this.UpdateTargetMode(index, event);
|
|
1304
|
+
}
|
|
1305
|
+
UpdateFieldTarget(index, event) {
|
|
613
1306
|
const fieldName = event.target.value;
|
|
614
1307
|
const target = this.spec.Outputs[index].Target;
|
|
615
1308
|
if (target.Mode === 'field') {
|
|
616
1309
|
target.EntityFieldName = fieldName;
|
|
1310
|
+
if (this.spec.Outputs[index].Constraint?.Type === 'enum') {
|
|
1311
|
+
this.prefillEnumValuesFromField(this.spec.Outputs[index]);
|
|
1312
|
+
}
|
|
617
1313
|
}
|
|
618
1314
|
this.emitChanges();
|
|
619
1315
|
}
|
|
620
|
-
|
|
1316
|
+
/** @deprecated Use {@link UpdateFieldTarget}. */
|
|
1317
|
+
updateFieldTarget(index, event) {
|
|
1318
|
+
return this.UpdateFieldTarget(index, event);
|
|
1319
|
+
}
|
|
1320
|
+
UpdateChildTargetEntity(index, event) {
|
|
621
1321
|
const entityName = event.target.value;
|
|
622
1322
|
const target = this.spec.Outputs[index].Target;
|
|
623
1323
|
if (target.Mode === 'child') {
|
|
@@ -625,7 +1325,11 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
625
1325
|
}
|
|
626
1326
|
this.emitChanges();
|
|
627
1327
|
}
|
|
628
|
-
|
|
1328
|
+
/** @deprecated Use {@link UpdateChildTargetEntity}. */
|
|
1329
|
+
updateChildTargetEntity(index, event) {
|
|
1330
|
+
return this.UpdateChildTargetEntity(index, event);
|
|
1331
|
+
}
|
|
1332
|
+
UpdateConstraintType(index, event) {
|
|
629
1333
|
const type = event.target.value;
|
|
630
1334
|
const output = this.spec.Outputs[index];
|
|
631
1335
|
if (type === 'none') {
|
|
@@ -633,9 +1337,15 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
633
1337
|
}
|
|
634
1338
|
else if (type === 'enum') {
|
|
635
1339
|
output.Constraint = { Type: 'enum', Values: [], OnViolation: 'fail' };
|
|
1340
|
+
this.prefillEnumValuesFromField(output);
|
|
636
1341
|
}
|
|
637
1342
|
else if (type === 'numeric') {
|
|
638
|
-
|
|
1343
|
+
if (this.IsDecisionPipeline) {
|
|
1344
|
+
output.Constraint = { Type: 'numeric', Levels: ['Low', 'Medium', 'High'], OnViolation: 'fail' };
|
|
1345
|
+
}
|
|
1346
|
+
else {
|
|
1347
|
+
output.Constraint = { Type: 'numeric', Min: 0, Max: 100, OnViolation: 'fail' };
|
|
1348
|
+
}
|
|
639
1349
|
}
|
|
640
1350
|
else if (type === 'boolean') {
|
|
641
1351
|
output.Constraint = { Type: 'boolean', OnViolation: 'fail' };
|
|
@@ -645,26 +1355,46 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
645
1355
|
}
|
|
646
1356
|
this.emitChanges();
|
|
647
1357
|
}
|
|
648
|
-
|
|
1358
|
+
/** @deprecated Use {@link UpdateConstraintType}. */
|
|
1359
|
+
updateConstraintType(index, event) {
|
|
1360
|
+
return this.UpdateConstraintType(index, event);
|
|
1361
|
+
}
|
|
1362
|
+
UpdateViolationPolicy(index, event) {
|
|
649
1363
|
const policy = event.target.value;
|
|
650
1364
|
if (this.spec.Outputs[index].Constraint) {
|
|
651
1365
|
this.spec.Outputs[index].Constraint.OnViolation = policy;
|
|
652
1366
|
}
|
|
653
1367
|
this.emitChanges();
|
|
654
1368
|
}
|
|
655
|
-
|
|
1369
|
+
/** @deprecated Use {@link UpdateViolationPolicy}. */
|
|
1370
|
+
updateViolationPolicy(index, event) {
|
|
1371
|
+
return this.UpdateViolationPolicy(index, event);
|
|
1372
|
+
}
|
|
1373
|
+
GetEnumValuesCsv(constraint) {
|
|
656
1374
|
if (!constraint || constraint.Type !== 'enum' || !Array.isArray(constraint.Values)) {
|
|
657
1375
|
return '';
|
|
658
1376
|
}
|
|
659
1377
|
return constraint.Values.join(', ');
|
|
660
1378
|
}
|
|
661
|
-
|
|
1379
|
+
/** @deprecated Use {@link GetEnumValuesCsv}. */
|
|
1380
|
+
getEnumValuesCsv(constraint) {
|
|
1381
|
+
return this.GetEnumValuesCsv(constraint);
|
|
1382
|
+
}
|
|
1383
|
+
GetNumericMin(constraint) {
|
|
662
1384
|
return constraint && constraint.Type === 'numeric' && constraint.Min !== undefined ? constraint.Min : '';
|
|
663
1385
|
}
|
|
664
|
-
|
|
1386
|
+
/** @deprecated Use {@link GetNumericMin}. */
|
|
1387
|
+
getNumericMin(constraint) {
|
|
1388
|
+
return this.GetNumericMin(constraint);
|
|
1389
|
+
}
|
|
1390
|
+
GetNumericMax(constraint) {
|
|
665
1391
|
return constraint && constraint.Type === 'numeric' && constraint.Max !== undefined ? constraint.Max : '';
|
|
666
1392
|
}
|
|
667
|
-
|
|
1393
|
+
/** @deprecated Use {@link GetNumericMax}. */
|
|
1394
|
+
getNumericMax(constraint) {
|
|
1395
|
+
return this.GetNumericMax(constraint);
|
|
1396
|
+
}
|
|
1397
|
+
UpdateEnumValues(index, event) {
|
|
668
1398
|
const val = event.target.value;
|
|
669
1399
|
const output = this.spec.Outputs[index];
|
|
670
1400
|
if (!output.Constraint || output.Constraint.Type !== 'enum') {
|
|
@@ -676,7 +1406,11 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
676
1406
|
.filter((s) => s.length > 0);
|
|
677
1407
|
this.emitChanges();
|
|
678
1408
|
}
|
|
679
|
-
|
|
1409
|
+
/** @deprecated Use {@link UpdateEnumValues}. */
|
|
1410
|
+
updateEnumValues(index, event) {
|
|
1411
|
+
return this.UpdateEnumValues(index, event);
|
|
1412
|
+
}
|
|
1413
|
+
UpdateNumericMin(index, event) {
|
|
680
1414
|
const val = parseFloat(event.target.value);
|
|
681
1415
|
const output = this.spec.Outputs[index];
|
|
682
1416
|
if (output.Constraint && output.Constraint.Type === 'numeric') {
|
|
@@ -684,7 +1418,11 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
684
1418
|
}
|
|
685
1419
|
this.emitChanges();
|
|
686
1420
|
}
|
|
687
|
-
|
|
1421
|
+
/** @deprecated Use {@link UpdateNumericMin}. */
|
|
1422
|
+
updateNumericMin(index, event) {
|
|
1423
|
+
return this.UpdateNumericMin(index, event);
|
|
1424
|
+
}
|
|
1425
|
+
UpdateNumericMax(index, event) {
|
|
688
1426
|
const val = parseFloat(event.target.value);
|
|
689
1427
|
const output = this.spec.Outputs[index];
|
|
690
1428
|
if (output.Constraint && output.Constraint.Type === 'numeric') {
|
|
@@ -692,25 +1430,41 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
692
1430
|
}
|
|
693
1431
|
this.emitChanges();
|
|
694
1432
|
}
|
|
695
|
-
|
|
1433
|
+
/** @deprecated Use {@link UpdateNumericMax}. */
|
|
1434
|
+
updateNumericMax(index, event) {
|
|
1435
|
+
return this.UpdateNumericMax(index, event);
|
|
1436
|
+
}
|
|
1437
|
+
UpdateWatermarkStrategy(event) {
|
|
696
1438
|
if (this.Record) {
|
|
697
1439
|
this.Record.WatermarkStrategy = event.target.value;
|
|
698
1440
|
}
|
|
699
1441
|
}
|
|
700
|
-
|
|
1442
|
+
/** @deprecated Use {@link UpdateWatermarkStrategy}. */
|
|
1443
|
+
updateWatermarkStrategy(event) {
|
|
1444
|
+
return this.UpdateWatermarkStrategy(event);
|
|
1445
|
+
}
|
|
1446
|
+
UpdateSkipUnchanged(event) {
|
|
701
1447
|
if (this.Record) {
|
|
702
1448
|
this.Record.SkipUnchanged = event.target.value === 'true';
|
|
703
1449
|
}
|
|
704
1450
|
}
|
|
705
|
-
|
|
1451
|
+
/** @deprecated Use {@link UpdateSkipUnchanged}. */
|
|
1452
|
+
updateSkipUnchanged(event) {
|
|
1453
|
+
return this.UpdateSkipUnchanged(event);
|
|
1454
|
+
}
|
|
1455
|
+
UpdateCacheable(event) {
|
|
706
1456
|
if (!this.spec.Caching)
|
|
707
1457
|
this.spec.Caching = { Cacheable: false };
|
|
708
1458
|
this.spec.Caching.Cacheable = event.target.value === 'true';
|
|
709
1459
|
this.emitChanges();
|
|
710
1460
|
}
|
|
711
|
-
|
|
1461
|
+
/** @deprecated Use {@link UpdateCacheable}. */
|
|
1462
|
+
updateCacheable(event) {
|
|
1463
|
+
return this.UpdateCacheable(event);
|
|
1464
|
+
}
|
|
1465
|
+
UpdateCacheKeyFields(event) {
|
|
712
1466
|
const val = event.target.value;
|
|
713
|
-
this.
|
|
1467
|
+
this.CacheKeyFieldsCsv = val;
|
|
714
1468
|
if (!this.spec.Caching)
|
|
715
1469
|
this.spec.Caching = { Cacheable: true };
|
|
716
1470
|
this.spec.Caching.KeyFields = val
|
|
@@ -719,21 +1473,239 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
719
1473
|
.filter((s) => s.length > 0);
|
|
720
1474
|
this.emitChanges();
|
|
721
1475
|
}
|
|
722
|
-
|
|
1476
|
+
/** @deprecated Use {@link UpdateCacheKeyFields}. */
|
|
1477
|
+
updateCacheKeyFields(event) {
|
|
1478
|
+
return this.UpdateCacheKeyFields(event);
|
|
1479
|
+
}
|
|
1480
|
+
UpdateCacheTTL(event) {
|
|
723
1481
|
const val = parseInt(event.target.value, 10);
|
|
724
1482
|
if (!this.spec.Caching)
|
|
725
1483
|
this.spec.Caching = { Cacheable: true };
|
|
726
1484
|
this.spec.Caching.TTLSeconds = isNaN(val) ? 86400 : val;
|
|
727
1485
|
this.emitChanges();
|
|
728
1486
|
}
|
|
729
|
-
|
|
1487
|
+
/** @deprecated Use {@link UpdateCacheTTL}. */
|
|
1488
|
+
updateCacheTTL(event) {
|
|
1489
|
+
return this.UpdateCacheTTL(event);
|
|
1490
|
+
}
|
|
1491
|
+
UpdateCacheScope(event) {
|
|
730
1492
|
const val = event.target.value;
|
|
731
1493
|
if (!this.spec.Caching)
|
|
732
1494
|
this.spec.Caching = { Cacheable: true };
|
|
733
1495
|
this.spec.Caching.Scope = val;
|
|
734
1496
|
this.emitChanges();
|
|
735
1497
|
}
|
|
1498
|
+
/** @deprecated Use {@link UpdateCacheScope}. */
|
|
1499
|
+
updateCacheScope(event) {
|
|
1500
|
+
return this.UpdateCacheScope(event);
|
|
1501
|
+
}
|
|
1502
|
+
/** Turns capture of the model's rationale on or off. Off removes the flag, so a spec that never set it keeps its hash. */
|
|
1503
|
+
UpdateCaptureReasoning(event) {
|
|
1504
|
+
if (event.target.value === 'true') {
|
|
1505
|
+
this.spec.CaptureReasoning = true;
|
|
1506
|
+
}
|
|
1507
|
+
else {
|
|
1508
|
+
delete this.spec.CaptureReasoning;
|
|
1509
|
+
}
|
|
1510
|
+
this.emitChanges();
|
|
1511
|
+
}
|
|
1512
|
+
OnPipelineTypeSelect(event) {
|
|
1513
|
+
const target = event.target;
|
|
1514
|
+
const newType = target.value;
|
|
1515
|
+
const currentType = this.CurrentPipelineTypeName;
|
|
1516
|
+
if (newType.toLowerCase() === currentType.toLowerCase()) {
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
const isNewTypeLLM = newType.trim().toLowerCase() === 'llm';
|
|
1520
|
+
const candidateSpec = {
|
|
1521
|
+
...this.spec,
|
|
1522
|
+
PipelineType: isNewTypeLLM ? undefined : newType.trim(),
|
|
1523
|
+
};
|
|
1524
|
+
if (newType.trim().toLowerCase() !== 'decision') {
|
|
1525
|
+
delete candidateSpec.Escalation;
|
|
1526
|
+
}
|
|
1527
|
+
const newCapabilities = GetFeaturePipelineCapabilities(newType);
|
|
1528
|
+
const lookup = this.buildFieldValuesLookup();
|
|
1529
|
+
const capIssues = ValidateOutputsAgainstCapabilities(candidateSpec, newCapabilities, lookup);
|
|
1530
|
+
let specIssues = [];
|
|
1531
|
+
const entity = this.Record?.EntityID ? this.ProviderToUse.EntityByID(this.Record.EntityID) : null;
|
|
1532
|
+
if (entity) {
|
|
1533
|
+
const stub = {
|
|
1534
|
+
Name: entity.Name,
|
|
1535
|
+
Fields: (entity.Fields ?? []).map((f) => ({
|
|
1536
|
+
Name: f.Name,
|
|
1537
|
+
TSType: f.TSType,
|
|
1538
|
+
IsVirtual: f.IsVirtual,
|
|
1539
|
+
AllowsNull: f.AllowsNull,
|
|
1540
|
+
RelatedEntity: f.RelatedEntity,
|
|
1541
|
+
RelatedEntityID: f.RelatedEntityID,
|
|
1542
|
+
EntityFieldValues: f.EntityFieldValues ? f.EntityFieldValues.map((v) => ({ Value: v.Value, Code: v.Code })) : undefined,
|
|
1543
|
+
})),
|
|
1544
|
+
};
|
|
1545
|
+
specIssues = validateSpec(candidateSpec, stub).filter((i) => i.Severity === 'error').map((i) => i.Message);
|
|
1546
|
+
}
|
|
1547
|
+
const allIssues = Array.from(new Set([...capIssues, ...specIssues]));
|
|
1548
|
+
if (allIssues.length > 0) {
|
|
1549
|
+
target.value = currentType;
|
|
1550
|
+
this.PendingPipelineType = newType;
|
|
1551
|
+
this.TypeSwitchIssues = allIssues;
|
|
1552
|
+
this.ShowTypeSwitchConfirm = true;
|
|
1553
|
+
this.cdr.detectChanges();
|
|
1554
|
+
}
|
|
1555
|
+
else {
|
|
1556
|
+
this.ApplyPipelineTypeChange(newType);
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
OnTypeSwitchConfirmed() {
|
|
1560
|
+
this.ShowTypeSwitchConfirm = false;
|
|
1561
|
+
if (this.PendingPipelineType) {
|
|
1562
|
+
this.ApplyPipelineTypeChange(this.PendingPipelineType);
|
|
1563
|
+
this.PendingPipelineType = null;
|
|
1564
|
+
}
|
|
1565
|
+
this.TypeSwitchIssues = [];
|
|
1566
|
+
this.cdr.detectChanges();
|
|
1567
|
+
}
|
|
1568
|
+
OnTypeSwitchCancelled() {
|
|
1569
|
+
this.ShowTypeSwitchConfirm = false;
|
|
1570
|
+
this.PendingPipelineType = null;
|
|
1571
|
+
this.TypeSwitchIssues = [];
|
|
1572
|
+
this.cdr.detectChanges();
|
|
1573
|
+
}
|
|
1574
|
+
ApplyPipelineTypeChange(newType) {
|
|
1575
|
+
if (newType.trim().toLowerCase() === 'llm') {
|
|
1576
|
+
delete this.spec.PipelineType;
|
|
1577
|
+
}
|
|
1578
|
+
else {
|
|
1579
|
+
this.spec.PipelineType = newType.trim();
|
|
1580
|
+
}
|
|
1581
|
+
if (!this.IsDecisionPipeline) {
|
|
1582
|
+
delete this.spec.Escalation;
|
|
1583
|
+
}
|
|
1584
|
+
this.emitChanges();
|
|
1585
|
+
}
|
|
1586
|
+
GetNumericLevels(output) {
|
|
1587
|
+
if (!output.Constraint || output.Constraint.Type !== 'numeric' || !Array.isArray(output.Constraint.Levels)) {
|
|
1588
|
+
return [];
|
|
1589
|
+
}
|
|
1590
|
+
return output.Constraint.Levels;
|
|
1591
|
+
}
|
|
1592
|
+
AddNumericLevel(index) {
|
|
1593
|
+
const output = this.spec.Outputs[index];
|
|
1594
|
+
if (output?.Constraint?.Type === 'numeric') {
|
|
1595
|
+
if (!Array.isArray(output.Constraint.Levels) || output.Constraint.Levels.length === 0) {
|
|
1596
|
+
output.Constraint.Levels = ['Low', 'Medium', 'High'];
|
|
1597
|
+
this.emitChanges();
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
if (output.Constraint.Levels.length < 10) {
|
|
1601
|
+
output.Constraint.Levels.push(`Level ${output.Constraint.Levels.length + 1}`);
|
|
1602
|
+
this.emitChanges();
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
RemoveNumericLevel(outputIndex, levelIndex) {
|
|
1607
|
+
const output = this.spec.Outputs[outputIndex];
|
|
1608
|
+
if (output?.Constraint?.Type === 'numeric' && Array.isArray(output.Constraint.Levels)) {
|
|
1609
|
+
if (output.Constraint.Levels.length > 2) {
|
|
1610
|
+
output.Constraint.Levels.splice(levelIndex, 1);
|
|
1611
|
+
this.emitChanges();
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
UpdateNumericLevel(outputIndex, levelIndex, event) {
|
|
1616
|
+
const val = event.target.value;
|
|
1617
|
+
const output = this.spec.Outputs[outputIndex];
|
|
1618
|
+
if (output?.Constraint?.Type === 'numeric' && Array.isArray(output.Constraint.Levels)) {
|
|
1619
|
+
output.Constraint.Levels[levelIndex] = val;
|
|
1620
|
+
this.emitChanges();
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
MoveNumericLevel(outputIndex, levelIndex, direction) {
|
|
1624
|
+
const output = this.spec.Outputs[outputIndex];
|
|
1625
|
+
if (output?.Constraint?.Type === 'numeric' && Array.isArray(output.Constraint.Levels)) {
|
|
1626
|
+
const targetIndex = direction === 'up' ? levelIndex - 1 : levelIndex + 1;
|
|
1627
|
+
if (targetIndex >= 0 && targetIndex < output.Constraint.Levels.length) {
|
|
1628
|
+
const item = output.Constraint.Levels.splice(levelIndex, 1)[0];
|
|
1629
|
+
output.Constraint.Levels.splice(targetIndex, 0, item);
|
|
1630
|
+
this.emitChanges();
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
GetEnumValues(output) {
|
|
1635
|
+
if (output.Constraint && output.Constraint.Type === 'enum' && Array.isArray(output.Constraint.Values)) {
|
|
1636
|
+
return output.Constraint.Values;
|
|
1637
|
+
}
|
|
1638
|
+
return [];
|
|
1639
|
+
}
|
|
1640
|
+
GetEnumValueDescription(output, val) {
|
|
1641
|
+
if (output.Constraint && output.Constraint.Type === 'enum') {
|
|
1642
|
+
return output.Constraint.ValueDescriptions?.[val] ?? '';
|
|
1643
|
+
}
|
|
1644
|
+
return '';
|
|
1645
|
+
}
|
|
1646
|
+
UpdateEnumValueDescription(outputIndex, val, event) {
|
|
1647
|
+
const desc = event.target.value;
|
|
1648
|
+
const output = this.spec.Outputs[outputIndex];
|
|
1649
|
+
if (output?.Constraint && output.Constraint.Type === 'enum') {
|
|
1650
|
+
if (!output.Constraint.ValueDescriptions) {
|
|
1651
|
+
output.Constraint.ValueDescriptions = {};
|
|
1652
|
+
}
|
|
1653
|
+
output.Constraint.ValueDescriptions[val] = desc;
|
|
1654
|
+
this.emitChanges();
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
GetBooleanThreshold(output) {
|
|
1658
|
+
if (output.Constraint && output.Constraint.Type === 'boolean' && output.Constraint.Threshold !== undefined) {
|
|
1659
|
+
return output.Constraint.Threshold;
|
|
1660
|
+
}
|
|
1661
|
+
return null;
|
|
1662
|
+
}
|
|
1663
|
+
UpdateBooleanThreshold(outputIndex, event) {
|
|
1664
|
+
const raw = event.target.value.trim();
|
|
1665
|
+
const output = this.spec.Outputs[outputIndex];
|
|
1666
|
+
if (output?.Constraint && output.Constraint.Type === 'boolean') {
|
|
1667
|
+
if (raw === '') {
|
|
1668
|
+
delete output.Constraint.Threshold;
|
|
1669
|
+
}
|
|
1670
|
+
else {
|
|
1671
|
+
const val = parseFloat(raw);
|
|
1672
|
+
output.Constraint.Threshold = isNaN(val) ? undefined : val;
|
|
1673
|
+
}
|
|
1674
|
+
this.emitChanges();
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
prefillEnumValuesFromField(output) {
|
|
1678
|
+
if (output.Target.Mode !== 'field' || output.Constraint?.Type !== 'enum') {
|
|
1679
|
+
return;
|
|
1680
|
+
}
|
|
1681
|
+
const fieldName = output.Target.EntityFieldName;
|
|
1682
|
+
if (!fieldName) {
|
|
1683
|
+
return;
|
|
1684
|
+
}
|
|
1685
|
+
const field = this.EntityFields.find((f) => f.Name === fieldName);
|
|
1686
|
+
if (field && Array.isArray(field.EntityFieldValues) && field.EntityFieldValues.length > 0) {
|
|
1687
|
+
if (!output.Constraint.Values || output.Constraint.Values.length === 0) {
|
|
1688
|
+
output.Constraint.Values = field.EntityFieldValues.map((v) => v.Value);
|
|
1689
|
+
}
|
|
1690
|
+
if (this.IsDecisionPipeline) {
|
|
1691
|
+
if (!output.Constraint.ValueDescriptions) {
|
|
1692
|
+
output.Constraint.ValueDescriptions = {};
|
|
1693
|
+
}
|
|
1694
|
+
for (const v of field.EntityFieldValues) {
|
|
1695
|
+
if (!output.Constraint.ValueDescriptions[v.Value] && v.Description) {
|
|
1696
|
+
output.Constraint.ValueDescriptions[v.Value] = v.Description;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
736
1702
|
emitChanges() {
|
|
1703
|
+
if (this.spec.PipelineType && this.spec.PipelineType.trim().toLowerCase() === 'llm') {
|
|
1704
|
+
delete this.spec.PipelineType;
|
|
1705
|
+
}
|
|
1706
|
+
if (!this.IsDecisionPipeline) {
|
|
1707
|
+
delete this.spec.Escalation;
|
|
1708
|
+
}
|
|
737
1709
|
if (this.Record) {
|
|
738
1710
|
this.spec.Name = this.Record.Name || '';
|
|
739
1711
|
this.spec.Description = this.Record.Description || '';
|
|
@@ -760,8 +1732,14 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
760
1732
|
}
|
|
761
1733
|
this.Record.OutputMapping = JSON.stringify({ fields });
|
|
762
1734
|
}
|
|
1735
|
+
buildFieldValuesLookup() {
|
|
1736
|
+
return (fieldName) => {
|
|
1737
|
+
const field = this.EntityFields.find((f) => f.Name.toLowerCase() === fieldName.toLowerCase());
|
|
1738
|
+
return field?.EntityFieldValues ? field.EntityFieldValues.map((v) => ({ Value: v.Value, Description: v.Description })) : undefined;
|
|
1739
|
+
};
|
|
1740
|
+
}
|
|
763
1741
|
recomputeValidation() {
|
|
764
|
-
this.
|
|
1742
|
+
this.RenderedConstraintPreview = renderConstraintBlock(this.spec.Outputs);
|
|
765
1743
|
const entity = this.Record?.EntityID ? this.ProviderToUse.EntityByID(this.Record.EntityID) : null;
|
|
766
1744
|
if (entity) {
|
|
767
1745
|
const stub = {
|
|
@@ -776,171 +1754,271 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
776
1754
|
EntityFieldValues: f.EntityFieldValues ? f.EntityFieldValues.map((v) => ({ Value: v.Value, Code: v.Code })) : undefined,
|
|
777
1755
|
})),
|
|
778
1756
|
};
|
|
779
|
-
this.
|
|
1757
|
+
this.ValidationErrors = validateSpec(this.spec, stub);
|
|
780
1758
|
}
|
|
781
1759
|
else {
|
|
782
|
-
this.
|
|
783
|
-
|
|
784
|
-
|
|
1760
|
+
this.ValidationErrors = validateSpec(this.spec);
|
|
1761
|
+
}
|
|
1762
|
+
const lookup = this.buildFieldValuesLookup();
|
|
1763
|
+
const capIssues = ValidateOutputsAgainstCapabilities(this.spec, this.CurrentCapabilities, lookup);
|
|
1764
|
+
for (const capIssue of capIssues) {
|
|
1765
|
+
this.ValidationErrors.push({
|
|
1766
|
+
Path: 'Outputs',
|
|
1767
|
+
Severity: 'error',
|
|
1768
|
+
Message: capIssue,
|
|
1769
|
+
FixRecommendation: 'Adjust output configuration to match the selected pipeline capabilities.',
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
if (this.IsDecisionPipeline && this.spec.Escalation && this.spec.Escalation.PipelineID && this.EscalationTargetsLoadError) {
|
|
1773
|
+
// The targets are unknown, not absent: say so, and leave the target to be checked at run time
|
|
1774
|
+
this.ValidationErrors.push({
|
|
1775
|
+
Path: 'Escalation.PipelineID',
|
|
1776
|
+
Severity: 'warning',
|
|
1777
|
+
Message: `The escalation target could not be checked: the pipelines on this entity could not be loaded (${this.EscalationTargetsLoadError}).`,
|
|
1778
|
+
FixRecommendation: 'Reopen the pipeline to retry. The target is still checked when the pipeline runs.',
|
|
1779
|
+
});
|
|
1780
|
+
}
|
|
1781
|
+
else if (this.IsDecisionPipeline && this.spec.Escalation) {
|
|
1782
|
+
const targetID = this.spec.Escalation.PipelineID;
|
|
1783
|
+
if (targetID && this.EscalationTargetsLoaded) {
|
|
1784
|
+
const match = this.AvailableEscalationTargets.find((t) => UUIDsEqual(t.ID, targetID));
|
|
1785
|
+
if (!match) {
|
|
1786
|
+
this.ValidationErrors.push({
|
|
1787
|
+
Path: 'Escalation.PipelineID',
|
|
785
1788
|
Severity: 'error',
|
|
786
|
-
Message: '
|
|
787
|
-
FixRecommendation: '
|
|
788
|
-
}
|
|
789
|
-
|
|
1789
|
+
Message: `Escalation target pipeline '${targetID}' was not found on this entity.`,
|
|
1790
|
+
FixRecommendation: 'Select a valid Active LLM Feature Pipeline on this entity.',
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1793
|
+
else {
|
|
1794
|
+
const problem = this.GetTargetProblem(match);
|
|
1795
|
+
if (problem) {
|
|
1796
|
+
this.ValidationErrors.push({
|
|
1797
|
+
Path: 'Escalation.PipelineID',
|
|
1798
|
+
Severity: 'error',
|
|
1799
|
+
Message: `Escalation target pipeline '${match.Name}' ${problem}.`,
|
|
1800
|
+
FixRecommendation: 'Select an Active LLM Feature Pipeline that produces every output of this Decision pipeline.',
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
790
1805
|
}
|
|
791
|
-
const hasErrors = this.
|
|
1806
|
+
const hasErrors = this.ValidationErrors.some((i) => i.Severity === 'error');
|
|
792
1807
|
this.ValidChange.emit(!hasErrors);
|
|
793
1808
|
}
|
|
794
1809
|
static ɵfac = /*@__PURE__*/ (() => { let ɵFeaturePipelineBuilderComponent_BaseFactory; return function FeaturePipelineBuilderComponent_Factory(__ngFactoryType__) { return (ɵFeaturePipelineBuilderComponent_BaseFactory || (ɵFeaturePipelineBuilderComponent_BaseFactory = i0.ɵɵgetInheritedFactory(FeaturePipelineBuilderComponent)))(__ngFactoryType__ || FeaturePipelineBuilderComponent); }; })();
|
|
795
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FeaturePipelineBuilderComponent, selectors: [["mj-feature-pipeline-builder"]], inputs: { Record: "Record", EntityID: "EntityID" }, outputs: { SpecChange: "SpecChange", ValidChange: "ValidChange" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls:
|
|
796
|
-
i0.ɵɵelementStart(0, "div", 0)(1, "section", 1)(2, "div", 2)(3, "
|
|
797
|
-
i0.ɵɵtext(
|
|
1810
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FeaturePipelineBuilderComponent, selectors: [["mj-feature-pipeline-builder"]], inputs: { Record: "Record", EntityID: "EntityID" }, outputs: { SpecChange: "SpecChange", ValidChange: "ValidChange" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 111, vars: 18, consts: [[1, "fpb"], [1, "rpe-sec", "fpb-type-sec"], [1, "rpe-grid2"], [1, "field"], [1, "mj-input", 3, "change"], [3, "value", "selected"], [1, "rpe-static-text"], [1, "rpe-grid2", "rpe-mt"], [1, "rpe-sec"], [1, "rpe-sec-h"], [1, "num"], [1, "rpe-desc"], [1, "rpe-grid3"], [1, "mj-input", 3, "change", "value"], ["value", "fields"], ["value", "document"], ["value", "query"], ["placeholder", "e.g. FirstName, LastName, Title", 1, "mj-input", 3, "input", "value"], ["value", "", "disabled", "", 3, "selected"], [1, "field", "rpe-mt"], [1, "rpe-sec-h", "fpb-split-h"], [1, "fpb-title-group"], ["mjButton", "", "size", "sm", "variant", "secondary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "fpb-empty-outputs"], [1, "fpb-outputs-list"], [1, "rpe-sec", "fpb-escalation-sec"], ["value", "Checksum"], ["value", "UpdatedAt"], ["value", "None"], ["value", "true"], ["value", "false"], [1, "rpe-grid3", "rpe-mt"], [1, "fpb-issues-card", "fpb-issues-card--error"], ["Type", "warning", "Title", "Switch Pipeline Type", "ConfirmText", "Switch Anyway", "CancelText", "Cancel", 3, "VisibleChange", "Confirmed", "Cancelled", "Visible", "Message"], [1, "fpb-confirm-issues"], [1, "mj-input", "fpb-reasoning-select", 3, "change", "value"], ["placeholder", "UUID of approved Query", 1, "mj-input", "mono", 3, "input", "value"], [1, "muted"], [1, "fpb-code-preview"], [1, "fa-solid", "fa-arrow-turn-up"], [1, "fpb-output-card"], [1, "fpb-output-head"], ["mjButton", "", "size", "sm", "variant", "flat", 3, "click"], [1, "fa-solid", "fa-trash"], ["placeholder", "e.g. SentimentScore", 1, "mj-input", 3, "input", "value"], ["placeholder", "e.g. $.sentiment or $", 1, "mj-input", "mono", 3, "input", "value"], ["value", "none", "disabled", "", 3, "selected"], ["value", "fail"], ["value", "null"], ["value", "coerce-to-other"], ["placeholder", "e.g. Positive, Neutral, Negative", 1, "mj-input", 3, "input", "value"], [1, "fpb-enum-descriptions"], [1, "fpb-enum-desc-row"], [1, "fpb-enum-val-badge"], [1, "mj-input", 3, "input", "value", "placeholder"], [1, "fpb-levels-header"], ["mjButton", "", "size", "sm", "variant", "secondary", "type", "button", 3, "click", "disabled"], [1, "fpb-levels-list"], [1, "fpb-level-row"], [1, "fpb-level-num"], ["placeholder", "Level label (e.g. Low, Medium, High)", 1, "mj-input", 3, "input", "value"], ["mjButton", "", "size", "sm", "variant", "flat", "type", "button", "title", "Move Up", 3, "click", "disabled"], [1, "fa-solid", "fa-arrow-up"], ["mjButton", "", "size", "sm", "variant", "flat", "type", "button", "title", "Move Down", 3, "click", "disabled"], [1, "fa-solid", "fa-arrow-down"], ["mjButton", "", "size", "sm", "variant", "flat", "type", "button", "title", "Remove Level", 3, "click", "disabled"], ["type", "number", 1, "mj-input", 3, "input", "value"], ["type", "number", "min", "0", "max", "1", "step", "0.05", "placeholder", "0.5", 1, "mj-input", 3, "input", "value"], [1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "fpb-escalation-toggle-row"], [1, "fpb-checkbox-label"], ["type", "checkbox", 3, "change", "checked"], [3, "value", "disabled", "selected"], ["type", "number", "min", "0", "max", "1", "step", "0.05", "placeholder", "0.7", 1, "mj-input", 3, "input", "value"], ["placeholder", "e.g. CurrentJobTitle", 1, "mj-input", 3, "input", "value"], ["value", "pipeline"], ["value", "prompt"], [1, "fa-solid", "fa-triangle-exclamation"]], template: function FeaturePipelineBuilderComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1811
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "section", 1)(2, "div", 2)(3, "div", 3)(4, "label");
|
|
1812
|
+
i0.ɵɵtext(5, "Pipeline Type");
|
|
1813
|
+
i0.ɵɵelementEnd();
|
|
1814
|
+
i0.ɵɵelementStart(6, "select", 4);
|
|
1815
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Template_select_change_6_listener($event) { return ctx.OnPipelineTypeSelect($event); });
|
|
1816
|
+
i0.ɵɵrepeaterCreate(7, FeaturePipelineBuilderComponent_For_8_Template, 2, 3, "option", 5, _forTrack0);
|
|
1817
|
+
i0.ɵɵelementEnd()();
|
|
1818
|
+
i0.ɵɵelementStart(9, "div", 3)(10, "label");
|
|
1819
|
+
i0.ɵɵtext(11, "Type Description");
|
|
1820
|
+
i0.ɵɵelementEnd();
|
|
1821
|
+
i0.ɵɵelementStart(12, "div", 6);
|
|
1822
|
+
i0.ɵɵtext(13);
|
|
1823
|
+
i0.ɵɵelementEnd()()();
|
|
1824
|
+
i0.ɵɵconditionalCreate(14, FeaturePipelineBuilderComponent_Conditional_14_Template, 9, 1, "div", 7);
|
|
1825
|
+
i0.ɵɵelementEnd();
|
|
1826
|
+
i0.ɵɵelementStart(15, "section", 8)(16, "div", 9)(17, "span", 10);
|
|
1827
|
+
i0.ɵɵtext(18, "1");
|
|
798
1828
|
i0.ɵɵelementEnd();
|
|
799
|
-
i0.ɵɵelementStart(
|
|
800
|
-
i0.ɵɵtext(
|
|
1829
|
+
i0.ɵɵelementStart(19, "h3");
|
|
1830
|
+
i0.ɵɵtext(20, "Context Source");
|
|
801
1831
|
i0.ɵɵelementEnd()();
|
|
802
|
-
i0.ɵɵelementStart(
|
|
803
|
-
i0.ɵɵtext(
|
|
1832
|
+
i0.ɵɵelementStart(21, "p", 11);
|
|
1833
|
+
i0.ɵɵtext(22, "Choose how data from each record is extracted and formatted before being sent to the LLM prompt.");
|
|
804
1834
|
i0.ɵɵelementEnd();
|
|
805
|
-
i0.ɵɵelementStart(
|
|
806
|
-
i0.ɵɵtext(
|
|
1835
|
+
i0.ɵɵelementStart(23, "div", 12)(24, "div", 3)(25, "label");
|
|
1836
|
+
i0.ɵɵtext(26, "Context Mode");
|
|
807
1837
|
i0.ɵɵelementEnd();
|
|
808
|
-
i0.ɵɵelementStart(
|
|
809
|
-
i0.ɵɵlistener("change", function
|
|
810
|
-
i0.ɵɵelementStart(
|
|
811
|
-
i0.ɵɵtext(
|
|
1838
|
+
i0.ɵɵelementStart(27, "select", 13);
|
|
1839
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Template_select_change_27_listener($event) { return ctx.onContextModeChange($event); });
|
|
1840
|
+
i0.ɵɵelementStart(28, "option", 14);
|
|
1841
|
+
i0.ɵɵtext(29, "Record Fields");
|
|
812
1842
|
i0.ɵɵelementEnd();
|
|
813
|
-
i0.ɵɵelementStart(
|
|
814
|
-
i0.ɵɵtext(
|
|
1843
|
+
i0.ɵɵelementStart(30, "option", 15);
|
|
1844
|
+
i0.ɵɵtext(31, "Entity Document (Template)");
|
|
815
1845
|
i0.ɵɵelementEnd();
|
|
816
|
-
i0.ɵɵelementStart(
|
|
817
|
-
i0.ɵɵtext(
|
|
1846
|
+
i0.ɵɵelementStart(32, "option", 16);
|
|
1847
|
+
i0.ɵɵtext(33, "Query (Graph Traversal)");
|
|
818
1848
|
i0.ɵɵelementEnd()()();
|
|
819
|
-
i0.ɵɵconditionalCreate(
|
|
820
|
-
i0.ɵɵconditionalCreate(
|
|
821
|
-
i0.ɵɵelementStart(
|
|
822
|
-
i0.ɵɵtext(
|
|
1849
|
+
i0.ɵɵconditionalCreate(34, FeaturePipelineBuilderComponent_Conditional_34_Template, 8, 1, "div", 3);
|
|
1850
|
+
i0.ɵɵconditionalCreate(35, FeaturePipelineBuilderComponent_Conditional_35_Template, 4, 1, "div", 3);
|
|
1851
|
+
i0.ɵɵelementStart(36, "div", 3)(37, "label");
|
|
1852
|
+
i0.ɵɵtext(38, "Field Filter (optional)");
|
|
823
1853
|
i0.ɵɵelementEnd();
|
|
824
|
-
i0.ɵɵelementStart(
|
|
825
|
-
i0.ɵɵlistener("input", function
|
|
1854
|
+
i0.ɵɵelementStart(39, "input", 17);
|
|
1855
|
+
i0.ɵɵlistener("input", function FeaturePipelineBuilderComponent_Template_input_input_39_listener($event) { return ctx.onFieldsCsvChange($event); });
|
|
826
1856
|
i0.ɵɵelementEnd()()()();
|
|
827
|
-
i0.ɵɵelementStart(
|
|
828
|
-
i0.ɵɵtext(
|
|
1857
|
+
i0.ɵɵelementStart(40, "section", 8)(41, "div", 9)(42, "span", 10);
|
|
1858
|
+
i0.ɵɵtext(43, "2");
|
|
829
1859
|
i0.ɵɵelementEnd();
|
|
830
|
-
i0.ɵɵelementStart(
|
|
831
|
-
i0.ɵɵtext(
|
|
1860
|
+
i0.ɵɵelementStart(44, "h3");
|
|
1861
|
+
i0.ɵɵtext(45, "AI Prompt");
|
|
832
1862
|
i0.ɵɵelementEnd()();
|
|
833
|
-
i0.ɵɵelementStart(
|
|
834
|
-
i0.ɵɵtext(
|
|
1863
|
+
i0.ɵɵelementStart(46, "div", 2)(47, "div", 3)(48, "label");
|
|
1864
|
+
i0.ɵɵtext(49, "Prompt");
|
|
835
1865
|
i0.ɵɵelementEnd();
|
|
836
|
-
i0.ɵɵelementStart(
|
|
837
|
-
i0.ɵɵlistener("change", function
|
|
838
|
-
i0.ɵɵelementStart(
|
|
839
|
-
i0.ɵɵtext(
|
|
1866
|
+
i0.ɵɵelementStart(50, "select", 4);
|
|
1867
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Template_select_change_50_listener($event) { return ctx.onPromptChange($event); });
|
|
1868
|
+
i0.ɵɵelementStart(51, "option", 18);
|
|
1869
|
+
i0.ɵɵtext(52, "\u2014 Select AI Prompt \u2014");
|
|
840
1870
|
i0.ɵɵelementEnd();
|
|
841
|
-
i0.ɵɵrepeaterCreate(
|
|
1871
|
+
i0.ɵɵrepeaterCreate(53, FeaturePipelineBuilderComponent_For_54_Template, 2, 3, "option", 5, _forTrack1);
|
|
842
1872
|
i0.ɵɵelementEnd()();
|
|
843
|
-
i0.ɵɵconditionalCreate(
|
|
1873
|
+
i0.ɵɵconditionalCreate(55, FeaturePipelineBuilderComponent_Conditional_55_Template, 5, 1, "div", 3);
|
|
844
1874
|
i0.ɵɵelementEnd();
|
|
845
|
-
i0.ɵɵconditionalCreate(
|
|
1875
|
+
i0.ɵɵconditionalCreate(56, FeaturePipelineBuilderComponent_Conditional_56_Template, 7, 1, "div", 19);
|
|
846
1876
|
i0.ɵɵelementEnd();
|
|
847
|
-
i0.ɵɵelementStart(
|
|
848
|
-
i0.ɵɵtext(
|
|
1877
|
+
i0.ɵɵelementStart(57, "section", 8)(58, "div", 20)(59, "div", 21)(60, "span", 10);
|
|
1878
|
+
i0.ɵɵtext(61, "3");
|
|
849
1879
|
i0.ɵɵelementEnd();
|
|
850
|
-
i0.ɵɵelementStart(
|
|
851
|
-
i0.ɵɵtext(
|
|
1880
|
+
i0.ɵɵelementStart(62, "h3");
|
|
1881
|
+
i0.ɵɵtext(63, "Outputs & Constraints");
|
|
852
1882
|
i0.ɵɵelementEnd()();
|
|
853
|
-
i0.ɵɵelementStart(
|
|
854
|
-
i0.ɵɵlistener("click", function
|
|
855
|
-
i0.ɵɵelement(
|
|
856
|
-
i0.ɵɵtext(
|
|
1883
|
+
i0.ɵɵelementStart(64, "button", 22);
|
|
1884
|
+
i0.ɵɵlistener("click", function FeaturePipelineBuilderComponent_Template_button_click_64_listener() { return ctx.addOutput(); });
|
|
1885
|
+
i0.ɵɵelement(65, "i", 23);
|
|
1886
|
+
i0.ɵɵtext(66, " Add Output ");
|
|
857
1887
|
i0.ɵɵelementEnd()();
|
|
858
|
-
i0.ɵɵelementStart(
|
|
859
|
-
i0.ɵɵtext(
|
|
1888
|
+
i0.ɵɵelementStart(67, "p", 11);
|
|
1889
|
+
i0.ɵɵtext(68, "Define the structured outputs produced by the pipeline, their type constraints, and target write-back destinations.");
|
|
860
1890
|
i0.ɵɵelementEnd();
|
|
861
|
-
i0.ɵɵconditionalCreate(
|
|
1891
|
+
i0.ɵɵconditionalCreate(69, FeaturePipelineBuilderComponent_Conditional_69_Template, 7, 0, "div", 24)(70, FeaturePipelineBuilderComponent_Conditional_70_Template, 3, 0, "div", 25);
|
|
862
1892
|
i0.ɵɵelementEnd();
|
|
863
|
-
i0.ɵɵ
|
|
864
|
-
i0.ɵɵ
|
|
1893
|
+
i0.ɵɵconditionalCreate(71, FeaturePipelineBuilderComponent_Conditional_71_Template, 13, 2, "section", 26);
|
|
1894
|
+
i0.ɵɵelementStart(72, "section", 8)(73, "div", 9)(74, "span", 10);
|
|
1895
|
+
i0.ɵɵtext(75, "4");
|
|
865
1896
|
i0.ɵɵelementEnd();
|
|
866
|
-
i0.ɵɵelementStart(
|
|
867
|
-
i0.ɵɵtext(
|
|
1897
|
+
i0.ɵɵelementStart(76, "h3");
|
|
1898
|
+
i0.ɵɵtext(77, "Caching & Watermarks");
|
|
868
1899
|
i0.ɵɵelementEnd()();
|
|
869
|
-
i0.ɵɵelementStart(
|
|
870
|
-
i0.ɵɵtext(
|
|
1900
|
+
i0.ɵɵelementStart(78, "div", 12)(79, "div", 3)(80, "label");
|
|
1901
|
+
i0.ɵɵtext(81, "Watermark Strategy");
|
|
871
1902
|
i0.ɵɵelementEnd();
|
|
872
|
-
i0.ɵɵelementStart(
|
|
873
|
-
i0.ɵɵlistener("change", function
|
|
874
|
-
i0.ɵɵelementStart(
|
|
875
|
-
i0.ɵɵtext(
|
|
1903
|
+
i0.ɵɵelementStart(82, "select", 13);
|
|
1904
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Template_select_change_82_listener($event) { return ctx.updateWatermarkStrategy($event); });
|
|
1905
|
+
i0.ɵɵelementStart(83, "option", 27);
|
|
1906
|
+
i0.ɵɵtext(84, "Checksum (Content Hash + Prompt Hash)");
|
|
876
1907
|
i0.ɵɵelementEnd();
|
|
877
|
-
i0.ɵɵelementStart(
|
|
878
|
-
i0.ɵɵtext(
|
|
1908
|
+
i0.ɵɵelementStart(85, "option", 28);
|
|
1909
|
+
i0.ɵɵtext(86, "UpdatedAt (Compare modified timestamp)");
|
|
879
1910
|
i0.ɵɵelementEnd();
|
|
880
|
-
i0.ɵɵelementStart(
|
|
881
|
-
i0.ɵɵtext(
|
|
1911
|
+
i0.ɵɵelementStart(87, "option", 29);
|
|
1912
|
+
i0.ɵɵtext(88, "None (Always process all records)");
|
|
882
1913
|
i0.ɵɵelementEnd()()();
|
|
883
|
-
i0.ɵɵelementStart(
|
|
884
|
-
i0.ɵɵtext(
|
|
1914
|
+
i0.ɵɵelementStart(89, "div", 3)(90, "label");
|
|
1915
|
+
i0.ɵɵtext(91, "Skip Unchanged Records");
|
|
885
1916
|
i0.ɵɵelementEnd();
|
|
886
|
-
i0.ɵɵelementStart(
|
|
887
|
-
i0.ɵɵlistener("change", function
|
|
888
|
-
i0.ɵɵelementStart(
|
|
889
|
-
i0.ɵɵtext(
|
|
1917
|
+
i0.ɵɵelementStart(92, "select", 13);
|
|
1918
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Template_select_change_92_listener($event) { return ctx.updateSkipUnchanged($event); });
|
|
1919
|
+
i0.ɵɵelementStart(93, "option", 30);
|
|
1920
|
+
i0.ɵɵtext(94, "Yes \u2014 Skip unchanged rows");
|
|
890
1921
|
i0.ɵɵelementEnd();
|
|
891
|
-
i0.ɵɵelementStart(
|
|
892
|
-
i0.ɵɵtext(
|
|
1922
|
+
i0.ɵɵelementStart(95, "option", 31);
|
|
1923
|
+
i0.ɵɵtext(96, "No \u2014 Recompute every time");
|
|
893
1924
|
i0.ɵɵelementEnd()()();
|
|
894
|
-
i0.ɵɵelementStart(
|
|
895
|
-
i0.ɵɵtext(
|
|
1925
|
+
i0.ɵɵelementStart(97, "div", 3)(98, "label");
|
|
1926
|
+
i0.ɵɵtext(99, "Enable Result Cache");
|
|
896
1927
|
i0.ɵɵelementEnd();
|
|
897
|
-
i0.ɵɵelementStart(
|
|
898
|
-
i0.ɵɵlistener("change", function
|
|
899
|
-
i0.ɵɵelementStart(
|
|
900
|
-
i0.ɵɵtext(
|
|
1928
|
+
i0.ɵɵelementStart(100, "select", 13);
|
|
1929
|
+
i0.ɵɵlistener("change", function FeaturePipelineBuilderComponent_Template_select_change_100_listener($event) { return ctx.updateCacheable($event); });
|
|
1930
|
+
i0.ɵɵelementStart(101, "option", 30);
|
|
1931
|
+
i0.ɵɵtext(102, "Yes \u2014 Cache outputs by distinct key");
|
|
901
1932
|
i0.ɵɵelementEnd();
|
|
902
|
-
i0.ɵɵelementStart(
|
|
903
|
-
i0.ɵɵtext(
|
|
1933
|
+
i0.ɵɵelementStart(103, "option", 31);
|
|
1934
|
+
i0.ɵɵtext(104, "No \u2014 Compute per row");
|
|
904
1935
|
i0.ɵɵelementEnd()()()();
|
|
905
|
-
i0.ɵɵconditionalCreate(
|
|
906
|
-
i0.ɵɵelementEnd();
|
|
907
|
-
i0.ɵɵconditionalCreate(91, FeaturePipelineBuilderComponent_Conditional_91_Template, 7, 0, "div", 28);
|
|
1936
|
+
i0.ɵɵconditionalCreate(105, FeaturePipelineBuilderComponent_Conditional_105_Template, 17, 3, "div", 32);
|
|
908
1937
|
i0.ɵɵelementEnd();
|
|
1938
|
+
i0.ɵɵconditionalCreate(106, FeaturePipelineBuilderComponent_Conditional_106_Template, 7, 0, "div", 33);
|
|
1939
|
+
i0.ɵɵelementStart(107, "mj-confirm-dialog", 34);
|
|
1940
|
+
i0.ɵɵtwoWayListener("VisibleChange", function FeaturePipelineBuilderComponent_Template_mj_confirm_dialog_VisibleChange_107_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.ShowTypeSwitchConfirm, $event) || (ctx.ShowTypeSwitchConfirm = $event); return $event; });
|
|
1941
|
+
i0.ɵɵlistener("Confirmed", function FeaturePipelineBuilderComponent_Template_mj_confirm_dialog_Confirmed_107_listener() { return ctx.OnTypeSwitchConfirmed(); })("Cancelled", function FeaturePipelineBuilderComponent_Template_mj_confirm_dialog_Cancelled_107_listener() { return ctx.OnTypeSwitchCancelled(); });
|
|
1942
|
+
i0.ɵɵelementStart(108, "ul", 35);
|
|
1943
|
+
i0.ɵɵrepeaterCreate(109, FeaturePipelineBuilderComponent_For_110_Template, 2, 1, "li", null, i0.ɵɵrepeaterTrackByIndex);
|
|
1944
|
+
i0.ɵɵelementEnd()()();
|
|
909
1945
|
} if (rf & 2) {
|
|
1946
|
+
i0.ɵɵadvance(7);
|
|
1947
|
+
i0.ɵɵrepeater(ctx.AvailablePipelineTypes);
|
|
1948
|
+
i0.ɵɵadvance(6);
|
|
1949
|
+
i0.ɵɵtextInterpolate(ctx.SelectedPipelineTypeDescription || "\u2014");
|
|
1950
|
+
i0.ɵɵadvance();
|
|
1951
|
+
i0.ɵɵconditional(ctx.ShowCaptureReasoning ? 14 : -1);
|
|
910
1952
|
i0.ɵɵadvance(13);
|
|
911
1953
|
i0.ɵɵproperty("value", ctx.contextMode);
|
|
912
1954
|
i0.ɵɵadvance(7);
|
|
913
|
-
i0.ɵɵconditional(ctx.contextMode === "document" ?
|
|
1955
|
+
i0.ɵɵconditional(ctx.contextMode === "document" ? 34 : -1);
|
|
914
1956
|
i0.ɵɵadvance();
|
|
915
|
-
i0.ɵɵconditional(ctx.contextMode === "query" ?
|
|
1957
|
+
i0.ɵɵconditional(ctx.contextMode === "query" ? 35 : -1);
|
|
916
1958
|
i0.ɵɵadvance(4);
|
|
917
1959
|
i0.ɵɵproperty("value", ctx.fieldsCsv);
|
|
918
|
-
i0.ɵɵadvance(
|
|
919
|
-
i0.ɵɵproperty("
|
|
920
|
-
i0.ɵɵadvance(
|
|
1960
|
+
i0.ɵɵadvance(12);
|
|
1961
|
+
i0.ɵɵproperty("selected", !ctx.SavedPromptListed);
|
|
1962
|
+
i0.ɵɵadvance(2);
|
|
921
1963
|
i0.ɵɵrepeater(ctx.availablePrompts);
|
|
922
1964
|
i0.ɵɵadvance(2);
|
|
923
|
-
i0.ɵɵconditional(ctx.selectedPrompt ?
|
|
1965
|
+
i0.ɵɵconditional(ctx.selectedPrompt ? 55 : -1);
|
|
924
1966
|
i0.ɵɵadvance();
|
|
925
|
-
i0.ɵɵconditional(ctx.renderedConstraintPreview ?
|
|
1967
|
+
i0.ɵɵconditional(ctx.renderedConstraintPreview ? 56 : -1);
|
|
926
1968
|
i0.ɵɵadvance(13);
|
|
927
|
-
i0.ɵɵconditional(!ctx.spec.Outputs || ctx.spec.Outputs.length === 0 ?
|
|
928
|
-
i0.ɵɵadvance(
|
|
1969
|
+
i0.ɵɵconditional(!ctx.spec.Outputs || ctx.spec.Outputs.length === 0 ? 69 : 70);
|
|
1970
|
+
i0.ɵɵadvance(2);
|
|
1971
|
+
i0.ɵɵconditional(ctx.IsDecisionPipeline ? 71 : -1);
|
|
1972
|
+
i0.ɵɵadvance(11);
|
|
929
1973
|
i0.ɵɵproperty("value", (ctx.Record == null ? null : ctx.Record.WatermarkStrategy) || "Checksum");
|
|
930
1974
|
i0.ɵɵadvance(10);
|
|
931
1975
|
i0.ɵɵproperty("value", (ctx.Record == null ? null : ctx.Record.SkipUnchanged) ? "true" : "false");
|
|
932
1976
|
i0.ɵɵadvance(8);
|
|
933
1977
|
i0.ɵɵproperty("value", ctx.spec.Caching.Cacheable ? "true" : "false");
|
|
934
1978
|
i0.ɵɵadvance(5);
|
|
935
|
-
i0.ɵɵconditional(ctx.spec.Caching.Cacheable ?
|
|
1979
|
+
i0.ɵɵconditional(ctx.spec.Caching.Cacheable ? 105 : -1);
|
|
936
1980
|
i0.ɵɵadvance();
|
|
937
|
-
i0.ɵɵconditional(ctx.validationErrors.length > 0 ?
|
|
938
|
-
|
|
1981
|
+
i0.ɵɵconditional(ctx.validationErrors.length > 0 ? 106 : -1);
|
|
1982
|
+
i0.ɵɵadvance();
|
|
1983
|
+
i0.ɵɵtwoWayProperty("Visible", ctx.ShowTypeSwitchConfirm);
|
|
1984
|
+
i0.ɵɵproperty("Message", "Switching to " + (ctx.PendingPipelineType || "selected type") + " will affect existing outputs:");
|
|
1985
|
+
i0.ɵɵadvance(2);
|
|
1986
|
+
i0.ɵɵrepeater(ctx.TypeSwitchIssues);
|
|
1987
|
+
} }, dependencies: [CommonModule, FormsModule, i1.NgSelectOption, i1.ɵNgSelectMultipleOption, MJButtonDirective, MJConfirmDialogComponent], styles: [".fpb[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 20px; }\n .rpe-desc[_ngcontent-%COMP%] { font-size: 13px; color: var(--mj-text-secondary); margin: -6px 0 16px 0; }\n .rpe-sec[_ngcontent-%COMP%] { background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-subtle); border-radius: var(--mj-radius-md, 10px); padding: 18px 20px; }\n .fpb-type-sec[_ngcontent-%COMP%] { border-left: 3px solid var(--mj-brand-primary); }\n .rpe-sec-h[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; }\n .rpe-sec-h[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { margin: 0; font-size: 16px; font-weight: 700; color: var(--mj-text-primary); }\n .rpe-sec-h[_ngcontent-%COMP%] .num[_ngcontent-%COMP%] { width: 24px; height: 24px; border-radius: 50%; background: var(--mj-brand-primary); color: #fff; display: grid; place-items: center; font-size: 12px; font-weight: 800; }\n .fpb-split-h[_ngcontent-%COMP%] { justify-content: space-between; }\n .fpb-title-group[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 11px; }\n .rpe-grid2[_ngcontent-%COMP%] { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n .rpe-grid3[_ngcontent-%COMP%] { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }\n .field[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 6px; }\n .field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] { font-size: 12.5px; font-weight: 600; color: var(--mj-text-secondary); }\n .rpe-mt[_ngcontent-%COMP%] { margin-top: 14px; }\n .mono[_ngcontent-%COMP%] { font-family: monospace; font-size: 12.5px; }\n .muted[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-weight: 400; }\n .rpe-static-text[_ngcontent-%COMP%] { font-size: 13px; color: var(--mj-text-muted); padding: 7px 0; }\n .fpb-code-preview[_ngcontent-%COMP%] { background: var(--mj-bg-surface-sunken, #0f172a); color: var(--mj-text-code, var(--mj-text-primary, #e2e8f0)); border: 1px solid var(--mj-border-subtle, #334155); padding: 12px; border-radius: 6px; font-size: 12px; font-family: var(--mj-font-mono, monospace); white-space: pre-wrap; word-break: break-word; max-height: 160px; overflow-y: auto; margin: 0; }\n .fpb-empty-outputs[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 10px; padding: 20px; border: 1px dashed var(--mj-border-subtle); border-radius: 8px; color: var(--mj-text-muted); font-size: 13px; }\n .fpb-outputs-list[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 16px; }\n .fpb-output-card[_ngcontent-%COMP%] { border: 1px solid var(--mj-border-subtle); border-radius: 8px; padding: 14px 16px; background: var(--mj-bg-surface); }\n .fpb-output-head[_ngcontent-%COMP%] { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; border-bottom: 1px solid var(--mj-border-subtle); padding-bottom: 8px; }\n .fpb-output-head[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] { margin: 0; font-size: 14px; font-weight: 600; }\n .fpb-issues-card[_ngcontent-%COMP%] { border-radius: 8px; padding: 12px 16px; font-size: 13px; }\n .fpb-issues-card--error[_ngcontent-%COMP%] { background: rgba(239, 68, 68, 0.08); border: 1px solid var(--mj-status-error); color: var(--mj-status-error-text); }\n .fpb-issues-card[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] { margin: 0 0 8px 0; font-size: 14px; display: flex; align-items: center; gap: 8px; }\n .fpb-issues-card[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] { margin: 0; padding-left: 20px; }\n .fpb-confirm-issues[_ngcontent-%COMP%] { margin: 10px 0 0 0; padding-left: 20px; color: var(--mj-status-error-text, var(--mj-text-primary)); font-size: 13px; }\n .fpb-confirm-issues[_ngcontent-%COMP%] li[_ngcontent-%COMP%] { margin-bottom: 4px; }\n .fpb-levels-header[_ngcontent-%COMP%] { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }\n .fpb-levels-list[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 8px; }\n .fpb-level-row[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 8px; }\n .fpb-level-num[_ngcontent-%COMP%] { width: 22px; height: 22px; display: grid; place-items: center; font-size: 11px; font-weight: 700; border-radius: var(--mj-radius-sm, 4px); background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); flex-shrink: 0; }\n .fpb-enum-descriptions[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }\n .fpb-enum-desc-row[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 10px; }\n .fpb-enum-val-badge[_ngcontent-%COMP%] { min-width: 90px; padding: 4px 8px; background: var(--mj-bg-surface-sunken); color: var(--mj-text-primary); border: 1px solid var(--mj-border-subtle); border-radius: var(--mj-radius-sm, 4px); font-size: 12px; font-weight: 600; text-align: center; flex-shrink: 0; }\n .fpb-escalation-toggle-row[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 8px; margin-top: 10px; }\n .fpb-checkbox-label[_ngcontent-%COMP%] { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; font-weight: 500; color: var(--mj-text-primary); user-select: none; }\n .fpb-checkbox-label[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%] { width: 16px; height: 16px; cursor: pointer; accent-color: var(--mj-brand-primary); }"], changeDetection: 0 });
|
|
939
1988
|
}
|
|
940
1989
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FeaturePipelineBuilderComponent, [{
|
|
941
1990
|
type: Component,
|
|
942
|
-
args: [{ selector: 'mj-feature-pipeline-builder', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, MJButtonDirective], template: `
|
|
1991
|
+
args: [{ selector: 'mj-feature-pipeline-builder', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, MJButtonDirective, MJConfirmDialogComponent], template: `
|
|
943
1992
|
<div class="fpb">
|
|
1993
|
+
<!-- PIPELINE TYPE SELECTOR -->
|
|
1994
|
+
<section class="rpe-sec fpb-type-sec">
|
|
1995
|
+
<div class="rpe-grid2">
|
|
1996
|
+
<div class="field">
|
|
1997
|
+
<label>Pipeline Type</label>
|
|
1998
|
+
<select class="mj-input" (change)="OnPipelineTypeSelect($event)">
|
|
1999
|
+
@for (t of AvailablePipelineTypes; track t.Name) {
|
|
2000
|
+
<option [value]="t.Name" [selected]="IsCurrentPipelineType(t.Name)">{{ t.DisplayName || t.Name }}</option>
|
|
2001
|
+
}
|
|
2002
|
+
</select>
|
|
2003
|
+
</div>
|
|
2004
|
+
<div class="field">
|
|
2005
|
+
<label>Type Description</label>
|
|
2006
|
+
<div class="rpe-static-text">{{ SelectedPipelineTypeDescription || '—' }}</div>
|
|
2007
|
+
</div>
|
|
2008
|
+
</div>
|
|
2009
|
+
@if (ShowCaptureReasoning) {
|
|
2010
|
+
<div class="rpe-grid2 rpe-mt">
|
|
2011
|
+
<div class="field">
|
|
2012
|
+
<label>Capture Reasoning</label>
|
|
2013
|
+
<select class="mj-input fpb-reasoning-select" [value]="spec.CaptureReasoning ? 'true' : 'false'" (change)="UpdateCaptureReasoning($event)">
|
|
2014
|
+
<option value="true">Yes — Keep the model's rationale with each Feature Value</option>
|
|
2015
|
+
<option value="false">No</option>
|
|
2016
|
+
</select>
|
|
2017
|
+
</div>
|
|
2018
|
+
</div>
|
|
2019
|
+
}
|
|
2020
|
+
</section>
|
|
2021
|
+
|
|
944
2022
|
<!-- STAGE 1: CONTEXT SOURCE -->
|
|
945
2023
|
<section class="rpe-sec">
|
|
946
2024
|
<div class="rpe-sec-h">
|
|
@@ -962,10 +2040,10 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
962
2040
|
@if (contextMode === 'document') {
|
|
963
2041
|
<div class="field">
|
|
964
2042
|
<label>Entity Document</label>
|
|
965
|
-
<select class="mj-input"
|
|
966
|
-
<option value="" disabled>— Select Entity Document —</option>
|
|
2043
|
+
<select class="mj-input" (change)="onEntityDocChange($event)">
|
|
2044
|
+
<option value="" disabled [selected]="!SavedEntityDocListed">— Select Entity Document —</option>
|
|
967
2045
|
@for (doc of availableDocs; track doc.ID) {
|
|
968
|
-
<option [value]="doc.ID">{{ doc.Name }}</option>
|
|
2046
|
+
<option [value]="doc.ID" [selected]="IsSavedEntityDoc(doc)">{{ doc.Name }}</option>
|
|
969
2047
|
}
|
|
970
2048
|
</select>
|
|
971
2049
|
</div>
|
|
@@ -994,10 +2072,10 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
994
2072
|
<div class="rpe-grid2">
|
|
995
2073
|
<div class="field">
|
|
996
2074
|
<label>Prompt</label>
|
|
997
|
-
<select class="mj-input"
|
|
998
|
-
<option value="" disabled>— Select AI Prompt —</option>
|
|
2075
|
+
<select class="mj-input" (change)="onPromptChange($event)">
|
|
2076
|
+
<option value="" disabled [selected]="!SavedPromptListed">— Select AI Prompt —</option>
|
|
999
2077
|
@for (p of availablePrompts; track p.ID) {
|
|
1000
|
-
<option [value]="p.ID">{{ p.Name }}</option>
|
|
2078
|
+
<option [value]="p.ID" [selected]="IsSavedPrompt(p)">{{ p.Name }}</option>
|
|
1001
2079
|
}
|
|
1002
2080
|
</select>
|
|
1003
2081
|
</div>
|
|
@@ -1028,7 +2106,7 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1028
2106
|
<i class="fa-solid fa-plus"></i> Add Output
|
|
1029
2107
|
</button>
|
|
1030
2108
|
</div>
|
|
1031
|
-
<p class="rpe-desc">Define the structured outputs produced by the
|
|
2109
|
+
<p class="rpe-desc">Define the structured outputs produced by the pipeline, their type constraints, and target write-back destinations.</p>
|
|
1032
2110
|
|
|
1033
2111
|
@if (!spec.Outputs || spec.Outputs.length === 0) {
|
|
1034
2112
|
<div class="fpb-empty-outputs">
|
|
@@ -1037,11 +2115,11 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1037
2115
|
</div>
|
|
1038
2116
|
} @else {
|
|
1039
2117
|
<div class="fpb-outputs-list">
|
|
1040
|
-
@for (output of spec.Outputs; track $index) {
|
|
2118
|
+
@for (output of spec.Outputs; track $index; let outputIndex = $index) {
|
|
1041
2119
|
<div class="fpb-output-card">
|
|
1042
2120
|
<div class="fpb-output-head">
|
|
1043
|
-
<h4>Output #{{
|
|
1044
|
-
<button mjButton size="sm" variant="flat" (click)="removeOutput(
|
|
2121
|
+
<h4>Output #{{ outputIndex + 1 }}: {{ output.Name || '(unnamed)' }}</h4>
|
|
2122
|
+
<button mjButton size="sm" variant="flat" (click)="removeOutput(outputIndex)">
|
|
1045
2123
|
<i class="fa-solid fa-trash"></i> Remove
|
|
1046
2124
|
</button>
|
|
1047
2125
|
</div>
|
|
@@ -1049,18 +2127,21 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1049
2127
|
<div class="rpe-grid3">
|
|
1050
2128
|
<div class="field">
|
|
1051
2129
|
<label>Output Name</label>
|
|
1052
|
-
<input class="mj-input" [value]="output.Name" (input)="updateOutputProp(
|
|
2130
|
+
<input class="mj-input" [value]="output.Name" (input)="updateOutputProp(outputIndex, 'Name', $event)" placeholder="e.g. SentimentScore">
|
|
1053
2131
|
</div>
|
|
1054
2132
|
<div class="field">
|
|
1055
2133
|
<label>JSON Path / Ref</label>
|
|
1056
|
-
<input class="mj-input mono" [value]="output.Ref" (input)="updateOutputProp(
|
|
2134
|
+
<input class="mj-input mono" [value]="output.Ref" (input)="updateOutputProp(outputIndex, 'Ref', $event)" placeholder="e.g. $.sentiment or $">
|
|
1057
2135
|
</div>
|
|
1058
2136
|
<div class="field">
|
|
1059
2137
|
<label>Target Mode</label>
|
|
1060
|
-
<select class="mj-input"
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
2138
|
+
<select class="mj-input" (change)="updateTargetMode(outputIndex, $event)">
|
|
2139
|
+
@if (!IsTargetModeOffered(output)) {
|
|
2140
|
+
<option value="" disabled [selected]="true">— Select Target Mode —</option>
|
|
2141
|
+
}
|
|
2142
|
+
@for (m of AvailableTargetModes; track m.Value) {
|
|
2143
|
+
<option [value]="m.Value" [selected]="m.Value === output.Target.Mode">{{ m.Label }}</option>
|
|
2144
|
+
}
|
|
1064
2145
|
</select>
|
|
1065
2146
|
</div>
|
|
1066
2147
|
</div>
|
|
@@ -1070,10 +2151,10 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1070
2151
|
@if (output.Target.Mode === 'field') {
|
|
1071
2152
|
<div class="field">
|
|
1072
2153
|
<label>Target Field</label>
|
|
1073
|
-
<select class="mj-input"
|
|
1074
|
-
<option value="" disabled>— Select Column —</option>
|
|
2154
|
+
<select class="mj-input" (change)="updateFieldTarget(outputIndex, $event)">
|
|
2155
|
+
<option value="" disabled [selected]="!IsEntityFieldListed(output.Target.EntityFieldName)">— Select Column —</option>
|
|
1075
2156
|
@for (f of entityFields; track f.Name) {
|
|
1076
|
-
<option [value]="f.Name">{{ f.DisplayName || f.Name }} ({{ f.TSType }})</option>
|
|
2157
|
+
<option [value]="f.Name" [selected]="f.Name === output.Target.EntityFieldName">{{ f.DisplayName || f.Name }} ({{ f.TSType }})</option>
|
|
1077
2158
|
}
|
|
1078
2159
|
</select>
|
|
1079
2160
|
</div>
|
|
@@ -1082,10 +2163,10 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1082
2163
|
@if (output.Target.Mode === 'child') {
|
|
1083
2164
|
<div class="field">
|
|
1084
2165
|
<label>Child Entity</label>
|
|
1085
|
-
<select class="mj-input"
|
|
1086
|
-
<option value="" disabled>— Select Entity —</option>
|
|
2166
|
+
<select class="mj-input" (change)="updateChildTargetEntity(outputIndex, $event)">
|
|
2167
|
+
<option value="" disabled [selected]="!IsEntityListed(output.Target.EntityName)">— Select Entity —</option>
|
|
1087
2168
|
@for (e of availableEntities; track e.ID) {
|
|
1088
|
-
<option [value]="e.Name">{{ e.DisplayName || e.Name }}</option>
|
|
2169
|
+
<option [value]="e.Name" [selected]="e.Name === output.Target.EntityName">{{ e.DisplayName || e.Name }}</option>
|
|
1089
2170
|
}
|
|
1090
2171
|
</select>
|
|
1091
2172
|
</div>
|
|
@@ -1094,19 +2175,20 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1094
2175
|
<!-- Constraint details -->
|
|
1095
2176
|
<div class="field">
|
|
1096
2177
|
<label>Constraint Type</label>
|
|
1097
|
-
<select class="mj-input"
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
2178
|
+
<select class="mj-input" (change)="updateConstraintType(outputIndex, $event)">
|
|
2179
|
+
@if (!IsConstraintTypeOffered(output)) {
|
|
2180
|
+
<option value="none" disabled [selected]="true">— Select Constraint —</option>
|
|
2181
|
+
}
|
|
2182
|
+
@for (t of AvailableConstraintTypes; track t.Value) {
|
|
2183
|
+
<option [value]="t.Value" [selected]="t.Value === SavedConstraintType(output)">{{ t.Label }}</option>
|
|
2184
|
+
}
|
|
1103
2185
|
</select>
|
|
1104
2186
|
</div>
|
|
1105
2187
|
|
|
1106
2188
|
@if (output.Constraint) {
|
|
1107
2189
|
<div class="field">
|
|
1108
2190
|
<label>Violation Policy</label>
|
|
1109
|
-
<select class="mj-input" [value]="output.Constraint.OnViolation || 'fail'" (change)="updateViolationPolicy(
|
|
2191
|
+
<select class="mj-input" [value]="output.Constraint.OnViolation || 'fail'" (change)="updateViolationPolicy(outputIndex, $event)">
|
|
1110
2192
|
<option value="fail">Fail Row</option>
|
|
1111
2193
|
<option value="null">Set Output to Null</option>
|
|
1112
2194
|
<option value="coerce-to-other">Coerce / Fallback</option>
|
|
@@ -1119,19 +2201,109 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1119
2201
|
@if (output.Constraint?.Type === 'enum') {
|
|
1120
2202
|
<div class="field rpe-mt">
|
|
1121
2203
|
<label>Allowed Values (comma separated)</label>
|
|
1122
|
-
<input class="mj-input" [value]="getEnumValuesCsv(output.Constraint)" (input)="updateEnumValues(
|
|
2204
|
+
<input class="mj-input" [value]="getEnumValuesCsv(output.Constraint)" (input)="updateEnumValues(outputIndex, $event)" placeholder="e.g. Positive, Neutral, Negative">
|
|
1123
2205
|
</div>
|
|
2206
|
+
@if (IsDecisionPipeline && GetEnumValues(output).length > 0) {
|
|
2207
|
+
<div class="field rpe-mt">
|
|
2208
|
+
<label>Value Descriptions <span class="muted">— Decision models require a description for every choice option</span></label>
|
|
2209
|
+
<div class="fpb-enum-descriptions">
|
|
2210
|
+
@for (val of GetEnumValues(output); track val) {
|
|
2211
|
+
<div class="fpb-enum-desc-row">
|
|
2212
|
+
<span class="fpb-enum-val-badge">{{ val }}</span>
|
|
2213
|
+
<input
|
|
2214
|
+
class="mj-input"
|
|
2215
|
+
[value]="GetEnumValueDescription(output, val)"
|
|
2216
|
+
(input)="UpdateEnumValueDescription(outputIndex, val, $event)"
|
|
2217
|
+
[placeholder]="'Description for ' + val">
|
|
2218
|
+
</div>
|
|
2219
|
+
}
|
|
2220
|
+
</div>
|
|
2221
|
+
</div>
|
|
2222
|
+
}
|
|
1124
2223
|
}
|
|
1125
2224
|
@if (output.Constraint?.Type === 'numeric') {
|
|
1126
|
-
|
|
1127
|
-
<div class="field">
|
|
1128
|
-
<
|
|
1129
|
-
|
|
2225
|
+
@if (IsDecisionPipeline) {
|
|
2226
|
+
<div class="field rpe-mt">
|
|
2227
|
+
<div class="fpb-levels-header">
|
|
2228
|
+
<label>Numeric Levels <span class="muted">(Ordered: lowest to highest, 2 to 10 levels)</span></label>
|
|
2229
|
+
<button
|
|
2230
|
+
mjButton
|
|
2231
|
+
size="sm"
|
|
2232
|
+
variant="secondary"
|
|
2233
|
+
type="button"
|
|
2234
|
+
[disabled]="GetNumericLevels(output).length >= 10"
|
|
2235
|
+
(click)="AddNumericLevel(outputIndex)">
|
|
2236
|
+
<i class="fa-solid fa-plus"></i> Add Level
|
|
2237
|
+
</button>
|
|
2238
|
+
</div>
|
|
2239
|
+
<div class="fpb-levels-list">
|
|
2240
|
+
@for (lvl of GetNumericLevels(output); track $index; let lvlIdx = $index; let first = $first; let last = $last) {
|
|
2241
|
+
<div class="fpb-level-row">
|
|
2242
|
+
<span class="fpb-level-num">{{ lvlIdx + 1 }}</span>
|
|
2243
|
+
<input
|
|
2244
|
+
class="mj-input"
|
|
2245
|
+
[value]="lvl"
|
|
2246
|
+
(input)="UpdateNumericLevel(outputIndex, lvlIdx, $event)"
|
|
2247
|
+
placeholder="Level label (e.g. Low, Medium, High)">
|
|
2248
|
+
<button
|
|
2249
|
+
mjButton
|
|
2250
|
+
size="sm"
|
|
2251
|
+
variant="flat"
|
|
2252
|
+
type="button"
|
|
2253
|
+
[disabled]="first"
|
|
2254
|
+
(click)="MoveNumericLevel(outputIndex, lvlIdx, 'up')"
|
|
2255
|
+
title="Move Up">
|
|
2256
|
+
<i class="fa-solid fa-arrow-up"></i>
|
|
2257
|
+
</button>
|
|
2258
|
+
<button
|
|
2259
|
+
mjButton
|
|
2260
|
+
size="sm"
|
|
2261
|
+
variant="flat"
|
|
2262
|
+
type="button"
|
|
2263
|
+
[disabled]="last"
|
|
2264
|
+
(click)="MoveNumericLevel(outputIndex, lvlIdx, 'down')"
|
|
2265
|
+
title="Move Down">
|
|
2266
|
+
<i class="fa-solid fa-arrow-down"></i>
|
|
2267
|
+
</button>
|
|
2268
|
+
<button
|
|
2269
|
+
mjButton
|
|
2270
|
+
size="sm"
|
|
2271
|
+
variant="flat"
|
|
2272
|
+
type="button"
|
|
2273
|
+
[disabled]="GetNumericLevels(output).length <= 2"
|
|
2274
|
+
(click)="RemoveNumericLevel(outputIndex, lvlIdx)"
|
|
2275
|
+
title="Remove Level">
|
|
2276
|
+
<i class="fa-solid fa-trash"></i>
|
|
2277
|
+
</button>
|
|
2278
|
+
</div>
|
|
2279
|
+
}
|
|
2280
|
+
</div>
|
|
1130
2281
|
</div>
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
<
|
|
2282
|
+
} @else {
|
|
2283
|
+
<div class="rpe-grid2 rpe-mt">
|
|
2284
|
+
<div class="field">
|
|
2285
|
+
<label>Min Value</label>
|
|
2286
|
+
<input class="mj-input" type="number" [value]="getNumericMin(output.Constraint)" (input)="updateNumericMin(outputIndex, $event)">
|
|
2287
|
+
</div>
|
|
2288
|
+
<div class="field">
|
|
2289
|
+
<label>Max Value</label>
|
|
2290
|
+
<input class="mj-input" type="number" [value]="getNumericMax(output.Constraint)" (input)="updateNumericMax(outputIndex, $event)">
|
|
2291
|
+
</div>
|
|
1134
2292
|
</div>
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
@if (output.Constraint?.Type === 'boolean' && IsDecisionPipeline) {
|
|
2296
|
+
<div class="field rpe-mt">
|
|
2297
|
+
<label>Decision Threshold (0.0 to 1.0) <span class="muted">— calibrated probability threshold for true</span></label>
|
|
2298
|
+
<input
|
|
2299
|
+
class="mj-input"
|
|
2300
|
+
type="number"
|
|
2301
|
+
min="0"
|
|
2302
|
+
max="1"
|
|
2303
|
+
step="0.05"
|
|
2304
|
+
placeholder="0.5"
|
|
2305
|
+
[value]="GetBooleanThreshold(output) ?? ''"
|
|
2306
|
+
(input)="UpdateBooleanThreshold(outputIndex, $event)">
|
|
1135
2307
|
</div>
|
|
1136
2308
|
}
|
|
1137
2309
|
</div>
|
|
@@ -1140,6 +2312,56 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1140
2312
|
}
|
|
1141
2313
|
</section>
|
|
1142
2314
|
|
|
2315
|
+
<!-- ESCALATION (DECISION PIPELINES ONLY) -->
|
|
2316
|
+
@if (IsDecisionPipeline) {
|
|
2317
|
+
<section class="rpe-sec fpb-escalation-sec">
|
|
2318
|
+
<div class="rpe-sec-h">
|
|
2319
|
+
<i class="fa-solid fa-arrow-up-right-from-square"></i>
|
|
2320
|
+
<h3>Borderline Escalation</h3>
|
|
2321
|
+
</div>
|
|
2322
|
+
<p class="rpe-desc">Records any output of which the decision model answers below this confidence are re-run through the chosen LLM pipeline. Only those records are re-run.</p>
|
|
2323
|
+
|
|
2324
|
+
<div class="fpb-escalation-toggle-row">
|
|
2325
|
+
<label class="fpb-checkbox-label">
|
|
2326
|
+
<input
|
|
2327
|
+
type="checkbox"
|
|
2328
|
+
[checked]="IsEscalationEnabled"
|
|
2329
|
+
(change)="OnEscalationToggle($event)">
|
|
2330
|
+
<span>Escalate borderline records to an LLM pipeline</span>
|
|
2331
|
+
</label>
|
|
2332
|
+
</div>
|
|
2333
|
+
|
|
2334
|
+
@if (IsEscalationEnabled) {
|
|
2335
|
+
<div class="rpe-grid2 rpe-mt">
|
|
2336
|
+
<div class="field">
|
|
2337
|
+
<label>Target LLM Pipeline</label>
|
|
2338
|
+
<select class="mj-input" (change)="OnEscalationTargetChange($event)">
|
|
2339
|
+
<option value="" disabled [selected]="!SavedEscalationTargetListed">{{ EscalationTargetsPlaceholder }}</option>
|
|
2340
|
+
@for (target of AvailableEscalationTargets; track target.ID) {
|
|
2341
|
+
<option [value]="target.ID" [disabled]="!!GetTargetProblem(target)" [selected]="IsSavedEscalationTarget(target)">
|
|
2342
|
+
{{ target.Name }}{{ GetTargetProblem(target) ? ' (' + GetTargetProblem(target) + ')' : '' }}
|
|
2343
|
+
</option>
|
|
2344
|
+
}
|
|
2345
|
+
</select>
|
|
2346
|
+
</div>
|
|
2347
|
+
|
|
2348
|
+
<div class="field">
|
|
2349
|
+
<label>Confidence Floor (0.0 to 1.0)</label>
|
|
2350
|
+
<input
|
|
2351
|
+
class="mj-input"
|
|
2352
|
+
type="number"
|
|
2353
|
+
min="0"
|
|
2354
|
+
max="1"
|
|
2355
|
+
step="0.05"
|
|
2356
|
+
placeholder="0.7"
|
|
2357
|
+
[value]="spec.Escalation?.BelowConfidence ?? ''"
|
|
2358
|
+
(input)="OnEscalationFloorChange($event)">
|
|
2359
|
+
</div>
|
|
2360
|
+
</div>
|
|
2361
|
+
}
|
|
2362
|
+
</section>
|
|
2363
|
+
}
|
|
2364
|
+
|
|
1143
2365
|
<!-- STAGE 4: MATERIALIZATION & WATERMARK -->
|
|
1144
2366
|
<section class="rpe-sec">
|
|
1145
2367
|
<div class="rpe-sec-h">
|
|
@@ -1205,8 +2427,25 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1205
2427
|
</ul>
|
|
1206
2428
|
</div>
|
|
1207
2429
|
}
|
|
2430
|
+
|
|
2431
|
+
<!-- TYPE SWITCH CONFIRMATION DIALOG -->
|
|
2432
|
+
<mj-confirm-dialog
|
|
2433
|
+
[(Visible)]="ShowTypeSwitchConfirm"
|
|
2434
|
+
Type="warning"
|
|
2435
|
+
Title="Switch Pipeline Type"
|
|
2436
|
+
[Message]="'Switching to ' + (PendingPipelineType || 'selected type') + ' will affect existing outputs:'"
|
|
2437
|
+
ConfirmText="Switch Anyway"
|
|
2438
|
+
CancelText="Cancel"
|
|
2439
|
+
(Confirmed)="OnTypeSwitchConfirmed()"
|
|
2440
|
+
(Cancelled)="OnTypeSwitchCancelled()">
|
|
2441
|
+
<ul class="fpb-confirm-issues">
|
|
2442
|
+
@for (issue of TypeSwitchIssues; track $index) {
|
|
2443
|
+
<li>{{ issue }}</li>
|
|
2444
|
+
}
|
|
2445
|
+
</ul>
|
|
2446
|
+
</mj-confirm-dialog>
|
|
1208
2447
|
</div>
|
|
1209
|
-
`, styles: ["\n .fpb { display: flex; flex-direction: column; gap: 20px; }\n .rpe-desc { font-size: 13px; color: var(--mj-text-secondary); margin: -6px 0 16px 0; }\n .rpe-sec { background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-subtle); border-radius: var(--mj-radius-md, 10px); padding: 18px 20px; }\n .rpe-sec-h { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; }\n .rpe-sec-h h3 { margin: 0; font-size: 16px; font-weight: 700; color: var(--mj-text-primary); }\n .rpe-sec-h .num { width: 24px; height: 24px; border-radius: 50%; background: var(--mj-brand-primary); color: #fff; display: grid; place-items: center; font-size: 12px; font-weight: 800; }\n .fpb-split-h { justify-content: space-between; }\n .fpb-title-group { display: flex; align-items: center; gap: 11px; }\n .rpe-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n .rpe-grid3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }\n .field { display: flex; flex-direction: column; gap: 6px; }\n .field label { font-size: 12.5px; font-weight: 600; color: var(--mj-text-secondary); }\n .rpe-mt { margin-top: 14px; }\n .mono { font-family: monospace; font-size: 12.5px; }\n .muted { color: var(--mj-text-muted); font-weight: 400; }\n .rpe-static-text { font-size: 13px; color: var(--mj-text-muted); padding: 7px 0; }\n .fpb-code-preview { background: var(--mj-bg-surface-sunken, #0f172a); color: var(--mj-text-code, var(--mj-text-primary, #e2e8f0)); border: 1px solid var(--mj-border-subtle, #334155); padding: 12px; border-radius: 6px; font-size: 12px; font-family: var(--mj-font-mono, monospace); white-space: pre-wrap; word-break: break-word; max-height: 160px; overflow-y: auto; margin: 0; }\n .fpb-empty-outputs { display: flex; align-items: center; gap: 10px; padding: 20px; border: 1px dashed var(--mj-border-subtle); border-radius: 8px; color: var(--mj-text-muted); font-size: 13px; }\n .fpb-outputs-list { display: flex; flex-direction: column; gap: 16px; }\n .fpb-output-card { border: 1px solid var(--mj-border-subtle); border-radius: 8px; padding: 14px 16px; background: var(--mj-bg-surface); }\n .fpb-output-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; border-bottom: 1px solid var(--mj-border-subtle); padding-bottom: 8px; }\n .fpb-output-head h4 { margin: 0; font-size: 14px; font-weight: 600; }\n .fpb-issues-card { border-radius: 8px; padding: 12px 16px; font-size: 13px; }\n .fpb-issues-card--error { background: rgba(239, 68, 68, 0.08); border: 1px solid var(--mj-status-error); color: var(--mj-status-error-text); }\n .fpb-issues-card h4 { margin: 0 0 8px 0; font-size: 14px; display: flex; align-items: center; gap: 8px; }\n .fpb-issues-card ul { margin: 0; padding-left: 20px; }\n "] }]
|
|
2448
|
+
`, styles: ["\n .fpb { display: flex; flex-direction: column; gap: 20px; }\n .rpe-desc { font-size: 13px; color: var(--mj-text-secondary); margin: -6px 0 16px 0; }\n .rpe-sec { background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-subtle); border-radius: var(--mj-radius-md, 10px); padding: 18px 20px; }\n .fpb-type-sec { border-left: 3px solid var(--mj-brand-primary); }\n .rpe-sec-h { display: flex; align-items: center; gap: 11px; margin-bottom: 14px; }\n .rpe-sec-h h3 { margin: 0; font-size: 16px; font-weight: 700; color: var(--mj-text-primary); }\n .rpe-sec-h .num { width: 24px; height: 24px; border-radius: 50%; background: var(--mj-brand-primary); color: #fff; display: grid; place-items: center; font-size: 12px; font-weight: 800; }\n .fpb-split-h { justify-content: space-between; }\n .fpb-title-group { display: flex; align-items: center; gap: 11px; }\n .rpe-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n .rpe-grid3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }\n .field { display: flex; flex-direction: column; gap: 6px; }\n .field label { font-size: 12.5px; font-weight: 600; color: var(--mj-text-secondary); }\n .rpe-mt { margin-top: 14px; }\n .mono { font-family: monospace; font-size: 12.5px; }\n .muted { color: var(--mj-text-muted); font-weight: 400; }\n .rpe-static-text { font-size: 13px; color: var(--mj-text-muted); padding: 7px 0; }\n .fpb-code-preview { background: var(--mj-bg-surface-sunken, #0f172a); color: var(--mj-text-code, var(--mj-text-primary, #e2e8f0)); border: 1px solid var(--mj-border-subtle, #334155); padding: 12px; border-radius: 6px; font-size: 12px; font-family: var(--mj-font-mono, monospace); white-space: pre-wrap; word-break: break-word; max-height: 160px; overflow-y: auto; margin: 0; }\n .fpb-empty-outputs { display: flex; align-items: center; gap: 10px; padding: 20px; border: 1px dashed var(--mj-border-subtle); border-radius: 8px; color: var(--mj-text-muted); font-size: 13px; }\n .fpb-outputs-list { display: flex; flex-direction: column; gap: 16px; }\n .fpb-output-card { border: 1px solid var(--mj-border-subtle); border-radius: 8px; padding: 14px 16px; background: var(--mj-bg-surface); }\n .fpb-output-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; border-bottom: 1px solid var(--mj-border-subtle); padding-bottom: 8px; }\n .fpb-output-head h4 { margin: 0; font-size: 14px; font-weight: 600; }\n .fpb-issues-card { border-radius: 8px; padding: 12px 16px; font-size: 13px; }\n .fpb-issues-card--error { background: rgba(239, 68, 68, 0.08); border: 1px solid var(--mj-status-error); color: var(--mj-status-error-text); }\n .fpb-issues-card h4 { margin: 0 0 8px 0; font-size: 14px; display: flex; align-items: center; gap: 8px; }\n .fpb-issues-card ul { margin: 0; padding-left: 20px; }\n .fpb-confirm-issues { margin: 10px 0 0 0; padding-left: 20px; color: var(--mj-status-error-text, var(--mj-text-primary)); font-size: 13px; }\n .fpb-confirm-issues li { margin-bottom: 4px; }\n .fpb-levels-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }\n .fpb-levels-list { display: flex; flex-direction: column; gap: 8px; }\n .fpb-level-row { display: flex; align-items: center; gap: 8px; }\n .fpb-level-num { width: 22px; height: 22px; display: grid; place-items: center; font-size: 11px; font-weight: 700; border-radius: var(--mj-radius-sm, 4px); background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); flex-shrink: 0; }\n .fpb-enum-descriptions { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }\n .fpb-enum-desc-row { display: flex; align-items: center; gap: 10px; }\n .fpb-enum-val-badge { min-width: 90px; padding: 4px 8px; background: var(--mj-bg-surface-sunken); color: var(--mj-text-primary); border: 1px solid var(--mj-border-subtle); border-radius: var(--mj-radius-sm, 4px); font-size: 12px; font-weight: 600; text-align: center; flex-shrink: 0; }\n .fpb-escalation-toggle-row { display: flex; align-items: center; gap: 8px; margin-top: 10px; }\n .fpb-checkbox-label { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; font-weight: 500; color: var(--mj-text-primary); user-select: none; }\n .fpb-checkbox-label input[type=\"checkbox\"] { width: 16px; height: 16px; cursor: pointer; accent-color: var(--mj-brand-primary); }\n "] }]
|
|
1210
2449
|
}], null, { Record: [{
|
|
1211
2450
|
type: Input
|
|
1212
2451
|
}], EntityID: [{
|
|
@@ -1216,5 +2455,5 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1216
2455
|
}], ValidChange: [{
|
|
1217
2456
|
type: Output
|
|
1218
2457
|
}] }); })();
|
|
1219
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FeaturePipelineBuilderComponent, { className: "FeaturePipelineBuilderComponent", filePath: "lib/feature-pipeline-builder/feature-pipeline-builder.component.ts", lineNumber:
|
|
2458
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FeaturePipelineBuilderComponent, { className: "FeaturePipelineBuilderComponent", filePath: "lib/feature-pipeline-builder/feature-pipeline-builder.component.ts", lineNumber: 584 }); })();
|
|
1220
2459
|
//# sourceMappingURL=feature-pipeline-builder.component.js.map
|