Skip to content

[codex] Expose host-owned runtime IDs through core runtime flows#740

Open
rahulkarajgikar wants to merge 4 commits intotruffle-ai:mainfrom
rahulkarajgikar:host-runtime-id
Open

[codex] Expose host-owned runtime IDs through core runtime flows#740
rahulkarajgikar wants to merge 4 commits intotruffle-ai:mainfrom
rahulkarajgikar:host-runtime-id

Conversation

@rahulkarajgikar
Copy link
Copy Markdown
Collaborator

@rahulkarajgikar rahulkarajgikar commented Apr 15, 2026

Summary

  • add a core hostRuntime runtime surface for host-owned IDs and normalize/validate it in one place
  • thread host runtime IDs through agent runtime config, events, sessions, hooks, tools, and telemetry propagation
  • add regression coverage for the new runtime propagation paths and hoist two slow CLI test imports so repo-wide test runs stay deterministic under load

Why

Host-owned runtime IDs were not represented consistently across core runtime flows. That made it hard for hosts to attach their own runtime identifiers and have those IDs survive through events, telemetry, session logging, and related execution contexts.

Impact

Core consumers can now pass host-owned runtime IDs once and receive them back consistently in runtime-adjacent surfaces. Telemetry baggage/span attributes and emitted runtime events now carry the same normalized host runtime identifiers.

Root Cause

Core runtime flows did not have a single typed surface for host-provided runtime IDs, so propagation behavior had to be inferred or reimplemented at individual call sites.

Validation

  • bash scripts/quality-checks.sh build all
  • bash scripts/quality-checks.sh openapi-docs all
  • bash scripts/quality-checks.sh test all
  • bash scripts/quality-checks.sh lint all
  • bash scripts/quality-checks.sh typecheck all
  • bash scripts/quality-checks.sh hono-inference all

Closes #735.

Summary by CodeRabbit

Release Notes

  • New Features
    • Host-owned runtime identifiers (runId, attemptId) are now supported and automatically propagated through events, hooks, session logging, tool execution, and telemetry for improved tracing and orchestration correlation.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 15, 2026

@rahulkarajgikar is attempting to deploy a commit to the Shaunak's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 15, 2026

📝 Walkthrough

Walkthrough

This PR introduces first-class support for host-owned runtime IDs (e.g., runId, attemptId) throughout the core runtime. It widens configuration layers to accept hostRuntime alongside usageScopeId, threads these IDs through agent lifecycle, event emission, session logging, and OpenTelemetry baggage propagation for end-to-end correlation.

Changes

