@rslsp1/fa-app-tools 7.0.1 → 7.4.0

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/szenen.mjs CHANGED
@@ -21,6 +21,9 @@ import {
21
21
  SZENEN_EVENT_TYPES,
22
22
  SZENEN_ITEM_PREFIX,
23
23
  SZENEN_SCHEMAS,
24
+ SZENEN_SNAPSHOT_FILE,
25
+ SZENEN_SNAPSHOT_PREFIX,
26
+ SZENEN_SNAPSHOT_SCHEMA_VERSION,
24
27
  SzenenView,
25
28
  UNCHECKED_PUBLISH_RULES,
26
29
  UPLOAD_MAX_BYTES,
@@ -32,6 +35,7 @@ import {
32
35
  bildPfad,
33
36
  buildSystemInstruction,
34
37
  buildSystemInstruction2,
38
+ buildSzenenSnapshot,
35
39
  buildUserPrompt,
36
40
  buildUserPrompt2,
37
41
  callOptional,
@@ -59,8 +63,10 @@ import {
59
63
  checkSzenenBatchOrigin,
60
64
  checkTitle,
61
65
  checkWriteDraftInput,
66
+ claimWon,
62
67
  collectImageBatches,
63
68
  collectImageGenerationOrders,
69
+ collectImageJobs,
64
70
  collectPromptRuns,
65
71
  collectSceneDerivationRecoveries,
66
72
  collectSceneDerivations,
@@ -82,6 +88,7 @@ import {
82
88
  createHfImageLibrary,
83
89
  createHfImageStore,
84
90
  createImageGenerationPort,
91
+ createImageJobPort,
85
92
  createSimulationSceneDerivationPort,
86
93
  createSimulationTextGenerationPort,
87
94
  derivationPoliciesOf,
@@ -96,6 +103,7 @@ import {
96
103
  findExecutableImageModel,
97
104
  findImageBatch,
98
105
  findImageGenerationOrder,
106
+ findImageJob,
99
107
  findPromptRun,
100
108
  findSceneDerivation,
101
109
  findSceneDerivationRecovery,
@@ -104,6 +112,7 @@ import {
104
112
  formatSeedListe,
105
113
  freezeDraftChain,
106
114
  freezeSceneWorkingState,
115
+ generationBatchIdOf,
107
116
  gesamtHerkunft,
108
117
  getSzenenSchemas,
109
118
  gruppiereZuItems,
@@ -112,14 +121,20 @@ import {
112
121
  isOk,
113
122
  isProjectionCurrent,
114
123
  isSzenenItemId,
124
+ istSzenenSnapshotDatei,
115
125
  istZipDatei,
116
126
  itemIdForRun,
127
+ itemsAusBestand,
128
+ jobsForPromptRun,
117
129
  ladeVorschauen,
118
130
  leseBilderAusZip,
119
131
  linkFor,
132
+ locatorAus,
120
133
  locatorTeile,
121
134
  logRevisionOf,
135
+ mergeSnapshotAndPending,
122
136
  mergeSzenenBatchOrigin,
137
+ mimeTypAus,
123
138
  mitDefaultVorlage,
124
139
  noticeFor,
125
140
  ordersForPromptRun,
@@ -127,6 +142,7 @@ import {
127
142
  parseDerivationResponse,
128
143
  parseRunResponse,
129
144
  parseSeedListe,
145
+ parseSzenenSnapshot,
130
146
  preferredHeadRevisionOf,
131
147
  promptDiagnosticsOf,
132
148
  publishedHeadsOf,
@@ -150,6 +166,7 @@ import {
150
166
  selectableTargetModels,
151
167
  showChain,
152
168
  simulatedAnswerFor,
169
+ szenenSnapshotFilename,
153
170
  typAusBytes,
154
171
  unclassifiedPublishRules,
155
172
  unsupportedReason,
@@ -158,7 +175,7 @@ import {
158
175
  validateElementVersion,
159
176
  validatePayload,
160
177
  withReference
161
- } from "./chunk-B2YV4TNI.mjs";
178
+ } from "./chunk-HUGUH4VB.mjs";
162
179
  import {
163
180
  ContractViolation,
164
181
  STYLE_PAYLOAD,
@@ -194,6 +211,7 @@ function totalModelCalls(checks) {
194
211
  // src/lib/szenen/inMemoryEventChannel.ts
195
212
  function createInMemoryEventChannel(options = {}) {
196
213
  const log = options.shared ?? [];
214
+ const snapshot = options.snapshot ?? null;
197
215
  let tick = 0;
198
216
  const now = options.now ?? (() => ++tick);
199
217
  const clientId = options.clientId ?? "client-a";
@@ -202,7 +220,8 @@ function createInMemoryEventChannel(options = {}) {
202
220
  return log;
203
221
  },
204
222
  async readEvents() {
205
- return log.map((event) => ({ ...event }));
223
+ const { events } = mergeSnapshotAndPending(snapshot, log);
224
+ return events.map((event) => ({ ...event }));
206
225
  },
207
226
  async appendEvent(type, payload) {
208
227
  log.push({ type, payload, clientId, ts: now() });
@@ -211,7 +230,7 @@ function createInMemoryEventChannel(options = {}) {
211
230
  log.push(event);
212
231
  },
213
232
  withClient(otherClientId) {
214
- return createInMemoryEventChannel({ clientId: otherClientId, now, shared: log });
233
+ return createInMemoryEventChannel({ clientId: otherClientId, now, shared: log, snapshot });
215
234
  }
216
235
  };
217
236
  return channel;
@@ -1640,6 +1659,120 @@ function checkSceneDerivationRecoveryRecord(candidate) {
1640
1659
  }
1641
1660
  return { ok: true };
1642
1661
  }
1662
+
1663
+ // src/lib/szenen/scenePromptOperation.ts
1664
+ var MCP_CLIENT_PROVIDER = "mcp_client";
1665
+ var UNVERIFIED_MODEL_ID = "mcp-client-unspecified";
1666
+ var istText2 = (wert) => typeof wert === "string" && wert.trim().length > 0;
1667
+ function collectPromptOperations(events) {
1668
+ const nachId = /* @__PURE__ */ new Map();
1669
+ for (const event of events) {
1670
+ if (event.type !== SZENEN_EVENT_TYPES.promptOperationPrepared) continue;
1671
+ const payload = event.payload;
1672
+ if (!payload || !istText2(payload.operation_id)) continue;
1673
+ if (nachId.has(payload.operation_id)) continue;
1674
+ nachId.set(payload.operation_id, payload);
1675
+ }
1676
+ return [...nachId.values()];
1677
+ }
1678
+ function findPromptOperation(events, operationId) {
1679
+ return collectPromptOperations(events).find((v) => v.operation_id === operationId) ?? null;
1680
+ }
1681
+ async function preparePromptOperation(input) {
1682
+ const now = input.now ?? (() => /* @__PURE__ */ new Date());
1683
+ const eingefroren = await freezeSceneWorkingState({
1684
+ sceneElementId: input.sceneElementId,
1685
+ store: input.store,
1686
+ resolver: input.resolver,
1687
+ contextChain: input.contextChain,
1688
+ userInstruction: input.userInstruction ?? null
1689
+ });
1690
+ if (eingefroren.kind !== "ok") return eingefroren;
1691
+ const rendererInput = eingefroren.input;
1692
+ return {
1693
+ kind: "ok",
1694
+ operation: {
1695
+ operation_id: input.operationId,
1696
+ scene: eingefroren.scene,
1697
+ context_id: input.contextId,
1698
+ user_instruction: input.userInstruction ?? null,
1699
+ renderer_input: rendererInput,
1700
+ renderer_instruction: buildSystemInstruction2(rendererInput),
1701
+ renderer_payload: buildUserPrompt2(rendererInput),
1702
+ response_contract: responseContractOf(rendererInput),
1703
+ prepared_by: input.preparedBy,
1704
+ created_at: now().toISOString()
1705
+ }
1706
+ };
1707
+ }
1708
+ function responseContractOf(input) {
1709
+ const model = input.target_model ?? {};
1710
+ return {
1711
+ format: "json",
1712
+ required_fields: ["positive", "negative", "feedback", "visibility", "notes"],
1713
+ negative_prompt_allowed: model.supports_negative_prompt === true,
1714
+ node_ids: input.scene.nodes.map((node) => node.node_id),
1715
+ prompt_language: typeof model.prompt_language === "string" ? model.prompt_language : "en"
1716
+ };
1717
+ }
1718
+ function completePromptOperation(input) {
1719
+ const now = input.now ?? (() => /* @__PURE__ */ new Date());
1720
+ const { operation } = input;
1721
+ const geparst = parseRunResponse(input.response);
1722
+ if (!geparst.ok) {
1723
+ return {
1724
+ kind: "rejected",
1725
+ message: `Die Antwort zu Vorgang ${operation.operation_id} ist nicht verwertbar: ${geparst.message}`
1726
+ };
1727
+ }
1728
+ const geprueft = checkRunResponse(geparst.value, operation.renderer_input);
1729
+ if (!geprueft.ok) {
1730
+ return {
1731
+ kind: "rejected",
1732
+ message: `Die Antwort zu Vorgang ${operation.operation_id} passt nicht zur eingefrorenen Eingabe: ${geprueft.message}`
1733
+ };
1734
+ }
1735
+ const origin = {
1736
+ host: "mcp",
1737
+ ...istText2(input.declaredModelId) ? { declared_model_id: input.declaredModelId } : {},
1738
+ renderer_instruction_was_system_prompt: false
1739
+ };
1740
+ return {
1741
+ kind: "ok",
1742
+ record: {
1743
+ run_id: input.runId,
1744
+ // Keine fingierten Kennungen (D-98/D-75) — genau wie beim
1745
+ // Szene-Direktlauf des bestehenden Pfads.
1746
+ shot_version_id: "",
1747
+ shot_element_id: "",
1748
+ scene_setup_version_id: "",
1749
+ camera_id: "",
1750
+ target_model_version_id: operation.renderer_input.target_model_resolution?.version_id ?? "",
1751
+ provider: MCP_CLIENT_PROVIDER,
1752
+ model_id: UNVERIFIED_MODEL_ID,
1753
+ // Die Renderer-Anweisung, wie sie der Vorgang eingefroren hat — nicht
1754
+ // eine zweite, jetzt neu gebaute Fassung.
1755
+ system_prompt: operation.renderer_instruction,
1756
+ input_payload: operation.renderer_input,
1757
+ status: "succeeded",
1758
+ failure: null,
1759
+ output: geprueft.output,
1760
+ raw_output: input.response,
1761
+ source: { kind: "scene_direct", scene: operation.scene },
1762
+ operation_id: operation.operation_id,
1763
+ execution_origin: origin,
1764
+ created_at: now().toISOString()
1765
+ }
1766
+ };
1767
+ }
1768
+ function runOfOperation(runs, operationId) {
1769
+ return runs.find(
1770
+ (run) => run.operation_id === operationId
1771
+ ) ?? null;
1772
+ }
1773
+ function sameResponseAs(run, response) {
1774
+ return (run.raw_output ?? "") === response;
1775
+ }
1643
1776
  export {
1644
1777
  ALL_PUBLISH_RULES,
1645
1778
  CATALOGUE_TYPES,
@@ -1651,6 +1784,7 @@ export {
1651
1784
  DERIVABLE_TYPES,
1652
1785
  ELEMENT_VERSION_SCHEMA_FILE,
1653
1786
  FLOW_EXECUTION_PATH,
1787
+ MCP_CLIENT_PROVIDER,
1654
1788
  PROBE_VERSION_ID,
1655
1789
  PROMPT_RULE_EFFECT,
1656
1790
  REFERENCE_FIELD,
@@ -1665,8 +1799,12 @@ export {
1665
1799
  SZENEN_EVENT_TYPES,
1666
1800
  SZENEN_ITEM_PREFIX,
1667
1801
  SZENEN_SCHEMAS,
1802
+ SZENEN_SNAPSHOT_FILE,
1803
+ SZENEN_SNAPSHOT_PREFIX,
1804
+ SZENEN_SNAPSHOT_SCHEMA_VERSION,
1668
1805
  SzenenView,
1669
1806
  UNCHECKED_PUBLISH_RULES,
1807
+ UNVERIFIED_MODEL_ID,
1670
1808
  UPLOAD_MAX_BYTES,
1671
1809
  UnsupportedSchemaError,
1672
1810
  VersionDagError,
@@ -1677,6 +1815,7 @@ export {
1677
1815
  buildSystemInstruction as buildDerivationSystemInstruction,
1678
1816
  buildUserPrompt as buildDerivationUserPrompt,
1679
1817
  buildSystemInstruction2 as buildSystemInstruction,
1818
+ buildSzenenSnapshot,
1680
1819
  buildUserPrompt2 as buildUserPrompt,
1681
1820
  buildVersionDag,
1682
1821
  callOptional,
@@ -1707,14 +1846,18 @@ export {
1707
1846
  checkSzenenBatchOrigin,
1708
1847
  checkTitle,
1709
1848
  checkWriteDraftInput,
1849
+ claimWon,
1710
1850
  collectImageBatches,
1711
1851
  collectImageGenerationOrders,
1852
+ collectImageJobs,
1853
+ collectPromptOperations,
1712
1854
  collectPromptRuns,
1713
1855
  collectProviderChecks,
1714
1856
  collectSceneDerivationRecoveries,
1715
1857
  collectSceneDerivations,
1716
1858
  collectVersionRefs,
1717
1859
  compileSchemas,
1860
+ completePromptOperation,
1718
1861
  createBrowserTextGenerationPort,
1719
1862
  createClientDerivationPort,
1720
1863
  createClientRunPort,
@@ -1732,6 +1875,7 @@ export {
1732
1875
  createHfImageLibrary,
1733
1876
  createHfImageStore,
1734
1877
  createImageGenerationPort,
1878
+ createImageJobPort,
1735
1879
  createInMemoryEventChannel,
1736
1880
  createMemoryViewPort,
1737
1881
  createSimulationSceneDerivationPort,
@@ -1750,6 +1894,8 @@ export {
1750
1894
  findExecutableImageModel,
1751
1895
  findImageBatch,
1752
1896
  findImageGenerationOrder,
1897
+ findImageJob,
1898
+ findPromptOperation,
1753
1899
  findPromptRun,
1754
1900
  findProviderCheck,
1755
1901
  findSceneDerivation,
@@ -1759,6 +1905,7 @@ export {
1759
1905
  formatSeedListe,
1760
1906
  freezeDraftChain,
1761
1907
  freezeSceneWorkingState,
1908
+ generationBatchIdOf,
1762
1909
  gesamtHerkunft,
1763
1910
  getSzenenSchemas,
1764
1911
  gruppiereZuItems,
@@ -1767,14 +1914,20 @@ export {
1767
1914
  isOk,
1768
1915
  isProjectionCurrent,
1769
1916
  isSzenenItemId,
1917
+ istSzenenSnapshotDatei,
1770
1918
  istZipDatei,
1771
1919
  itemIdForRun,
1920
+ itemsAusBestand,
1921
+ jobsForPromptRun,
1772
1922
  ladeVorschauen,
1773
1923
  leseBilderAusZip,
1774
1924
  linkFor,
1925
+ locatorAus,
1775
1926
  locatorTeile,
1776
1927
  logRevisionOf,
1928
+ mergeSnapshotAndPending,
1777
1929
  mergeSzenenBatchOrigin,
1930
+ mimeTypAus,
1778
1931
  mitDefaultVorlage,
1779
1932
  noticeFor,
1780
1933
  ordersForPromptRun,
@@ -1782,8 +1935,10 @@ export {
1782
1935
  parseDerivationResponse,
1783
1936
  parseRunResponse,
1784
1937
  parseSeedListe,
1938
+ parseSzenenSnapshot,
1785
1939
  preferredHeadRevisionOf,
1786
1940
  preferredVersionId,
1941
+ preparePromptOperation,
1787
1942
  promptDiagnosticsOf,
1788
1943
  publishedHeadsOf,
1789
1944
  recoveriesForRun,
@@ -1796,19 +1951,23 @@ export {
1796
1951
  resolveShotPayload,
1797
1952
  resolveTargetModelOver,
1798
1953
  resolverFromQueries,
1954
+ responseContractOf,
1799
1955
  roundOfRun,
1800
1956
  rulesWithoutPromptEffect,
1801
1957
  runElementStoreContract,
1958
+ runOfOperation,
1802
1959
  runPromptDerivation,
1803
1960
  runPublishChecks,
1804
1961
  runSceneDerivation,
1805
1962
  runStoreDifferential,
1963
+ sameResponseAs,
1806
1964
  sceneOnlyCapabilities,
1807
1965
  scopeOfPath,
1808
1966
  seedFehlerText,
1809
1967
  selectableTargetModels,
1810
1968
  showChain,
1811
1969
  simulatedAnswerFor,
1970
+ szenenSnapshotFilename,
1812
1971
  totalModelCalls,
1813
1972
  typAusBytes,
1814
1973
  unclassifiedPublishRules,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rslsp1/fa-app-tools",
3
- "version": "7.0.1",
3
+ "version": "7.4.0",
4
4
  "description": "Shared tools and hooks for Fine Art flow apps",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -28,7 +28,8 @@
28
28
  "scripts": {
29
29
  "build": "node scripts/sync-szenen-styles.js && tsup",
30
30
  "prepublishOnly": "npm run build",
31
- "test": "vitest run"
31
+ "test": "vitest run",
32
+ "mutation:szenen": "stryker run stryker.szenen.conf.mjs"
32
33
  },
33
34
  "peerDependencies": {
34
35
  "react": ">=18"
@@ -39,9 +40,12 @@
39
40
  "zustand": "^5.0.14"
40
41
  },
41
42
  "devDependencies": {
43
+ "@stryker-mutator/core": "9.6.1",
44
+ "@stryker-mutator/vitest-runner": "9.6.1",
42
45
  "@testing-library/dom": "^10.4.1",
43
46
  "@testing-library/react": "^16.3.2",
44
47
  "@types/react": "^19.0.0",
48
+ "@vitest/coverage-v8": "2.1.9",
45
49
  "@xyflow/react": "^12.10.2",
46
50
  "jsdom": "^29.1.1",
47
51
  "motion": "^12.40.0",