@memberjunction/ng-record-process-studio 6.2.0-edge.1 → 6.2.0-edge.3
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 +111 -1
- 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 +1394 -335
- package/dist/lib/feature-pipeline-builder/feature-pipeline-builder.component.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);
|
|
310
|
+
} }
|
|
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));
|
|
203
370
|
} }
|
|
204
|
-
function
|
|
205
|
-
const
|
|
206
|
-
i0.ɵɵelementStart(0, "div",
|
|
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(
|
|
308
|
-
i0.ɵɵconditional(
|
|
475
|
+
i0.ɵɵrepeater(ctx_r1.AvailableTargetModes);
|
|
476
|
+
i0.ɵɵadvance(3);
|
|
477
|
+
i0.ɵɵconditional(output_r11.Target.Mode === "field" ? 24 : -1);
|
|
478
|
+
i0.ɵɵadvance();
|
|
479
|
+
i0.ɵɵconditional(output_r11.Target.Mode === "child" ? 25 : -1);
|
|
480
|
+
i0.ɵɵadvance(5);
|
|
481
|
+
i0.ɵɵconditional(!ctx_r1.IsConstraintTypeOffered(output_r11) ? 30 : -1);
|
|
482
|
+
i0.ɵɵadvance();
|
|
483
|
+
i0.ɵɵrepeater(ctx_r1.AvailableConstraintTypes);
|
|
484
|
+
i0.ɵɵadvance(2);
|
|
485
|
+
i0.ɵɵconditional(output_r11.Constraint ? 33 : -1);
|
|
309
486
|
i0.ɵɵadvance();
|
|
310
|
-
i0.ɵɵconditional((
|
|
487
|
+
i0.ɵɵconditional((output_r11.Constraint == null ? null : output_r11.Constraint.Type) === "enum" ? 34 : -1);
|
|
311
488
|
i0.ɵɵadvance();
|
|
312
|
-
i0.ɵɵconditional((
|
|
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,6 +668,132 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
406
668
|
Outputs: [],
|
|
407
669
|
Caching: { Cacheable: false },
|
|
408
670
|
};
|
|
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
|
+
}
|
|
409
797
|
AvailablePrompts = [];
|
|
410
798
|
/** @deprecated Use {@link AvailablePrompts}. */
|
|
411
799
|
get availablePrompts() {
|
|
@@ -498,13 +886,20 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
498
886
|
}
|
|
499
887
|
async ngOnInit() {
|
|
500
888
|
this.AvailableEntities = [...this.ProviderToUse.Entities].sort((a, b) => (a.DisplayName || a.Name).localeCompare(b.DisplayName || b.Name));
|
|
889
|
+
await this.loadPipelineTypes();
|
|
501
890
|
await this.loadPrompts();
|
|
502
891
|
await this.loadEntityDocs();
|
|
892
|
+
await this.LoadEscalationTargets();
|
|
503
893
|
this.SyncFromRecord();
|
|
504
894
|
}
|
|
505
895
|
ngOnChanges(changes) {
|
|
506
896
|
if (changes['Record'] || changes['EntityID']) {
|
|
507
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
|
+
}
|
|
508
903
|
}
|
|
509
904
|
}
|
|
510
905
|
SyncFromRecord() {
|
|
@@ -519,6 +914,16 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
519
914
|
this.spec.Context = parsed.Context ?? {};
|
|
520
915
|
this.spec.Caching = parsed.Caching ?? { Cacheable: false };
|
|
521
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;
|
|
522
927
|
}
|
|
523
928
|
}
|
|
524
929
|
}
|
|
@@ -550,6 +955,7 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
550
955
|
if (this.Record?.PromptID) {
|
|
551
956
|
this.SelectedPrompt = this.AvailablePrompts.find((p) => UUIDsEqual(p.ID, this.Record?.PromptID)) ?? null;
|
|
552
957
|
}
|
|
958
|
+
this.ensureLoadedTypeIncluded();
|
|
553
959
|
this.recomputeValidation();
|
|
554
960
|
this.cdr.detectChanges();
|
|
555
961
|
}
|
|
@@ -557,6 +963,71 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
557
963
|
syncFromRecord() {
|
|
558
964
|
return this.SyncFromRecord();
|
|
559
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
|
+
}
|
|
560
1031
|
async loadPrompts() {
|
|
561
1032
|
try {
|
|
562
1033
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
@@ -599,6 +1070,106 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
599
1070
|
LogError('Error loading Entity Documents', undefined, error);
|
|
600
1071
|
}
|
|
601
1072
|
}
|
|
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
|
+
}
|
|
602
1173
|
OnContextModeChange(event) {
|
|
603
1174
|
this.ContextMode = event.target.value;
|
|
604
1175
|
if (!this.spec.Context)
|
|
@@ -676,6 +1247,12 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
676
1247
|
EntityFieldName: this.EntityFields.length > 0 ? this.EntityFields[0].Name : '',
|
|
677
1248
|
},
|
|
678
1249
|
};
|
|
1250
|
+
if (this.IsDecisionPipeline) {
|
|
1251
|
+
newOutput.Constraint = {
|
|
1252
|
+
Type: 'boolean',
|
|
1253
|
+
OnViolation: 'fail',
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
679
1256
|
this.spec.Outputs.push(newOutput);
|
|
680
1257
|
this.emitChanges();
|
|
681
1258
|
}
|
|
@@ -730,6 +1307,9 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
730
1307
|
const target = this.spec.Outputs[index].Target;
|
|
731
1308
|
if (target.Mode === 'field') {
|
|
732
1309
|
target.EntityFieldName = fieldName;
|
|
1310
|
+
if (this.spec.Outputs[index].Constraint?.Type === 'enum') {
|
|
1311
|
+
this.prefillEnumValuesFromField(this.spec.Outputs[index]);
|
|
1312
|
+
}
|
|
733
1313
|
}
|
|
734
1314
|
this.emitChanges();
|
|
735
1315
|
}
|
|
@@ -757,9 +1337,15 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
757
1337
|
}
|
|
758
1338
|
else if (type === 'enum') {
|
|
759
1339
|
output.Constraint = { Type: 'enum', Values: [], OnViolation: 'fail' };
|
|
1340
|
+
this.prefillEnumValuesFromField(output);
|
|
760
1341
|
}
|
|
761
1342
|
else if (type === 'numeric') {
|
|
762
|
-
|
|
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
|
+
}
|
|
763
1349
|
}
|
|
764
1350
|
else if (type === 'boolean') {
|
|
765
1351
|
output.Constraint = { Type: 'boolean', OnViolation: 'fail' };
|
|
@@ -913,7 +1499,213 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
913
1499
|
updateCacheScope(event) {
|
|
914
1500
|
return this.UpdateCacheScope(event);
|
|
915
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
|
+
}
|
|
916
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
|
+
}
|
|
917
1709
|
if (this.Record) {
|
|
918
1710
|
this.spec.Name = this.Record.Name || '';
|
|
919
1711
|
this.spec.Description = this.Record.Description || '';
|
|
@@ -940,6 +1732,12 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
940
1732
|
}
|
|
941
1733
|
this.Record.OutputMapping = JSON.stringify({ fields });
|
|
942
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
|
+
}
|
|
943
1741
|
recomputeValidation() {
|
|
944
1742
|
this.RenderedConstraintPreview = renderConstraintBlock(this.spec.Outputs);
|
|
945
1743
|
const entity = this.Record?.EntityID ? this.ProviderToUse.EntityByID(this.Record.EntityID) : null;
|
|
@@ -959,168 +1757,268 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
959
1757
|
this.ValidationErrors = validateSpec(this.spec, stub);
|
|
960
1758
|
}
|
|
961
1759
|
else {
|
|
962
|
-
this.ValidationErrors = this.spec
|
|
963
|
-
|
|
964
|
-
|
|
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',
|
|
965
1788
|
Severity: 'error',
|
|
966
|
-
Message: '
|
|
967
|
-
FixRecommendation: '
|
|
968
|
-
}
|
|
969
|
-
|
|
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
|
+
}
|
|
970
1805
|
}
|
|
971
1806
|
const hasErrors = this.ValidationErrors.some((i) => i.Severity === 'error');
|
|
972
1807
|
this.ValidChange.emit(!hasErrors);
|
|
973
1808
|
}
|
|
974
1809
|
static ɵfac = /*@__PURE__*/ (() => { let ɵFeaturePipelineBuilderComponent_BaseFactory; return function FeaturePipelineBuilderComponent_Factory(__ngFactoryType__) { return (ɵFeaturePipelineBuilderComponent_BaseFactory || (ɵFeaturePipelineBuilderComponent_BaseFactory = i0.ɵɵgetInheritedFactory(FeaturePipelineBuilderComponent)))(__ngFactoryType__ || FeaturePipelineBuilderComponent); }; })();
|
|
975
|
-
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:
|
|
976
|
-
i0.ɵɵelementStart(0, "div", 0)(1, "section", 1)(2, "div", 2)(3, "
|
|
977
|
-
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");
|
|
978
1820
|
i0.ɵɵelementEnd();
|
|
979
|
-
i0.ɵɵelementStart(
|
|
980
|
-
i0.ɵɵtext(
|
|
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");
|
|
1828
|
+
i0.ɵɵelementEnd();
|
|
1829
|
+
i0.ɵɵelementStart(19, "h3");
|
|
1830
|
+
i0.ɵɵtext(20, "Context Source");
|
|
981
1831
|
i0.ɵɵelementEnd()();
|
|
982
|
-
i0.ɵɵelementStart(
|
|
983
|
-
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.");
|
|
984
1834
|
i0.ɵɵelementEnd();
|
|
985
|
-
i0.ɵɵelementStart(
|
|
986
|
-
i0.ɵɵtext(
|
|
1835
|
+
i0.ɵɵelementStart(23, "div", 12)(24, "div", 3)(25, "label");
|
|
1836
|
+
i0.ɵɵtext(26, "Context Mode");
|
|
987
1837
|
i0.ɵɵelementEnd();
|
|
988
|
-
i0.ɵɵelementStart(
|
|
989
|
-
i0.ɵɵlistener("change", function
|
|
990
|
-
i0.ɵɵelementStart(
|
|
991
|
-
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");
|
|
992
1842
|
i0.ɵɵelementEnd();
|
|
993
|
-
i0.ɵɵelementStart(
|
|
994
|
-
i0.ɵɵtext(
|
|
1843
|
+
i0.ɵɵelementStart(30, "option", 15);
|
|
1844
|
+
i0.ɵɵtext(31, "Entity Document (Template)");
|
|
995
1845
|
i0.ɵɵelementEnd();
|
|
996
|
-
i0.ɵɵelementStart(
|
|
997
|
-
i0.ɵɵtext(
|
|
1846
|
+
i0.ɵɵelementStart(32, "option", 16);
|
|
1847
|
+
i0.ɵɵtext(33, "Query (Graph Traversal)");
|
|
998
1848
|
i0.ɵɵelementEnd()()();
|
|
999
|
-
i0.ɵɵconditionalCreate(
|
|
1000
|
-
i0.ɵɵconditionalCreate(
|
|
1001
|
-
i0.ɵɵelementStart(
|
|
1002
|
-
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)");
|
|
1003
1853
|
i0.ɵɵelementEnd();
|
|
1004
|
-
i0.ɵɵelementStart(
|
|
1005
|
-
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); });
|
|
1006
1856
|
i0.ɵɵelementEnd()()()();
|
|
1007
|
-
i0.ɵɵelementStart(
|
|
1008
|
-
i0.ɵɵtext(
|
|
1857
|
+
i0.ɵɵelementStart(40, "section", 8)(41, "div", 9)(42, "span", 10);
|
|
1858
|
+
i0.ɵɵtext(43, "2");
|
|
1009
1859
|
i0.ɵɵelementEnd();
|
|
1010
|
-
i0.ɵɵelementStart(
|
|
1011
|
-
i0.ɵɵtext(
|
|
1860
|
+
i0.ɵɵelementStart(44, "h3");
|
|
1861
|
+
i0.ɵɵtext(45, "AI Prompt");
|
|
1012
1862
|
i0.ɵɵelementEnd()();
|
|
1013
|
-
i0.ɵɵelementStart(
|
|
1014
|
-
i0.ɵɵtext(
|
|
1863
|
+
i0.ɵɵelementStart(46, "div", 2)(47, "div", 3)(48, "label");
|
|
1864
|
+
i0.ɵɵtext(49, "Prompt");
|
|
1015
1865
|
i0.ɵɵelementEnd();
|
|
1016
|
-
i0.ɵɵelementStart(
|
|
1017
|
-
i0.ɵɵlistener("change", function
|
|
1018
|
-
i0.ɵɵelementStart(
|
|
1019
|
-
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");
|
|
1020
1870
|
i0.ɵɵelementEnd();
|
|
1021
|
-
i0.ɵɵrepeaterCreate(
|
|
1871
|
+
i0.ɵɵrepeaterCreate(53, FeaturePipelineBuilderComponent_For_54_Template, 2, 3, "option", 5, _forTrack1);
|
|
1022
1872
|
i0.ɵɵelementEnd()();
|
|
1023
|
-
i0.ɵɵconditionalCreate(
|
|
1873
|
+
i0.ɵɵconditionalCreate(55, FeaturePipelineBuilderComponent_Conditional_55_Template, 5, 1, "div", 3);
|
|
1024
1874
|
i0.ɵɵelementEnd();
|
|
1025
|
-
i0.ɵɵconditionalCreate(
|
|
1875
|
+
i0.ɵɵconditionalCreate(56, FeaturePipelineBuilderComponent_Conditional_56_Template, 7, 1, "div", 19);
|
|
1026
1876
|
i0.ɵɵelementEnd();
|
|
1027
|
-
i0.ɵɵelementStart(
|
|
1028
|
-
i0.ɵɵtext(
|
|
1877
|
+
i0.ɵɵelementStart(57, "section", 8)(58, "div", 20)(59, "div", 21)(60, "span", 10);
|
|
1878
|
+
i0.ɵɵtext(61, "3");
|
|
1029
1879
|
i0.ɵɵelementEnd();
|
|
1030
|
-
i0.ɵɵelementStart(
|
|
1031
|
-
i0.ɵɵtext(
|
|
1880
|
+
i0.ɵɵelementStart(62, "h3");
|
|
1881
|
+
i0.ɵɵtext(63, "Outputs & Constraints");
|
|
1032
1882
|
i0.ɵɵelementEnd()();
|
|
1033
|
-
i0.ɵɵelementStart(
|
|
1034
|
-
i0.ɵɵlistener("click", function
|
|
1035
|
-
i0.ɵɵelement(
|
|
1036
|
-
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 ");
|
|
1037
1887
|
i0.ɵɵelementEnd()();
|
|
1038
|
-
i0.ɵɵelementStart(
|
|
1039
|
-
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.");
|
|
1040
1890
|
i0.ɵɵelementEnd();
|
|
1041
|
-
i0.ɵɵconditionalCreate(
|
|
1891
|
+
i0.ɵɵconditionalCreate(69, FeaturePipelineBuilderComponent_Conditional_69_Template, 7, 0, "div", 24)(70, FeaturePipelineBuilderComponent_Conditional_70_Template, 3, 0, "div", 25);
|
|
1042
1892
|
i0.ɵɵelementEnd();
|
|
1043
|
-
i0.ɵɵ
|
|
1044
|
-
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");
|
|
1045
1896
|
i0.ɵɵelementEnd();
|
|
1046
|
-
i0.ɵɵelementStart(
|
|
1047
|
-
i0.ɵɵtext(
|
|
1897
|
+
i0.ɵɵelementStart(76, "h3");
|
|
1898
|
+
i0.ɵɵtext(77, "Caching & Watermarks");
|
|
1048
1899
|
i0.ɵɵelementEnd()();
|
|
1049
|
-
i0.ɵɵelementStart(
|
|
1050
|
-
i0.ɵɵtext(
|
|
1900
|
+
i0.ɵɵelementStart(78, "div", 12)(79, "div", 3)(80, "label");
|
|
1901
|
+
i0.ɵɵtext(81, "Watermark Strategy");
|
|
1051
1902
|
i0.ɵɵelementEnd();
|
|
1052
|
-
i0.ɵɵelementStart(
|
|
1053
|
-
i0.ɵɵlistener("change", function
|
|
1054
|
-
i0.ɵɵelementStart(
|
|
1055
|
-
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)");
|
|
1056
1907
|
i0.ɵɵelementEnd();
|
|
1057
|
-
i0.ɵɵelementStart(
|
|
1058
|
-
i0.ɵɵtext(
|
|
1908
|
+
i0.ɵɵelementStart(85, "option", 28);
|
|
1909
|
+
i0.ɵɵtext(86, "UpdatedAt (Compare modified timestamp)");
|
|
1059
1910
|
i0.ɵɵelementEnd();
|
|
1060
|
-
i0.ɵɵelementStart(
|
|
1061
|
-
i0.ɵɵtext(
|
|
1911
|
+
i0.ɵɵelementStart(87, "option", 29);
|
|
1912
|
+
i0.ɵɵtext(88, "None (Always process all records)");
|
|
1062
1913
|
i0.ɵɵelementEnd()()();
|
|
1063
|
-
i0.ɵɵelementStart(
|
|
1064
|
-
i0.ɵɵtext(
|
|
1914
|
+
i0.ɵɵelementStart(89, "div", 3)(90, "label");
|
|
1915
|
+
i0.ɵɵtext(91, "Skip Unchanged Records");
|
|
1065
1916
|
i0.ɵɵelementEnd();
|
|
1066
|
-
i0.ɵɵelementStart(
|
|
1067
|
-
i0.ɵɵlistener("change", function
|
|
1068
|
-
i0.ɵɵelementStart(
|
|
1069
|
-
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");
|
|
1070
1921
|
i0.ɵɵelementEnd();
|
|
1071
|
-
i0.ɵɵelementStart(
|
|
1072
|
-
i0.ɵɵtext(
|
|
1922
|
+
i0.ɵɵelementStart(95, "option", 31);
|
|
1923
|
+
i0.ɵɵtext(96, "No \u2014 Recompute every time");
|
|
1073
1924
|
i0.ɵɵelementEnd()()();
|
|
1074
|
-
i0.ɵɵelementStart(
|
|
1075
|
-
i0.ɵɵtext(
|
|
1925
|
+
i0.ɵɵelementStart(97, "div", 3)(98, "label");
|
|
1926
|
+
i0.ɵɵtext(99, "Enable Result Cache");
|
|
1076
1927
|
i0.ɵɵelementEnd();
|
|
1077
|
-
i0.ɵɵelementStart(
|
|
1078
|
-
i0.ɵɵlistener("change", function
|
|
1079
|
-
i0.ɵɵelementStart(
|
|
1080
|
-
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");
|
|
1081
1932
|
i0.ɵɵelementEnd();
|
|
1082
|
-
i0.ɵɵelementStart(
|
|
1083
|
-
i0.ɵɵtext(
|
|
1933
|
+
i0.ɵɵelementStart(103, "option", 31);
|
|
1934
|
+
i0.ɵɵtext(104, "No \u2014 Compute per row");
|
|
1084
1935
|
i0.ɵɵelementEnd()()()();
|
|
1085
|
-
i0.ɵɵconditionalCreate(
|
|
1086
|
-
i0.ɵɵelementEnd();
|
|
1087
|
-
i0.ɵɵconditionalCreate(91, FeaturePipelineBuilderComponent_Conditional_91_Template, 7, 0, "div", 28);
|
|
1936
|
+
i0.ɵɵconditionalCreate(105, FeaturePipelineBuilderComponent_Conditional_105_Template, 17, 3, "div", 32);
|
|
1088
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()()();
|
|
1089
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);
|
|
1090
1952
|
i0.ɵɵadvance(13);
|
|
1091
1953
|
i0.ɵɵproperty("value", ctx.contextMode);
|
|
1092
1954
|
i0.ɵɵadvance(7);
|
|
1093
|
-
i0.ɵɵconditional(ctx.contextMode === "document" ?
|
|
1955
|
+
i0.ɵɵconditional(ctx.contextMode === "document" ? 34 : -1);
|
|
1094
1956
|
i0.ɵɵadvance();
|
|
1095
|
-
i0.ɵɵconditional(ctx.contextMode === "query" ?
|
|
1957
|
+
i0.ɵɵconditional(ctx.contextMode === "query" ? 35 : -1);
|
|
1096
1958
|
i0.ɵɵadvance(4);
|
|
1097
1959
|
i0.ɵɵproperty("value", ctx.fieldsCsv);
|
|
1098
|
-
i0.ɵɵadvance(
|
|
1099
|
-
i0.ɵɵproperty("
|
|
1100
|
-
i0.ɵɵadvance(
|
|
1960
|
+
i0.ɵɵadvance(12);
|
|
1961
|
+
i0.ɵɵproperty("selected", !ctx.SavedPromptListed);
|
|
1962
|
+
i0.ɵɵadvance(2);
|
|
1101
1963
|
i0.ɵɵrepeater(ctx.availablePrompts);
|
|
1102
1964
|
i0.ɵɵadvance(2);
|
|
1103
|
-
i0.ɵɵconditional(ctx.selectedPrompt ?
|
|
1965
|
+
i0.ɵɵconditional(ctx.selectedPrompt ? 55 : -1);
|
|
1104
1966
|
i0.ɵɵadvance();
|
|
1105
|
-
i0.ɵɵconditional(ctx.renderedConstraintPreview ?
|
|
1967
|
+
i0.ɵɵconditional(ctx.renderedConstraintPreview ? 56 : -1);
|
|
1106
1968
|
i0.ɵɵadvance(13);
|
|
1107
|
-
i0.ɵɵconditional(!ctx.spec.Outputs || ctx.spec.Outputs.length === 0 ?
|
|
1108
|
-
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);
|
|
1109
1973
|
i0.ɵɵproperty("value", (ctx.Record == null ? null : ctx.Record.WatermarkStrategy) || "Checksum");
|
|
1110
1974
|
i0.ɵɵadvance(10);
|
|
1111
1975
|
i0.ɵɵproperty("value", (ctx.Record == null ? null : ctx.Record.SkipUnchanged) ? "true" : "false");
|
|
1112
1976
|
i0.ɵɵadvance(8);
|
|
1113
1977
|
i0.ɵɵproperty("value", ctx.spec.Caching.Cacheable ? "true" : "false");
|
|
1114
1978
|
i0.ɵɵadvance(5);
|
|
1115
|
-
i0.ɵɵconditional(ctx.spec.Caching.Cacheable ?
|
|
1979
|
+
i0.ɵɵconditional(ctx.spec.Caching.Cacheable ? 105 : -1);
|
|
1980
|
+
i0.ɵɵadvance();
|
|
1981
|
+
i0.ɵɵconditional(ctx.validationErrors.length > 0 ? 106 : -1);
|
|
1116
1982
|
i0.ɵɵadvance();
|
|
1117
|
-
i0.ɵɵ
|
|
1118
|
-
|
|
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 });
|
|
1119
1988
|
}
|
|
1120
1989
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FeaturePipelineBuilderComponent, [{
|
|
1121
1990
|
type: Component,
|
|
1122
|
-
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: `
|
|
1123
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
|
+
|
|
1124
2022
|
<!-- STAGE 1: CONTEXT SOURCE -->
|
|
1125
2023
|
<section class="rpe-sec">
|
|
1126
2024
|
<div class="rpe-sec-h">
|
|
@@ -1142,10 +2040,10 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1142
2040
|
@if (contextMode === 'document') {
|
|
1143
2041
|
<div class="field">
|
|
1144
2042
|
<label>Entity Document</label>
|
|
1145
|
-
<select class="mj-input"
|
|
1146
|
-
<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>
|
|
1147
2045
|
@for (doc of availableDocs; track doc.ID) {
|
|
1148
|
-
<option [value]="doc.ID">{{ doc.Name }}</option>
|
|
2046
|
+
<option [value]="doc.ID" [selected]="IsSavedEntityDoc(doc)">{{ doc.Name }}</option>
|
|
1149
2047
|
}
|
|
1150
2048
|
</select>
|
|
1151
2049
|
</div>
|
|
@@ -1174,10 +2072,10 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1174
2072
|
<div class="rpe-grid2">
|
|
1175
2073
|
<div class="field">
|
|
1176
2074
|
<label>Prompt</label>
|
|
1177
|
-
<select class="mj-input"
|
|
1178
|
-
<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>
|
|
1179
2077
|
@for (p of availablePrompts; track p.ID) {
|
|
1180
|
-
<option [value]="p.ID">{{ p.Name }}</option>
|
|
2078
|
+
<option [value]="p.ID" [selected]="IsSavedPrompt(p)">{{ p.Name }}</option>
|
|
1181
2079
|
}
|
|
1182
2080
|
</select>
|
|
1183
2081
|
</div>
|
|
@@ -1208,7 +2106,7 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1208
2106
|
<i class="fa-solid fa-plus"></i> Add Output
|
|
1209
2107
|
</button>
|
|
1210
2108
|
</div>
|
|
1211
|
-
<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>
|
|
1212
2110
|
|
|
1213
2111
|
@if (!spec.Outputs || spec.Outputs.length === 0) {
|
|
1214
2112
|
<div class="fpb-empty-outputs">
|
|
@@ -1217,11 +2115,11 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1217
2115
|
</div>
|
|
1218
2116
|
} @else {
|
|
1219
2117
|
<div class="fpb-outputs-list">
|
|
1220
|
-
@for (output of spec.Outputs; track $index) {
|
|
2118
|
+
@for (output of spec.Outputs; track $index; let outputIndex = $index) {
|
|
1221
2119
|
<div class="fpb-output-card">
|
|
1222
2120
|
<div class="fpb-output-head">
|
|
1223
|
-
<h4>Output #{{
|
|
1224
|
-
<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)">
|
|
1225
2123
|
<i class="fa-solid fa-trash"></i> Remove
|
|
1226
2124
|
</button>
|
|
1227
2125
|
</div>
|
|
@@ -1229,18 +2127,21 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1229
2127
|
<div class="rpe-grid3">
|
|
1230
2128
|
<div class="field">
|
|
1231
2129
|
<label>Output Name</label>
|
|
1232
|
-
<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">
|
|
1233
2131
|
</div>
|
|
1234
2132
|
<div class="field">
|
|
1235
2133
|
<label>JSON Path / Ref</label>
|
|
1236
|
-
<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 $">
|
|
1237
2135
|
</div>
|
|
1238
2136
|
<div class="field">
|
|
1239
2137
|
<label>Target Mode</label>
|
|
1240
|
-
<select class="mj-input"
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
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
|
+
}
|
|
1244
2145
|
</select>
|
|
1245
2146
|
</div>
|
|
1246
2147
|
</div>
|
|
@@ -1250,10 +2151,10 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1250
2151
|
@if (output.Target.Mode === 'field') {
|
|
1251
2152
|
<div class="field">
|
|
1252
2153
|
<label>Target Field</label>
|
|
1253
|
-
<select class="mj-input"
|
|
1254
|
-
<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>
|
|
1255
2156
|
@for (f of entityFields; track f.Name) {
|
|
1256
|
-
<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>
|
|
1257
2158
|
}
|
|
1258
2159
|
</select>
|
|
1259
2160
|
</div>
|
|
@@ -1262,10 +2163,10 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1262
2163
|
@if (output.Target.Mode === 'child') {
|
|
1263
2164
|
<div class="field">
|
|
1264
2165
|
<label>Child Entity</label>
|
|
1265
|
-
<select class="mj-input"
|
|
1266
|
-
<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>
|
|
1267
2168
|
@for (e of availableEntities; track e.ID) {
|
|
1268
|
-
<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>
|
|
1269
2170
|
}
|
|
1270
2171
|
</select>
|
|
1271
2172
|
</div>
|
|
@@ -1274,19 +2175,20 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1274
2175
|
<!-- Constraint details -->
|
|
1275
2176
|
<div class="field">
|
|
1276
2177
|
<label>Constraint Type</label>
|
|
1277
|
-
<select class="mj-input"
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
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
|
+
}
|
|
1283
2185
|
</select>
|
|
1284
2186
|
</div>
|
|
1285
2187
|
|
|
1286
2188
|
@if (output.Constraint) {
|
|
1287
2189
|
<div class="field">
|
|
1288
2190
|
<label>Violation Policy</label>
|
|
1289
|
-
<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)">
|
|
1290
2192
|
<option value="fail">Fail Row</option>
|
|
1291
2193
|
<option value="null">Set Output to Null</option>
|
|
1292
2194
|
<option value="coerce-to-other">Coerce / Fallback</option>
|
|
@@ -1299,19 +2201,109 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1299
2201
|
@if (output.Constraint?.Type === 'enum') {
|
|
1300
2202
|
<div class="field rpe-mt">
|
|
1301
2203
|
<label>Allowed Values (comma separated)</label>
|
|
1302
|
-
<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">
|
|
1303
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
|
+
}
|
|
1304
2223
|
}
|
|
1305
2224
|
@if (output.Constraint?.Type === 'numeric') {
|
|
1306
|
-
|
|
1307
|
-
<div class="field">
|
|
1308
|
-
<
|
|
1309
|
-
|
|
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>
|
|
1310
2281
|
</div>
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
<
|
|
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>
|
|
1314
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)">
|
|
1315
2307
|
</div>
|
|
1316
2308
|
}
|
|
1317
2309
|
</div>
|
|
@@ -1320,6 +2312,56 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1320
2312
|
}
|
|
1321
2313
|
</section>
|
|
1322
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
|
+
|
|
1323
2365
|
<!-- STAGE 4: MATERIALIZATION & WATERMARK -->
|
|
1324
2366
|
<section class="rpe-sec">
|
|
1325
2367
|
<div class="rpe-sec-h">
|
|
@@ -1385,8 +2427,25 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1385
2427
|
</ul>
|
|
1386
2428
|
</div>
|
|
1387
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>
|
|
1388
2447
|
</div>
|
|
1389
|
-
`, 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 "] }]
|
|
1390
2449
|
}], null, { Record: [{
|
|
1391
2450
|
type: Input
|
|
1392
2451
|
}], EntityID: [{
|
|
@@ -1396,5 +2455,5 @@ export class FeaturePipelineBuilderComponent extends BaseAngularComponent {
|
|
|
1396
2455
|
}], ValidChange: [{
|
|
1397
2456
|
type: Output
|
|
1398
2457
|
}] }); })();
|
|
1399
|
-
(() => { (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 }); })();
|
|
1400
2459
|
//# sourceMappingURL=feature-pipeline-builder.component.js.map
|