Add Salesforce Apex native Agent 365 observability sample#327
Open
rbrighenti wants to merge 1 commit into
Open
Add Salesforce Apex native Agent 365 observability sample#327rbrighenti wants to merge 1 commit into
rbrighenti wants to merge 1 commit into
Conversation
Add Salesforce/Apex observability sample under a new top-level `salesforce/` folder. What this sample demonstrates: - Apex exposed as an Agent 365 tool surface (REST + Agentforce @InvocableMethod) - Native Apex OTLP span emission, correlated to the agent turn by a shared W3C trace id (fail-open, async via Queueable, config-gated) - Hand-rolled FMI 3-hop agent-bound token in Apex (MSAL is unavailable in Apex) - Salesforce originating a trace from an Agentforce turn Repo integration: - Top-level README, CLAUDE.md, and .gitignore updated for Salesforce.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new top-level salesforce/ area containing an SFDX sample that demonstrates native Salesforce Apex Agent 365 observability: emitting Agent 365 OTLP spans from Apex, correlating spans to an agent turn via W3C trace context, and (optionally) originating traces from an Agentforce turn with deterministic seeding.
Changes:
- Introduces
salesforce/apex-observability/SFDX project with Apex classes, metadata, scripts, and docs for Agent 365 OTLP emission + FMI 3-hop agent-bound token acquisition. - Adds Apex unit tests covering trace parsing/seeding, OTLP body shape, token hop behavior, fail-open behavior, and gating.
- Updates repository-level docs and ignore rules to include the new Salesforce/Apex samples.
Reviewed changes
Copilot reviewed 67 out of 68 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| salesforce/docs/design.md | Cross-sample Salesforce design/convention guidance. |
| salesforce/apex-observability/sfdx-project.json | SFDX project definition for the sample. |
| salesforce/apex-observability/scripts/verify-span.apex | Execute-Anonymous smoke script to enqueue and verify span ingest. |
| salesforce/apex-observability/scripts/create-obs-config.apex | Execute-Anonymous seeding script for CMDT config record. |
| salesforce/apex-observability/README.md | End-to-end sample documentation (deploy/config/test/troubleshoot). |
| salesforce/apex-observability/force-app/main/default/permissionsets/A365_Observability.permissionset-meta.xml | Permission set for Apex class + external credential principal access. |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/A365_Observability_Config__mdt.object-meta.xml | CMDT type for non-secret runtime config. |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/fields/Enabled__c.field-meta.xml | CMDT kill switch for boundary emission. |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/fields/TenantId__c.field-meta.xml | CMDT tenant id field for routing/headers. |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/fields/AgentId__c.field-meta.xml | CMDT agent id field for routing/token binding. |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/fields/IngestBase__c.field-meta.xml | CMDT ingest base field (documented host). |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/fields/ObsScope__c.field-meta.xml | CMDT observability scope field. |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/fields/FmiScope__c.field-meta.xml | CMDT FMI scope field. |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/fields/UseS2SEndpoint__c.field-meta.xml | CMDT toggle for S2S vs non-S2S ingest path. |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/fields/ServiceName__c.field-meta.xml | CMDT boundary service.name field. |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/fields/AgentforceServiceName__c.field-meta.xml | CMDT originated-trace service.name field. |
| salesforce/apex-observability/force-app/main/default/objects/A365_Observability_Config__mdt/fields/OriginateEnabled__c.field-meta.xml | CMDT kill switch for origination path. |
| salesforce/apex-observability/force-app/main/default/namedCredentials/A365_Obs_Token.namedCredential-meta.xml | Named Credential for FMI hop 1/2 (Basic auth injected). |
| salesforce/apex-observability/force-app/main/default/namedCredentials/A365_Obs_TokenJwt.namedCredential-meta.xml | Named Credential for FMI hop 3 (no auth header). |
| salesforce/apex-observability/force-app/main/default/namedCredentials/A365_Obs_Ingest.namedCredential-meta.xml | Named Credential for OTLP ingest endpoint. |
| salesforce/apex-observability/force-app/main/default/namedCredentials/A365_Callback.namedCredential-meta.xml | Named Credential placeholder for optional /callback callout. |
| salesforce/apex-observability/force-app/main/default/externalCredentials/A365_Obs_Entra.externalCredential-meta.xml | External Credential to hold blueprint secret (Setup-entered). |
| salesforce/apex-observability/force-app/main/default/customMetadata/A365_Observability_Config.Default.md-meta.xml | Template CMDT record (excluded from deploy; used as documentation). |
| salesforce/apex-observability/force-app/main/default/cachePartitions/A365Obs.cachePartition-meta.xml | Optional Platform Cache partition for token/root dedup caching. |
| salesforce/apex-observability/force-app/main/default/classes/A365Trace.cls | W3C traceparent parsing + deterministic seed helpers. |
| salesforce/apex-observability/force-app/main/default/classes/A365Trace.cls-meta.xml | ApexClass metadata for A365Trace. |
| salesforce/apex-observability/force-app/main/default/classes/A365TraceTest.cls | Unit tests for traceparent parsing and id generation. |
| salesforce/apex-observability/force-app/main/default/classes/A365TraceTest.cls-meta.xml | ApexClass metadata for A365TraceTest. |
| salesforce/apex-observability/force-app/main/default/classes/A365TraceSeedTest.cls | Unit tests for deterministic seed helpers. |
| salesforce/apex-observability/force-app/main/default/classes/A365TraceSeedTest.cls-meta.xml | ApexClass metadata for A365TraceSeedTest. |
| salesforce/apex-observability/force-app/main/default/classes/A365ObsConfig.cls | CMDT reader with safe defaults + test override support. |
| salesforce/apex-observability/force-app/main/default/classes/A365ObsConfig.cls-meta.xml | ApexClass metadata for A365ObsConfig. |
| salesforce/apex-observability/force-app/main/default/classes/A365ObsSpan.cls | OTLP JSON body builder matching Agent 365 ingest expectations. |
| salesforce/apex-observability/force-app/main/default/classes/A365ObsSpan.cls-meta.xml | ApexClass metadata for A365ObsSpan. |
| salesforce/apex-observability/force-app/main/default/classes/A365ObsSpanTest.cls | Unit tests for OTLP body wire shape and correlation. |
| salesforce/apex-observability/force-app/main/default/classes/A365ObsSpanTest.cls-meta.xml | ApexClass metadata for A365ObsSpanTest. |
| salesforce/apex-observability/force-app/main/default/classes/A365ObsToken.cls | FMI 3-hop token acquisition + caching helpers. |
| salesforce/apex-observability/force-app/main/default/classes/A365ObsToken.cls-meta.xml | ApexClass metadata for A365ObsToken. |
| salesforce/apex-observability/force-app/main/default/classes/A365ObsTokenTest.cls | Unit tests for hop bodies, ordering, and error behavior. |
| salesforce/apex-observability/force-app/main/default/classes/A365ObsTokenTest.cls-meta.xml | ApexClass metadata for A365ObsTokenTest. |
| salesforce/apex-observability/force-app/main/default/classes/A365Telemetry.cls | Public façade for boundary emission + origination paths. |
| salesforce/apex-observability/force-app/main/default/classes/A365Telemetry.cls-meta.xml | ApexClass metadata for A365Telemetry. |
| salesforce/apex-observability/force-app/main/default/classes/A365TelemetryQueueable.cls | Async worker to acquire token and POST OTLP spans. |
| salesforce/apex-observability/force-app/main/default/classes/A365TelemetryQueueable.cls-meta.xml | ApexClass metadata for A365TelemetryQueueable. |
| salesforce/apex-observability/force-app/main/default/classes/A365TelemetryTest.cls | Unit tests for boundary emission, gating, fail-open, caching. |
| salesforce/apex-observability/force-app/main/default/classes/A365TelemetryTest.cls-meta.xml | ApexClass metadata for A365TelemetryTest. |
| salesforce/apex-observability/force-app/main/default/classes/A365TelemetryOriginateTest.cls | Unit tests for origination path behavior and dedup. |
| salesforce/apex-observability/force-app/main/default/classes/A365TelemetryOriginateTest.cls-meta.xml | ApexClass metadata for A365TelemetryOriginateTest. |
| salesforce/apex-observability/force-app/main/default/classes/A365ToolRest.cls | Apex REST tool surface + SERVER span emission. |
| salesforce/apex-observability/force-app/main/default/classes/A365ToolRest.cls-meta.xml | ApexClass metadata for A365ToolRest. |
| salesforce/apex-observability/force-app/main/default/classes/A365ToolRestTest.cls | REST contract tests + emission enabled/disabled regression guards. |
| salesforce/apex-observability/force-app/main/default/classes/A365ToolRestTest.cls-meta.xml | ApexClass metadata for A365ToolRestTest. |
| salesforce/apex-observability/force-app/main/default/classes/A365Callout.cls | Optional outbound callback callout + CLIENT span emission. |
| salesforce/apex-observability/force-app/main/default/classes/A365Callout.cls-meta.xml | ApexClass metadata for A365Callout. |
| salesforce/apex-observability/force-app/main/default/classes/A365CalloutTest.cls | Unit tests for callback behavior + client-span emission. |
| salesforce/apex-observability/force-app/main/default/classes/A365CalloutTest.cls-meta.xml | ApexClass metadata for A365CalloutTest. |
| salesforce/apex-observability/force-app/main/default/classes/A365AgentforceTool.cls | Agentforce invocable action that originates traces from a turn. |
| salesforce/apex-observability/force-app/main/default/classes/A365AgentforceTool.cls-meta.xml | ApexClass metadata for A365AgentforceTool. |
| salesforce/apex-observability/force-app/main/default/classes/A365AgentforceToolTest.cls | Unit tests for Agentforce origination behavior + fallbacks. |
| salesforce/apex-observability/force-app/main/default/classes/A365AgentforceToolTest.cls-meta.xml | ApexClass metadata for A365AgentforceToolTest. |
| salesforce/apex-observability/docs/design.md | Sample-specific architecture (flows/token model/wire shape). |
| salesforce/apex-observability/agent/README.md | Instructions for building the optional Agentforce agent per-org. |
| salesforce/apex-observability/agent/A365_Observability_Sample.agent | Reference Agent Script wiring for Agentforce origination path. |
| salesforce/apex-observability/.gitignore | Sample-level ignore rules for SFDX artifacts/logs. |
| salesforce/apex-observability/.forceignore | Excludes CMDT record deploy to avoid CLI UNKNOWN_EXCEPTION issues. |
| README.md | Updates repository summary to include Salesforce/Apex samples. |
| CLAUDE.md | Documents Salesforce sample layout and CLI commands; adds Apex header guidance. |
| .gitignore | Adds repository-level ignores for SFDX local artifacts. |
| --> | ||
| <NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
| <label>A365 Callback</label> | ||
| <endpoint>https://REPLACE-WITH-YOUR-TUNNEL-URL.devtunnels.ms</endpoint> |
Comment on lines
+55
to
+61
| String tenantId = A365ObsConfig.tenantId(); | ||
| String agentId = A365ObsConfig.agentId(); | ||
| String token = A365ObsToken.getToken(); | ||
|
|
||
| String body = A365ObsSpan.buildBody( | ||
| tenantId, agentId, traceId, parentSpanId, spanId, | ||
| spanName, kind, statusCode, attrs, startNs, endNs, serviceName); |
| | `Enabled__c` | `true` | Master kill switch for the boundary emitter (`false` = no-op). | | ||
| | `TenantId__c` | `<<TENANT_ID>>` | Entra tenant id. | | ||
| | `AgentId__c` | `<<AGENT_ID>>` | Agent 365 agent id (in the ingest URL; token `azp` must match). | | ||
| | `IngestBase__c` | `https://agent365.svc.cloud.microsoft` | OTLP ingest host. | |
|
|
||
| This samples repository is currently in active development and contains: | ||
| - **Sample Agents**: Production-ready examples in C#/.NET, Python, and Node.js/TypeScript demonstrating observability, notifications, tooling, and hosting patterns | ||
| - **Sample Agents**: Production-ready examples in C#/.NET, Python, Node.js/TypeScript, and Salesforce/Apex demonstrating observability, notifications, tooling, and hosting patterns |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add Salesforce/Apex observability sample under a new top-level
salesforce/folder.What this sample demonstrates: