@futdevpro/nts-dynamo 1.15.107 → 1.15.111

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.
Files changed (27) hide show
  1. package/.dynamo/logs/cicd-pipeline/output.log +1836 -1821
  2. package/.dynamo/logs/cicd-pipeline/status.json +37 -23
  3. package/build/_modules/ai/_collections/ai-provider-error.util.d.ts +9 -0
  4. package/build/_modules/ai/_collections/ai-provider-error.util.d.ts.map +1 -1
  5. package/build/_modules/ai/_collections/ai-provider-error.util.js +42 -3
  6. package/build/_modules/ai/_collections/ai-provider-error.util.js.map +1 -1
  7. package/build/_modules/ai/_modules/ai-mock/_collections/aim-fixture-serializer.util.d.ts +8 -0
  8. package/build/_modules/ai/_modules/ai-mock/_collections/aim-fixture-serializer.util.d.ts.map +1 -1
  9. package/build/_modules/ai/_modules/ai-mock/_collections/aim-fixture-serializer.util.js +2 -1
  10. package/build/_modules/ai/_modules/ai-mock/_collections/aim-fixture-serializer.util.js.map +1 -1
  11. package/build/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.d.ts +13 -3
  12. package/build/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.d.ts.map +1 -1
  13. package/build/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.js +13 -3
  14. package/build/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.js.map +1 -1
  15. package/build/_modules/server/server-status/server-status.control-service.d.ts +10 -0
  16. package/build/_modules/server/server-status/server-status.control-service.d.ts.map +1 -1
  17. package/build/_modules/server/server-status/server-status.control-service.js +21 -0
  18. package/build/_modules/server/server-status/server-status.control-service.js.map +1 -1
  19. package/package.json +2 -2
  20. package/scripts/_seed-out/aim-seed.fixtures.ts +161 -0
  21. package/scripts/_seed-out/seed-raw.json +153 -0
  22. package/scripts/ai-fixture-seed.js +126 -0
  23. package/src/_modules/ai/_collections/ai-provider-error.util.ts +49 -3
  24. package/src/_modules/ai/_modules/ai-mock/_collections/aim-fixture-serializer.util.ts +11 -1
  25. package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.ts +13 -3
  26. package/src/_modules/server/server-status/server-status.control-service.spec.ts +40 -0
  27. package/src/_modules/server/server-status/server-status.control-service.ts +40 -0
