@revealui/ai 0.8.0 → 0.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 +25 -12
- package/dist/client/hooks/useAgentStream.d.ts.map +1 -1
- package/dist/client/hooks/useAgentStream.js +1 -29
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/inference/context-assembly.d.ts.map +1 -1
- package/dist/inference/context-assembly.js +1 -3
- package/dist/inference/overflow-compressor.d.ts.map +1 -1
- package/dist/inference/overflow-compressor.js +1 -3
- package/dist/ingestion/pipeline.d.ts.map +1 -1
- package/dist/ingestion/pipeline.js +1 -3
- package/dist/ingestion/text-splitter.d.ts.map +1 -1
- package/dist/ingestion/text-splitter.js +1 -3
- package/dist/internal/token-estimate.d.ts +6 -0
- package/dist/internal/token-estimate.d.ts.map +1 -0
- package/dist/internal/token-estimate.js +7 -0
- package/dist/llm/client.d.ts +4 -3
- package/dist/llm/client.d.ts.map +1 -1
- package/dist/llm/client.js +11 -4
- package/dist/llm/local-ai-profile.d.ts +39 -0
- package/dist/llm/local-ai-profile.d.ts.map +1 -0
- package/dist/llm/local-ai-profile.js +165 -0
- package/dist/llm/providers/inference-snaps.d.ts +24 -13
- package/dist/llm/providers/inference-snaps.d.ts.map +1 -1
- package/dist/llm/providers/inference-snaps.js +21 -17
- package/dist/llm/providers/us-origin-snaps.d.ts +79 -0
- package/dist/llm/providers/us-origin-snaps.d.ts.map +1 -0
- package/dist/llm/providers/us-origin-snaps.js +108 -0
- package/dist/observability/export.d.ts +78 -0
- package/dist/observability/export.d.ts.map +1 -0
- package/dist/observability/export.js +229 -0
- package/dist/observability/index.d.ts +19 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +16 -0
- package/dist/observability/instrumentation.d.ts +68 -0
- package/dist/observability/instrumentation.d.ts.map +1 -0
- package/dist/observability/instrumentation.js +219 -0
- package/dist/observability/storage.d.ts +39 -0
- package/dist/observability/storage.d.ts.map +1 -0
- package/dist/observability/storage.js +184 -0
- package/dist/orchestration/runtime.d.ts +7 -0
- package/dist/orchestration/runtime.d.ts.map +1 -1
- package/dist/orchestration/runtime.js +9 -2
- package/dist/orchestration/ticket-agent.d.ts +10 -0
- package/dist/orchestration/ticket-agent.d.ts.map +1 -1
- package/dist/orchestration/ticket-agent.js +7 -1
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +4 -0
- package/dist/skills/integration/agent-skill-provider.d.ts +0 -5
- package/dist/skills/integration/agent-skill-provider.d.ts.map +1 -1
- package/dist/skills/integration/agent-skill-provider.js +3 -9
- package/dist/tools/admin/factory.d.ts +6 -0
- package/dist/tools/admin/factory.d.ts.map +1 -1
- package/dist/tools/admin/factory.js +3 -2
- package/dist/tools/coding/index.d.ts +6 -0
- package/dist/tools/coding/index.d.ts.map +1 -1
- package/dist/tools/coding/index.js +7 -2
- package/dist/tools/governance.d.ts +37 -0
- package/dist/tools/governance.d.ts.map +1 -0
- package/dist/tools/governance.js +42 -0
- package/dist/tools/integrity-audit.d.ts +27 -0
- package/dist/tools/integrity-audit.d.ts.map +1 -0
- package/dist/tools/integrity-audit.js +64 -0
- package/dist/tools/mcp-adapter.d.ts +23 -3
- package/dist/tools/mcp-adapter.d.ts.map +1 -1
- package/dist/tools/mcp-adapter.js +189 -132
- package/dist/tools/mcp-sampling.d.ts +3 -3
- package/dist/tools/mcp-sampling.js +3 -3
- package/dist/tools/web/duck-duck-go.d.ts.map +1 -1
- package/dist/tools/web/duck-duck-go.js +1 -4
- package/dist/tools/web/exa.d.ts.map +1 -1
- package/dist/tools/web/exa.js +1 -4
- package/dist/tools/web/tavily.d.ts.map +1 -1
- package/dist/tools/web/tavily.js +1 -4
- package/package.json +68 -33
|
@@ -4,35 +4,45 @@
|
|
|
4
4
|
* Local inference via Canonical's inference-snaps OpenAI-compatible API.
|
|
5
5
|
* No API key required. Zero cost, fully offline, hardware-optimized.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
7
|
+
* Product hardline: US-origin snap models only (see us-origin-snaps.ts).
|
|
8
|
+
* Allowlisted snaps (install these):
|
|
9
|
+
* nemotron-3-nano - NVIDIA general + tools (default)
|
|
10
|
+
* nemotron-3-nano-omni - NVIDIA multimodal
|
|
11
|
+
* gemma3 / gemma4 - Google general + vision + tools
|
|
12
|
+
*
|
|
13
|
+
* Canonical also publishes non-US snaps (deepseek-r1, qwen-*, glm-*). Those
|
|
14
|
+
* are rejected at construction unless REVEALUI_ALLOW_NON_US_MODELS=1.
|
|
14
15
|
*
|
|
15
16
|
* Install a model:
|
|
16
|
-
* sudo snap install
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* sudo snap install nemotron-3-nano
|
|
18
|
+
* nemotron-3-nano set http.port=9090 # optional: change port
|
|
19
|
+
* nemotron-3-nano status # shows base URL and available models
|
|
19
20
|
*
|
|
20
21
|
* Set env vars:
|
|
21
22
|
* INFERENCE_SNAPS_BASE_URL=http://localhost:9090/v1
|
|
22
|
-
* LLM_MODEL=
|
|
23
|
-
* LLM_EMBED_MODEL=
|
|
23
|
+
* LLM_MODEL=nemotron-3-nano # must match an allowlisted snap model ID
|
|
24
|
+
* LLM_EMBED_MODEL=nemotron-3-nano
|
|
24
25
|
*
|
|
25
26
|
* Docs: https://documentation.ubuntu.com/inference-snaps
|
|
26
27
|
*/
|
|
27
28
|
import type { Embedding, LLMChatOptions, LLMChunk, LLMEmbedOptions, LLMProvider, LLMProviderConfig, LLMResponse, LLMStreamOptions, Message, ReasonerCapabilities } from './base.js';
|
|
29
|
+
import { DEFAULT_US_ORIGIN_INFERENCE_SNAP } from './us-origin-snaps.js';
|
|
28
30
|
export interface InferenceSnapsProviderConfig extends Omit<LLMProviderConfig, 'apiKey'> {
|
|
29
31
|
apiKey?: string;
|
|
30
32
|
/** Base URL of the inference-snaps service, e.g. http://localhost:9090/v1 */
|
|
31
33
|
baseURL: string;
|
|
32
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Chat/vision model name — must match an allowlisted snap model ID
|
|
36
|
+
* (e.g. 'nemotron-3-nano', 'gemma4'). See US_ORIGIN_INFERENCE_SNAP_IDS.
|
|
37
|
+
*/
|
|
33
38
|
model?: string;
|
|
34
39
|
/** Embedding model name. Defaults to the chat model when omitted. */
|
|
35
40
|
embedModel?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Bypass US-origin allowlist for this instance (operator/tests only).
|
|
43
|
+
* Prefer the process env REVEALUI_ALLOW_NON_US_MODELS=1 when needed.
|
|
44
|
+
*/
|
|
45
|
+
allowNonUsModels?: boolean;
|
|
36
46
|
}
|
|
37
47
|
export declare class InferenceSnapsProvider implements LLMProvider {
|
|
38
48
|
private inner;
|
|
@@ -44,4 +54,5 @@ export declare class InferenceSnapsProvider implements LLMProvider {
|
|
|
44
54
|
stream(messages: Message[], options?: LLMStreamOptions): AsyncIterable<LLMChunk>;
|
|
45
55
|
embed(text: string | string[], _options?: LLMEmbedOptions): Promise<Embedding | Embedding[]>;
|
|
46
56
|
}
|
|
57
|
+
export { DEFAULT_US_ORIGIN_INFERENCE_SNAP };
|
|
47
58
|
//# sourceMappingURL=inference-snaps.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inference-snaps.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/inference-snaps.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"inference-snaps.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/inference-snaps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,cAAc,EACd,QAAQ,EACR,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,OAAO,EACP,oBAAoB,EACrB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAEL,gCAAgC,EACjC,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,sBAAuB,YAAW,WAAW;IACxD,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,4BAA4B;IAchD,YAAY,IAAI,oBAAoB;IAgBpC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IAIzE,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,aAAa,CAAC,QAAQ,CAAC;IAI1E,KAAK,CACT,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,QAAQ,CAAC,EAAE,eAAe,GACzB,OAAO,CAAC,SAAS,GAAG,SAAS,EAAE,CAAC;CAsBpC;AAED,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
|
|
@@ -4,46 +4,49 @@
|
|
|
4
4
|
* Local inference via Canonical's inference-snaps OpenAI-compatible API.
|
|
5
5
|
* No API key required. Zero cost, fully offline, hardware-optimized.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
7
|
+
* Product hardline: US-origin snap models only (see us-origin-snaps.ts).
|
|
8
|
+
* Allowlisted snaps (install these):
|
|
9
|
+
* nemotron-3-nano - NVIDIA general + tools (default)
|
|
10
|
+
* nemotron-3-nano-omni - NVIDIA multimodal
|
|
11
|
+
* gemma3 / gemma4 - Google general + vision + tools
|
|
12
|
+
*
|
|
13
|
+
* Canonical also publishes non-US snaps (deepseek-r1, qwen-*, glm-*). Those
|
|
14
|
+
* are rejected at construction unless REVEALUI_ALLOW_NON_US_MODELS=1.
|
|
14
15
|
*
|
|
15
16
|
* Install a model:
|
|
16
|
-
* sudo snap install
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* sudo snap install nemotron-3-nano
|
|
18
|
+
* nemotron-3-nano set http.port=9090 # optional: change port
|
|
19
|
+
* nemotron-3-nano status # shows base URL and available models
|
|
19
20
|
*
|
|
20
21
|
* Set env vars:
|
|
21
22
|
* INFERENCE_SNAPS_BASE_URL=http://localhost:9090/v1
|
|
22
|
-
* LLM_MODEL=
|
|
23
|
-
* LLM_EMBED_MODEL=
|
|
23
|
+
* LLM_MODEL=nemotron-3-nano # must match an allowlisted snap model ID
|
|
24
|
+
* LLM_EMBED_MODEL=nemotron-3-nano
|
|
24
25
|
*
|
|
25
26
|
* Docs: https://documentation.ubuntu.com/inference-snaps
|
|
26
27
|
*/
|
|
27
28
|
import { OpenAICompatProvider } from './openai-compat.js';
|
|
29
|
+
import { assertUsOriginInferenceSnap, DEFAULT_US_ORIGIN_INFERENCE_SNAP, } from './us-origin-snaps.js';
|
|
28
30
|
export class InferenceSnapsProvider {
|
|
29
31
|
inner;
|
|
30
32
|
embedModel;
|
|
31
33
|
baseURL;
|
|
32
34
|
constructor(config) {
|
|
33
35
|
this.baseURL = config.baseURL;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const assertOpts = { allowNonUs: config.allowNonUsModels === true };
|
|
37
|
+
const model = assertUsOriginInferenceSnap(config.model, assertOpts);
|
|
38
|
+
this.embedModel = assertUsOriginInferenceSnap(config.embedModel ?? model, assertOpts);
|
|
36
39
|
this.inner = new OpenAICompatProvider({
|
|
37
40
|
...config,
|
|
38
41
|
// inference-snaps ignores the API key; OpenAI client requires a non-empty value
|
|
39
42
|
apiKey: config.apiKey ?? 'inference-snaps',
|
|
40
43
|
baseURL: config.baseURL,
|
|
41
|
-
model
|
|
44
|
+
model,
|
|
42
45
|
});
|
|
43
46
|
}
|
|
44
47
|
capabilities() {
|
|
45
|
-
// Profile for the default model (
|
|
46
|
-
// negotiation (e.g.
|
|
48
|
+
// Profile for the default US-origin model (text + tools). Per-model capability
|
|
49
|
+
// negotiation (e.g. nemotron-3-nano-omni vision) is a follow-up.
|
|
47
50
|
return {
|
|
48
51
|
providerTag: 'inference-snaps',
|
|
49
52
|
tools: true,
|
|
@@ -80,3 +83,4 @@ export class InferenceSnapsProvider {
|
|
|
80
83
|
return Array.isArray(text) ? embeddings : embeddings[0];
|
|
81
84
|
}
|
|
82
85
|
}
|
|
86
|
+
export { DEFAULT_US_ORIGIN_INFERENCE_SNAP };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-origin Inference Snap allowlist (product hardline).
|
|
3
|
+
*
|
|
4
|
+
* Canonical's snap catalog includes PRC-origin models (DeepSeek, Qwen, GLM).
|
|
5
|
+
* RevealUI product local inference is **US-origin weights only**, fail-closed.
|
|
6
|
+
*
|
|
7
|
+
* Definition: open weights published by an organization whose ultimate parent
|
|
8
|
+
* is incorporated in the United States. Packaging (Canonical snaps) is not origin.
|
|
9
|
+
*
|
|
10
|
+
* Allowlist today (Canonical catalog, 2026-07):
|
|
11
|
+
* - nemotron-3-nano / nemotron-3-nano-omni — NVIDIA
|
|
12
|
+
* - gemma3 / gemma4 — Google (Alphabet)
|
|
13
|
+
*
|
|
14
|
+
* Escape (operator-only, never seed, always loud in the error path):
|
|
15
|
+
* REVEALUI_ALLOW_NON_US_MODELS=1
|
|
16
|
+
*
|
|
17
|
+
* Companion ADR: .jv docs/decisions/2026-07-24-us-origin-inference-snaps.md
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Product install/list catalog (snap name + operator-facing description).
|
|
21
|
+
* SSOT for harnesses InferenceService + Studio install UIs.
|
|
22
|
+
* Order: product default first (nemotron for capable hosts; gemma preferred on low-RAM via profile daily).
|
|
23
|
+
*/
|
|
24
|
+
export declare const PRODUCT_INFERENCE_SNAP_CATALOG: readonly [{
|
|
25
|
+
readonly id: "nemotron-3-nano";
|
|
26
|
+
readonly description: "NVIDIA (US) — general + tools; product default on capable hosts";
|
|
27
|
+
}, {
|
|
28
|
+
readonly id: "nemotron-3-nano-omni";
|
|
29
|
+
readonly description: "NVIDIA (US) — multimodal (text/image/video/audio in)";
|
|
30
|
+
}, {
|
|
31
|
+
readonly id: "gemma4";
|
|
32
|
+
readonly description: "Google (US) — general + vision + tools";
|
|
33
|
+
}, {
|
|
34
|
+
readonly id: "gemma3";
|
|
35
|
+
readonly description: "Google (US) — general + vision; prefer 270m on low-RAM hosts";
|
|
36
|
+
}];
|
|
37
|
+
export type UsOriginInferenceSnapId = (typeof PRODUCT_INFERENCE_SNAP_CATALOG)[number]['id'];
|
|
38
|
+
/** Snap model IDs permitted for product Inference Snaps usage. */
|
|
39
|
+
export declare const US_ORIGIN_INFERENCE_SNAP_IDS: readonly UsOriginInferenceSnapId[];
|
|
40
|
+
/** Default chat/embed model when none is specified (env factory / provider). */
|
|
41
|
+
export declare const DEFAULT_US_ORIGIN_INFERENCE_SNAP: UsOriginInferenceSnapId;
|
|
42
|
+
/** Preferred snap on constrained hosts (profile `snaps` tier). */
|
|
43
|
+
export declare const DEFAULT_LOW_RAM_INFERENCE_SNAP: UsOriginInferenceSnapId;
|
|
44
|
+
/** Preferred Ollama model for profile `daily` tier (fits ~4GB WSL). */
|
|
45
|
+
export declare const DEFAULT_DAILY_OLLAMA_MODEL = "gemma3:1b";
|
|
46
|
+
/** Operator escape env var. Never set in customer seed or CI green paths. */
|
|
47
|
+
export declare const NON_US_MODELS_ESCAPE_ENV = "REVEALUI_ALLOW_NON_US_MODELS";
|
|
48
|
+
export declare class NonUsOriginInferenceSnapError extends Error {
|
|
49
|
+
readonly code: "NON_US_ORIGIN_INFERENCE_SNAP";
|
|
50
|
+
readonly modelId: string;
|
|
51
|
+
constructor(modelId: string);
|
|
52
|
+
}
|
|
53
|
+
/** Normalize a snap model id for allowlist comparison. */
|
|
54
|
+
export declare function normalizeInferenceSnapModelId(modelId: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* True when the model id is on the US-origin product allowlist.
|
|
57
|
+
*
|
|
58
|
+
* Accepts exact snap ids (`nemotron-3-nano`) and engine-served variants that
|
|
59
|
+
* Canonical publishes under the same snap (e.g.
|
|
60
|
+
* `nemotron-3-nano-30b-a3b-q4-k-m`, `gemma4:e2b` style suffixes with `-` or `:`).
|
|
61
|
+
* Match longest snap id first so `nemotron-3-nano-omni` wins over `nemotron-3-nano`.
|
|
62
|
+
*/
|
|
63
|
+
export declare function isUsOriginInferenceSnap(modelId: string): boolean;
|
|
64
|
+
/** True when the operator escape hatch is enabled. */
|
|
65
|
+
export declare function isNonUsModelsEscapeEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
66
|
+
export interface AssertUsOriginInferenceSnapOptions {
|
|
67
|
+
/** Force-allow non-US models (tests / explicit callers). Overrides env when true. */
|
|
68
|
+
allowNonUs?: boolean;
|
|
69
|
+
/** Env source for the escape hatch (defaults to process.env). */
|
|
70
|
+
env?: NodeJS.ProcessEnv;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolve and enforce the US-origin allowlist.
|
|
74
|
+
*
|
|
75
|
+
* @returns the model id to use (default when empty/undefined)
|
|
76
|
+
* @throws {NonUsOriginInferenceSnapError} when model is off-allowlist and escape is off
|
|
77
|
+
*/
|
|
78
|
+
export declare function assertUsOriginInferenceSnap(modelId: string | undefined, options?: AssertUsOriginInferenceSnapOptions): string;
|
|
79
|
+
//# sourceMappingURL=us-origin-snaps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"us-origin-snaps.d.ts","sourceRoot":"","sources":["../../../src/llm/providers/us-origin-snaps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;GAIG;AACH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;EAiBjC,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAE5F,kEAAkE;AAClE,eAAO,MAAM,4BAA4B,EAAE,SAAS,uBAAuB,EAClB,CAAC;AAE1D,gFAAgF;AAChF,eAAO,MAAM,gCAAgC,EAAE,uBAA2C,CAAC;AAE3F,kEAAkE;AAClE,eAAO,MAAM,8BAA8B,EAAE,uBAAkC,CAAC;AAEhF,uEAAuE;AACvE,eAAO,MAAM,0BAA0B,cAAc,CAAC;AAEtD,6EAA6E;AAC7E,eAAO,MAAM,wBAAwB,iCAAiC,CAAC;AAEvE,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,IAAI,EAAG,8BAA8B,CAAU;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,MAAM;CAW5B;AAED,0DAA0D;AAC1D,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQhE;AAED,sDAAsD;AACtD,wBAAgB,0BAA0B,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAGxF;AAED,MAAM,WAAW,kCAAkC;IACjD,qFAAqF;IACrF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,CAAC,EAAE,kCAAkC,GAC3C,MAAM,CAcR"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-origin Inference Snap allowlist (product hardline).
|
|
3
|
+
*
|
|
4
|
+
* Canonical's snap catalog includes PRC-origin models (DeepSeek, Qwen, GLM).
|
|
5
|
+
* RevealUI product local inference is **US-origin weights only**, fail-closed.
|
|
6
|
+
*
|
|
7
|
+
* Definition: open weights published by an organization whose ultimate parent
|
|
8
|
+
* is incorporated in the United States. Packaging (Canonical snaps) is not origin.
|
|
9
|
+
*
|
|
10
|
+
* Allowlist today (Canonical catalog, 2026-07):
|
|
11
|
+
* - nemotron-3-nano / nemotron-3-nano-omni — NVIDIA
|
|
12
|
+
* - gemma3 / gemma4 — Google (Alphabet)
|
|
13
|
+
*
|
|
14
|
+
* Escape (operator-only, never seed, always loud in the error path):
|
|
15
|
+
* REVEALUI_ALLOW_NON_US_MODELS=1
|
|
16
|
+
*
|
|
17
|
+
* Companion ADR: .jv docs/decisions/2026-07-24-us-origin-inference-snaps.md
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Product install/list catalog (snap name + operator-facing description).
|
|
21
|
+
* SSOT for harnesses InferenceService + Studio install UIs.
|
|
22
|
+
* Order: product default first (nemotron for capable hosts; gemma preferred on low-RAM via profile daily).
|
|
23
|
+
*/
|
|
24
|
+
export const PRODUCT_INFERENCE_SNAP_CATALOG = [
|
|
25
|
+
{
|
|
26
|
+
id: 'nemotron-3-nano',
|
|
27
|
+
description: 'NVIDIA (US) — general + tools; product default on capable hosts',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: 'nemotron-3-nano-omni',
|
|
31
|
+
description: 'NVIDIA (US) — multimodal (text/image/video/audio in)',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: 'gemma4',
|
|
35
|
+
description: 'Google (US) — general + vision + tools',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'gemma3',
|
|
39
|
+
description: 'Google (US) — general + vision; prefer 270m on low-RAM hosts',
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
/** Snap model IDs permitted for product Inference Snaps usage. */
|
|
43
|
+
export const US_ORIGIN_INFERENCE_SNAP_IDS = PRODUCT_INFERENCE_SNAP_CATALOG.map((entry) => entry.id);
|
|
44
|
+
/** Default chat/embed model when none is specified (env factory / provider). */
|
|
45
|
+
export const DEFAULT_US_ORIGIN_INFERENCE_SNAP = 'nemotron-3-nano';
|
|
46
|
+
/** Preferred snap on constrained hosts (profile `snaps` tier). */
|
|
47
|
+
export const DEFAULT_LOW_RAM_INFERENCE_SNAP = 'gemma3';
|
|
48
|
+
/** Preferred Ollama model for profile `daily` tier (fits ~4GB WSL). */
|
|
49
|
+
export const DEFAULT_DAILY_OLLAMA_MODEL = 'gemma3:1b';
|
|
50
|
+
/** Operator escape env var. Never set in customer seed or CI green paths. */
|
|
51
|
+
export const NON_US_MODELS_ESCAPE_ENV = 'REVEALUI_ALLOW_NON_US_MODELS';
|
|
52
|
+
export class NonUsOriginInferenceSnapError extends Error {
|
|
53
|
+
code = 'NON_US_ORIGIN_INFERENCE_SNAP';
|
|
54
|
+
modelId;
|
|
55
|
+
constructor(modelId) {
|
|
56
|
+
super(`Inference Snap model "${modelId}" is not on the US-origin allowlist ` +
|
|
57
|
+
`(${US_ORIGIN_INFERENCE_SNAP_IDS.join(', ')}). ` +
|
|
58
|
+
'Product local inference is US-origin snaps only. ' +
|
|
59
|
+
`Install: sudo snap install ${DEFAULT_US_ORIGIN_INFERENCE_SNAP}. ` +
|
|
60
|
+
`Operator escape (audited, never seed): ${NON_US_MODELS_ESCAPE_ENV}=1`);
|
|
61
|
+
this.name = 'NonUsOriginInferenceSnapError';
|
|
62
|
+
this.modelId = modelId;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Normalize a snap model id for allowlist comparison. */
|
|
66
|
+
export function normalizeInferenceSnapModelId(modelId) {
|
|
67
|
+
return modelId.trim().toLowerCase();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* True when the model id is on the US-origin product allowlist.
|
|
71
|
+
*
|
|
72
|
+
* Accepts exact snap ids (`nemotron-3-nano`) and engine-served variants that
|
|
73
|
+
* Canonical publishes under the same snap (e.g.
|
|
74
|
+
* `nemotron-3-nano-30b-a3b-q4-k-m`, `gemma4:e2b` style suffixes with `-` or `:`).
|
|
75
|
+
* Match longest snap id first so `nemotron-3-nano-omni` wins over `nemotron-3-nano`.
|
|
76
|
+
*/
|
|
77
|
+
export function isUsOriginInferenceSnap(modelId) {
|
|
78
|
+
const id = normalizeInferenceSnapModelId(modelId);
|
|
79
|
+
const snaps = [...US_ORIGIN_INFERENCE_SNAP_IDS].sort((a, b) => b.length - a.length);
|
|
80
|
+
for (const snap of snaps) {
|
|
81
|
+
if (id === snap)
|
|
82
|
+
return true;
|
|
83
|
+
if (id.startsWith(`${snap}-`) || id.startsWith(`${snap}:`))
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
/** True when the operator escape hatch is enabled. */
|
|
89
|
+
export function isNonUsModelsEscapeEnabled(env = process.env) {
|
|
90
|
+
const value = env[NON_US_MODELS_ESCAPE_ENV];
|
|
91
|
+
return value === '1' || value === 'true';
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Resolve and enforce the US-origin allowlist.
|
|
95
|
+
*
|
|
96
|
+
* @returns the model id to use (default when empty/undefined)
|
|
97
|
+
* @throws {NonUsOriginInferenceSnapError} when model is off-allowlist and escape is off
|
|
98
|
+
*/
|
|
99
|
+
export function assertUsOriginInferenceSnap(modelId, options) {
|
|
100
|
+
const resolved = modelId !== undefined && modelId.trim() !== ''
|
|
101
|
+
? modelId.trim()
|
|
102
|
+
: DEFAULT_US_ORIGIN_INFERENCE_SNAP;
|
|
103
|
+
const allowNonUs = options?.allowNonUs === true || isNonUsModelsEscapeEnabled(options?.env ?? process.env);
|
|
104
|
+
if (!(allowNonUs || isUsOriginInferenceSnap(resolved))) {
|
|
105
|
+
throw new NonUsOriginInferenceSnapError(resolved);
|
|
106
|
+
}
|
|
107
|
+
return resolved;
|
|
108
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @revealui/ai - Export Utilities
|
|
3
|
+
*
|
|
4
|
+
* Export agent events to various formats (JSON, CSV, NDJSON).
|
|
5
|
+
*/
|
|
6
|
+
import type { AgentEventLogger } from './logger.js';
|
|
7
|
+
import type { AnyAgentEvent, EventFilter } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Export events to JSON format
|
|
10
|
+
*/
|
|
11
|
+
export declare function exportToJSON(events: AnyAgentEvent[], options?: {
|
|
12
|
+
pretty?: boolean;
|
|
13
|
+
metadata?: Record<string, unknown>;
|
|
14
|
+
}): string;
|
|
15
|
+
/**
|
|
16
|
+
* Export events to CSV format
|
|
17
|
+
*/
|
|
18
|
+
export declare function exportToCSV(events: AnyAgentEvent[]): string;
|
|
19
|
+
/**
|
|
20
|
+
* Export events to NDJSON format (newline-delimited JSON)
|
|
21
|
+
*/
|
|
22
|
+
export declare function exportToNDJSON(events: AnyAgentEvent[]): string;
|
|
23
|
+
/**
|
|
24
|
+
* Export events to a file (Node.js)
|
|
25
|
+
*/
|
|
26
|
+
export declare function exportToFile(events: AnyAgentEvent[], filePath: string, format?: 'json' | 'csv' | 'ndjson'): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Create a downloadable file blob (Browser)
|
|
29
|
+
*/
|
|
30
|
+
export declare function createDownloadableBlob(events: AnyAgentEvent[], format?: 'json' | 'csv' | 'ndjson'): Blob;
|
|
31
|
+
/**
|
|
32
|
+
* Trigger download in browser
|
|
33
|
+
*/
|
|
34
|
+
export declare function downloadEvents(events: AnyAgentEvent[], filename: string, format?: 'json' | 'csv' | 'ndjson'): void;
|
|
35
|
+
/**
|
|
36
|
+
* Export helper class with logger integration
|
|
37
|
+
*/
|
|
38
|
+
export declare class EventExporter {
|
|
39
|
+
private logger;
|
|
40
|
+
constructor(logger: AgentEventLogger);
|
|
41
|
+
/**
|
|
42
|
+
* Export all events
|
|
43
|
+
*/
|
|
44
|
+
exportAll(format?: 'json' | 'csv' | 'ndjson'): string;
|
|
45
|
+
/**
|
|
46
|
+
* Export filtered events
|
|
47
|
+
*/
|
|
48
|
+
exportFiltered(filter: EventFilter, format?: 'json' | 'csv' | 'ndjson'): string;
|
|
49
|
+
/**
|
|
50
|
+
* Export to file (Node.js)
|
|
51
|
+
*/
|
|
52
|
+
exportToFile(filePath: string, format?: 'json' | 'csv' | 'ndjson', filter?: EventFilter): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Download in browser
|
|
55
|
+
*/
|
|
56
|
+
download(filename: string, format?: 'json' | 'csv' | 'ndjson', filter?: EventFilter): void;
|
|
57
|
+
/**
|
|
58
|
+
* Export by time range
|
|
59
|
+
*/
|
|
60
|
+
exportTimeRange(start: Date, end: Date, format?: 'json' | 'csv' | 'ndjson'): string;
|
|
61
|
+
/**
|
|
62
|
+
* Export by agent
|
|
63
|
+
*/
|
|
64
|
+
exportByAgent(agentId: string, format?: 'json' | 'csv' | 'ndjson'): string;
|
|
65
|
+
/**
|
|
66
|
+
* Export by session
|
|
67
|
+
*/
|
|
68
|
+
exportBySession(sessionId: string, format?: 'json' | 'csv' | 'ndjson'): string;
|
|
69
|
+
/**
|
|
70
|
+
* Export errors only
|
|
71
|
+
*/
|
|
72
|
+
exportErrors(format?: 'json' | 'csv' | 'ndjson'): string;
|
|
73
|
+
/**
|
|
74
|
+
* Export LLM calls only
|
|
75
|
+
*/
|
|
76
|
+
exportLLMCalls(format?: 'json' | 'csv' | 'ndjson'): string;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/observability/export.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE7D;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,aAAa,EAAE,EACvB,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GACA,MAAM,CAaR;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAyD3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAE9D;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,aAAa,EAAE,EACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,GACzC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,aAAa,EAAE,EACvB,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,GACzC,IAAI,CAoBN;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EAAE,EACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,GACzC,IAAI,CAgBN;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAmB;gBAErB,MAAM,EAAE,gBAAgB;IAIpC;;OAEG;IACH,SAAS,CAAC,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,GAAG,MAAM;IAa7D;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,GAAG,MAAM;IAgBvF;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,EAC1C,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC;IAKhB;;OAEG;IACH,QAAQ,CACN,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,EAC1C,MAAM,CAAC,EAAE,WAAW,GACnB,IAAI;IAKP;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,GAAG,MAAM;IAU3F;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,GAAG,MAAM;IAIlF;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,GAAG,MAAM;IAItF;;OAEG;IACH,YAAY,CAAC,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,GAAG,MAAM;IAIhE;;OAEG;IACH,cAAc,CAAC,MAAM,GAAE,MAAM,GAAG,KAAK,GAAG,QAAiB,GAAG,MAAM;CAGnE"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @revealui/ai - Export Utilities
|
|
3
|
+
*
|
|
4
|
+
* Export agent events to various formats (JSON, CSV, NDJSON).
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Export events to JSON format
|
|
8
|
+
*/
|
|
9
|
+
export function exportToJSON(events, options) {
|
|
10
|
+
const data = options?.metadata
|
|
11
|
+
? {
|
|
12
|
+
metadata: {
|
|
13
|
+
exportedAt: new Date().toISOString(),
|
|
14
|
+
eventCount: events.length,
|
|
15
|
+
...options.metadata,
|
|
16
|
+
},
|
|
17
|
+
events,
|
|
18
|
+
}
|
|
19
|
+
: events;
|
|
20
|
+
return options?.pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Export events to CSV format
|
|
24
|
+
*/
|
|
25
|
+
export function exportToCSV(events) {
|
|
26
|
+
if (events.length === 0) {
|
|
27
|
+
return '';
|
|
28
|
+
}
|
|
29
|
+
// Define common columns
|
|
30
|
+
const columns = [
|
|
31
|
+
'timestamp',
|
|
32
|
+
'eventType',
|
|
33
|
+
'agentId',
|
|
34
|
+
'sessionId',
|
|
35
|
+
'taskId',
|
|
36
|
+
// Decision-specific
|
|
37
|
+
'reasoning',
|
|
38
|
+
'chosenTool',
|
|
39
|
+
'confidence',
|
|
40
|
+
// Tool call-specific
|
|
41
|
+
'toolName',
|
|
42
|
+
'success',
|
|
43
|
+
'durationMs',
|
|
44
|
+
'errorMessage',
|
|
45
|
+
// LLM call-specific
|
|
46
|
+
'provider',
|
|
47
|
+
'model',
|
|
48
|
+
'promptTokens',
|
|
49
|
+
'completionTokens',
|
|
50
|
+
'cost',
|
|
51
|
+
'cacheHit',
|
|
52
|
+
// Error-specific
|
|
53
|
+
'message',
|
|
54
|
+
'recoverable',
|
|
55
|
+
'errorCode',
|
|
56
|
+
];
|
|
57
|
+
// Create CSV header
|
|
58
|
+
const header = columns.join(',');
|
|
59
|
+
// Create CSV rows
|
|
60
|
+
const rows = events.map((event) => {
|
|
61
|
+
const row = [];
|
|
62
|
+
for (const column of columns) {
|
|
63
|
+
const value = event[column];
|
|
64
|
+
if (value === undefined || value === null) {
|
|
65
|
+
row.push('');
|
|
66
|
+
}
|
|
67
|
+
else if (typeof value === 'string' && (value.includes(',') || value.includes('"'))) {
|
|
68
|
+
// Escape strings with commas or quotes
|
|
69
|
+
row.push(`"${value.replace(/"/g, '""')}"`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
row.push(String(value));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return row.join(',');
|
|
76
|
+
});
|
|
77
|
+
return [header, ...rows].join('\n');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Export events to NDJSON format (newline-delimited JSON)
|
|
81
|
+
*/
|
|
82
|
+
export function exportToNDJSON(events) {
|
|
83
|
+
return events.map((event) => JSON.stringify(event)).join('\n');
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Export events to a file (Node.js)
|
|
87
|
+
*/
|
|
88
|
+
export async function exportToFile(events, filePath, format = 'json') {
|
|
89
|
+
const fs = await import('node:fs/promises');
|
|
90
|
+
let content;
|
|
91
|
+
switch (format) {
|
|
92
|
+
case 'json':
|
|
93
|
+
content = exportToJSON(events, { pretty: true });
|
|
94
|
+
break;
|
|
95
|
+
case 'csv':
|
|
96
|
+
content = exportToCSV(events);
|
|
97
|
+
break;
|
|
98
|
+
case 'ndjson':
|
|
99
|
+
content = exportToNDJSON(events);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Create a downloadable file blob (Browser)
|
|
106
|
+
*/
|
|
107
|
+
export function createDownloadableBlob(events, format = 'json') {
|
|
108
|
+
let content;
|
|
109
|
+
let mimeType;
|
|
110
|
+
switch (format) {
|
|
111
|
+
case 'json':
|
|
112
|
+
content = exportToJSON(events, { pretty: true });
|
|
113
|
+
mimeType = 'application/json';
|
|
114
|
+
break;
|
|
115
|
+
case 'csv':
|
|
116
|
+
content = exportToCSV(events);
|
|
117
|
+
mimeType = 'text/csv';
|
|
118
|
+
break;
|
|
119
|
+
case 'ndjson':
|
|
120
|
+
content = exportToNDJSON(events);
|
|
121
|
+
mimeType = 'application/x-ndjson';
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
return new Blob([content], { type: mimeType });
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Trigger download in browser
|
|
128
|
+
*/
|
|
129
|
+
export function downloadEvents(events, filename, format = 'json') {
|
|
130
|
+
if (typeof window === 'undefined') {
|
|
131
|
+
throw new Error('downloadEvents can only be used in browser environments');
|
|
132
|
+
}
|
|
133
|
+
const blob = createDownloadableBlob(events, format);
|
|
134
|
+
const url = URL.createObjectURL(blob);
|
|
135
|
+
const a = document.createElement('a');
|
|
136
|
+
a.href = url;
|
|
137
|
+
a.download = filename;
|
|
138
|
+
document.body.appendChild(a);
|
|
139
|
+
a.click();
|
|
140
|
+
document.body.removeChild(a);
|
|
141
|
+
URL.revokeObjectURL(url);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Export helper class with logger integration
|
|
145
|
+
*/
|
|
146
|
+
export class EventExporter {
|
|
147
|
+
logger;
|
|
148
|
+
constructor(logger) {
|
|
149
|
+
this.logger = logger;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Export all events
|
|
153
|
+
*/
|
|
154
|
+
exportAll(format = 'json') {
|
|
155
|
+
const events = this.logger.getEvents();
|
|
156
|
+
switch (format) {
|
|
157
|
+
case 'json':
|
|
158
|
+
return exportToJSON(events, { pretty: true });
|
|
159
|
+
case 'csv':
|
|
160
|
+
return exportToCSV(events);
|
|
161
|
+
case 'ndjson':
|
|
162
|
+
return exportToNDJSON(events);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Export filtered events
|
|
167
|
+
*/
|
|
168
|
+
exportFiltered(filter, format = 'json') {
|
|
169
|
+
const events = this.logger.getEvents(filter);
|
|
170
|
+
switch (format) {
|
|
171
|
+
case 'json':
|
|
172
|
+
return exportToJSON(events, {
|
|
173
|
+
pretty: true,
|
|
174
|
+
metadata: { filter },
|
|
175
|
+
});
|
|
176
|
+
case 'csv':
|
|
177
|
+
return exportToCSV(events);
|
|
178
|
+
case 'ndjson':
|
|
179
|
+
return exportToNDJSON(events);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Export to file (Node.js)
|
|
184
|
+
*/
|
|
185
|
+
async exportToFile(filePath, format = 'json', filter) {
|
|
186
|
+
const events = filter ? this.logger.getEvents(filter) : this.logger.getEvents();
|
|
187
|
+
await exportToFile(events, filePath, format);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Download in browser
|
|
191
|
+
*/
|
|
192
|
+
download(filename, format = 'json', filter) {
|
|
193
|
+
const events = filter ? this.logger.getEvents(filter) : this.logger.getEvents();
|
|
194
|
+
downloadEvents(events, filename, format);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Export by time range
|
|
198
|
+
*/
|
|
199
|
+
exportTimeRange(start, end, format = 'json') {
|
|
200
|
+
return this.exportFiltered({
|
|
201
|
+
startTime: start.getTime(),
|
|
202
|
+
endTime: end.getTime(),
|
|
203
|
+
}, format);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Export by agent
|
|
207
|
+
*/
|
|
208
|
+
exportByAgent(agentId, format = 'json') {
|
|
209
|
+
return this.exportFiltered({ agentId }, format);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Export by session
|
|
213
|
+
*/
|
|
214
|
+
exportBySession(sessionId, format = 'json') {
|
|
215
|
+
return this.exportFiltered({ sessionId }, format);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Export errors only
|
|
219
|
+
*/
|
|
220
|
+
exportErrors(format = 'json') {
|
|
221
|
+
return this.exportFiltered({ eventType: 'error' }, format);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Export LLM calls only
|
|
225
|
+
*/
|
|
226
|
+
exportLLMCalls(format = 'json') {
|
|
227
|
+
return this.exportFiltered({ eventType: 'llm_call' }, format);
|
|
228
|
+
}
|
|
229
|
+
}
|