Cohort / File(s) Summary
Host Runtime Infrastructure
packages/core/src/runtime/host-runtime.ts, packages/core/src/runtime/index.ts
New modules defining HostRuntimeContext/HostRuntimeIds types, Zod validation schemas, and utilities to normalize, extract from baggage, and propagate IDs via OpenTelemetry baggage entries and span attributes.
Agent Config & Creation
packages/agent-config/src/resolver/to-dexto-agent-options.ts, packages/agent-config/src/resolver/to-dexto-agent-options.test.ts, packages/agent-management/src/AgentFactory.ts, packages/agent-management/src/agent-creation.ts
Widened runtimeOverrides type across all layers to accept hostRuntime in addition to usageScopeId. Added test case validating nested hostRuntime.ids handling.
Core Agent Implementation
packages/core/src/agent/DextoAgent.ts, packages/core/src/agent/runtime-config.ts, packages/core/src/agent/types.ts, packages/core/src/agent/index.ts
Added optional hostRuntime field to AgentRuntimeSettings and DextoAgentConfigInput. Extended DextoAgent to normalize, store, and inject hostRuntime into tool execution contexts, event emission, and response shaping. Re-exported HostRuntimeContext/HostRuntimeIds types.
Event System
packages/core/src/events/index.ts, packages/core/src/events/index.test.ts
Introduced HostRuntimeTypedEventEmitter that intercepts emit() calls to inject hostRuntime into payloads. Changed AgentEventMap/SessionEventMap from interfaces to WithHostRuntime<...> mapped types. Updated AgentEventBus, SessionEventBus, and TypedEventEmitter to extend new emitter. Added test validating hostRuntime.ids in event payloads.
Sessions & Session Logging
packages/core/src/session/chat-session.ts, packages/core/src/session/session-manager.ts, packages/core/src/session/session-manager.test.ts
Extended SessionLoggerFactory options to include optional hostRuntime. Updated session creation to pass hostRuntime from runtime config to session logger. Added test verifying session logger receives host runtime context.
Hooks
packages/core/src/hooks/types.ts, packages/core/src/hooks/manager.ts, packages/core/src/hooks/manager.test.ts
Added optional hostRuntime field to HookExecutionContext. Updated executeHooks() to retrieve full runtime config (including hostRuntime) instead of just LLM config and inject it into hook context. Added test verifying hook context includes host runtime IDs.
Telemetry
packages/core/src/telemetry/decorators.ts, packages/core/src/telemetry/utils.ts, packages/core/src/telemetry/utils.test.ts
Refactored span enrichment in decorators to extract hostRuntime from baggage and set corresponding span attributes. Updated getBaggageValues to include hostRuntime from context. Extended addBaggageAttributesToSpan to set attributes from getHostRuntimeAttributes(). Added comprehensive tests.
Tools & Tools Execution
packages/core/src/tools/types.ts
Added optional hostRuntime field to ToolExecutionContextBase to enable tools to access host-provided runtime context.
Public API Exports
packages/core/src/index.ts, packages/core/src/index.browser.ts
Added top-level re-export export * from './runtime/index.js' and explicit type exports for HostRuntimeContext/HostRuntimeIds to make them available through main package entry point.
Test Utilities
packages/cli/src/cli/modes/cli.test.ts, packages/cli/src/cli/utils/config-validation.test.ts, packages/core/src/agent/DextoAgent.lifecycle.test.ts, packages/server/src/hono/__tests__/test-fixtures.ts
Refactored test scoping to declare shared variables at module level and populate once in beforeAll. Updated test fixtures to accept hostRuntime in runtimeOverrides. Added new lifecycle test validating tool execution context includes host runtime IDs.
Changeset
.changeset/host-runtime-ids-through-core.md
New changeset documenting patch-level updates to @dexto/core, @dexto/agent-config, @dexto/agent-management for host runtime ID propagation.

Sequence Diagram

sequenceDiagram
    participant Host
    participant Agent as DextoAgent
    participant EventBus
    participant Telemetry
    participant Tools

    Host->>Agent: createAgent(options.runtimeOverrides.hostRuntime)
    Agent->>Agent: validateConfig() + normalizeHostRuntimeContext()
    Agent->>Agent: store hostRuntime in private field
    
    Note over Agent: During execution...
    
    Agent->>EventBus: emit(event) with hostRuntime in config
    EventBus->>EventBus: HostRuntimeTypedEventEmitter.emit()
    EventBus->>EventBus: inject hostRuntime into payload
    EventBus->>Host: event payload with hostRuntime { ids }
    
    Agent->>Telemetry: stream() / generate()
    Telemetry->>Telemetry: buildHostRuntimeBaggageEntries(hostRuntime)
    Telemetry->>Telemetry: merge into baggage before sessionId
    
    Agent->>Tools: setToolExecutionContextFactory()
    Tools->>Tools: tool context includes hostRuntime.ids
    Tools->>Host: toolContext { sessionId, hostRuntime }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • feat: add OTEL telemetry #412 — Main PR extends the telemetry instrumentation foundation (decorators.ts, utils.ts) to propagate hostRuntime via OpenTelemetry baggage and span attributes, building directly on prior telemetry plumbing work.
  • cleanup: make usage scope explicit runtime config #676 — Main PR extends the runtime-overrides flow introduced in #676 by widening the same agent-creation and to-dexto-agent-options paths to also carry hostRuntime alongside usageScopeId.
  • Updated telemetry metrics #444 — Both PRs modify the same telemetry and baggage correlation paths (packages/core/src/telemetry/*) to add runtime metadata propagation through spans and context.

Poem

🐰 A host whispers IDs through the core,
RunIds and attempts, now tracked evermore!
Through events and telemetry, baggage they flow,
Each tool and each hook now has context to know,
Runtime awareness, from surface to floor! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.46% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title '[codex] Expose host-owned runtime IDs through core runtime flows' directly and clearly describes the main objective of adding first-class support for host-owned runtime IDs throughout core runtime surfaces.
Linked Issues check ✅ Passed The PR fully implements issue #735's acceptance criteria: hosts can pass stable runtime IDs, those IDs are surfaced through event emission, logging/telemetry, tool execution, and session/runtime plumbing, and the design remains generic across runtimes.
Out of Scope Changes check ✅ Passed All changes directly support the core objective of exposing host-owned runtime IDs: type expansions to accept hostRuntime, implementation of host runtime propagation through events/hooks/tools/telemetry, test coverage, and CLI test refactoring for determinism.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