@@ -0,0 +1,161 @@
1
+ import { DyNTS_AIMock_Fixture } from '../_models/interfaces/aim-fixture.interface';
2
+
3
+ /**
4
+ * Valodi AI-generalasbol beegetve (live capture 2026-07-21). Kezzel NE szerkeszd.
5
+ *
6
+ * Determinisztikus sorrend (match-kulcs szerint) + rendezett objektum-kulcsok, hogy az ujra-generalas
7
+ * ne okozzon zajos diff-et. Forras: `DyNTS_AIMock_FixtureSerializer_Util`.
8
+ */
9
+ export const DyNTS_AIMock_TextFixtures: DyNTS_AIMock_Fixture[] = [
10
+ {
11
+ "capturedAt": "2026-07-22T00:58:38.792Z",
12
+ "config": {
13
+ "temperature": 0
14
+ },
15
+ "input": "Reply with exactly: PONG",
16
+ "inputHash": "0fb5aed1b51b28b04409b7963b2453fe1597d198c3b8396fc8ebd072104511de",
17
+ "modality": "text",
18
+ "model": "gpt-4o-mini",
19
+ "output": {
20
+ "content": "PONG",
21
+ "finish_reason": "stop",
22
+ "usage": {
23
+ "completion_tokens": 2,
24
+ "completion_tokens_details": {
25
+ "accepted_prediction_tokens": 0,
26
+ "audio_tokens": 0,
27
+ "reasoning_tokens": 0,
28
+ "rejected_prediction_tokens": 0
29
+ },
30
+ "prompt_tokens": 13,
31
+ "prompt_tokens_details": {
32
+ "audio_tokens": 0,
33
+ "cached_tokens": 0
34
+ },
35
+ "total_tokens": 15
36
+ }
37
+ },
38
+ "provider": "open-ai",
39
+ "sourceModel": "gpt-4o-mini"
40
+ },
41
+ {
42
+ "capturedAt": "2026-07-22T00:58:37.828Z",
43
+ "config": {
44
+ "temperature": 0
45
+ },
46
+ "input": "Reply with exactly: PONG",
47
+ "inputHash": "0fb5aed1b51b28b04409b7963b2453fe1597d198c3b8396fc8ebd072104511de",
48
+ "modality": "text",
49
+ "model": "gpt-5.4-nano",
50
+ "output": {
51
+ "content": "PONG",
52
+ "finish_reason": "stop",
53
+ "usage": {
54
+ "completion_tokens": 5,
55
+ "completion_tokens_details": {
56
+ "accepted_prediction_tokens": 0,
57
+ "audio_tokens": 0,
58
+ "reasoning_tokens": 0,
59
+ "rejected_prediction_tokens": 0
60
+ },
61
+ "prompt_tokens": 12,
62
+ "prompt_tokens_details": {
63
+ "audio_tokens": 0,
64
+ "cached_tokens": 0
65
+ },
66
+ "total_tokens": 17
67
+ }
68
+ },
69
+ "provider": "open-ai",
70
+ "sourceModel": "gpt-5.4-nano"
71
+ },
72
+ {
73
+ "capturedAt": "2026-07-22T00:58:38.316Z",
74
+ "config": {
75
+ "temperature": 0
76
+ },
77
+ "input": "What is the capital of Hungary? One word.",
78
+ "inputHash": "85c5b3ea12c8e34d97a18cb75ae55936aeb2ef0af90eb2f395a44ace6ce997e8",
79
+ "modality": "text",
80
+ "model": "gpt-5.4-nano",
81
+ "output": {
82
+ "content": "Budapest",
83
+ "finish_reason": "stop",
84
+ "usage": {
85
+ "completion_tokens": 5,
86
+ "completion_tokens_details": {
87
+ "accepted_prediction_tokens": 0,
88
+ "audio_tokens": 0,
89
+ "reasoning_tokens": 0,
90
+ "rejected_prediction_tokens": 0
91
+ },
92
+ "prompt_tokens": 16,
93
+ "prompt_tokens_details": {
94
+ "audio_tokens": 0,
95
+ "cached_tokens": 0
96
+ },
97
+ "total_tokens": 21
98
+ }
99
+ },
100
+ "provider": "open-ai",
101
+ "sourceModel": "gpt-5.4-nano"
102
+ },
103
+ {
104
+ "capturedAt": "2026-07-22T00:58:39.151Z",
105
+ "config": {},
106
+ "input": "artificial intelligence",
107
+ "inputHash": "803b3eb2b6af027151950019f2d5ede506a6636a9eafd262b27c23e3f834056f",
108
+ "modality": "embedding",
109
+ "model": "text-embedding-3-small",
110
+ "output": {
111
+ "dimensions": 1536,
112
+ "embeddingHead": [
113
+ 0.0005774497985839844,
114
+ -0.012481689453125,
115
+ -0.01143646240234375,
116
+ -0.0247344970703125,
117
+ 0.011383056640625,
118
+ -0.006069183349609375,
119
+ -0.0209503173828125,
120
+ 0.03741455078125
121
+ ],
122
+ "model": "text-embedding-3-small",
123
+ "object": "list",
124
+ "usage": {
125
+ "prompt_tokens": 3,
126
+ "total_tokens": 3
127
+ }
128
+ },
129
+ "provider": "open-ai",
130
+ "sourceModel": "text-embedding-3-small"
131
+ },
132
+ {
133
+ "capturedAt": "2026-07-22T00:58:39.020Z",
134
+ "config": {},
135
+ "input": "the quick brown fox",
136
+ "inputHash": "9ecb36561341d18eb65484e833efea61edc74b84cf5e6ae1b81c63533e25fc8f",
137
+ "modality": "embedding",
138
+ "model": "text-embedding-3-small",
139
+ "output": {
140
+ "dimensions": 1536,
141
+ "embeddingHead": [
142
+ -0.033355712890625,
143
+ -0.00183868408203125,
144
+ 0.005237579345703125,
145
+ -0.06304931640625,
146
+ -0.04779052734375,
147
+ 0.0018625259399414062,
148
+ 0.016876220703125,
149
+ 0.034820556640625
150
+ ],
151
+ "model": "text-embedding-3-small",
152
+ "object": "list",
153
+ "usage": {
154
+ "prompt_tokens": 4,
155
+ "total_tokens": 4
156
+ }
157
+ },
158
+ "provider": "open-ai",
159
+ "sourceModel": "text-embedding-3-small"
160
+ }
161
+ ];
@@ -0,0 +1,153 @@
1
+ [
2
+ {
3
+ "provider": "open-ai",
4
+ "model": "gpt-5.4-nano",
5
+ "modality": "text",
6
+ "config": {
7
+ "temperature": 0
8
+ },
9
+ "input": "Reply with exactly: PONG",
10
+ "inputHash": "0fb5aed1b51b28b04409b7963b2453fe1597d198c3b8396fc8ebd072104511de",
11
+ "output": {
12
+ "content": "PONG",
13
+ "finish_reason": "stop",
14
+ "usage": {
15
+ "prompt_tokens": 12,
16
+ "completion_tokens": 5,
17
+ "total_tokens": 17,
18
+ "prompt_tokens_details": {
19
+ "cached_tokens": 0,
20
+ "audio_tokens": 0
21
+ },
22
+ "completion_tokens_details": {
23
+ "reasoning_tokens": 0,
24
+ "audio_tokens": 0,
25
+ "accepted_prediction_tokens": 0,
26
+ "rejected_prediction_tokens": 0
27
+ }
28
+ }
29
+ },
30
+ "capturedAt": "2026-07-22T00:58:37.828Z",
31
+ "sourceModel": "gpt-5.4-nano"
32
+ },
33
+ {
34
+ "provider": "open-ai",
35
+ "model": "gpt-5.4-nano",
36
+ "modality": "text",
37
+ "config": {
38
+ "temperature": 0
39
+ },
40
+ "input": "What is the capital of Hungary? One word.",
41
+ "inputHash": "85c5b3ea12c8e34d97a18cb75ae55936aeb2ef0af90eb2f395a44ace6ce997e8",
42
+ "output": {
43
+ "content": "Budapest",
44
+ "finish_reason": "stop",
45
+ "usage": {
46
+ "prompt_tokens": 16,
47
+ "completion_tokens": 5,
48
+ "total_tokens": 21,
49
+ "prompt_tokens_details": {
50
+ "cached_tokens": 0,
51
+ "audio_tokens": 0
52
+ },
53
+ "completion_tokens_details": {
54
+ "reasoning_tokens": 0,
55
+ "audio_tokens": 0,
56
+ "accepted_prediction_tokens": 0,
57
+ "rejected_prediction_tokens": 0
58
+ }
59
+ }
60
+ },
61
+ "capturedAt": "2026-07-22T00:58:38.316Z",
62
+ "sourceModel": "gpt-5.4-nano"
63
+ },
64
+ {
65
+ "provider": "open-ai",
66
+ "model": "gpt-4o-mini",
67
+ "modality": "text",
68
+ "config": {
69
+ "temperature": 0
70
+ },
71
+ "input": "Reply with exactly: PONG",
72
+ "inputHash": "0fb5aed1b51b28b04409b7963b2453fe1597d198c3b8396fc8ebd072104511de",
73
+ "output": {
74
+ "content": "PONG",
75
+ "finish_reason": "stop",
76
+ "usage": {
77
+ "prompt_tokens": 13,
78
+ "completion_tokens": 2,
79
+ "total_tokens": 15,
80
+ "prompt_tokens_details": {
81
+ "cached_tokens": 0,
82
+ "audio_tokens": 0
83
+ },
84
+ "completion_tokens_details": {
85
+ "reasoning_tokens": 0,
86
+ "audio_tokens": 0,
87
+ "accepted_prediction_tokens": 0,
88
+ "rejected_prediction_tokens": 0
89
+ }
90
+ }
91
+ },
92
+ "capturedAt": "2026-07-22T00:58:38.792Z",
93
+ "sourceModel": "gpt-4o-mini"
94
+ },
95
+ {
96
+ "provider": "open-ai",
97
+ "model": "text-embedding-3-small",
98
+ "modality": "embedding",
99
+ "config": {},
100
+ "input": "the quick brown fox",
101
+ "inputHash": "9ecb36561341d18eb65484e833efea61edc74b84cf5e6ae1b81c63533e25fc8f",
102
+ "output": {
103
+ "object": "list",
104
+ "model": "text-embedding-3-small",
105
+ "dimensions": 1536,
106
+ "embeddingHead": [
107
+ -0.033355712890625,
108
+ -0.00183868408203125,
109
+ 0.005237579345703125,
110
+ -0.06304931640625,
111
+ -0.04779052734375,
112
+ 0.0018625259399414062,
113
+ 0.016876220703125,
114
+ 0.034820556640625
115
+ ],
116
+ "usage": {
117
+ "prompt_tokens": 4,
118
+ "total_tokens": 4
119
+ }
120
+ },
121
+ "capturedAt": "2026-07-22T00:58:39.020Z",
122
+ "sourceModel": "text-embedding-3-small"
123
+ },
124
+ {
125
+ "provider": "open-ai",
126
+ "model": "text-embedding-3-small",
127
+ "modality": "embedding",
128
+ "config": {},
129
+ "input": "artificial intelligence",
130
+ "inputHash": "803b3eb2b6af027151950019f2d5ede506a6636a9eafd262b27c23e3f834056f",
131
+ "output": {
132
+ "object": "list",
133
+ "model": "text-embedding-3-small",
134
+ "dimensions": 1536,
135
+ "embeddingHead": [
136
+ 0.0005774497985839844,
137
+ -0.012481689453125,
138
+ -0.01143646240234375,
139
+ -0.0247344970703125,
140
+ 0.011383056640625,
141
+ -0.006069183349609375,
142
+ -0.0209503173828125,
143
+ 0.03741455078125
144
+ ],
145
+ "usage": {
146
+ "prompt_tokens": 3,
147
+ "total_tokens": 3
148
+ }
149
+ },
150
+ "capturedAt": "2026-07-22T00:58:39.151Z",
151
+ "sourceModel": "text-embedding-3-small"
152
+ }
153
+ ]
@@ -0,0 +1,126 @@
1
+ /**
2
+ * FIZETOS fixture-seed (MP-3 SP-3.3) — a VALODI `DyNTS_AIMock_FixtureHarness_Service`-en es a
3
+ * `DyNTS_AIMock_FixtureSerializer_Util`-on keresztul, hogy a sajat kodutunkat is bizonyitsa (dogfooding).
4
+ *
5
+ * ⚠️ EZ PENZT KOLT. Szandekosan KICSI es KORLATOZOTT:
6
+ * - csak a legolcsobb engedett modellek (`gpt-5.4-nano` text, `text-embedding-3-small` embedding)
7
+ * - rovid promptok + szuk `max_completion_tokens`
8
+ * - kep-generalas NINCS (kulon dontes targya)
9
+ * - MINDEN fixture AZONNAL lemezre irodik (runbook §2c) — kvota-kifogyas nem viszi el az addigi munkat
10
+ * - 429 eseten az adott provider leall, a tobbi megy tovabb
11
+ * - a futas vegen kiirja a TENYLEGES token-fogyast
12
+ *
13
+ * Futtatas: node scripts/ai-fixture-seed.js
14
+ */
15
+
16
+ const fs = require('fs');
17
+ const path = require('path');
18
+
19
+ const ENV_PATH = path.resolve(__dirname, '../../../fdp-devops/.env');
20
+ const AIMOCK = path.resolve(__dirname, '../build/_modules/ai/_modules/ai-mock');
21
+ const OUT_DIR = path.resolve(__dirname, '_seed-out');
22
+ const RAW_FILE = path.join(OUT_DIR, 'seed-raw.json');
23
+
24
+ const { DyNTS_AIMock_FixtureHarness_Service } = require(path.join(AIMOCK, '_services/aim-fixture-harness.service'));
25
+ const { DyNTS_AIMock_FixtureSerializer_Util } = require(path.join(AIMOCK, '_collections/aim-fixture-serializer.util'));
26
+ const { DyNTS_AIMock_Modality } = require(path.join(AIMOCK, '_enums/aim-modality.enum'));
27
+ const { DyFM_OAI_Models } = require('@futdevpro/fsm-dynamo/ai/open-ai');
28
+
29
+ function loadKey() {
30
+ for (const line of fs.readFileSync(ENV_PATH, 'utf8').split(/\r?\n/)) {
31
+ const m = line.match(/^OPENAI_API_KEY=(.*)$/);
32
+ if (m) { return m[1].trim().replace(/^["']|["']$/g, ''); }
33
+ }
34
+ return null;
35
+ }
36
+
37
+ const usage = { prompt: 0, completion: 0, calls: 0 };
38
+ let quotaStop = false;
39
+
40
+ /** VALODI generator — ez az egyetlen pont, ahol penz folyik. */
41
+ function makeGenerator(key) {
42
+ return async (request) => {
43
+ if (request.modality === DyNTS_AIMock_Modality.embedding) {
44
+ const r = await fetch('https://api.openai.com/v1/embeddings', {
45
+ method: 'POST',
46
+ headers: { Authorization: `Bearer ${key}`, 'content-type': 'application/json' },
47
+ body: JSON.stringify({ model: request.model, input: request.input, ...(request.config || {}) }),
48
+ });
49
+ if (r.status === 429) { quotaStop = true; throw new Error('429 quota'); }
50
+ const j = await r.json();
51
+ if (j.error) { throw new Error(j.error.message); }
52
+ usage.prompt += j.usage?.prompt_tokens || 0;
53
+ usage.calls++;
54
+ // a teljes vektor helyett a dimenziot + az elso 8 erteket orizzuk (a fixture-fajl maradjon kezelheto)
55
+ return { object: j.object, model: j.model, dimensions: j.data[0].embedding.length,
56
+ embeddingHead: j.data[0].embedding.slice(0, 8), usage: j.usage };
57
+ }
58
+
59
+ const r = await fetch('https://api.openai.com/v1/chat/completions', {
60
+ method: 'POST',
61
+ headers: { Authorization: `Bearer ${key}`, 'content-type': 'application/json' },
62
+ body: JSON.stringify({ model: request.model, messages: [ { role: 'user', content: request.input } ],
63
+ max_completion_tokens: 64, ...(request.config || {}) }),
64
+ });
65
+ if (r.status === 429) { quotaStop = true; throw new Error('429 quota'); }
66
+ const j = await r.json();
67
+ if (j.error) { throw new Error(j.error.message); }
68
+ usage.prompt += j.usage?.prompt_tokens || 0;
69
+ usage.completion += j.usage?.completion_tokens || 0;
70
+ usage.calls++;
71
+ return { content: j.choices[0].message.content, finish_reason: j.choices[0].finish_reason, usage: j.usage };
72
+ };
73
+ }
74
+
75
+ const SEED = [
76
+ { model: 'gpt-5.4-nano', modality: DyNTS_AIMock_Modality.text, config: { temperature: 0 }, input: 'Reply with exactly: PONG' },
77
+ { model: 'gpt-5.4-nano', modality: DyNTS_AIMock_Modality.text, config: { temperature: 0 }, input: 'What is the capital of Hungary? One word.' },
78
+ { model: 'gpt-4o-mini', modality: DyNTS_AIMock_Modality.text, config: { temperature: 0 }, input: 'Reply with exactly: PONG' },
79
+ { model: 'text-embedding-3-small', modality: DyNTS_AIMock_Modality.embedding, config: {}, input: 'the quick brown fox' },
80
+ { model: 'text-embedding-3-small', modality: DyNTS_AIMock_Modality.embedding, config: {}, input: 'artificial intelligence' },
81
+ ];
82
+
83
+ (async () => {
84
+ const key = loadKey();
85
+ if (!key) { console.error('OPENAI_API_KEY hianyzik'); process.exit(1); }
86
+
87
+ const harness = new DyNTS_AIMock_FixtureHarness_Service({
88
+ generator: makeGenerator(key),
89
+ registry: DyFM_OAI_Models,
90
+ allowRealSpend: true, // ⚠️ JOVAHAGYOTT futas (G1). Alapertelmezesben ez false.
91
+ });
92
+
93
+ fs.mkdirSync(OUT_DIR, { recursive: true });
94
+ const fixtures = [];
95
+
96
+ console.log('FIZETOS seed — kicsi es korlatozott, fixture-onkent lemezre irva\n');
97
+
98
+ for (const s of SEED) {
99
+ if (quotaStop) { console.log(` KIHAGYVA (kvota): ${s.model} / ${s.input.slice(0, 30)}`); continue; }
100
+ try {
101
+ const f = await harness.capture({ provider: 'open-ai', model: s.model, modality: s.modality,
102
+ config: s.config, input: s.input });
103
+ fixtures.push(f);
104
+ fs.writeFileSync(RAW_FILE, JSON.stringify(fixtures, null, 2)); // INKREMENTALIS
105
+ console.log(` ✅ ${s.model} [${s.modality}] "${s.input.slice(0, 32)}"`);
106
+ } catch (e) {
107
+ console.log(` ❌ ${s.model}: ${e.message.slice(0, 90)}`);
108
+ }
109
+ }
110
+
111
+ if (fixtures.length) {
112
+ const src = DyNTS_AIMock_FixtureSerializer_Util.toConstantFile({
113
+ constName: 'DyNTS_AIMock_TextFixtures', fixtures, importPath: '../_models/interfaces/aim-fixture.interface',
114
+ headerNote: 'Valodi AI-generalasbol beegetve (live capture 2026-07-21). Kezzel NE szerkeszd.',
115
+ });
116
+ const again = DyNTS_AIMock_FixtureSerializer_Util.toConstantFile({
117
+ constName: 'DyNTS_AIMock_TextFixtures', fixtures, importPath: '../_models/interfaces/aim-fixture.interface',
118
+ headerNote: 'Valodi AI-generalasbol beegetve (live capture 2026-07-21). Kezzel NE szerkeszd.',
119
+ });
120
+ fs.writeFileSync(path.join(OUT_DIR, 'aim-seed.fixtures.ts'), src);
121
+ console.log(`\n determinizmus (ketszer szerializalva byte-azonos): ${src === again ? '✅ IGEN' : '❌ NEM'}`);
122
+ }
123
+
124
+ console.log(`\n📊 TENYLEGES fogyas: ${usage.calls} hivas · prompt ${usage.prompt} token · completion ${usage.completion} token`);
125
+ console.log(` ${fixtures.length} fixture → ${OUT_DIR}`);
126
+ })();
@@ -34,8 +34,14 @@ export class DyNTS_AI_ProviderError_Util {
34
34
  type: 'error',
35
35
  error: {
36
36
  type: 'invalid_request_error',
37
- message: `${set.param}: Extra inputs are not permitted for model '${set.model}'.`,
37
+ // MERT (capture 2026-07-21, claude-opus-4-8 + temperature): a valodi uzenet ez, NEM a korabbi
38
+ // kozelitesem ("Extra inputs are not permitted").
39
+ message: `\`${set.param}\` is deprecated for this model.`,
38
40
  },
41
+ // VERIFIED (capture 2026-07-21): a valodi Anthropic hiba-body TOP-LEVEL `request_id`-t is hoz —
42
+ // ez korabban hianyzott a sablonbol. Fixture-oknel a rogzitett valodi ertek szerepel; itt
43
+ // szintetikus placeholder, hogy az ALAK hu legyen.
44
+ request_id: 'req_mock',
39
45
  },
40
46
  reason: `invalid_request_error:${set.param}`,
41
47
  };
@@ -82,17 +88,57 @@ export class DyNTS_AI_ProviderError_Util {
82
88
  };
83
89
  }
84
90
 
91
+ // MERT (capture 2026-07-21, gpt-4o-mini + temperature: 3): a valodi OpenAI range-hiba kodja
92
+ // `decimal_above_max_value`, NEM az altalam felteteleztt `invalid_value`, es a message formatuma ez:
93
+ // "Invalid 'temperature': decimal above maximum value. Expected a value <= 2, but got 3 instead."
85
94
  return {
86
95
  httpStatus: 400,
87
96
  providerErrorBody: {
88
97
  error: {
89
- message: `Invalid value for '${set.param}': ${set.detail} (model '${set.model}').`,
98
+ message: `Invalid '${set.param}': ${set.detail}.`,
90
99
  type: 'invalid_request_error',
91
100
  param: set.param,
92
- code: 'invalid_value',
101
+ code: 'decimal_above_max_value',
93
102
  },
94
103
  },
95
104
  reason: `invalid_value:${set.param}`,
96
105
  };
97
106
  }
