@salesforce/sfdx-agent-sdk 0.6.0 → 0.7.0

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.
@@ -157,7 +157,7 @@ export class DefaultAgentManager {
157
157
  const runtime = await this.agentConnectivityResolver.resolve(projectRoot, config);
158
158
  await this.harness.createAgent(agentId, projectRoot, runtime.llmGatewayClient, toHarnessConfig(config, runtime.orgJwt), options.abortSignal !== undefined ? { abortSignal: options.abortSignal } : undefined);
159
159
  const agentSlice = this.router.registerAgent(agentId);
160
- const agent = new DefaultAgent(this.harness, agentId, projectRoot, config, runtime.llmGatewayClient, runtime.orgConnection, runtime.orgJwt, this.agentConnectivityResolver, this.router, agentSlice, { telemetry: this.telemetryBus, log: this.logBus }, this.clock, this.agentIdGenerator);
160
+ const agent = new DefaultAgent(this.harness, agentId, projectRoot, config, runtime.llmGatewayClient, runtime.orgConnection, runtime.orgJwt, this.agentConnectivityResolver, this.identityStore, this.router, agentSlice, { telemetry: this.telemetryBus, log: this.logBus }, this.clock, this.agentIdGenerator);
161
161
  this.agents.set(agentId, agent);
162
162
  this.telemetryBus.emit({
163
163
  type: 'agent-created',
package/dist/agent.d.ts CHANGED
@@ -5,6 +5,7 @@ import { type ChatSession } from './chat-session.js';
5
5
  import type { McpServerInfo } from './mcp-config.js';
6
6
  import { type JSONWebToken, type LLMGatewayClient } from '@salesforce/llm-gateway-sdk';
7
7
  import type { AgentConnectivityResolver } from './agent-connectivity-resolver.js';
8
+ import type { AgentIdentityStore } from './internal/agent-identity-store.js';
8
9
  import type { TelemetryRouter, TelemetrySlice } from './internal/telemetry-router.js';
9
10
  import type { TelemetryBus, TelemetryEventCallback } from './types/telemetry-events.js';
10
11
  /**
@@ -110,6 +111,7 @@ export declare class DefaultAgent implements Agent {
110
111
  private orgConnection;
111
112
  private orgJwt;
112
113
  private readonly agentConnectivityResolver;
114
+ private readonly identityStore;
113
115
  private readonly sessions;
114
116
  private readonly sessionSliceUnregisters;
115
117
  private readonly router;
@@ -129,11 +131,13 @@ export declare class DefaultAgent implements Agent {
129
131
  * @param orgConnection - Authenticated org connection carrying identity and env inference.
130
132
  * @param orgJwt - Self-refreshing JWT for the resolved org (used for MCP auth injection).
131
133
  * @param agentConnectivityResolver - Used to re-resolve org connectivity when the org or model changes.
134
+ * @param identityStore - SDK-owned persistence for the `{ agentId, projectRoot, AgentConfig }` triple. The agent
135
+ * calls `write()` on a successful `updateAgentConfig` so disk state and in-memory state stay in lockstep.
132
136
  * @param router - Telemetry router used to obtain session slices when sessions are created.
133
137
  * @param inbound - Router slice delivering harness events routed to this agent (non-session-scoped).
134
138
  * @param parent - Manager's bus pair; this agent forwards its events upward into them.
135
139
  */
136
- constructor(harness: AgentHarness, agentId: string, projectRoot: string, config: AgentConfig, llmGatewayClient: LLMGatewayClient, orgConnection: OrgConnection, orgJwt: JSONWebToken, agentConnectivityResolver: AgentConnectivityResolver, router: TelemetryRouter, inbound: TelemetrySlice, parent: AgentParentBuses, clock?: Clock, idGenerator?: UniqueIDGenerator);
140
+ constructor(harness: AgentHarness, agentId: string, projectRoot: string, config: AgentConfig, llmGatewayClient: LLMGatewayClient, orgConnection: OrgConnection, orgJwt: JSONWebToken, agentConnectivityResolver: AgentConnectivityResolver, identityStore: AgentIdentityStore, router: TelemetryRouter, inbound: TelemetrySlice, parent: AgentParentBuses, clock?: Clock, idGenerator?: UniqueIDGenerator);
137
141
  /**
138
142
  * @requirements
139
143
  * - MUST return the agent's ID.
@@ -154,7 +158,9 @@ export declare class DefaultAgent implements Agent {
154
158
  * - MUST guarantee that the `agentId` remains unchanged during the merge.
155
159
  * - MUST destroy the existing agent in the harness by delegating to `this.harness.destroyAgent(this.getId())`.
156
160
  * - MUST recreate the agent in the harness with the newly merged configuration by delegating to `this.harness.createAgent(...)`.
157
- * - MUST preserve the previous in-memory config state if recreation fails.
161
+ * - MUST persist the merged config via `this.identityStore.write(...)` after the harness recreate succeeds and
162
+ * before the in-memory swaps, so a write failure rolls back through the same catch path as a recreate failure.
163
+ * - MUST preserve the previous in-memory config state if recreation or persistence fails.
158
164
  */
159
165
  updateAgentConfig(config?: AgentConfig, options?: {
160
166
  abortSignal?: AbortSignal;
package/dist/agent.js CHANGED
@@ -20,6 +20,7 @@ export class DefaultAgent {
20
20
  orgConnection;
21
21
  orgJwt;
22
22
  agentConnectivityResolver;
23
+ identityStore;
23
24
  sessions = new Map();
24
25
  sessionSliceUnregisters = new Map();
25
26
  router;
@@ -39,11 +40,13 @@ export class DefaultAgent {
39
40
  * @param orgConnection - Authenticated org connection carrying identity and env inference.
40
41
  * @param orgJwt - Self-refreshing JWT for the resolved org (used for MCP auth injection).
41
42
  * @param agentConnectivityResolver - Used to re-resolve org connectivity when the org or model changes.
43
+ * @param identityStore - SDK-owned persistence for the `{ agentId, projectRoot, AgentConfig }` triple. The agent
44
+ * calls `write()` on a successful `updateAgentConfig` so disk state and in-memory state stay in lockstep.
42
45
  * @param router - Telemetry router used to obtain session slices when sessions are created.
43
46
  * @param inbound - Router slice delivering harness events routed to this agent (non-session-scoped).
44
47
  * @param parent - Manager's bus pair; this agent forwards its events upward into them.
45
48
  */
46
- constructor(harness, agentId, projectRoot, config, llmGatewayClient, orgConnection, orgJwt, agentConnectivityResolver, router, inbound, parent, clock = new RealClock(), idGenerator = new UUIDGenerator()) {
49
+ constructor(harness, agentId, projectRoot, config, llmGatewayClient, orgConnection, orgJwt, agentConnectivityResolver, identityStore, router, inbound, parent, clock = new RealClock(), idGenerator = new UUIDGenerator()) {
47
50
  this.harness = harness;
48
51
  this.agentId = agentId;
49
52
  this.projectRoot = projectRoot;
@@ -52,6 +55,7 @@ export class DefaultAgent {
52
55
  this.orgConnection = orgConnection;
53
56
  this.orgJwt = orgJwt;
54
57
  this.agentConnectivityResolver = agentConnectivityResolver;
58
+ this.identityStore = identityStore;
55
59
  this.router = router;
56
60
  this.clock = clock;
57
61
  this.idGenerator = idGenerator;
@@ -93,7 +97,9 @@ export class DefaultAgent {
93
97
  * - MUST guarantee that the `agentId` remains unchanged during the merge.
94
98
  * - MUST destroy the existing agent in the harness by delegating to `this.harness.destroyAgent(this.getId())`.
95
99
  * - MUST recreate the agent in the harness with the newly merged configuration by delegating to `this.harness.createAgent(...)`.
96
- * - MUST preserve the previous in-memory config state if recreation fails.
100
+ * - MUST persist the merged config via `this.identityStore.write(...)` after the harness recreate succeeds and
101
+ * before the in-memory swaps, so a write failure rolls back through the same catch path as a recreate failure.
102
+ * - MUST preserve the previous in-memory config state if recreation or persistence fails.
97
103
  */
98
104
  async updateAgentConfig(config = {}, options) {
99
105
  this.assertNotDisposed();
@@ -121,6 +127,10 @@ export class DefaultAgent {
121
127
  await this.harness.destroyAgent(this.agentId);
122
128
  try {
123
129
  await this.harness.createAgent(this.agentId, this.projectRoot, nextClient, toHarnessConfig(nextConfig, nextOrgJwt), options);
130
+ // Persist before the in-memory swaps so a write failure flows through the same
131
+ // catch block as a recreate failure: the rollback restores the harness with
132
+ // previousConfig and disk state remains the pre-update record.
133
+ await this.identityStore.write(this.agentId, this.projectRoot, nextConfig);
124
134
  this.config = nextConfig;
125
135
  this.llmGatewayClient = nextClient;
126
136
  this.orgConnection = nextConnection;
@@ -138,6 +148,12 @@ export class DefaultAgent {
138
148
  if (nextClient === previousClient) {
139
149
  previousClient.setModel(Models.getByName(previousModelName));
140
150
  }
151
+ // Clear any nextConfig registration left behind by a successful harness recreate
152
+ // before the rollback createAgent runs. On the harness-recreate-failure path this
153
+ // is a no-op (the agent was never registered with nextConfig); on the
154
+ // identityStore.write-failure path it removes the live nextConfig so the rollback
155
+ // doesn't trip the harness's duplicate-registration guard.
156
+ await this.harness.destroyAgent(this.agentId);
141
157
  await this.harness.createAgent(this.agentId, this.projectRoot, previousClient, toHarnessConfig(previousConfig, previousOrgJwt));
142
158
  }
143
159
  catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/sfdx-agent-sdk",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Harness-agnostic agentic infrastructure for Salesforce developer experience tooling",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",