agentfootprint 2.7.3 → 2.8.1
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 +157 -394
- package/dist/adapters/observability/agentcore.js +188 -0
- package/dist/adapters/observability/agentcore.js.map +1 -0
- package/dist/core/RunnerBase.js +6 -0
- package/dist/core/RunnerBase.js.map +1 -1
- package/dist/esm/adapters/observability/agentcore.js +184 -0
- package/dist/esm/adapters/observability/agentcore.js.map +1 -0
- package/dist/esm/core/RunnerBase.js +6 -0
- package/dist/esm/core/RunnerBase.js.map +1 -1
- package/dist/esm/observability-providers.js +37 -0
- package/dist/esm/observability-providers.js.map +1 -0
- package/dist/esm/strategies/attach.js +227 -0
- package/dist/esm/strategies/attach.js.map +1 -0
- package/dist/esm/strategies/compose.js +158 -0
- package/dist/esm/strategies/compose.js.map +1 -0
- package/dist/esm/strategies/defaults/chatBubbleLiveStatus.js +34 -0
- package/dist/esm/strategies/defaults/chatBubbleLiveStatus.js.map +1 -0
- package/dist/esm/strategies/defaults/consoleObservability.js +61 -0
- package/dist/esm/strategies/defaults/consoleObservability.js.map +1 -0
- package/dist/esm/strategies/defaults/inMemorySinkCost.js +48 -0
- package/dist/esm/strategies/defaults/inMemorySinkCost.js.map +1 -0
- package/dist/esm/strategies/defaults/index.js +31 -0
- package/dist/esm/strategies/defaults/index.js.map +1 -0
- package/dist/esm/strategies/defaults/noopLens.js +29 -0
- package/dist/esm/strategies/defaults/noopLens.js.map +1 -0
- package/dist/esm/strategies/index.js +37 -0
- package/dist/esm/strategies/index.js.map +1 -0
- package/dist/esm/strategies/registry.js +102 -0
- package/dist/esm/strategies/registry.js.map +1 -0
- package/dist/esm/strategies/types.js +36 -0
- package/dist/esm/strategies/types.js.map +1 -0
- package/dist/observability-providers.js +41 -0
- package/dist/observability-providers.js.map +1 -0
- package/dist/strategies/attach.js +256 -0
- package/dist/strategies/attach.js.map +1 -0
- package/dist/strategies/compose.js +165 -0
- package/dist/strategies/compose.js.map +1 -0
- package/dist/strategies/defaults/chatBubbleLiveStatus.js +38 -0
- package/dist/strategies/defaults/chatBubbleLiveStatus.js.map +1 -0
- package/dist/strategies/defaults/consoleObservability.js +65 -0
- package/dist/strategies/defaults/consoleObservability.js.map +1 -0
- package/dist/strategies/defaults/inMemorySinkCost.js +52 -0
- package/dist/strategies/defaults/inMemorySinkCost.js.map +1 -0
- package/dist/strategies/defaults/index.js +38 -0
- package/dist/strategies/defaults/index.js.map +1 -0
- package/dist/strategies/defaults/noopLens.js +33 -0
- package/dist/strategies/defaults/noopLens.js.map +1 -0
- package/dist/strategies/index.js +61 -0
- package/dist/strategies/index.js.map +1 -0
- package/dist/strategies/registry.js +118 -0
- package/dist/strategies/registry.js.map +1 -0
- package/dist/strategies/types.js +37 -0
- package/dist/strategies/types.js.map +1 -0
- package/dist/types/adapters/observability/agentcore.d.ts +86 -0
- package/dist/types/adapters/observability/agentcore.d.ts.map +1 -0
- package/dist/types/core/RunnerBase.d.ts.map +1 -1
- package/dist/types/core/runner.d.ts +29 -2
- package/dist/types/core/runner.d.ts.map +1 -1
- package/dist/types/observability-providers.d.ts +37 -0
- package/dist/types/observability-providers.d.ts.map +1 -0
- package/dist/types/strategies/attach.d.ts +48 -0
- package/dist/types/strategies/attach.d.ts.map +1 -0
- package/dist/types/strategies/compose.d.ts +49 -0
- package/dist/types/strategies/compose.d.ts.map +1 -0
- package/dist/types/strategies/defaults/chatBubbleLiveStatus.d.ts +37 -0
- package/dist/types/strategies/defaults/chatBubbleLiveStatus.d.ts.map +1 -0
- package/dist/types/strategies/defaults/consoleObservability.d.ts +43 -0
- package/dist/types/strategies/defaults/consoleObservability.d.ts.map +1 -0
- package/dist/types/strategies/defaults/inMemorySinkCost.d.ts +51 -0
- package/dist/types/strategies/defaults/inMemorySinkCost.d.ts.map +1 -0
- package/dist/types/strategies/defaults/index.d.ts +31 -0
- package/dist/types/strategies/defaults/index.d.ts.map +1 -0
- package/dist/types/strategies/defaults/noopLens.d.ts +29 -0
- package/dist/types/strategies/defaults/noopLens.d.ts.map +1 -0
- package/dist/types/strategies/index.d.ts +37 -0
- package/dist/types/strategies/index.d.ts.map +1 -0
- package/dist/types/strategies/registry.d.ts +71 -0
- package/dist/types/strategies/registry.d.ts.map +1 -0
- package/dist/types/strategies/types.d.ts +304 -0
- package/dist/types/strategies/types.d.ts.map +1 -0
- package/package.json +14 -5
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agentfootprint/strategies` — typed strategy interfaces + default
|
|
3
|
+
* sinks for the v2.8 grouped-enabler architecture.
|
|
4
|
+
*
|
|
5
|
+
* See:
|
|
6
|
+
* - `docs/inspiration/strategy-everywhere.md` — design memo + AWS-first roadmap
|
|
7
|
+
* - `types.ts` — typed interfaces (Observability, Cost, LiveStatus, Lens)
|
|
8
|
+
* - `defaults/` — the 4 in-core default strategies
|
|
9
|
+
*
|
|
10
|
+
* Vendor strategies ship under three GROUPED subpaths (matching the
|
|
11
|
+
* parallel-providers pattern v2.5 established for `llm-providers` /
|
|
12
|
+
* `tool-providers` / `memory-providers`). Each subpath holds N
|
|
13
|
+
* vendor-named factories — adding a vendor never adds a new subpath:
|
|
14
|
+
*
|
|
15
|
+
* - `agentfootprint/observability-providers`
|
|
16
|
+
* agentcoreObservability (v2.8.1)
|
|
17
|
+
* cloudwatchObservability (v2.8.2)
|
|
18
|
+
* xrayObservability (v2.8.3)
|
|
19
|
+
* otelObservability (v2.9.x)
|
|
20
|
+
* datadogObservability (v2.9.x)
|
|
21
|
+
*
|
|
22
|
+
* - `agentfootprint/cost-providers`
|
|
23
|
+
* stripeCost (v2.10.x)
|
|
24
|
+
*
|
|
25
|
+
* - `agentfootprint/lens-providers`
|
|
26
|
+
* browserLens / cliLens (v2.12.x)
|
|
27
|
+
*
|
|
28
|
+
* Each adapter lazy-imports its vendor SDK via `lib/lazyRequire.ts`,
|
|
29
|
+
* so consumers who never call a particular factory don't have to
|
|
30
|
+
* install that SDK. Peer-deps are declared in package.json with
|
|
31
|
+
* `peerDependenciesMeta.{name}.optional = true`.
|
|
32
|
+
*/
|
|
33
|
+
export * from './types.js';
|
|
34
|
+
export * from './defaults/index.js';
|
|
35
|
+
export { composeObservability, composeCost, composeLiveStatus, composeLens } from './compose.js';
|
|
36
|
+
export { attachObservabilityStrategy, attachCostStrategy, attachLiveStatusStrategy, } from './attach.js';
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/strategies/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACjG,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,wBAAwB,GAIzB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strategy registry — name → factory for each of the 4 groups.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `src/cache/strategyRegistry.ts` exactly: maps a string name
|
|
5
|
+
* to a factory function that takes vendor-specific config and returns
|
|
6
|
+
* a typed strategy instance. Vendor adapter subpaths self-register on
|
|
7
|
+
* import via side-effect.
|
|
8
|
+
*
|
|
9
|
+
* Two ways consumers wire a strategy:
|
|
10
|
+
*
|
|
11
|
+
* 1. By NAME (registry lookup) — the recommended path for vendor
|
|
12
|
+
* adapters:
|
|
13
|
+
* ```ts
|
|
14
|
+
* import 'agentfootprint/observability-datadog'; // self-registers 'datadog'
|
|
15
|
+
* agent.enable.observability({ vendor: 'datadog', config: { apiKey } });
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* 2. By INSTANCE (explicit pass) — for custom in-house strategies
|
|
19
|
+
* or test mocks:
|
|
20
|
+
* ```ts
|
|
21
|
+
* agent.enable.observability({ strategy: myCustomStrategy });
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* The two paths are mutually exclusive in `EnableOptions` — the type
|
|
25
|
+
* union enforces that consumers pick one.
|
|
26
|
+
*
|
|
27
|
+
* Lookup is exact-match by name (case-insensitive fallback). Unknown
|
|
28
|
+
* names return `undefined`; the consumer's `enable.X` then no-ops
|
|
29
|
+
* (per "do nothing if not configured" rule).
|
|
30
|
+
*/
|
|
31
|
+
// ─── 4 registries (one per group) ────────────────────────────────────
|
|
32
|
+
const OBSERVABILITY_REGISTRY = new Map();
|
|
33
|
+
const COST_REGISTRY = new Map();
|
|
34
|
+
const LIVE_STATUS_REGISTRY = new Map();
|
|
35
|
+
const LENS_REGISTRY = new Map();
|
|
36
|
+
// ─── Register / lookup / list — observability ────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Register a vendor observability strategy by name. Called from the
|
|
39
|
+
* vendor's subpath at module load (side-effect import):
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* // agentfootprint/observability-datadog/index.ts
|
|
43
|
+
* import { registerObservabilityStrategy } from 'agentfootprint/strategies';
|
|
44
|
+
* registerObservabilityStrategy('datadog', (config) => datadogObservability(config));
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* Replacing an existing registration is allowed — most-recent wins.
|
|
48
|
+
* Useful for test mocks.
|
|
49
|
+
*/
|
|
50
|
+
export function registerObservabilityStrategy(name, factory) {
|
|
51
|
+
OBSERVABILITY_REGISTRY.set(name, factory);
|
|
52
|
+
}
|
|
53
|
+
/** Look up an observability factory by vendor name. Case-insensitive
|
|
54
|
+
* fallback. Returns `undefined` when the name is unknown — caller
|
|
55
|
+
* decides to noop or throw. */
|
|
56
|
+
export function getObservabilityStrategy(name) {
|
|
57
|
+
return OBSERVABILITY_REGISTRY.get(name) ?? OBSERVABILITY_REGISTRY.get(name.toLowerCase());
|
|
58
|
+
}
|
|
59
|
+
/** Diagnostic — list all registered vendor names. */
|
|
60
|
+
export function listObservabilityStrategies() {
|
|
61
|
+
return [...OBSERVABILITY_REGISTRY.keys()];
|
|
62
|
+
}
|
|
63
|
+
// ─── Cost ────────────────────────────────────────────────────────────
|
|
64
|
+
export function registerCostStrategy(name, factory) {
|
|
65
|
+
COST_REGISTRY.set(name, factory);
|
|
66
|
+
}
|
|
67
|
+
export function getCostStrategy(name) {
|
|
68
|
+
return COST_REGISTRY.get(name) ?? COST_REGISTRY.get(name.toLowerCase());
|
|
69
|
+
}
|
|
70
|
+
export function listCostStrategies() {
|
|
71
|
+
return [...COST_REGISTRY.keys()];
|
|
72
|
+
}
|
|
73
|
+
// ─── Live status ─────────────────────────────────────────────────────
|
|
74
|
+
export function registerLiveStatusStrategy(name, factory) {
|
|
75
|
+
LIVE_STATUS_REGISTRY.set(name, factory);
|
|
76
|
+
}
|
|
77
|
+
export function getLiveStatusStrategy(name) {
|
|
78
|
+
return LIVE_STATUS_REGISTRY.get(name) ?? LIVE_STATUS_REGISTRY.get(name.toLowerCase());
|
|
79
|
+
}
|
|
80
|
+
export function listLiveStatusStrategies() {
|
|
81
|
+
return [...LIVE_STATUS_REGISTRY.keys()];
|
|
82
|
+
}
|
|
83
|
+
// ─── Lens ────────────────────────────────────────────────────────────
|
|
84
|
+
export function registerLensStrategy(name, factory) {
|
|
85
|
+
LENS_REGISTRY.set(name, factory);
|
|
86
|
+
}
|
|
87
|
+
export function getLensStrategy(name) {
|
|
88
|
+
return LENS_REGISTRY.get(name) ?? LENS_REGISTRY.get(name.toLowerCase());
|
|
89
|
+
}
|
|
90
|
+
export function listLensStrategies() {
|
|
91
|
+
return [...LENS_REGISTRY.keys()];
|
|
92
|
+
}
|
|
93
|
+
// ─── Test helpers ────────────────────────────────────────────────────
|
|
94
|
+
/** Reset every registry to empty. Tests only — not in the public
|
|
95
|
+
* barrel. */
|
|
96
|
+
export function _resetRegistriesForTests() {
|
|
97
|
+
OBSERVABILITY_REGISTRY.clear();
|
|
98
|
+
COST_REGISTRY.clear();
|
|
99
|
+
LIVE_STATUS_REGISTRY.clear();
|
|
100
|
+
LENS_REGISTRY.clear();
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/strategies/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAmBH,wEAAwE;AAExE,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAgC,CAAC;AACvE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAuB,CAAC;AACrD,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAA6B,CAAC;AAClE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAuB,CAAC;AAErD,wEAAwE;AAExE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,6BAA6B,CAAC,IAAY,EAAE,OAA6B;IACvF,sBAAsB,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED;;gCAEgC;AAChC,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,OAAO,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAC5F,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,2BAA2B;IACzC,OAAO,CAAC,GAAG,sBAAsB,CAAC,IAAI,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,wEAAwE;AAExE,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,OAAoB;IACrE,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,CAAC,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,wEAAwE;AAExE,MAAM,UAAU,0BAA0B,CAAC,IAAY,EAAE,OAA0B;IACjF,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,OAAO,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO,CAAC,GAAG,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,wEAAwE;AAExE,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,OAAoB;IACrE,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,CAAC,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,wEAAwE;AAExE;cACc;AACd,MAAM,UAAU,wBAAwB;IACtC,sBAAsB,CAAC,KAAK,EAAE,CAAC;IAC/B,aAAa,CAAC,KAAK,EAAE,CAAC;IACtB,oBAAoB,CAAC,KAAK,EAAE,CAAC;IAC7B,aAAa,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strategy interface types for the v2.8 grouped-enabler architecture.
|
|
3
|
+
*
|
|
4
|
+
* Pattern: Strategy + Bridge + Hexagonal port. See the design memo
|
|
5
|
+
* `docs/inspiration/strategy-everywhere.md`.
|
|
6
|
+
*
|
|
7
|
+
* Four groups, four typed strategy interfaces. Each follows the same
|
|
8
|
+
* shape (one canonical contract, locked at the type level):
|
|
9
|
+
*
|
|
10
|
+
* 1. `name: string` — registry key for auto-registration
|
|
11
|
+
* 2. `capabilities: {...}` — what this strategy supports
|
|
12
|
+
* 3. `onEvent(...)` — hot path; sync, side-effect-only
|
|
13
|
+
* 4. `flush?(): Promise<void>` — optional batch flushing
|
|
14
|
+
* 5. `stop?(): void` — optional teardown
|
|
15
|
+
*
|
|
16
|
+
* Design constraints (from the panel review):
|
|
17
|
+
* - **PASSIVE / non-blocking by construction.** Strategies are
|
|
18
|
+
* observers — they NEVER block the agent loop. Async work
|
|
19
|
+
* (HTTP shipment, disk I/O, batching) is the STRATEGY's internal
|
|
20
|
+
* concern: buffer in `onEvent` (sync), drain in `flush()` (async
|
|
21
|
+
* OK). The dispatcher never awaits a strategy's `onEvent`.
|
|
22
|
+
* - `onEvent` MUST be sync `void`. MUST NOT throw. Errors caught +
|
|
23
|
+
* routed to `_onError` at the dispatch layer; one bad strategy
|
|
24
|
+
* never breaks the agent loop.
|
|
25
|
+
* - Idempotent registration — registering the same `name` twice
|
|
26
|
+
* replaces, doesn't double-fire.
|
|
27
|
+
* - `stop()` is idempotent — halts everything that strategy enabled,
|
|
28
|
+
* nothing else, calling twice is a no-op.
|
|
29
|
+
* - `flush()` is optional, may be sync OR async — strategies that
|
|
30
|
+
* don't batch can omit it. Consumer's `agent.run()` lifecycle
|
|
31
|
+
* calls flush at boundary points (turn end, run end) so batched
|
|
32
|
+
* strategies don't lose tail events. Flush is the ONLY async
|
|
33
|
+
* path; the hot path is always sync.
|
|
34
|
+
*/
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/strategies/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* agentfootprint/observability-providers — vendor observability strategies.
|
|
4
|
+
*
|
|
5
|
+
* Grouped subpath following the parallel-providers pattern v2.5
|
|
6
|
+
* established for `llm-providers` / `tool-providers` /
|
|
7
|
+
* `memory-providers`. Adding a new vendor adds an export here, NOT
|
|
8
|
+
* a new subpath — keeps `package.json#exports` from sprawling.
|
|
9
|
+
*
|
|
10
|
+
* Each adapter lazy-imports its vendor SDK via `lib/lazyRequire.ts`,
|
|
11
|
+
* so consumers who never call a particular factory don't have to
|
|
12
|
+
* install that SDK. Peer-deps are declared in package.json with
|
|
13
|
+
* `peerDependenciesMeta.{name}.optional = true`.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { agentcoreObservability } from 'agentfootprint/observability-providers';
|
|
18
|
+
* import { microtaskBatchDriver } from 'footprintjs/detach';
|
|
19
|
+
*
|
|
20
|
+
* agent.enable.observability({
|
|
21
|
+
* strategy: agentcoreObservability({
|
|
22
|
+
* region: 'us-east-1',
|
|
23
|
+
* logGroupName: '/agentfootprint/my-agent',
|
|
24
|
+
* }),
|
|
25
|
+
* // Recommended — keeps the agent loop unblocked by network latency.
|
|
26
|
+
* detach: { driver: microtaskBatchDriver, mode: 'forget' },
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* Roadmap:
|
|
31
|
+
* - agentcoreObservability ← v2.8.1 (this release)
|
|
32
|
+
* - cloudwatchObservability ← v2.8.2
|
|
33
|
+
* - xrayObservability ← v2.8.3
|
|
34
|
+
* - otelObservability ← v2.9.x
|
|
35
|
+
* - datadogObservability ← v2.9.x
|
|
36
|
+
*/
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.agentcoreObservability = void 0;
|
|
39
|
+
var agentcore_js_1 = require("./adapters/observability/agentcore.js");
|
|
40
|
+
Object.defineProperty(exports, "agentcoreObservability", { enumerable: true, get: function () { return agentcore_js_1.agentcoreObservability; } });
|
|
41
|
+
//# sourceMappingURL=observability-providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability-providers.js","sourceRoot":"","sources":["../src/observability-providers.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;AAEH,sEAG+C;AAF7C,sHAAA,sBAAsB,OAAA"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Wire each grouped strategy to its data source on the dispatcher /
|
|
4
|
+
* recorder substrate. These are the 4 `enable.*` facades' actual
|
|
5
|
+
* implementations; `RunnerBase.enable` calls them with the right
|
|
6
|
+
* dispatcher / attach handle.
|
|
7
|
+
*
|
|
8
|
+
* Pattern: every facade follows the same shape:
|
|
9
|
+
*
|
|
10
|
+
* 1. Resolve strategy (consumer-supplied OR default)
|
|
11
|
+
* 2. Run `strategy.validate?()` — early-fail on misconfig (New Relic
|
|
12
|
+
* panel review)
|
|
13
|
+
* 3. Set up subscription / projection
|
|
14
|
+
* 4. Apply per-strategy event-type filter (`relevantEventTypes`)
|
|
15
|
+
* 5. Apply per-call sample rate
|
|
16
|
+
* 6. Wrap calls in try/catch — route errors to `_onError` (passive
|
|
17
|
+
* recorder rule: never throw to caller)
|
|
18
|
+
* 7. Return Unsubscribe (or handle for lens)
|
|
19
|
+
*/
|
|
20
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
23
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
24
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
25
|
+
}
|
|
26
|
+
Object.defineProperty(o, k2, desc);
|
|
27
|
+
}) : (function(o, m, k, k2) {
|
|
28
|
+
if (k2 === undefined) k2 = k;
|
|
29
|
+
o[k2] = m[k];
|
|
30
|
+
}));
|
|
31
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
32
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33
|
+
}) : function(o, v) {
|
|
34
|
+
o["default"] = v;
|
|
35
|
+
});
|
|
36
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.attachLiveStatusStrategy = exports.attachCostStrategy = exports.attachObservabilityStrategy = void 0;
|
|
45
|
+
const footprintjs_1 = require("footprintjs");
|
|
46
|
+
const thinkingTemplates_js_1 = require("../recorders/observability/thinking/thinkingTemplates.js");
|
|
47
|
+
// Registry-lookup helpers (`getObservabilityStrategy` etc.) are
|
|
48
|
+
// defined in `./registry.js` and used by consumers via the
|
|
49
|
+
// `enable.*({ vendor, config })` path elsewhere — not used in the
|
|
50
|
+
// current attach() implementations, which take `opts.strategy` directly.
|
|
51
|
+
/**
|
|
52
|
+
* Sentinel returned when consumer calls `enable.X()` without supplying
|
|
53
|
+
* a strategy or vendor. We DON'T auto-default — that would be an
|
|
54
|
+
* unwelcome opinion. Consumer chose to call `enable.X` but didn't hand
|
|
55
|
+
* us anywhere to ship; just no-op silently and return a stoppable
|
|
56
|
+
* unsubscribe so the call site stays composable.
|
|
57
|
+
*/
|
|
58
|
+
const NOOP_UNSUBSCRIBE = () => { };
|
|
59
|
+
/** Build a one-stage flowchart that performs `args.work(event)` and
|
|
60
|
+
* routes any thrown error to `args.onError`. The driver schedules
|
|
61
|
+
* this chart per event. */
|
|
62
|
+
function buildDetachWrapperChart(args) {
|
|
63
|
+
return (0, footprintjs_1.flowChart)('agentfootprint:detach:wrapper', async (scope) => {
|
|
64
|
+
const event = scope.$getArgs();
|
|
65
|
+
try {
|
|
66
|
+
args.work(event);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
args.onError?.(err instanceof Error ? err : new Error(String(err)), event);
|
|
70
|
+
}
|
|
71
|
+
}, 'wrap').build();
|
|
72
|
+
}
|
|
73
|
+
let detachExecutorSingleton;
|
|
74
|
+
/** Lazy-import a shared `FlowChartExecutor` we use purely as the
|
|
75
|
+
* bare-executor entry point for `detachAndForget` / `detachAndJoinLater`.
|
|
76
|
+
* No chart actually runs through it — we just need its detach methods. */
|
|
77
|
+
async function getDetachExecutor() {
|
|
78
|
+
if (detachExecutorSingleton)
|
|
79
|
+
return detachExecutorSingleton;
|
|
80
|
+
const fp = await Promise.resolve().then(() => __importStar(require('footprintjs')));
|
|
81
|
+
// Trivial host chart — never run, just satisfies the constructor.
|
|
82
|
+
const noopChart = fp.flowChart('agentfootprint:detach:host', async () => { }, 'host').build();
|
|
83
|
+
detachExecutorSingleton = new fp.FlowChartExecutor(noopChart);
|
|
84
|
+
return detachExecutorSingleton;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Build an event-handling function that respects `opts.detach`.
|
|
88
|
+
*
|
|
89
|
+
* - `opts.detach` undefined → returns a sync handler that runs
|
|
90
|
+
* `work(event)` inline and routes errors to `onError`. Same as
|
|
91
|
+
* pre-v2.8 behavior.
|
|
92
|
+
*
|
|
93
|
+
* - `opts.detach` set → returns a handler that schedules a wrapper
|
|
94
|
+
* chart on the driver. `mode === 'forget'` discards the handle;
|
|
95
|
+
* `mode === 'join-later'` delivers it to `opts.detach.onHandle`.
|
|
96
|
+
*
|
|
97
|
+
* The detached path is async-loaded — the executor singleton is built
|
|
98
|
+
* on first call so consumers who don't enable detach pay zero cost.
|
|
99
|
+
*/
|
|
100
|
+
function buildEventHandler(detach, args) {
|
|
101
|
+
if (!detach) {
|
|
102
|
+
// Sync path — current behavior.
|
|
103
|
+
return (event) => {
|
|
104
|
+
try {
|
|
105
|
+
args.work(event);
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
args.onError?.(err instanceof Error ? err : new Error(String(err)), event);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// Detached path — schedule via the driver. We need the wrapper chart
|
|
113
|
+
// (for the runChild side) and the executor (for the bare-executor
|
|
114
|
+
// entry point that returns / discards the handle).
|
|
115
|
+
const wrapperChart = buildDetachWrapperChart(args);
|
|
116
|
+
const mode = detach.mode ?? 'forget';
|
|
117
|
+
const onHandle = detach.onHandle;
|
|
118
|
+
if (mode === 'join-later' && !onHandle) {
|
|
119
|
+
throw new TypeError(`[enable.*] detach.mode === 'join-later' requires \`onHandle\`. ` +
|
|
120
|
+
`Without it, the returned DetachHandle would be unreachable. ` +
|
|
121
|
+
`Pass \`onHandle: (h) => myHandles.push(h)\` (and await later via ` +
|
|
122
|
+
`Promise.all(myHandles.map(h => h.wait()))).`);
|
|
123
|
+
}
|
|
124
|
+
return (event) => {
|
|
125
|
+
// Lazy-resolve the executor. The Promise here is fire-and-forget
|
|
126
|
+
// itself — we never await it, so the agent loop returns sync. Any
|
|
127
|
+
// error from the import OR the schedule call routes to onError.
|
|
128
|
+
getDetachExecutor()
|
|
129
|
+
.then((exec) => {
|
|
130
|
+
if (mode === 'forget') {
|
|
131
|
+
exec.detachAndForget(detach.driver, wrapperChart, event);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const handle = exec.detachAndJoinLater(detach.driver, wrapperChart, event);
|
|
135
|
+
onHandle(handle);
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
.catch((err) => {
|
|
139
|
+
args.onError?.(err instanceof Error ? err : new Error(String(err)), event);
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const TIER_FILTER = {
|
|
144
|
+
minimal: (t) => t.startsWith('agentfootprint.error.') || t.startsWith('agentfootprint.agent.'),
|
|
145
|
+
standard: (t) => !t.startsWith('agentfootprint.stream.token'),
|
|
146
|
+
firehose: () => true,
|
|
147
|
+
};
|
|
148
|
+
function attachObservabilityStrategy(dispatcher, opts = {}) {
|
|
149
|
+
const strategy = opts.strategy;
|
|
150
|
+
// Consumer chose to call enable.observability() but didn't supply
|
|
151
|
+
// a strategy. Don't auto-default — that imposes an opinion. Just
|
|
152
|
+
// no-op so the call site stays composable.
|
|
153
|
+
if (!strategy)
|
|
154
|
+
return NOOP_UNSUBSCRIBE;
|
|
155
|
+
strategy.validate?.();
|
|
156
|
+
const tierFilter = TIER_FILTER[opts.tier ?? 'standard'];
|
|
157
|
+
const sampleRate = opts.sampleRate ?? 1;
|
|
158
|
+
const relevant = strategy.relevantEventTypes
|
|
159
|
+
? new Set(strategy.relevantEventTypes)
|
|
160
|
+
: null;
|
|
161
|
+
// Build the event handler ONCE per attach call. Sync if no
|
|
162
|
+
// `opts.detach`; otherwise schedules on the driver so the agent
|
|
163
|
+
// loop never blocks on slow exporters.
|
|
164
|
+
const handle = buildEventHandler(opts.detach, {
|
|
165
|
+
work: (event) => strategy.exportEvent(event),
|
|
166
|
+
onError: (err, event) => strategy._onError?.(err, event),
|
|
167
|
+
});
|
|
168
|
+
return dispatcher.on('*', (event) => {
|
|
169
|
+
if (!tierFilter(event.type))
|
|
170
|
+
return;
|
|
171
|
+
if (relevant && !relevant.has(event.type))
|
|
172
|
+
return;
|
|
173
|
+
if (sampleRate < 1 && Math.random() > sampleRate)
|
|
174
|
+
return;
|
|
175
|
+
handle(event);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
exports.attachObservabilityStrategy = attachObservabilityStrategy;
|
|
179
|
+
/**
|
|
180
|
+
* Subscribe to `agentfootprint.cost.tick` events, project payload into
|
|
181
|
+
* the canonical `CostTick` shape, hand to strategy.
|
|
182
|
+
*/
|
|
183
|
+
function attachCostStrategy(dispatcher, opts = {}) {
|
|
184
|
+
const strategy = opts.strategy;
|
|
185
|
+
if (!strategy)
|
|
186
|
+
return NOOP_UNSUBSCRIBE;
|
|
187
|
+
strategy.validate?.();
|
|
188
|
+
// Cost strategy detach mirrors observability — sync by default,
|
|
189
|
+
// schedules on the driver when `opts.detach` is set. Useful when
|
|
190
|
+
// `recordCost` does heavy work (per-tick DB write, vendor budget
|
|
191
|
+
// API, etc.).
|
|
192
|
+
const handle = buildEventHandler(opts.detach, {
|
|
193
|
+
work: (tickInput) => strategy.recordCost(tickInput),
|
|
194
|
+
onError: (err, tickInput) => strategy._onError?.(err, tickInput),
|
|
195
|
+
});
|
|
196
|
+
return dispatcher.on('agentfootprint.cost.tick', (event) => {
|
|
197
|
+
const p = event.payload;
|
|
198
|
+
const tick = {
|
|
199
|
+
cumulativeInputTokens: Number(p.cumulativeInputTokens ?? 0),
|
|
200
|
+
cumulativeOutputTokens: Number(p.cumulativeOutputTokens ?? 0),
|
|
201
|
+
cumulativeCostUsd: Number(p.cumulativeCostUsd ?? 0),
|
|
202
|
+
recentInputTokens: Number(p.recentInputTokens ?? 0),
|
|
203
|
+
recentOutputTokens: Number(p.recentOutputTokens ?? 0),
|
|
204
|
+
recentCostUsd: Number(p.recentCostUsd ?? 0),
|
|
205
|
+
model: String(p.model ?? 'unknown'),
|
|
206
|
+
...(typeof p.iteration === 'number' ? { iteration: p.iteration } : {}),
|
|
207
|
+
...(typeof p.runtimeStageId === 'string' ? { runtimeStageId: p.runtimeStageId } : {}),
|
|
208
|
+
};
|
|
209
|
+
handle(tick);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
exports.attachCostStrategy = attachCostStrategy;
|
|
213
|
+
/**
|
|
214
|
+
* Subscribe to '*', maintain a rolling event log, project current
|
|
215
|
+
* thinking state on each event, render via templates, hand to strategy.
|
|
216
|
+
*
|
|
217
|
+
* Lower bound on emissions: dedupes — only fires `renderStatus` when
|
|
218
|
+
* the rendered line CHANGES (avoids floods on every token).
|
|
219
|
+
*/
|
|
220
|
+
/** Sliding-window cap for `attachLiveStatusStrategy`'s internal event
|
|
221
|
+
* log. Long-lived agent servers would otherwise leak memory through
|
|
222
|
+
* unbounded growth (per OTel SIG panel review). The cap is high
|
|
223
|
+
* enough that `selectThinkingState` always sees the relevant recent
|
|
224
|
+
* history. */
|
|
225
|
+
const LIVE_STATUS_LOG_CAP = 1000;
|
|
226
|
+
function attachLiveStatusStrategy(dispatcher, opts) {
|
|
227
|
+
opts.strategy.validate?.();
|
|
228
|
+
const templates = { ...thinkingTemplates_js_1.defaultThinkingTemplates, ...(opts.templates ?? {}) };
|
|
229
|
+
const ctx = { appName: opts.appName ?? 'Agent' };
|
|
230
|
+
const eventLog = [];
|
|
231
|
+
let lastLine = null;
|
|
232
|
+
return dispatcher.on('*', (event) => {
|
|
233
|
+
eventLog.push(event);
|
|
234
|
+
// Sliding-window — drop oldest when over cap. O(1) amortized
|
|
235
|
+
// because shift() runs only once per overflow.
|
|
236
|
+
while (eventLog.length > LIVE_STATUS_LOG_CAP)
|
|
237
|
+
eventLog.shift();
|
|
238
|
+
const state = (0, thinkingTemplates_js_1.selectThinkingState)(eventLog);
|
|
239
|
+
if (!state) {
|
|
240
|
+
lastLine = null;
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const line = (0, thinkingTemplates_js_1.renderThinkingLine)(state, ctx, templates);
|
|
244
|
+
if (line === null || line === lastLine)
|
|
245
|
+
return;
|
|
246
|
+
lastLine = line;
|
|
247
|
+
try {
|
|
248
|
+
opts.strategy.renderStatus({ line, state });
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
opts.strategy._onError?.(err instanceof Error ? err : new Error(String(err)), event);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
exports.attachLiveStatusStrategy = attachLiveStatusStrategy;
|
|
256
|
+
//# sourceMappingURL=attach.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../../src/strategies/attach.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `compose([...])` — fan-out combinator.
|
|
4
|
+
*
|
|
5
|
+
* Pattern: Composite. Same shape as React's children array, RxJS's
|
|
6
|
+
* `merge`, OTel's `MultiSpanProcessor`. Pass an array of
|
|
7
|
+
* strategies; get back a single strategy that fan-outs each
|
|
8
|
+
* call to every child.
|
|
9
|
+
*
|
|
10
|
+
* Use when:
|
|
11
|
+
* - Multi-vendor pipelines (`compose([datadog(), otel(), console()])`)
|
|
12
|
+
* - Test instrumentation alongside production sink
|
|
13
|
+
* (`compose([inMemorySink(), stripeBilling()])`) so test assertions
|
|
14
|
+
* can read ticks while production also ships
|
|
15
|
+
* - Tier-staging — local dev mirrors what production sees
|
|
16
|
+
*
|
|
17
|
+
* Per-child error isolation: if one child's `exportEvent` throws, the
|
|
18
|
+
* other children still receive the event. The throwing child's
|
|
19
|
+
* `_onError` is called (if present); otherwise the error is logged
|
|
20
|
+
* via `console.warn` once. One bad sink never breaks the chain.
|
|
21
|
+
*
|
|
22
|
+
* Capabilities are OR-ed across children — if any child supports a
|
|
23
|
+
* capability, the composite reports it as supported. The dispatcher
|
|
24
|
+
* uses this to decide whether to bother building event objects at all.
|
|
25
|
+
*
|
|
26
|
+
* Idempotent operations:
|
|
27
|
+
* - `flush()` — calls every child's `flush()` (sync or async)
|
|
28
|
+
* concurrently, awaits all
|
|
29
|
+
* - `stop()` — calls every child's `stop()` once, in order; failures
|
|
30
|
+
* in one child don't block the others
|
|
31
|
+
*/
|
|
32
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
+
exports.composeLens = exports.composeLiveStatus = exports.composeCost = exports.composeObservability = void 0;
|
|
34
|
+
// ─── Internal helpers ────────────────────────────────────────────────
|
|
35
|
+
/** Run `cb()` for every child; isolate errors via the child's
|
|
36
|
+
* `_onError` or a single `console.warn`. */
|
|
37
|
+
function safeForEach(children, cb) {
|
|
38
|
+
for (const child of children) {
|
|
39
|
+
try {
|
|
40
|
+
cb(child);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
44
|
+
if (child._onError) {
|
|
45
|
+
try {
|
|
46
|
+
child._onError(e);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Even _onError can throw; final fallback is silent drop —
|
|
50
|
+
// we MUST NOT propagate to the caller (passive recorder rule).
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// eslint-disable-next-line no-console
|
|
55
|
+
console.warn('[compose] child threw and has no _onError:', e.message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** OR-merge a capability bag across children. Generic over the
|
|
61
|
+
* concrete capability type — the runtime walk treats every entry as
|
|
62
|
+
* `boolean | undefined` regardless of the typed shape. */
|
|
63
|
+
function mergeCaps(children) {
|
|
64
|
+
const merged = {};
|
|
65
|
+
for (const c of children) {
|
|
66
|
+
for (const [k, v] of Object.entries(c.capabilities)) {
|
|
67
|
+
if (v === true)
|
|
68
|
+
merged[k] = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return merged;
|
|
72
|
+
}
|
|
73
|
+
/** Run every child's optional `flush` concurrently. */
|
|
74
|
+
async function flushAll(children) {
|
|
75
|
+
const promises = [];
|
|
76
|
+
for (const c of children) {
|
|
77
|
+
if (!c.flush)
|
|
78
|
+
continue;
|
|
79
|
+
try {
|
|
80
|
+
const result = c.flush();
|
|
81
|
+
if (result instanceof Promise)
|
|
82
|
+
promises.push(result.catch(() => { }));
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// ignore — passive recorder rule
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (promises.length > 0)
|
|
89
|
+
await Promise.all(promises);
|
|
90
|
+
}
|
|
91
|
+
function stopAll(children) {
|
|
92
|
+
for (const c of children) {
|
|
93
|
+
if (!c.stop)
|
|
94
|
+
continue;
|
|
95
|
+
try {
|
|
96
|
+
c.stop();
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// ignore — passive recorder rule
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// ─── Composite factories — one per strategy kind ─────────────────────
|
|
104
|
+
/**
|
|
105
|
+
* Compose multiple ObservabilityStrategies into a single fan-out.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* const all = composeObservability([
|
|
109
|
+
* consoleObservability(),
|
|
110
|
+
* datadogObservability({ apiKey }),
|
|
111
|
+
* otelObservability(tracer),
|
|
112
|
+
* ]);
|
|
113
|
+
*/
|
|
114
|
+
function composeObservability(children) {
|
|
115
|
+
return {
|
|
116
|
+
name: 'compose',
|
|
117
|
+
capabilities: mergeCaps(children),
|
|
118
|
+
exportEvent(event) {
|
|
119
|
+
safeForEach(children, (c) => c.exportEvent(event));
|
|
120
|
+
},
|
|
121
|
+
flush: () => flushAll(children),
|
|
122
|
+
stop: () => stopAll(children),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
exports.composeObservability = composeObservability;
|
|
126
|
+
/** Compose CostStrategies. */
|
|
127
|
+
function composeCost(children) {
|
|
128
|
+
return {
|
|
129
|
+
name: 'compose',
|
|
130
|
+
capabilities: mergeCaps(children),
|
|
131
|
+
recordCost(tick) {
|
|
132
|
+
safeForEach(children, (c) => c.recordCost(tick));
|
|
133
|
+
},
|
|
134
|
+
flush: () => flushAll(children),
|
|
135
|
+
stop: () => stopAll(children),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
exports.composeCost = composeCost;
|
|
139
|
+
/** Compose LiveStatusStrategies. */
|
|
140
|
+
function composeLiveStatus(children) {
|
|
141
|
+
return {
|
|
142
|
+
name: 'compose',
|
|
143
|
+
capabilities: mergeCaps(children),
|
|
144
|
+
renderStatus(update) {
|
|
145
|
+
safeForEach(children, (c) => c.renderStatus(update));
|
|
146
|
+
},
|
|
147
|
+
flush: () => flushAll(children),
|
|
148
|
+
stop: () => stopAll(children),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
exports.composeLiveStatus = composeLiveStatus;
|
|
152
|
+
/** Compose LensStrategies. */
|
|
153
|
+
function composeLens(children) {
|
|
154
|
+
return {
|
|
155
|
+
name: 'compose',
|
|
156
|
+
capabilities: mergeCaps(children),
|
|
157
|
+
renderGraph(update) {
|
|
158
|
+
safeForEach(children, (c) => c.renderGraph(update));
|
|
159
|
+
},
|
|
160
|
+
flush: () => flushAll(children),
|
|
161
|
+
stop: () => stopAll(children),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
exports.composeLens = composeLens;
|
|
165
|
+
//# sourceMappingURL=compose.js.map
|