107
+
108
+ /**
109
+ * Ismeretlen modell → **HTTP 404** (NEM 400), `code: 'model_not_found'`.
110
+ * MERT (capture 2026-07-21): `The model \`X\` does not exist or you do not have access to it.`
111
+ * @param set - provider + a nem letezo modell-azonosito
112
+ */
113
+ static buildModelNotFoundError(
114
+ set: {
115
+ provider: string,
116
+ model: string,
117
+ }
118
+ ): DyNTS_AI_ProviderError {
119
+ if (set.provider === this.anthropicProviderId) {
120
+ return {
121
+ httpStatus: 404,
122
+ providerErrorBody: {
123
+ type: 'error',
124
+ error: { type: 'not_found_error', message: `model: ${set.model}` },
125
+ request_id: 'req_mock',
126
+ },
127
+ reason: `not_found_error:${set.model}`,
128
+ };
129
+ }
130
+
131
+ return {
132
+ httpStatus: 404,
133
+ providerErrorBody: {
134
+ error: {
135
+ message: `The model \`${set.model}\` does not exist or you do not have access to it.`,
136
+ type: 'invalid_request_error',
137
+ param: null,
138
+ code: 'model_not_found',
139
+ },
140
+ },
141
+ reason: `model_not_found:${set.model}`,
142
+ };
143
+ }
98
144
  }
