@salesforce/agentic-common 0.5.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.
- package/README.md +51 -3
- package/dist/backfill-created-at.d.ts +24 -0
- package/dist/backfill-created-at.js +34 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/sf-api-env.d.ts +14 -1
- package/dist/sf-api-env.js +13 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@ interface consumed by the other packages in this monorepo.
|
|
|
6
6
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
9
|
-
> **Closed source.** This package is published to npm under the [Salesforce Public Code License](../../LICENSE.txt) and
|
|
9
|
+
> **Closed source.** This package is published to npm under the [Salesforce Public Code License](../../LICENSE.txt) and
|
|
10
|
+
> is for use by Salesforce only.
|
|
10
11
|
|
|
11
12
|
```typescript
|
|
12
13
|
import { EventBus, LogBus } from '@salesforce/agentic-common';
|
|
@@ -81,6 +82,35 @@ enum SfApiEnv {
|
|
|
81
82
|
}
|
|
82
83
|
```
|
|
83
84
|
|
|
85
|
+
### `inferSfApiEnv(instanceUrl, options?): SfApiEnv`
|
|
86
|
+
|
|
87
|
+
Maps a Salesforce instance URL to a `SfApiEnv`. `OrgConnection.getInferredSfApiEnv()` is the typical entry point; direct
|
|
88
|
+
callers use this when they have an `instanceUrl` but not a connection (e.g. building a Salesforce platform MCP URL from
|
|
89
|
+
a token + instance URL).
|
|
90
|
+
|
|
91
|
+
Resolution order:
|
|
92
|
+
|
|
93
|
+
1. If `SF_API_ENV` is set to a valid value, return it.
|
|
94
|
+
2. STM patterns → `Stage`.
|
|
95
|
+
3. OrgFarm dev / perf / test sub-segments under `.pc-rnd.` → `Dev` / `Perf` / `Test`.
|
|
96
|
+
4. `.pc-rnd.` host with no recognized sub-segment → `options.pcRndFallback ?? Test`. `.pc-rnd.` is an internal-only
|
|
97
|
+
OrgFarm domain (by definition not Prod), so the default degrades a future unrecognized sub-segment to a sibling
|
|
98
|
+
non-prod host rather than leaking traffic from a non-prod org to the Prod servlet.
|
|
99
|
+
5. `.crm.dev` workspaces, `localhost.sfdcdev.`, `.internal.` → `Dev`.
|
|
100
|
+
6. Anything else → `Prod`.
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
function inferSfApiEnv(instanceUrl: string, options?: { pcRndFallback?: SfApiEnv }): SfApiEnv;
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { SfApiEnv, inferSfApiEnv } from '@salesforce/agentic-common';
|
|
108
|
+
|
|
109
|
+
inferSfApiEnv('https://myorg.test1.pc-rnd.salesforce.com'); // SfApiEnv.Test
|
|
110
|
+
inferSfApiEnv('https://myorg.qa1.pc-rnd.salesforce.com'); // SfApiEnv.Test (default fallback)
|
|
111
|
+
inferSfApiEnv('https://myorg.qa1.pc-rnd.salesforce.com', { pcRndFallback: SfApiEnv.Prod }); // SfApiEnv.Prod
|
|
112
|
+
```
|
|
113
|
+
|
|
84
114
|
### `Clock` / `RealClock`
|
|
85
115
|
|
|
86
116
|
Abstract time source for dependency injection. Use `RealClock` in production; extend `Clock` in tests for deterministic
|
|
@@ -261,8 +291,8 @@ Splits a markdown document into its YAML frontmatter block and body content. Rec
|
|
|
261
291
|
frontmatter block at the start of a document and normalizes CRLF line endings to LF. When no frontmatter block is
|
|
262
292
|
present, `frontmatter` is `null` and `body` is the full input.
|
|
263
293
|
|
|
264
|
-
The frontmatter is returned unparsed so callers can choose whether to parse it as YAML, JSON, or treat it as opaque
|
|
265
|
-
|
|
294
|
+
The frontmatter is returned unparsed so callers can choose whether to parse it as YAML, JSON, or treat it as opaque text
|
|
295
|
+
— keeping a YAML runtime out of `@salesforce/agentic-common`.
|
|
266
296
|
|
|
267
297
|
```typescript
|
|
268
298
|
import { splitFrontmatterAndBody } from '@salesforce/agentic-common';
|
|
@@ -279,6 +309,24 @@ type FrontmatterSplit = {
|
|
|
279
309
|
};
|
|
280
310
|
```
|
|
281
311
|
|
|
312
|
+
### `backfillCreatedAt<T extends { createdAt?: Date }>(messages: T[], clock: Clock): T[]`
|
|
313
|
+
|
|
314
|
+
Backfills missing `createdAt` timestamps on a batch of message-shaped records, stepping per-position via
|
|
315
|
+
`clock.nextAfter` so a bulk insert produces strictly-ascending timestamps rather than ms-precision ties tie-broken by
|
|
316
|
+
stable sort. Records that already carry a `createdAt` pass through unchanged (same reference, no clone). Records missing
|
|
317
|
+
one are cloned with a freshly-stepped value: the first missing position seeds from `clock.now()`, each subsequent
|
|
318
|
+
missing position uses `clock.nextAfter(<prior>)`.
|
|
319
|
+
|
|
320
|
+
Used by `sfdx-agent-sdk`'s `ChatSession.addContext()` and both harnesses' `addContext` boundaries so the read-side
|
|
321
|
+
"every Message has populated `createdAt`; sort ascending" contract is upheld regardless of consumer-construction style.
|
|
322
|
+
Generic over the record shape, so any consumer with a `createdAt?: Date` field can reuse the same policy.
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import { backfillCreatedAt, RealClock } from '@salesforce/agentic-common';
|
|
326
|
+
|
|
327
|
+
const filled = backfillCreatedAt(messages, new RealClock());
|
|
328
|
+
```
|
|
329
|
+
|
|
282
330
|
## Development
|
|
283
331
|
|
|
284
332
|
See [DEVELOPING.md](../../DEVELOPING.md) for build-from-source setup, scripts, and monorepo commands.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Clock } from './clock.js';
|
|
2
|
+
/**
|
|
3
|
+
* Backfills missing `createdAt` timestamps on a batch of message-shaped
|
|
4
|
+
* records, stepping per-position via `clock.nextAfter` so a bulk insert
|
|
5
|
+
* produces strictly-ascending timestamps rather than ms-precision ties
|
|
6
|
+
* tie-broken by stable sort.
|
|
7
|
+
*
|
|
8
|
+
* Records that already carry a `createdAt` are returned unchanged (same
|
|
9
|
+
* reference, no clone). Records missing one are cloned with a freshly-
|
|
10
|
+
* stepped `createdAt`. The first missing position seeds from `clock.now()`;
|
|
11
|
+
* each subsequent missing position uses `clock.nextAfter(<prior>)`.
|
|
12
|
+
*
|
|
13
|
+
* Generic over the record shape so this can be reused by:
|
|
14
|
+
* - The SDK's `DefaultChatSession.addContext` (over `Message`)
|
|
15
|
+
* - Both production harnesses' `addContext` boundaries
|
|
16
|
+
*
|
|
17
|
+
* Anywhere the message-shape contract requires an ascending sortable
|
|
18
|
+
* timestamp, this is the single backfill site so the three implementations
|
|
19
|
+
* can't drift on subtle policy questions (clamp-to-lastExplicit, behavior
|
|
20
|
+
* at the boundary between explicit and implicit positions, etc.).
|
|
21
|
+
*/
|
|
22
|
+
export declare function backfillCreatedAt<T extends {
|
|
23
|
+
createdAt?: Date;
|
|
24
|
+
}>(messages: T[], clock: Clock): T[];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026, Salesforce, Inc. All rights reserved.
|
|
3
|
+
* See LICENSE.txt for license terms.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Backfills missing `createdAt` timestamps on a batch of message-shaped
|
|
7
|
+
* records, stepping per-position via `clock.nextAfter` so a bulk insert
|
|
8
|
+
* produces strictly-ascending timestamps rather than ms-precision ties
|
|
9
|
+
* tie-broken by stable sort.
|
|
10
|
+
*
|
|
11
|
+
* Records that already carry a `createdAt` are returned unchanged (same
|
|
12
|
+
* reference, no clone). Records missing one are cloned with a freshly-
|
|
13
|
+
* stepped `createdAt`. The first missing position seeds from `clock.now()`;
|
|
14
|
+
* each subsequent missing position uses `clock.nextAfter(<prior>)`.
|
|
15
|
+
*
|
|
16
|
+
* Generic over the record shape so this can be reused by:
|
|
17
|
+
* - The SDK's `DefaultChatSession.addContext` (over `Message`)
|
|
18
|
+
* - Both production harnesses' `addContext` boundaries
|
|
19
|
+
*
|
|
20
|
+
* Anywhere the message-shape contract requires an ascending sortable
|
|
21
|
+
* timestamp, this is the single backfill site so the three implementations
|
|
22
|
+
* can't drift on subtle policy questions (clamp-to-lastExplicit, behavior
|
|
23
|
+
* at the boundary between explicit and implicit positions, etc.).
|
|
24
|
+
*/
|
|
25
|
+
export function backfillCreatedAt(messages, clock) {
|
|
26
|
+
let last;
|
|
27
|
+
return messages.map((m) => {
|
|
28
|
+
if (m.createdAt)
|
|
29
|
+
return m;
|
|
30
|
+
last = last ? clock.nextAfter(last) : clock.now();
|
|
31
|
+
return { ...m, createdAt: last };
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=backfill-created-at.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { backfillCreatedAt } from './backfill-created-at.js';
|
|
1
2
|
export { Clock, RealClock } from './clock.js';
|
|
2
3
|
export { type OrgConnection, RealOrgConnection } from './connection.js';
|
|
3
4
|
export { type OrgConnectionFactory, RealOrgConnectionFactory } from './connection-factory.js';
|
|
@@ -7,5 +8,5 @@ export { type UniqueIDGenerator, UUIDGenerator } from './id-generator.js';
|
|
|
7
8
|
export { LogBus, type LogLevel, type LogRecord } from './log.js';
|
|
8
9
|
export { type FrontmatterSplit, splitFrontmatterAndBody } from './markdown-frontmatter.js';
|
|
9
10
|
export { BackoffRetryer, DEFAULT_RETRY_OPTIONS, NoOpRetryer, type Retryer, type RetryAttemptInfo, type RetryCallbacks, type RetryExhaustedInfo, type RetryOptions, } from './retryer.js';
|
|
10
|
-
export { SfApiEnv } from './sf-api-env.js';
|
|
11
|
+
export { inferSfApiEnv, SfApiEnv } from './sf-api-env.js';
|
|
11
12
|
export { buildSummaryPrompt } from './summary-prompt.js';
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Copyright 2026, Salesforce, Inc. All rights reserved.
|
|
3
3
|
* See LICENSE.txt for license terms.
|
|
4
4
|
*/
|
|
5
|
+
export { backfillCreatedAt } from './backfill-created-at.js';
|
|
5
6
|
export { Clock, RealClock } from './clock.js';
|
|
6
7
|
export { RealOrgConnection } from './connection.js';
|
|
7
8
|
export { RealOrgConnectionFactory } from './connection-factory.js';
|
|
@@ -11,6 +12,6 @@ export { UUIDGenerator } from './id-generator.js';
|
|
|
11
12
|
export { LogBus } from './log.js';
|
|
12
13
|
export { splitFrontmatterAndBody } from './markdown-frontmatter.js';
|
|
13
14
|
export { BackoffRetryer, DEFAULT_RETRY_OPTIONS, NoOpRetryer, } from './retryer.js';
|
|
14
|
-
export { SfApiEnv } from './sf-api-env.js';
|
|
15
|
+
export { inferSfApiEnv, SfApiEnv } from './sf-api-env.js';
|
|
15
16
|
export { buildSummaryPrompt } from './summary-prompt.js';
|
|
16
17
|
//# sourceMappingURL=index.js.map
|
package/dist/sf-api-env.d.ts
CHANGED
|
@@ -16,6 +16,19 @@ export declare enum SfApiEnv {
|
|
|
16
16
|
* - OrgFarm dev patterns (`.devX.*.pc-rnd.*`) or workspaces (`.crm.dev`) → `dev`
|
|
17
17
|
* - OrgFarm perf patterns (`.perfXX.*.pc-rnd.*`) → `perf`
|
|
18
18
|
* - OrgFarm test patterns (`.testX.*.pc-rnd.*`) → `test`
|
|
19
|
+
* - `pc-rnd` hosts with no recognized sub-segment → `options.pcRndFallback` (default `test`)
|
|
19
20
|
* - Everything else (including unrecognized internal URLs) → `prod`
|
|
21
|
+
*
|
|
22
|
+
* @param instanceUrl - Salesforce org instance URL.
|
|
23
|
+
* @param options - Optional resolution overrides.
|
|
24
|
+
* @param options.pcRndFallback - Environment to return when the URL is a `.pc-rnd.`
|
|
25
|
+
* host that does not match a recognized `.devN.` / `.perfN.` / `.testN.` sub-segment.
|
|
26
|
+
* Defaults to {@link SfApiEnv.Test}: `.pc-rnd.` is an internal-only OrgFarm domain,
|
|
27
|
+
* so by definition not Prod — a future unrecognized sub-segment degrades to a
|
|
28
|
+
* sibling non-prod host instead of leaking traffic from a non-prod org to the
|
|
29
|
+
* Prod servlet. Callers with a stronger guarantee (e.g. inputs are pre-validated
|
|
30
|
+
* to be Prod-class hosts) can pass another value to override.
|
|
20
31
|
*/
|
|
21
|
-
export declare function inferSfApiEnv(instanceUrl: string
|
|
32
|
+
export declare function inferSfApiEnv(instanceUrl: string, options?: {
|
|
33
|
+
pcRndFallback?: SfApiEnv;
|
|
34
|
+
}): SfApiEnv;
|
package/dist/sf-api-env.js
CHANGED
|
@@ -21,9 +21,20 @@ export var SfApiEnv;
|
|
|
21
21
|
* - OrgFarm dev patterns (`.devX.*.pc-rnd.*`) or workspaces (`.crm.dev`) → `dev`
|
|
22
22
|
* - OrgFarm perf patterns (`.perfXX.*.pc-rnd.*`) → `perf`
|
|
23
23
|
* - OrgFarm test patterns (`.testX.*.pc-rnd.*`) → `test`
|
|
24
|
+
* - `pc-rnd` hosts with no recognized sub-segment → `options.pcRndFallback` (default `test`)
|
|
24
25
|
* - Everything else (including unrecognized internal URLs) → `prod`
|
|
26
|
+
*
|
|
27
|
+
* @param instanceUrl - Salesforce org instance URL.
|
|
28
|
+
* @param options - Optional resolution overrides.
|
|
29
|
+
* @param options.pcRndFallback - Environment to return when the URL is a `.pc-rnd.`
|
|
30
|
+
* host that does not match a recognized `.devN.` / `.perfN.` / `.testN.` sub-segment.
|
|
31
|
+
* Defaults to {@link SfApiEnv.Test}: `.pc-rnd.` is an internal-only OrgFarm domain,
|
|
32
|
+
* so by definition not Prod — a future unrecognized sub-segment degrades to a
|
|
33
|
+
* sibling non-prod host instead of leaking traffic from a non-prod org to the
|
|
34
|
+
* Prod servlet. Callers with a stronger guarantee (e.g. inputs are pre-validated
|
|
35
|
+
* to be Prod-class hosts) can pass another value to override.
|
|
25
36
|
*/
|
|
26
|
-
export function inferSfApiEnv(instanceUrl) {
|
|
37
|
+
export function inferSfApiEnv(instanceUrl, options) {
|
|
27
38
|
const envVar = process.env['SF_API_ENV']?.toLowerCase();
|
|
28
39
|
if (envVar && Object.values(SfApiEnv).includes(envVar)) {
|
|
29
40
|
return envVar;
|
|
@@ -44,6 +55,7 @@ export function inferSfApiEnv(instanceUrl) {
|
|
|
44
55
|
if (/\.test\d+\./.test(lower)) {
|
|
45
56
|
return SfApiEnv.Test;
|
|
46
57
|
}
|
|
58
|
+
return options?.pcRndFallback ?? SfApiEnv.Test;
|
|
47
59
|
}
|
|
48
60
|
if (lower.includes('.crm.dev') || lower.includes('localhost.sfdcdev.') || lower.includes('.internal.')) {
|
|
49
61
|
return SfApiEnv.Dev;
|