# Conflicts:
#	packages/cli/src/cli/modes/cli.test.ts
#	packages/cli/src/cli/utils/config-validation.test.ts
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dexto-docs Ready Ready Preview, Comment Apr 15, 2026 1:42pm

Request Review

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
packages/core/src/index.ts (1)

92-93: Prefer explicit runtime re-exports at the package root.

Adding another export * here means anything later added to packages/core/src/runtime/index.ts silently becomes part of @dexto/core's public API. Re-export the intended host-runtime symbols explicitly so the root surface stays deliberate.

As per coding guidelines: "Use selective barrel strategy: only add index.ts at real public module boundaries; prefer direct imports internally and avoid deep re-export chains" and "Avoid wildcard exports; prefer explicit named exports in all TypeScript files".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/index.ts` around lines 92 - 93, Replace the wildcard
re-export "export * from './runtime/index.js'" with explicit named exports so
the public surface is deliberate: open the runtime barrel
(packages/core/src/runtime/index.ts) and list each host-runtime symbol to
re-export (for example HostRuntime, RuntimeConfig, startRuntime, createHost —
use the actual exported identifiers from that file), then update
packages/core/src/index.ts to export those names instead of using "export *".
Ensure you remove the wildcard export and only re-export the intended symbols so
new additions to runtime/index.ts don't inadvertently become public API.
packages/core/src/runtime/host-runtime.ts (1)

59-76: Potential duplicate baggage entries for well-known keys.

When a well-known key (e.g., runId) is present, it's emitted twice: once with the prefix (hostRuntime.ids.runId) and once without (runId). This is intentional for compatibility, but consider documenting this behavior in a comment to clarify why both entries are created.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/runtime/host-runtime.ts` around lines 59 - 76, The
getHostRuntimeBaggageEntries function currently emits two baggage entries for
well-known keys (one prefixed with HOST_RUNTIME_ENTRY_PREFIX and one bare) which
can look like duplicates; add a concise inline comment above the loop in
getHostRuntimeBaggageEntries explaining that this duplication is intentional for
backward compatibility (preserving both legacy bare keys and new prefixed keys),
referencing HOST_RUNTIME_ENTRY_PREFIX, isWellKnownHostRuntimeIdKey and
HostRuntimeContext so future readers understand why both entries (e.g., runId
and hostRuntime.ids.runId) are created.
packages/core/src/events/index.ts (1)

1033-1063: Consider adding explicit return type annotation for clarity.

The HostRuntimeTypedEventEmitter logic is sound—it correctly guards against non-object payloads and avoids overwriting existing hostRuntime fields. However, the type assertion on lines 1057-1059 could be simplified.

One minor observation: the isEventPayloadObject guard correctly excludes arrays and nulls but allows Date, Error, and other object subclasses. This should be fine for event payloads in practice, but worth noting.

