Release 6.4.4-pre3
Pre-releaseRelease Notes — Cumulocity Dynamic Mapper v6.4.4
August 2026 · Dynamic Mapper Service
This release adds an AI-generated alternative to code templates when creating Smart
Functions, bundles a connector's connection-lifecycle status transitions into a single
event per connect/disconnect attempt instead of one independent event per status change,
and fixes a bug that left devices permanently unreachable — with repeated error-log
noise — once their auto-created device was deleted from inventory. It also fixes two
Message Explorer bugs — an "Edit session" drawer that could silently fail to close, and
OUTBOUND sessions scoped to a device group never receiving any messages — plus several
follow-on fixes to AI Smart Function generation surfaced while working on the Message
Explorer.
👤 Customer-Facing Changes
Changes that affect what users see or how the product behaves.
✨ New Features
-
Generate Smart Functions with AI instead of a code template #543
- When creating a new Inbound/Outbound mapping with transformation type Smart Function
(JavaScript), the "Select Payload Format and Transformation Type" step now offers an
explicit choice — "Choose Code Template" vs. "Generate with AI" — whenever an AI
agent is deployed for Smart Functions. The choice defaults to "Generate with AI" when an
agent is available, falling back to the template dropdown otherwise. - Generation is deferred until the Transformation step, where the real source/target
templates are available, and triggers automatically the first time that step is reached. - Fixed a related bug along the way: the auto-triggered generation could send a stale
default source template to the AI agent instead of the user's just-edited one, because it
relied on a change-event mirror that didn't fire for all edit paths (e.g. some tree-mode
interactions). It now reads the live content directly from the JSON editor. - Fixed a bug that made AI generation appear to silently do nothing for OUTBOUND Smart
Functions: outbound mappings have no fixed target template by design — the function body
itself builds whatever payload the target broker/protocol expects — but generation
treated the resulting emptytargetTemplateas missing information and had the AI agent
stop and ask a clarifying question instead of generating code, every single time. The
prompt (and the agent's own system prompt) now explain that this is expected and instruct
it to generate directly from the source template and topic instead. INBOUND generation was
also missing a concrete reference for what its target Cumulocity payload should look like
for a knowntargetAPI(e.g.MEASUREMENT) — a standard sample payload is now included. - Fixed "Generate with AI" not auto-opening on the Transformation step when creating a
mapping from a captured message in the Message Explorer — that entry point never
forwarded the user's "Generate with AI" choice into the stepper, so generation silently
never started. Creating a mapping via the normal "+ Add mapping" flow was unaffected. - The AI prompt's very first chat message used to embed the mapping's full JSON (including
managed-object metadata,selflinks, etc.) inline, making it a large, hard-to-read wall
of raw JSON in the transcript. The mapping data is now sent to the agent as hidden
grounding context instead, so the visible chat message is a short, readable sentence.
- When creating a new Inbound/Outbound mapping with transformation type Smart Function
-
Open version history and see draft status directly from the Versions list #546
- The Monitoring → Versions pages (Versions inbound / Versions outbound) now have a
"Versions" row action that opens the existing version-history drawer for that mapping,
instead of requiring a detour through the main Mapping grid. - Added a "Status" column showing a
draftbadge for any mapping with unpublished draft
changes, so pending drafts are visible across the whole list at a glance instead of only
after opening each mapping individually.
- The Monitoring → Versions pages (Versions inbound / Versions outbound) now have a
-
Connector status log now shows one event per connect/disconnect attempt instead of one per status change #547
- Every connector status transition (
CONNECTING,CONNECTED,DISCONNECTING,
DISCONNECTED,RETRYING,FAILED) used to be posted as an independent Cumulocity
event, so a single connect attempt with one retry produced 3–4 unrelated rows in
Monitoring → Service events and the per-connector Details & logs page, with no
way to tell which rows belonged together. Each connection-lifecycle session is now
bundled into a single event that's updated in place as it progresses — the same
"History of changes" pattern Cumulocity Operations use — with an entry-count badge, an
"open"/error indicator, and an expandable compact timeline of that session's
transitions. CONFIGURED(a settle/idle marker, never itself part of a connect/disconnect attempt)
no longer generates its own event at all — it was showing up as an extra, low-signal
bundle on every disconnect/reconnect cycle. The connector's live status display is
unaffected; only the persisted event history changed.- Fixed a related bug found while verifying this in production: the MQTT and AMQP
connectors could report the same physical disconnect twice — once via the explicit
disconnect call, once via the underlying client library's own disconnected/exception
listener firing as a side effect of that same call — which showed up as two separate
sessions instead of one. Every other connector type (Kafka, Pulsar, HTTP, WebHook) was
checked and found not to have this pattern.
- Every connector status transition (
🐛 Bug Fixes
-
Message Explorer: OUTBOUND sessions scoped to a device group never received any messages #551
- Selecting a single device as the OUTBOUND source worked fine, but selecting a device
group silently returned nothing. The service created a single Notification 2.0
subscription on the group's own managed object — which delivers no device events at
all — and then filtered incoming messages by exact equality with the group's own id,
which real device messages (carrying the device's id) could never match anyway. - Fixed by resolving the selected source into its concrete device set (a plain device
resolves to itself, a group expands to every device it contains), subscribing each
resolved device individually, and matching incoming messages by membership in that
resolved set instead of exact-id equality. Session teardown now also unsubscribes the
full expanded device set instead of just the original group id.
- Selecting a single device as the OUTBOUND source worked fine, but selecting a device
-
Message Explorer: "Edit session" drawer could silently fail to close #550
- Editing an OUTBOUND session scoped to a device/group and clicking "Update" without
reselecting a device did nothing — the drawer stayed open with no visible feedback.
The edit drawer restored the session's topic, connector, and other fields from the
existing session, but never restored the previously selected device into the asset
selector, so the Update button stayed disabled the whole time (the click that "did
nothing" was landing on a disabled button). - Fixed by restoring the selected device (and its cached name, to avoid a redundant
inventory lookup) when the edit drawer opens.
- Editing an OUTBOUND session scoped to a device/group and clicking "Update" without
-
Deleted devices left the mapper permanently unable to re-create them #544
- Once a device that the mapper had created implicitly (
createNonExistingDevice: true)
was later deleted from Cumulocity inventory, every subsequent inbound message for the
same external ID kept resolving to the deleted device's stale internal id — forever. This
produced a permanent per-message failure loop: repeated404s from the notification
subscription API, or422 Source object does not exist in inventoryfrom
measurement/event creation, with the device never recreated even though
createNonExistingDevicewas enabled. - Root cause:
TenantRegistry's external-ID resolution cache had no invalidation path —
aremoveFromExternalIdCachemethod existed for exactly this purpose but had never
been wired up to any actual failure path. The mapper's Notification 2.0 stream also
didn't help: it only reacted toUPDATEevents, silently droppingDELETE(and
CREATE) notifications without evicting anything. - Fixed by evicting the stale cache entry as soon as a deletion is discovered — via a real
inventory lookup, via a Notification 2.0DELETEevent (now handled, with the
now-pointless subscription torn down), and via the existing422-retry path in the
inbound message pipeline (which previously cleared a different, unrelated cache). A
message for a deleted device's external ID still hits one failure to discover the
deletion — unavoidable, that's how it's detected — but the very next message now gets a
freshly created device instead of repeating the same failure indefinitely. - Also cleaned up related error-log noise: the same failure was previously logged three
times, with a full stack trace each time, as it propagated up through nested handlers
that just rethrew it unchanged. Now logged once, at the point where it's actually
handled.
- Once a device that the mapper had created implicitly (
⚙️ Internal / Implementation Changes
Refactoring, code-quality, and platform maintenance work with no intended change in
customer-visible behavior.
- Added regression coverage for the device-recreation fix #544
- New unit tests for
TenantRegistry's external-ID cache reverse-index/eviction, for
InventoryCacheEnrichmentService's device-not-found path, and for
CacheInventoryUpdateClient's Notification 2.0DELETEhandling. - New shell integration test
(test-inbound-implicit-device-recreate-after-delete.sh, registered in theinbound
suite): create an implicit device, delete it, resend a message for the same external ID,
and assert a new device is auto-created with a different internal id.
- New unit tests for
Cumulocity Dynamic Mapper · v6.4.4 · August 2026
All releases on GitHub
Full Changelog: v6.4.3...develop