You are not logged in.
Thanks. I opened an issue on your repo, I think it will be better to discuss findings and issues there.
Kokoro-82M now runs natively too, in the same repo: https://github.com/flydev-fr/mormot2-qwen-tts
it is much lighter than qwen3-tts and runs on the CPU only, about 30x real time, with the first sound after ~56 ms. The phonemes come from espeak-ng, loaded at runtime. I checked every stage against the PyTorch reference. The README has the details - feel free to check it.
the code is public now: https://github.com/flydev-fr/mormot2-qwen-tts
the reference you asked for is in tests/data/infer-ref/qwen3-tts-lm, in your infer-ref format. It has embeddings in and logits out for both Qwen3 stacks of the model, computed by PyTorch in float32, so you can drop the folder into mormot2-ai as is.
one more finding: the Vulkan backend caches weights by host address, so weights freed and reallocated at the same address come back stale.
great. I will make a standalone sample and will publish it on github this evening or tomorrow on the morning ![]()
I've done some testing, the goal was for a hobby project, to run a TTS model natively in delphi, no python at all. Model is Qwen3-TTS-12Hz-0.6B-CustomVoice. The setup:
delphi 13, mormot 2.4 trunk, Win64, win11 and an AMD RX 9060 XT gpu through Vulkan.
What I reused from mormot2-ai:
- safetensors loader, Qwen2 BPE tokenizer, CPU backend (AVX2 kernels + thread pool), sampler
- the Vulkan backend: Q8_0 linear shaders, plus rmsnorm, qkrope, attention, swiglu and addnorm, recorded the way TQwen3Vulkan.Chunk does it
What I wrote on top:
- the talker and the code predictor - Qwen3 stacks fed with embeddings instead of token ids
- the 12 Hz audio decoder (causal convolutions, SnakeBeta, sliding-window transformer)
- frame-by-frame streaming to waveOut
The 12 Hz decoder runs on the GPU as well, with four small compute shaders of my own (a tiled conv-as-GEMM with fused epilogues, SnakeBeta, depthwise conv, LayerNorm), built on the TInferVulkan batch API. It is x29 real time on its own, and its wav stays within 5e-6 of PyTorch.
Correctness, checked layer by layer against the official python package (qwen_tts, PyTorch, float32, greedy):
- the decoder wav matches within 2.5e-6
- in FP32 on CPU the generated codes are identical to PyTorch on 4 test sentences (french, english, accents, a 12s text)
Perf, same machine and same model:
python bridge (ROCm) mormot2-ai, native
speed x0.8-1.2 real time x5.9 real time
first sound ~2 s ~95 ms
model load - ~1.4 s
VRAM - ~0.9 GB (Q8_0 talker + F32 decoder)
on disk ~9.5 GB of pytorch nothing but the 2.4 GB modelTalker and code predictor run on Vulkan in Q8_0, about 12 ms per 80 ms audio frame. The CPU-only fallback (Q8_0) still runs the talker at x3.3 real time.
A few things I ran into, just in case it helps someone:
- InferRowToF32 doesn't read BF16, which is the format of the TTS weights - I widened the rows myself
- TBpeTokenizer only loads tokenizer.json. This model ships vocab.json + merges.txt, so I subclassed it and called the protected Build
- TQwen3Vulkan only accepts token ids. An entry point taking embeddings would make it reusable for TTS and multimodal models - for now I just copied the push-constant records to rebuild the same pass
- with the KV cache in F16 my checks drifted by ~2.3e-2 relative, against 2.6e-5 in F32. I keep F32, the context is short anyway
- a TInferThreadPool work item that allocates on the heap gets serialized by the memory manager - a 22-thread Q8 conversion took 3.5s instead of 0.6s, a stack buffer fixed it
great work @sh17 ![]()
edit: a few precisions, the 12 Hz decoder is not entirely on the GPU: the quantizer, the pre-conv and the sliding-window transformer stay on the CPU, only the heavy part (upsampling, ConvNeXt and the convolution blocks) runs on the GPU, and
- decoder wav vs PyTorch: within 2.5e-6 on the CPU, 4.8e-6 on the GPU
You are right! the edition dates currently represent rolling fetch windows rather than calendar days. Fixing it, so each edition covers one complete calendar day.
the marmot is alive - it's my automation, not the data.
github has been firing the scheduled workflow 6-8h late since oct 10 to actual ~10-11 UTC. My review step runs at 06:00 and gives up at 06:49, so the payload lands after its own window and then gets skipped the next morning. I wasn't aware that github cron is best-effort.
Fixed it by letting the llm check more often instead of relying only on the cron. It's running and should be back later this evening ![]()
ps: And I will be back about my last PR you fixed with some others findings ![]()
I wasn't sure, everything is green again - thanks.
not related to this issue, on win11 / delphi 13 this one remains for days and I don't think anyone has reported it:
4.1. Ui pdf: Metafile rendering and orientation: #6 Hash32()=$0EA8AE59 expected=$FE2D27CA ! - Metafile rendering and orientation: 1 / 19 FAILED 239.38ms
I have to go away, I created a gist with the explanation, patch and logs if it helps: https://gist.github.com/flydev-fr/de9c2 … 0222bd54f9
@ab, I wanted to re-pin my current projects on the latest master to get the recently merged fixes (#622, #629), but since yesterday the regression tests fail on Windows, fpc 3.2.3 and Delphi 13 Win64.
Bisected to 2acff7c18 (net: fixed servers main thread startup): the http.sys main thread does not start any more. THttpApiServer.Create forces hsoCreateSuspended so that THttpServerGeneric.Create the main thread suspended, and before said commit it resumed it itself at the end of the constructor.
Do you want I open an issue?
ATM i build it by myself i make pr if its ready
Share!! ![]()
a quick note about a related project: PWeb (or mtron, name isn't decided yet) - github.com/flydev-fr/pweb
it is a desktop runtime for FPC/Lazarus (delphi soon), in the spirit of Electron or Tauri: mormot2 plus the OS WebView (WebView2, WebKitGTK, WKWebView), with a JS, React or pas2js frontend. There is no HTTP between the UI and Pascal. The UI calls regular mORMot 2 interface-based services in-process, through TRestServer.Uri(), with no socket and no port.
If a pas2js implementation would help your work, feel free to look at:
sdk/pas2js - pweb.native.pas: a promise-based Service.Method call with named JSON arguments and typed errors, plus its test suite
examples/05-pas2js - a complete pas2js frontend calling a mormot service
tools/templates/pas2js - the project template
v := await(JSValue, PWebInvoke('CalculatorService.Add', New(['a', 20, 'b', 22])));the transport there is the WebView bridge rather than HTTP, but the call shape is transport-agnostic. It might fit behind a Mustache-generated client.
About mobile: Android and iOS are planned. The first desktop release (Windows, Linux, macOS) should be out very soon, and the mobile targets come next (android_webview, JAVA layer are already set up).
perfect, thanks ![]()
The run/tests are green and the patch file is there: mormot2-2026-09-16-abi-fixes.patch
if everything make sense, I can send a PR if you want.
edit 2: mormot2 regression suite is missing after patch test to really confirm, they should be ran on every platform, I will add them this afternoon.
hi @ab, I am working on tauri-like project and found again ABI issues, I rechecked on current mormot2 commit 5f5bd05 (an hour ago).
[/AI
]
The following three ABI/signature mismatches exists. They are independent, but I am grouping them here because they all concern calling conventions or C/Pascal boundaries. Detailed reports and reproductions are linked below.
1. Currency interface results remain incorrect on SysV x64 and AArch64
Commit 790154af correctly fixed Win64 by retaining the Currency result read from RAX. However, the same ABIX64 block is also used by SysV x64.
The hosted result matrix is:
Windows x86-64: 5 / 5
Linux x86-64: 1 / 5
macOS x86-64: 1 / 5
macOS AArch64: 0 / 5On SysV x64, only the zero-argument method succeeds. Methods with arguments return pointer-shaped values from RAX. The previous XMM0 path did not work either, so merely restoring the former branch would not be a safe correction.
AArch64 still explicitly stores D0 for imvCurrency, but all five measured return cases fail there.
This is not a SysV regression introduced by 790154af: Currency results were already wrong before it. That commit fixed Win64 while leaving the other ABIs unresolved.
Detailed report and reproduction: mormot-imvcurrency-rax-sysv-x64.md
Suggested direction: separate the result handling by ABI and add the five-method Currency matrix to the cross-platform tests. The SysV compiler-generated convention probably needs to be measured before choosing RAX, XMM0, or a hidden result location.
2. JS_SetMaxStackSize takes the wrong opaque pointer type
The Pascal binding still declares:
procedure JS_SetMaxStackSize(ctx: JSContext; stack_size: PtrUInt);The QuickJS header shipped in the same repository declares:
void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);Passing a JSContext where QuickJS expects a JSRuntime makes the C function write the stack limit at a runtime-relative offset inside the context object. This was reproduced as an access violation under allocation pressure. Using an otherwise identical declaration with JSRuntime is stable.
The mechanical correction appears to be:
procedure JS_SetMaxStackSize(rt: JSRuntime; stack_size: PtrUInt);
cdecl; external {$ifdef QJSDLL}QJ{$endif};Detailed report: mormot-quickjs-js-setmaxstacksize-signature.md
3. pas_malloc and pas_malloc_usable_size still truncate size_t on 64-bit targets
The current Pascal exports include:
function pas_malloc(size: cardinal): pointer; cdecl;
function pas_malloc_usable_size(P: pointer): integer; cdecl;The patched QuickJS C header calls them as:
void *pas_malloc(size_t size);
size_t pas_malloc_usable_size(void *ptr);On a 64-bit target, a request above 4 GiB is therefore truncated to its low 32 bits. The allocation may succeed with a much smaller buffer than the C caller requested.
This seems related to issue #324, but the correction made for that issue widened pas_realloc and several libc declarations while leaving pas_malloc and pas_malloc_usable_size unchanged.
Suggested ABI types:
function pas_malloc(size: PtrUInt): pointer; cdecl;
function pas_realloc(P: pointer; size: PtrUInt): pointer; cdecl;
function pas_malloc_usable_size(P: pointer): PtrUInt; cdecl;pas_calloc should use pointer-sized unsigned operands and reject multiplication overflow. The Delphi-local allocator implementations in mormot.lib.quickjs.pas should also be audited because they still use 32-bit sizes and a four-byte stored-size prefix.
Detailed report: mormot-static-pas-malloc-size-t.md
[/AI]
The repo made last month (mormot-fpc-win64-callmethod-unwind) is currently being updated, with patches and added tests that could be included on the framework tests. I'll post to confirm. I thought you might want to take a look since you're working on the assembly code as I write this ![]()
- thread ref: https://synopse.info/forum/viewtopic.php?id=4418
thanks! good timing, I've just been asked to add report generation and pdf export on our backend, and I never touched the pdf side of mormot until now. will give it a try this week.
yes and no. on my side I use fpc only to compile headless and cross-platform. but delphi stays the everyday IDE here for debugging - for me lazarus is terrible.
edit: I must admit I always look at this through the mORMot 2 prism, as it supports both worlds ![]()
Understood, thanks.
@sh17 did I miss something about the "FPC only" note in the README file?
delphi:
Software version tested: 1.0 (2026-09-04 11:53:55)
Generated with: Delphi 12.3 Athens 64 bit Win compiler
Time elapsed for all tests: 2.53s
Performed 4 Sep 2026, 11:54:04 by badb on DESKTOP-5501FNL
Total assertions failed for all test suits: 0 / 892
! All tests passed successfully.fpc:
Software version tested: 1.0 (2026-09-04 11:53:52)
Generated with: Free Pascal 3.2.3 64 bit Win compiler
Time elapsed for all tests: 2.46s
Performed 4 Sep 2026, 11:54:01 by badb on DESKTOP-5501FNL
Total assertions failed for all test suits: 0 / 892
! All tests passed successfully.I had to fix a small inconsistent check (ansi vs utf8).
yes, this tool is useful!
If any of you have ideas on how to set up the workflows for code review, I'll take them - my attempts fail so far, and it's a cost and logic problem.
"edition": "2026-09-03",
"totals": {
"commits": 22,
"sessions": 61,
"cost_usd": 54.5882,
"turns": 1198,
"seconds": 11152
}$54 and 1198 turns on claude-opus_&_sonnet-5, for one day of commits. 3 hours of model time
I should probably go read how Mozilla runs their security tooling minus Mythos llm ![]()
PS: it runs on a personal subscription so those dollars are an API-list equivalent, not a bill. Just a way to compare runs.
on delphi 12.3 and win11, your first SizeCheck program returns and no exception triggered.
SizeOf(TRWLightLock) = 4
SizeOf(Windows.TSystemTime) = 16
SizeOf(mormot.core.os.TSystemTime) = 16Sorry, merged, thanks ![]()
site update:
the digest is now in 4 languages - english, french, chinese and russian. @zen010101 chinese is in
new UI, denser, and readable on a phone now
what do you think about it?
@ab your correction is in. The model reasoned fine about pascal semantics and just never opened the body of the function.
What about not only a sumup but a code review, to identify any security issue or potential regression?
Perhaps too many false positives...
I have that in mind since some time but.. two things were a blocker.
first, the false positives, imo gemini would produce far too many on this codebase - the ones that hold up on mormot2 at this level are opus-5, gpt-5.6 and qwen-3.8.
second, no api key on my side. So I will run it on a personal subscription, with opus, through claude-code-action. No idea what that eats in tokens, honestly - that is a good part of what I want to find out.
I also added a custom build of tokensave to the CI, patched so it indexes the framework .inc files and not only the .pas ones. mormot2 keeps ~61k lines in 15 .inc files - the whole posix/windows layer - and without the patch the code graph is blind exactly where it matters. I checked the parse before wiring it (fresh rebase on this morning): mormot.core.os.posix.inc gives 764 routines, os.windows.inc 612, as clean as a normal unit. Should help a lot on "who calls this", which is the question the reviewer keeps needing.
and what filters is not the model, it is the bar:
a finding must quote the code that proves it, verbatim. A script re-reads that file at that sha and rejects the finding when the quote is not in it
a finding must name a public entry point that reaches the defect, with the call quoted too. No path, it goes to an "unverified" bucket instead
then it spends a pass trying to refute its own finding, and writes down what it checked
the workflow (pipeline):
one session per commit, as a matrix - 25 commits, 25 isolated sessions, each with mORMot2 checked out at its own sha, so it can open a whole function body and git grep the callers. Each run returns its own usage, so it gets logged and I can show it.
one more thing on the "potential regression" part. An edition is a window closed at midnight, but the code settles over several days - a change can land one morning and get its own fix a few commits later, which happened this week on the wake-up path rewritten at 16617/16618 and fixed at 16623. A one-day view cannot see that, so recommending the first revision is simply wrong.
The payload now looks ahead: for each commit, the later commits touching the same routines, flagged when they look like a fix - thanks @landrix ![]()
so tomorow the next CI job will ran on claude and then next is running some days or a week and posting what it found and what it cost. Misses included.
I had scheduled another LLM on the same commits, and this morning I got this one: https://github.com/flydev-fr/mormot2-da … 5285473602
imo it's more relevant, especially on the mistake you pointed out - it got the `var variant` part right:
(the #3 - MEDIUM: ORM Variant lifetime leak fixed, plus TOrmTable Variant-generation refactoring)
And it links to your blog post from yesterday. I'll let both run in parallel for a few days and compare before picking one but I think this last is far more specific.
I fixed the gitHub URL.
I'll add the Chinese version @zen ![]()
I will put a link to my boss so that he knows what I did everyday.
![]()
Hi, friday afternoon ai driven fun: a small static site that reads the day's commits from synopse/mormot2 upstream and rewrites them for people who don't have the internals in their head - what changed, what it means for an existing Delphi/FPC backend, and whether you actually need to do anything about it.
https://github.com/flydev-fr/mormot2-daily-dev or https://mormot2daily.fsb.dev/
How it works: every morning a job pulls the new commits with their diffs, an AI agent reads them and writes a structured summary, and that summary is schema-validated before anything gets published. There's an RSS feed if you'd rather read it with your coffee and a JSON feed.
The caveat: the summaries are machine-written and can be wrong. Every entry links to its commit, and the commit is the source of truth. Entries are tagged *interpretation* when the reviewer is reasoning about consequences rather than reporting what the diff actually says, and *auto-classified* when a day didn't get reviewed at all. You should know which sentences to trust.
Today's edition, for a taste: the async thread wake-up went lockless, `TOrmTable.GetAsVariant` quietly changed from `out` to `var`, and `Lecuyer` moved units.
If it's useful I'll keep it running. It will be improved from time to time.
Have a nice weekend ![]()

@ab the probe against pristine 896f1c1, with none of the patches applied, is fully green, thanks ![]()
Sure, you can grab it from github: x64callmethod.o
It's assembled from src/x64callmethod.asm with ml64, .debug$S stripped and timestamp zeroed; CI only publishes it after it passed the full suite in a linked executable.
You can also rebuild it with pwsh tools/make-dist.ps1.
Two notes about this one:
1. it contains both fixes: unwind metadata and imvCurrency RAX
2. it hard-codes TCallMethodArgs layout
@ab the repo is available here: https://github.com/flydev-fr/mormot-fpc … hod-unwind
Context: I am developing Tauri-like desktop runtime using mormot2 directly in-process. Since the app does not use http or sockets, its RPC layer calls registered SOA through TRestServer.Uri(), which exposed the FPC Win64 CallMethod() problem.
There is also a github actions running on windows-latest. It install the required toolchain (fpc and msvc), first reproduces the two issues against the mormot code, then applies the MASM replacment and runs the full patched test suite.
The corresponding CI run and its summary are available here:
https://github.com/flydev-fr/mormot-fpc … 1578488309
PS: the exact pinned mormot version isn't particularly important here.
Edit: x64callmethod.asm live in "src" folder
I hit this exact FPC/Win64 issue yesterday with mormot2, on version 3.2.2 and 3.2.3. I found a workaround which seems to fix the exception unwinding reliably. I have also been able to reproduce and test a small MASM replacment quite extensively with regression test around it (one additional issue appeared during that testing about fpc returns imvCurrency through RAX).
If you are interested, I can post the details and I can clean this into a minimal standalone patch/test case on a github repo?
You really deserve all the credit for sticking with it and working so hard to understand those mormots ![]()
Over these past two years, we’ve seen your questions become more and more specific and it really shows how much effort and persistence you’ve put into learning and understanding it.
Congrats to you!!
Just cross linking two threads here for reference:
https://synopse.info/forum/viewtopic.ph … 620#p41620 (mormot.i18n.pas)
https://synopse.info/forum/viewtopic.php?id=7337
I can't wait for i18n support to be added to ![]()
Done. PS: I have no idea what I’m doing when it comes to licensing ![]()
The docs site is live, it should be easier to read than the md files on github.
And a small note on what is Nanobot in mormot-ai-sdk/ex/nanobot-sdk, it's an example of an autonomous personal AI assistant, like openclaw - it can interact with your computer files, using browser, etc and show how to use the current mormot.ai sdk.
Hi all,
@sh17 sorry for the delay
Following up on my last post - the code goes public today: https://github.com/flydev-fr/mormot.ai
Two independent pieces under the mormot.ai.* namespace, both mormot2 only, no external dependencies:
1. LiteLLM SDK port (mormot.ai.litellm.*): Its an unified LLM client - one call, any provider.
2. pgvector / RAG stack: Vector search and RAG over pascal source code: TPgVector binary wire-format codec, a pascal source chunker, an embedding-client interface, hybrid retrieval blending cosine similarity and PostgreSQL tsvector, a RAG orchestrator, and three CLI programs, and an attempt to ingest mormot2 code and build a chatbot using ollama/devstral-2, actually working.
There is a full docs site covering both parts: https://mormot-ai.fsb.dev
(serving the published "docs" folder).
Fair warning: the code works but is not finished, and the docs track it closely rather than exactly. Usable, not perfect.
Bonus: this documentation site is built and served with Mormotsaurus, a small CLI tool for authoring and publishing static documentation sites - itself written with mormot2 mvc layer. Windows and Linux binaries are in the repo for now; it will get its own repository soon.
Isn't fable5 trained on @ab code ?! ![]()
Hello,
@sh17 I will push what I have. Also, @ab is right, JP's neural-api is really great!
That works for me - and I'll check what you did with the sqlite-vec extension, since I'm very interested in it and for sure will complete the db vector adaptors nicely (see below).
Back in May, while working on my LiteLLM port, I also wrote some code around LLMs, RAG, and similar topics, but targeting PostgreSQL through custom bindings for pgvector/pgvector - there are only abstract classes for sqlite.
I don’t think I've pushed any of that code to github yet, but i'll definitely do it soon (I'm currently on vacation). And I just remember that the namespace was already `mormot.ai.*`, and I think I had started working on a complete set of ai-related units, similar to what you mentioned in your first post. See:

Thanks. Yes, the extensions are meant to be written using mormot only. The spec revision will be updated next week to the latest version.
Regarding authorization, it is indeed planned and will follow MCP security/authorization, with optional support for our secure RESTful authentication scheme.
I don’t know about @ab’s decision, but FYI, a few weeks ago I wrote a mormot-only port of LiteLLM to add an AI gateway providing simplified model access. It is still not polished, as I was missing the now-available streamable HTTP transport and will be pushed to the extensions repo soon.
Do not hesitate to reuse any code and to let use know about any update on your side ![]()
edit: small note,
(incl. the Claude CLI demo). That directly answers the streaming question from my post.
This demo use the mormot.ext.os extension, more info there.
Hey @sh17, did you checked my mcp extension there? I pushed a new update 4 days ago that add streamable-http transport support (up to 2025-03-26 version and will be very soon updated to the latest).
Cross-platform. Fully testable. You can find also some demos.
And here I am, missing yet another event.. This time it was actually geographically accessible, but I moved to the Balkans four days ago. meh ![]()
mORMot 2 wins the Niklaus Wirth Award 2026
Insane - and absolutely deserved.
If by vscode you mean the Claude code, codex or gemini ide extension or the integrated terminal, then yes.
bravo! ![]()
hey @zen - small question, once the workflow architecture is complete, did you scaffold the project with vanilla claude agents by just running /bmad-create-story ?
To test BMAD this afternoon, I have reset my claude installation, installed BMAD and mormot2-superpowers plugin. Then ran BMAD on a new project and once BMAD finished, I ran /bmad-help and then it started using mormot2-superpowers on the BMAD architecture document.
Architecture workflow complete. All 8 steps signed off, frontmatter sealed: stepsCompleted: [1..8],
status: complete, completedAt: 2026-05-14.What we built together
A 30 + KB architecture document at _bmad-output/planning-artifacts/architecture.md that takes the PRD's 55 FRs and ~45 NFRs and lays them out as a concrete, implementable system:
...
Persistent memory written this session- feedback-fpc-toolchain.md — FPC 3.2.3-fixed path
- feedback-no-ifdef-fpc.md — mORMot 2 abstracts compiler divergence
- feedback-mormot2-tests-as-docs.md — test/ + ex/ as the canonical reference
- feedback-mormot2-track-master.md — track master, not stable tags; local clone is truth
- project-license-deprio.md — license work deprioritized for v1
- reference-mormot-soa-blogs.md — Synopse SOA blog + forum #3621 URLsNext concrete steps
1. Run Skill: mormot2-superpowers:mormot2-init to scaffold .claude/mormot2.config.json with the FPC 3.2.3-fixed path
and the mORMot 2 + mormot-extensions search paths.
...
btw - started at 12:45 and it just finished (almost 10 hours non-stop) - all tests are greens and I didn't write a single line of code written (sadly..) and still not reviewed the code but I must admit BMAD is powerful (I was using cavekit blueprints which is a bit similar but not powerful as BMAD is from what I feel).
Yes of course, and what you mean by "the service cannot work properly"? Try to first accept un-safe cert from the browser, I mean, just open the url of the service api call on a browser-tab, accept un-safe connection once, then api calls will work.
// - secTLS will use HTTPS secure connection (user-provided self-signed or not)
// - secTLSSelfSigned will use HTTPS secure connection with a (temporary) self-signed certificate (will generate an temporary self-signed certificate at startup)
it's expected for a self-signed certificate, you should be able to read SEC_E_CERT_UNKNOWN / error 87. It means windows/SChannel cannot validate the certificate chain or certificate trust state. Ignore at debugger level. You can also add the certificate to your host store and test again (for the science..).
I just reproduce in Linux with 8 threads, need to click for a long time :-), and yes happen after Begin/End CurrentThread.
yes ok - confirmed on my side too.
Im not on computer atm, will tell you that in an hour or so as I dont remember.
I reproduced it with sample on #60 - on Delphi 12.3 (not tested against fpc yet) and only with useHttpSocket. If you set thread pool to, eg. 8 you can get the issue quite fast. On delphi, debugger almost stay silent and program hung. If an instance of the services is registered on server, with the orm instance passed on constructor, then the debugger can catch the AV easily on delphi 12.3.