@things-factory/figure-ui 10.1.15 → 10.1.16
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/client/modeller/figure-source.ts +32 -6
- package/client/pages/figure-modeller-page.ts +81 -43
- package/dist-client/modeller/figure-source.d.ts +21 -8
- package/dist-client/modeller/figure-source.js.map +1 -1
- package/dist-client/pages/figure-modeller-page.d.ts +38 -2
- package/dist-client/pages/figure-modeller-page.js +77 -41
- package/dist-client/pages/figure-modeller-page.js.map +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -147,32 +147,31 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
|
|
|
147
147
|
detail: { figureId: this.figure?.id, source: this.folded }
|
|
148
148
|
}));
|
|
149
149
|
};
|
|
150
|
-
|
|
150
|
+
/*
|
|
151
|
+
`detail.staged` is the dock's answer to "did anything actually happen to my candidate". The
|
|
152
|
+
listener is synchronous, so the dock reads it right after dispatching and only then tells the
|
|
153
|
+
chat card to say so. It used to be called `accepted`, which claimed more than it knew — the
|
|
154
|
+
page had put the candidate somewhere, not the person had agreed to it.
|
|
155
|
+
*/
|
|
156
|
+
this.receiveDockProposal = (event) => {
|
|
151
157
|
const detail = event.detail;
|
|
152
158
|
if (!detail)
|
|
153
159
|
return;
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
catch {
|
|
162
|
-
// ignore
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
const source = detail?.source || (detail?.proposal?.source ? (typeof detail.proposal.source === 'string' ? JSON.parse(detail.proposal.source) : detail.proposal.source) : undefined);
|
|
160
|
+
const source = detail?.source ||
|
|
161
|
+
(detail?.proposal?.source
|
|
162
|
+
? typeof detail.proposal.source === 'string'
|
|
163
|
+
? JSON.parse(detail.proposal.source)
|
|
164
|
+
: detail.proposal.source
|
|
165
|
+
: undefined);
|
|
166
166
|
if (source) {
|
|
167
|
-
this.
|
|
168
|
-
detail.accepted = true;
|
|
167
|
+
detail.staged = this.openProposalForReview(source, detail.proposal);
|
|
169
168
|
}
|
|
170
169
|
};
|
|
171
170
|
this.onFigureAiStage = (event) => {
|
|
172
171
|
const detail = event.detail;
|
|
173
172
|
const source = detail?.source || (detail?.proposal?.source ? (typeof detail.proposal.source === 'string' ? JSON.parse(detail.proposal.source) : detail.proposal.source) : undefined);
|
|
174
173
|
if (source) {
|
|
175
|
-
this.
|
|
174
|
+
this.openProposalForReview(source, detail.proposal);
|
|
176
175
|
}
|
|
177
176
|
};
|
|
178
177
|
this.onSaveRequest = () => {
|
|
@@ -727,36 +726,73 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
|
|
|
727
726
|
}));
|
|
728
727
|
}
|
|
729
728
|
}
|
|
730
|
-
|
|
729
|
+
/**
|
|
730
|
+
* A candidate from the dock opens the review lane. It does not become the draft.
|
|
731
|
+
*
|
|
732
|
+
* This used to write `board` and `parts` straight onto the working draft and then set
|
|
733
|
+
* `proposalSession = undefined` — the dock's candidate overwrote what the author had open and
|
|
734
|
+
* erased the lane built to review it. There was no moment where the person said yes, and a
|
|
735
|
+
* draft has no version history to go back to, so the previous work was simply gone.
|
|
736
|
+
*
|
|
737
|
+
* `ai-client-base`'s analysis contract states this as a literal type: `approvalRequired: true`,
|
|
738
|
+
* and of `proposal`, "It is never an instruction to mutate canonical state." The in-page
|
|
739
|
+
* `figure-ask` entrance already honoured it through `openAiProposal`; the dock entrance is now
|
|
740
|
+
* the same door. Applying is what the take button does, from the lane, per change.
|
|
741
|
+
*
|
|
742
|
+
* ## Why the overwrite was there — so it does not come back
|
|
743
|
+
*
|
|
744
|
+
* The dock opened the review lane originally. Before `c42a0b63df` this handler read:
|
|
745
|
+
*
|
|
746
|
+
* if (!this.active || (detail?.figureId ?? '') !== (this.figure?.id ?? '')) return
|
|
747
|
+
* if (detail?.draftType && detail.draftType !== this.folded?.type) return
|
|
748
|
+
* if (detail?.baseSource && detail.baseSource !== JSON.stringify(this.folded)) return
|
|
749
|
+
* this.receive(detail.proposal)
|
|
750
|
+
*
|
|
751
|
+
* Three guards, each a silent `return`, and the last compared a serialized source byte for byte.
|
|
752
|
+
* Any difference that changed nothing at all dropped the candidate with no message, so the dock
|
|
753
|
+
* would report a candidate and the screen would show none.
|
|
754
|
+
*
|
|
755
|
+
* The `ox-assistant-chat` migration fixed that by replacing the path rather than the guards, and
|
|
756
|
+
* the review lane went out with them — `applySourceDirectly` wrote straight to the draft, and
|
|
757
|
+
* cleared `proposalSession` on the way past. **Nobody decided that reviews were unwanted here.**
|
|
758
|
+
* It was the cost of loosening a guard by deleting what stood around it.
|
|
759
|
+
*
|
|
760
|
+
* So the guards are gone and stay gone, and the lane is back. If a candidate ever seems not to
|
|
761
|
+
* arrive, the thing to look for is a silent `return` on this path — not the lane.
|
|
762
|
+
*
|
|
763
|
+
* Returns whether the lane opened, so the dock can tell the chat whether to say it staged.
|
|
764
|
+
*/
|
|
765
|
+
openProposalForReview(rawSource, proposal) {
|
|
731
766
|
const source = typeof rawSource === 'string' ? JSON.parse(rawSource) : rawSource;
|
|
732
767
|
if (!source || !Array.isArray(source.parts))
|
|
733
|
-
return;
|
|
734
|
-
this.recordHistory();
|
|
768
|
+
return false;
|
|
735
769
|
try {
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
770
|
+
/*
|
|
771
|
+
The dock sends a FigureProposal whose metrics sit at the top level; the staged-on-navigate
|
|
772
|
+
path carries the raw tool result, which nests them under score/cost. Read both rather than
|
|
773
|
+
making one of the two entrances reshape its payload.
|
|
774
|
+
*/
|
|
775
|
+
this.proposalSession = proposalSessions.openAiProposal(this.folded, {
|
|
776
|
+
source: JSON.stringify(source),
|
|
777
|
+
grade: proposal?.grade ?? proposal?.score?.grade,
|
|
778
|
+
triangles: proposal?.triangles ?? proposal?.cost?.triangles,
|
|
779
|
+
groups: proposal?.groups ?? proposal?.cost?.groups,
|
|
780
|
+
attempts: proposal?.attempts,
|
|
781
|
+
quality: proposal?.quality
|
|
782
|
+
});
|
|
783
|
+
this.mode = 'edit';
|
|
749
784
|
this.requestUpdate();
|
|
750
|
-
|
|
785
|
+
return true;
|
|
751
786
|
}
|
|
752
787
|
catch (e) {
|
|
753
|
-
console.error('[FigureModeller] Failed to
|
|
788
|
+
console.error('[FigureModeller] Failed to open the AI candidate for review:', e);
|
|
789
|
+
return false;
|
|
754
790
|
}
|
|
755
791
|
}
|
|
756
792
|
connectedCallback() {
|
|
757
793
|
super.connectedCallback();
|
|
758
794
|
window.addEventListener('figure-ai-context-request', this.announceAiContext);
|
|
759
|
-
window.addEventListener('figure-ai-review', this.
|
|
795
|
+
window.addEventListener('figure-ai-review', this.receiveDockProposal);
|
|
760
796
|
window.addEventListener('figure-ai-stage', this.onFigureAiStage);
|
|
761
797
|
window.addEventListener('figure-save-request', this.onSaveRequest);
|
|
762
798
|
window.addEventListener('keydown', this.handleKeyDown);
|
|
@@ -766,7 +802,7 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
|
|
|
766
802
|
window.removeEventListener('figure-save-request', this.onSaveRequest);
|
|
767
803
|
window.removeEventListener('figure-ai-stage', this.onFigureAiStage);
|
|
768
804
|
window.removeEventListener('figure-ai-context-request', this.announceAiContext);
|
|
769
|
-
window.removeEventListener('figure-ai-review', this.
|
|
805
|
+
window.removeEventListener('figure-ai-review', this.receiveDockProposal);
|
|
770
806
|
window.dispatchEvent(new CustomEvent('figure-ai-context', { detail: undefined }));
|
|
771
807
|
super.disconnectedCallback();
|
|
772
808
|
}
|
|
@@ -1216,7 +1252,7 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
|
|
|
1216
1252
|
}
|
|
1217
1253
|
const pending = consumePendingFigureProposal();
|
|
1218
1254
|
if (pending?.source) {
|
|
1219
|
-
this.
|
|
1255
|
+
this.openProposalForReview(pending.source, pending.proposal);
|
|
1220
1256
|
}
|
|
1221
1257
|
return;
|
|
1222
1258
|
}
|
|
@@ -1236,7 +1272,7 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
|
|
|
1236
1272
|
this.startNew();
|
|
1237
1273
|
const pending = consumePendingFigureProposal();
|
|
1238
1274
|
if (pending?.source) {
|
|
1239
|
-
this.
|
|
1275
|
+
this.openProposalForReview(pending.source, pending.proposal);
|
|
1240
1276
|
}
|
|
1241
1277
|
return;
|
|
1242
1278
|
}
|
|
@@ -1244,7 +1280,7 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
|
|
|
1244
1280
|
this.startNew();
|
|
1245
1281
|
const pending = consumePendingFigureProposal();
|
|
1246
1282
|
if (pending?.source) {
|
|
1247
|
-
this.
|
|
1283
|
+
this.openProposalForReview(pending.source, pending.proposal);
|
|
1248
1284
|
}
|
|
1249
1285
|
return;
|
|
1250
1286
|
}
|
|
@@ -1252,13 +1288,13 @@ let FigureModellerPage = class FigureModellerPage extends FigureModellerPageBase
|
|
|
1252
1288
|
this.startNew();
|
|
1253
1289
|
const pending = consumePendingFigureProposal();
|
|
1254
1290
|
if (pending?.source) {
|
|
1255
|
-
this.
|
|
1291
|
+
this.openProposalForReview(pending.source, pending.proposal);
|
|
1256
1292
|
}
|
|
1257
1293
|
return;
|
|
1258
1294
|
}
|
|
1259
1295
|
const pending = consumePendingFigureProposal();
|
|
1260
1296
|
if (pending?.source) {
|
|
1261
|
-
this.
|
|
1297
|
+
this.openProposalForReview(pending.source, pending.proposal);
|
|
1262
1298
|
}
|
|
1263
1299
|
}
|
|
1264
1300
|
async load(id) {
|