♻️ Optional: Simplify the type assertion
-        const argsWithHostRuntime = [
-            { ...payload, hostRuntime: this.hostRuntime } as TEventMap[K],
-        ] as TEventMap[K] extends void ? [] : [TEventMap[K]];
+        const augmentedPayload = { ...payload, hostRuntime: this.hostRuntime };
+        return super.emit(event, augmentedPayload as TEventMap[K]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/events/index.ts` around lines 1033 - 1063, The emit method
in HostRuntimeTypedEventEmitter can avoid the noisy conditional assertion by
creating a typed payload-with-host and explicitly typing the args tuple: after
validating payload with isEventPayloadObject, build const payloadWithHost = {
...payload, hostRuntime: this.hostRuntime } as TEventMap[K] and then create
const argsWithHostRuntime: TEventMap[K] extends void ? [] : [TEventMap[K]] =
[payloadWithHost] as any; finally call return super.emit(event,
...argsWithHostRuntime); keep the emit return type as boolean and ensure the
local constants reference HostRuntimeTypedEventEmitter.emit,
isEventPayloadObject, payloadWithHost and argsWithHostRuntime for clarity.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/hooks/manager.ts`:
- Around line 171-173: runtimeConfig is returning a mutable hostRuntime object
from options.stateManager.getRuntimeConfig(options.sessionId) and you're passing
that reference into untrusted hook code; defensively clone hostRuntime (and its
ids array) before exposing it to hooks so hooks cannot mutate runtime
identifiers. Locate where runtimeConfig (and llmConfig) and hostRuntime are
retrieved in manager.ts (the call to options.stateManager.getRuntimeConfig) and
replace the direct reference with a cloned copy (e.g., a shallow clone of the
hostRuntime object plus a copy of hostRuntime.ids) and pass that clone into the
hook invocation instead of the original.

In `@packages/core/src/session/chat-session.ts`:
- Around line 156-158: The SessionEventBus is being constructed with a
non-session-scoped host runtime
(this.services.stateManager.getRuntimeConfig().hostRuntime), which can emit
events with incorrect correlation IDs; change the binding to use the
session-scoped runtime config instead (e.g.
this.services.stateManager.getSessionRuntimeConfig().hostRuntime or the
equivalent session-scoped accessor) when creating the SessionEventBus so events
carry the session's hostRuntime/correlation info.

In `@packages/core/src/telemetry/decorators.ts`:
- Around line 113-144: Compute a single resolved host-runtime context and runId
before setting span attributes instead of writing them from two separate
sources; e.g., create a resolvedHostRuntime by explicitly choosing precedence
between the incoming hostRuntime param and contextObj?.hostRuntime and derive a
single resolvedRunId (prefer resolvedHostRuntime.ids.runId if present, else
contextObj?.runId, else hostRuntime runId), then call
getHostRuntimeAttributes(resolvedHostRuntime) once and set both 'runId' and
'hostRuntime.ids.runId' (and their baggage keys) from resolvedRunId so
span.setAttribute and baggage keys remain consistent (affects code around
getHostRuntimeAttributes, contextObj, componentName, and runId usage).

---

Nitpick comments:
In `@packages/core/src/events/index.ts`:
- Around line 1033-1063: The emit method in HostRuntimeTypedEventEmitter can
avoid the noisy conditional assertion by creating a typed payload-with-host and
explicitly typing the args tuple: after validating payload with
isEventPayloadObject, build const payloadWithHost = { ...payload, hostRuntime:
this.hostRuntime } as TEventMap[K] and then create const argsWithHostRuntime:
TEventMap[K] extends void ? [] : [TEventMap[K]] = [payloadWithHost] as any;
finally call return super.emit(event, ...argsWithHostRuntime); keep the emit
return type as boolean and ensure the local constants reference
HostRuntimeTypedEventEmitter.emit, isEventPayloadObject, payloadWithHost and
argsWithHostRuntime for clarity.

In `@packages/core/src/index.ts`:
- Around line 92-93: Replace the wildcard re-export "export * from
'./runtime/index.js'" with explicit named exports so the public surface is
deliberate: open the runtime barrel (packages/core/src/runtime/index.ts) and
list each host-runtime symbol to re-export (for example HostRuntime,
RuntimeConfig, startRuntime, createHost — use the actual exported identifiers
from that file), then update packages/core/src/index.ts to export those names
instead of using "export *". Ensure you remove the wildcard export and only
re-export the intended symbols so new additions to runtime/index.ts don't
inadvertently become public API.

In `@packages/core/src/runtime/host-runtime.ts`:
- Around line 59-76: The getHostRuntimeBaggageEntries function currently emits
two baggage entries for well-known keys (one prefixed with
HOST_RUNTIME_ENTRY_PREFIX and one bare) which can look like duplicates; add a
concise inline comment above the loop in getHostRuntimeBaggageEntries explaining
that this duplication is intentional for backward compatibility (preserving both
legacy bare keys and new prefixed keys), referencing HOST_RUNTIME_ENTRY_PREFIX,
isWellKnownHostRuntimeIdKey and HostRuntimeContext so future readers understand
why both entries (e.g., runId and hostRuntime.ids.runId) are created.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 19c17ed5-3568-4526-80e8-9ec13860052d

📥 Commits

Reviewing files that changed from the base of the PR and between 9710d2e and cc88e8b.

📒 Files selected for processing (29)
  • docs/static/openapi/openapi.json
  • packages/agent-config/src/resolver/to-dexto-agent-options.test.ts
  • packages/agent-config/src/resolver/to-dexto-agent-options.ts
  • packages/agent-management/src/AgentFactory.ts
  • packages/agent-management/src/agent-creation.ts
  • packages/cli/src/cli/modes/cli.test.ts
  • packages/cli/src/cli/utils/config-validation.test.ts
  • packages/core/src/agent/DextoAgent.lifecycle.test.ts
  • packages/core/src/agent/DextoAgent.ts
  • packages/core/src/agent/index.ts
  • packages/core/src/agent/runtime-config.ts
  • packages/core/src/agent/types.ts
  • packages/core/src/events/index.test.ts
  • packages/core/src/events/index.ts
  • packages/core/src/hooks/manager.test.ts
  • packages/core/src/hooks/manager.ts
  • packages/core/src/hooks/types.ts
  • packages/core/src/index.browser.ts
  • packages/core/src/index.ts
  • packages/core/src/runtime/host-runtime.ts
  • packages/core/src/runtime/index.ts
  • packages/core/src/session/chat-session.ts
  • packages/core/src/session/session-manager.test.ts
  • packages/core/src/session/session-manager.ts
  • packages/core/src/telemetry/decorators.ts
  • packages/core/src/telemetry/utils.test.ts
  • packages/core/src/telemetry/utils.ts
  • packages/core/src/tools/types.ts
  • packages/server/src/hono/__tests__/test-fixtures.ts

Comment on lines +171 to 173
const runtimeConfig = options.stateManager.getRuntimeConfig(options.sessionId);
const llmConfig = runtimeConfig.llm;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Defensively clone hostRuntime before exposing it to hooks.

Line 178 passes a mutable reference from runtime config into untrusted hook code. A hook can mutate hostRuntime.ids and corrupt correlation identifiers for later flows.

🔧 Proposed fix
-        const context: HookExecutionContext = {
+        const hostRuntime =
+            runtimeConfig.hostRuntime === undefined
+                ? undefined
+                : {
+                      ...runtimeConfig.hostRuntime,
+                      ids: runtimeConfig.hostRuntime.ids
+                          ? { ...runtimeConfig.hostRuntime.ids }
+                          : undefined,
+                  };
+
+        const context: HookExecutionContext = {
             sessionId: options.sessionId ?? undefined,
             userId: asyncCtx?.userId ?? undefined,
             tenantId: asyncCtx?.tenantId ?? undefined,
-            hostRuntime: runtimeConfig.hostRuntime,
+            hostRuntime,
             llmConfig,
             logger: this.logger,

Also applies to: 178-178

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/hooks/manager.ts` around lines 171 - 173, runtimeConfig is
returning a mutable hostRuntime object from
options.stateManager.getRuntimeConfig(options.sessionId) and you're passing that
reference into untrusted hook code; defensively clone hostRuntime (and its ids
array) before exposing it to hooks so hooks cannot mutate runtime identifiers.
Locate where runtimeConfig (and llmConfig) and hostRuntime are retrieved in
manager.ts (the call to options.stateManager.getRuntimeConfig) and replace the
direct reference with a cloned copy (e.g., a shallow clone of the hostRuntime
object plus a copy of hostRuntime.ids) and pass that clone into the hook
invocation instead of the original.

Comment on lines +156 to +158
this.eventBus = new SessionEventBus(
this.services.stateManager.getRuntimeConfig().hostRuntime
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use session-scoped runtime config when binding SessionEventBus host runtime.

This currently binds hostRuntime from non-session-scoped config. If session runtime differs, emitted events can carry incorrect correlation IDs.

Suggested fix
-        this.eventBus = new SessionEventBus(
-            this.services.stateManager.getRuntimeConfig().hostRuntime
-        );
+        this.eventBus = new SessionEventBus(
+            this.services.stateManager.getRuntimeConfig(this.id).hostRuntime
+        );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.eventBus = new SessionEventBus(
this.services.stateManager.getRuntimeConfig().hostRuntime
);
this.eventBus = new SessionEventBus(
this.services.stateManager.getRuntimeConfig(this.id).hostRuntime
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/session/chat-session.ts` around lines 156 - 158, The
SessionEventBus is being constructed with a non-session-scoped host runtime
(this.services.stateManager.getRuntimeConfig().hostRuntime), which can emit
events with incorrect correlation IDs; change the binding to use the
session-scoped runtime config instead (e.g.
this.services.stateManager.getSessionRuntimeConfig().hostRuntime or the
equivalent session-scoped accessor) when creating the SessionEventBus so events
carry the session's hostRuntime/correlation info.

Comment on lines +113 to +144
for (const [key, value] of Object.entries(getHostRuntimeAttributes(hostRuntime))) {
span.setAttribute(key, value);
}

const contextObj =
this && typeof this === 'object'
? (this as {
name?: string;
runId?: string;
hostRuntime?: HostRuntimeContext | undefined;
constructor?: { name?: string };
})
: undefined;
const inferredName = contextObj?.name ?? contextObj?.constructor?.name;

if (componentName) {
span.setAttribute('componentName', componentName);
span.setAttribute('baggage.componentName', componentName);
} else if (this && typeof this === 'object') {
const contextObj = this as {
name?: string;
runId?: string;
constructor?: { name?: string };
};
// Prefer instance.name, fallback to constructor.name
const inferredName = contextObj.name ?? contextObj.constructor?.name;
if (inferredName) {
span.setAttribute('componentName', inferredName);
}
if (contextObj.runId) {
span.setAttribute('runId', contextObj.runId);
span.setAttribute('baggage.runId', contextObj.runId);
}
} else if (inferredName) {
span.setAttribute('componentName', inferredName);
}

// Merge with existing baggage to preserve parent context values
const existingBaggage = propagation.getBaggage(ctx);
const baggageEntries: Record<string, BaggageEntry> = {};
if (contextObj?.runId) {
span.setAttribute('runId', contextObj.runId);
span.setAttribute('baggage.runId', contextObj.runId);
}

// Copy all existing baggage entries to preserve custom baggage
if (existingBaggage) {
existingBaggage.getAllEntries().forEach(([key, entry]) => {
baggageEntries[key] = entry;
});
}
for (const [key, value] of Object.entries(
getHostRuntimeAttributes(contextObj?.hostRuntime)
)) {
span.setAttribute(key, value);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Resolve one effective host-runtime context before writing run IDs.

These branches can leave runId and hostRuntime.ids.runId out of sync. If parent baggage already contains hostRuntime.ids.runId and this instance only supplies runId, the bare runId gets overwritten but the prefixed host-runtime entry does not. Downstream getBaggageValues() will then return one run ID from runId and a different one inside hostRuntime.ids, which breaks correlation.

💡 Suggested direction
-            for (const [key, value] of Object.entries(getHostRuntimeAttributes(hostRuntime))) {
-                span.setAttribute(key, value);
-            }
-
             const contextObj =
                 this && typeof this === 'object'
                     ? (this as {
                           name?: string;
                           runId?: string;
                           hostRuntime?: HostRuntimeContext | undefined;
                           constructor?: { name?: string };
                       })
                     : undefined;
             const inferredName = contextObj?.name ?? contextObj?.constructor?.name;
+            const effectiveHostRuntime =
+                contextObj?.hostRuntime ??
+                (contextObj?.runId !== undefined
+                    ? { ids: { runId: String(contextObj.runId) } }
+                    : hostRuntime);
+
+            for (const [key, value] of Object.entries(
+                getHostRuntimeAttributes(effectiveHostRuntime)
+            )) {
+                span.setAttribute(key, value);
+            }
 
             if (componentName) {
                 span.setAttribute('componentName', componentName);
                 span.setAttribute('baggage.componentName', componentName);
             } else if (inferredName) {
                 span.setAttribute('componentName', inferredName);
             }
 
             if (contextObj?.runId) {
                 span.setAttribute('runId', contextObj.runId);
                 span.setAttribute('baggage.runId', contextObj.runId);
             }
-
-            for (const [key, value] of Object.entries(
-                getHostRuntimeAttributes(contextObj?.hostRuntime)
-            )) {
-                span.setAttribute(key, value);
-            }
 ...
-            if (contextObj?.runId !== undefined) {
-                baggageEntries.runId = {
-                    ...baggageEntries.runId,
-                    value: String(contextObj.runId),
-                };
-            }
-
-            Object.assign(baggageEntries, getHostRuntimeBaggageEntries(contextObj?.hostRuntime));
+            Object.assign(baggageEntries, getHostRuntimeBaggageEntries(effectiveHostRuntime));

As per coding guidelines: "Avoid multi-source values encoded as optional + fallback + fallback chains; prefer a single source of truth with explicit resolver function" and "Do not mix multiple fields that can each be 'the name' / 'the title' / 'the config' without an explicit resolver + tests".

Also applies to: 186-193

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/telemetry/decorators.ts` around lines 113 - 144, Compute a
single resolved host-runtime context and runId before setting span attributes
instead of writing them from two separate sources; e.g., create a
resolvedHostRuntime by explicitly choosing precedence between the incoming
hostRuntime param and contextObj?.hostRuntime and derive a single resolvedRunId
(prefer resolvedHostRuntime.ids.runId if present, else contextObj?.runId, else
hostRuntime runId), then call getHostRuntimeAttributes(resolvedHostRuntime) once
and set both 'runId' and 'hostRuntime.ids.runId' (and their baggage keys) from
resolvedRunId so span.setAttribute and baggage keys remain consistent (affects
code around getHostRuntimeAttributes, contextObj, componentName, and runId
usage).

…runtime-id

# Conflicts:
#	packages/cli/src/cli/utils/config-validation.test.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
packages/core/src/session/chat-session.ts (1)

158-160: ⚠️ Potential issue | 🟠 Major

Use session-scoped runtime config when binding SessionEventBus.

At Line 159, getRuntimeConfig() is called without this.id, so the event bus may capture non-session hostRuntime and emit incorrect correlation IDs for this session.

Suggested fix
-        this.eventBus = new SessionEventBus(
-            this.services.stateManager.getRuntimeConfig().hostRuntime
-        );
+        this.eventBus = new SessionEventBus(
+            this.services.stateManager.getRuntimeConfig(this.id).hostRuntime
+        );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/session/chat-session.ts` around lines 158 - 160,
SessionEventBus is being constructed with a global runtime config via
this.services.stateManager.getRuntimeConfig() which omits the session id and can
capture the wrong hostRuntime; change the call to use the session-scoped runtime
config (e.g. this.services.stateManager.getRuntimeConfig(this.id)) and pass its
hostRuntime into the SessionEventBus constructor so emitted events carry the
correct session correlation IDs; update the instantiation of SessionEventBus
accordingly in the chat session constructor where this.eventBus is set.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/core/src/session/chat-session.ts`:
- Around line 158-160: SessionEventBus is being constructed with a global
runtime config via this.services.stateManager.getRuntimeConfig() which omits the
session id and can capture the wrong hostRuntime; change the call to use the
session-scoped runtime config (e.g.
this.services.stateManager.getRuntimeConfig(this.id)) and pass its hostRuntime
into the SessionEventBus constructor so emitted events carry the correct session
correlation IDs; update the instantiation of SessionEventBus accordingly in the
chat session constructor where this.eventBus is set.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 03275ae6-c88f-46da-b716-9af8f387752f

📥 Commits

Reviewing files that changed from the base of the PR and between cc88e8b and 96ec596.

📒 Files selected for processing (13)
  • .changeset/host-runtime-ids-through-core.md
  • packages/agent-config/src/resolver/to-dexto-agent-options.test.ts
  • packages/agent-config/src/resolver/to-dexto-agent-options.ts
  • packages/agent-management/src/AgentFactory.ts
  • packages/agent-management/src/agent-creation.ts
  • packages/cli/src/cli/modes/cli.test.ts
  • packages/cli/src/cli/utils/config-validation.test.ts
  • packages/core/src/agent/DextoAgent.lifecycle.test.ts
  • packages/core/src/agent/DextoAgent.ts
  • packages/core/src/session/chat-session.ts
  • packages/core/src/session/session-manager.test.ts
  • packages/core/src/session/session-manager.ts
  • packages/server/src/hono/__tests__/test-fixtures.ts
✅ Files skipped from review due to trivial changes (4)
  • .changeset/host-runtime-ids-through-core.md
  • packages/core/src/agent/DextoAgent.lifecycle.test.ts
  • packages/agent-config/src/resolver/to-dexto-agent-options.ts
  • packages/cli/src/cli/modes/cli.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/cli/src/cli/utils/config-validation.test.ts
  • packages/agent-config/src/resolver/to-dexto-agent-options.test.ts
  • packages/agent-management/src/AgentFactory.ts
  • packages/agent-management/src/agent-creation.ts
  • packages/core/src/session/session-manager.test.ts
  • packages/core/src/agent/DextoAgent.ts
  • packages/core/src/session/session-manager.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose host-owned runtime IDs cleanly through core runtime flows

1 participant