@@ -22,6 +22,14 @@ export class DyNTS_AIMock_FixtureSerializer_Util {
22
22
  constName: string,
23
23
  fixtures: DyNTS_AIMock_Fixture[],
24
24
  headerNote?: string,
25
+ /**
26
+ * A generalt fajl import-utvonala a `DyNTS_AIMock_Fixture` tipushoz.
27
+ *
28
+ * Default a publikus package-utvonal (KULSO consumer fixture-fajljaihoz). **A csomagon BELULRE**
29
+ * kerulo fixture-oknel relativ utat kell adni (pl. `'../_models/interfaces/aim-fixture.interface'`),
30
+ * kulonben a fajl onmagara hivatkozna a package-nevvel, ami build-kor nem oldodik fel.
31
+ */
32
+ importPath?: string,
25
33
  }
26
34
  ): string {
27
35
  const sorted: DyNTS_AIMock_Fixture[] = this.sortFixtures(set.fixtures);
@@ -31,8 +39,10 @@ export class DyNTS_AIMock_FixtureSerializer_Util {
31
39
 
32
40
  const note: string = set.headerNote ?? 'Auto-generalt fixture-keszlet — kezzel NE szerkeszd.';
33
41
 
42
+ const importPath: string = set.importPath ?? '@futdevpro/nts-dynamo/ai/ai-mock';
43
+
34
44
  return [
35
- `import { DyNTS_AIMock_Fixture } from '@futdevpro/nts-dynamo/ai/ai-mock';`,
45
+ `import { DyNTS_AIMock_Fixture } from '${importPath}';`,
36
46
  '',
37
47
  '/**',
38
48
  ` * ${note}`,
@@ -706,9 +706,19 @@ export class DyNTS_OAI_LLM_ServiceBase extends DyNTS_AI_LLM_ServiceBase {
706
706
  }
707
707
 
708
708
  /**
709
- * Reasoning modell-e (GPT-5.x sor vagy o-series, pl. o1/o3/o4)? Ezek elutasitjak a
710
- * sampling-parametereket (temperature != 1, top_p, frequency/presence_penalty). A `gpt-4o`
711
- * NEM reasoning (a 'gpt-5' prefix nem illeszti, 'o'-prefix sem).
709
+ * ⚠️ **TUL TAG HEURISZTIKA csak FALLBACK, ne ez legyen az igazsag forrasa.**
710
+ *
711
+ * Eredetileg (FR-047) azt felteteleztuk, hogy MINDEN `gpt-5.x` + o-series modell elutasitja a
712
+ * sampling-parametereket. **Live capture 2026-07-21 ezt MEGCAFOLTA:**
713
+ * - elutasit: `gpt-5.5`, `o3-mini`, `o4-mini`
714
+ * - **ELFOGADJA**: `gpt-5.4-mini`, `gpt-5.4-nano` (HTTP 200, `reasoning_tokens: 0`)
715
+ *
716
+ * Vagyis erre a ket modellre ez a regex **NEMAN kidobna ervenyes parametereket** — halkan rontva a
717
+ * kimenetet. Ezert az `applySamplingParams` a **registry `settingsSchema`-t reszesiti elonyben**, es ezt
718
+ * a heurisztikat CSAK akkor hasznalja, ha az adott modellhez nincs schema (regi fsm-verzio / ismeretlen
719
+ * modell). Amint a populalt schema mindenhol elerheto, ez a metodus elhagyhato.
720
+ *
721
+ * Reszletek: `documentations/plans/ai-mocking-system/CAPTURE-FINDINGS.md` §1.
712
722
  */
713
723
  protected isReasoningModel(modelId: string): boolean {
714
724
  return /^gpt-5/.test(modelId) || /^o[0-9]/.test(modelId);
@@ -529,6 +529,46 @@ describe('| DyNTS_ServerStatus_ControlService', () => {
529
529
  expect(result.dbPingOk).toBe(false);
530
530
  });
531
531
 
532
+ // DIAGNOSZTIKA (2026-07-22) — a "readiness 503, de az app kiszolgál" flotta-lelet miatt.
533
+ // A lényeg: a diag-mezők akkor is kitöltődnek, amikor a probe NEM-ready-t jelent — épp AKKOR
534
+ // kellenek, hogy a következő mérés eldöntse, a probe mér-e rosszul vagy a DB halott-e.
535
+ it('| should populate diagnostics fields EVEN when not ready (this is when they matter)', async () => {
536
+ const fakeConnection = {
537
+ readyState: 0,
538
+ db: undefined,
539
+ host: 'mongodb',
540
+ name: 'adventor',
541
+ models: { user: {}, preset: {} },
542
+ };
543
+ spyOn(service as any, 'getMongooseConnection').and.returnValue(fakeConnection);
544
+
545
+ const result = await service.checkDbReadiness();
546
+
547
+ expect(result.ready).toBe(false);
548
+ expect(result.dbHost).toBe('mongodb');
549
+ expect(result.dbName).toBe('adventor');
550
+ // 0 model a default connectionön = a data-layer NEM ezt a handle-t használja (a fő gyanú)
551
+ expect(result.dbModelCount).toBe(2);
552
+ expect(result.dbConnectionCount).toEqual(jasmine.any(Number));
553
+ expect(result.dbOtherReadyStates).toEqual(jasmine.any(Array));
554
+ });
555
+
556
+ it('| should stay ready even if diagnostics collection throws (probe must never fail)', async () => {
557
+ // a diag-gyűjtés SAJÁT try-ban van → a getter-robbanás nem ronthatja el a readiness-választ
558
+ const fakeConnection = {
559
+ readyState: 1,
560
+ db: { admin: () => ({ ping: async () => ({ ok: 1 }) }) },
561
+ get host(): string { throw new Error('diag boom'); },
562
+ };
563
+ spyOn(service as any, 'getMongooseConnection').and.returnValue(fakeConnection);
564
+
565
+ const result = await service.checkDbReadiness();
566
+
567
+ expect(result.ready).toBe(true);
568
+ expect(result.dbReadyState).toBe(1);
569
+ expect(result.dbPingOk).toBe(true);
570
+ });
571
+
532
572
  it('| should NOT be ready when connected but ping fails (DB unresponsive)', async () => {
533
573
  const fakeConnection = {
534
574
  readyState: 1,
@@ -44,6 +44,24 @@ export interface DyNTS_DbReadiness {
44
44
  serverVersion: string;
45
45
  /** AZ APP saját verziója (`DyNTS_global_settings.systemVersion`) — deploy-verifikációhoz. */
46
46
  appVersion?: string;
47
+
48
+ // --- DIAGNOSZTIKA (2026-07-22) — a flotta-szintű "readiness 503, de az app kiszolgál" lelet miatt ---
49
+ // Élesben mérve: az adventor / token-service / master-prompter MIND `dbReadyState:0`-t adott, miközben
50
+ // kiszolgáltak, a Mongo bizonyítottan élt, és a reconnect-guard (amely UGYANEZT a readyState-et olvassa)
51
+ // egyetlen warningot sem logolt. Öt hipotézist zártunk ki méréssel (több replika · két mongoose-példány ·
52
+ // esModule default-export · leszármazott-override · halott DB) — a gyökér-ok NEM dőlt el. Ezek a mezők
53
+ // teszik a KÖVETKEZŐ mérést döntővé, találgatás nélkül. Mind ADDITÍV + opcionális → nem törnek meg semmit.
54
+
55
+ /** Hány mongoose-connection létezik ebben a process-ben (`mongoose.connections.length`). >1 → nem a default-on megy a data-layer. */
56
+ dbConnectionCount?: number;
57
+ /** A default connection cél-hosztja (`connection.host`) — üres/undefined, ha a connect sosem futott le rajta. */
58
+ dbHost?: string;
59
+ /** A default connection adatbázis-neve (`connection.name`). */
60
+ dbName?: string;
61
+ /** Hány model van a default connectionre regisztrálva. 0 → a data-layer NEM ezt a connectiont használja. */
62
+ dbModelCount?: number;
63
+ /** A NEM-default connectionök readyState-jei — ha itt van 1-es, a probe rossz handle-t mér. */
64
+ dbOtherReadyStates?: number[];
47
65
  }
48
66
 
49
67
  export abstract class DyNTS_ServerStatus_ControlService<
@@ -232,6 +250,27 @@ export abstract class DyNTS_ServerStatus_ControlService<
232
250
  dbPingOk = false;
233
251
  }
234
252
 
253
+ // DIAGNOSZTIKA (2026-07-22): sosem dobhat — a probe-nak determinisztikusan kell válaszolnia,
254
+ // ezért a diag-gyűjtés SAJÁT try-ban van (ha bármelyik mező kiolvasása elszáll, a readiness
255
+ // válasz attól még ép marad).
256
+ let diagnostics: Partial<DyNTS_DbReadiness> = {};
257
+ try {
258
+ const conn: mongoose.Connection = this.getMongooseConnection();
259
+ const all: mongoose.Connection[] = mongoose.connections ?? [];
260
+
261
+ diagnostics = {
262
+ dbConnectionCount: all.length,
263
+ dbHost: conn?.host,
264
+ dbName: conn?.name,
265
+ dbModelCount: Object.keys(conn?.models ?? {}).length,
266
+ // a default connectiont kihagyjuk — csak a "van-e MÁSIK, élő handle" kérdés érdekes
267
+ dbOtherReadyStates: all.filter((c: mongoose.Connection): boolean => c !== conn)
268
+ .map((c: mongoose.Connection): number => c?.readyState ?? -1),
269
+ };
270
+ } catch (error) {
271
+ DyFM_Log.warn('(checkDbReadiness) diagnostics collection failed (non-fatal)', error);
272
+ }
273
+
235
274
  return {
236
275
  ready: dbReadyState === 1 && dbPingOk,
237
276
  dbReadyState: dbReadyState,
@@ -239,6 +278,7 @@ export abstract class DyNTS_ServerStatus_ControlService<
239
278
  uptime: +new Date() - +this.up,
240
279
  serverVersion: this.serverVersion,
241
280
  appVersion: this.appVersion,
281
+ ...diagnostics,
242
282
  };
243
283
  }
244
284