pi-openai-toolkit 0.20.8 → 0.21.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.
Files changed (54) hide show
  1. package/LICENSE +21 -21
  2. package/NOTICE +83 -83
  3. package/README.md +8 -26
  4. package/README.zh.md +8 -26
  5. package/config.schema.json +278 -366
  6. package/docs/configuration.md +294 -310
  7. package/docs/internals.md +166 -175
  8. package/package.json +3 -13
  9. package/src/compact-client.ts +412 -389
  10. package/src/compaction-errors.ts +96 -0
  11. package/src/compaction-projection.ts +35 -35
  12. package/src/config/legacy.ts +519 -717
  13. package/src/config/migration.ts +103 -100
  14. package/src/config/notifications.ts +36 -28
  15. package/src/config/policy.ts +10 -18
  16. package/src/config/v2.ts +1167 -1380
  17. package/src/config.ts +310 -319
  18. package/src/context-management/codex-provider.ts +270 -270
  19. package/src/context-management/history-notes.ts +357 -357
  20. package/src/context-management/manual-compact.ts +0 -11
  21. package/src/context-management/tools.ts +371 -371
  22. package/src/context-management/types.ts +168 -168
  23. package/src/context-management/window-manager.ts +801 -801
  24. package/src/debug.ts +238 -237
  25. package/src/deferred-tool-carryover.ts +282 -282
  26. package/src/details-store.ts +151 -151
  27. package/src/extension-runtime.ts +1662 -1616
  28. package/src/image-generation/extension.ts +189 -189
  29. package/src/image-generation/protocol.ts +579 -579
  30. package/src/image-generation/types.ts +300 -300
  31. package/src/payload-rewrite.ts +515 -518
  32. package/src/pi-context-hook.ts +117 -117
  33. package/src/remote-v2-client.ts +811 -814
  34. package/src/request-context-cache.ts +155 -155
  35. package/src/responses-headers.ts +180 -180
  36. package/src/runtime.ts +865 -832
  37. package/src/serializer.ts +882 -882
  38. package/src/supported-environment.ts +27 -27
  39. package/src/types.ts +565 -648
  40. package/src/web-search/alpha-client.ts +876 -876
  41. package/src/web-search/extension.ts +530 -530
  42. package/src/web-search/payload.ts +299 -299
  43. package/src/web-search/prompt.ts +60 -60
  44. package/src/web-search/types.ts +166 -166
  45. package/tsconfig.check.json +50 -54
  46. package/src/auto-mode/classifier.ts +0 -161
  47. package/src/auto-mode/extension.ts +0 -691
  48. package/src/auto-mode/model-selection-guard.ts +0 -52
  49. package/src/auto-mode/policy.ts +0 -146
  50. package/src/auto-mode/prompt.ts +0 -279
  51. package/src/auto-mode/reviewer.ts +0 -325
  52. package/src/auto-mode/tool-review-tui.ts +0 -211
  53. package/src/auto-mode/transcript.ts +0 -135
  54. package/src/auto-mode/types.ts +0 -137
@@ -1,100 +1,103 @@
1
- import { resolveToolkitConfig } from "../config";
2
- import type { LoadedToolkitConfig } from "../types";
3
- import type { ConfigOrigin } from "./policy";
4
- import { resolveV2Config } from "./v2";
5
-
6
- export type MigrationPreview = {
7
- status: "ready" | "needs-review" | "already-v2" | "unavailable";
8
- candidate?: Record<string, unknown>;
9
- /** Controlled explanations, never arbitrary raw input values. */
10
- reasons: string[];
11
- /** Unknown names are masked; paths never expose unknown values. */
12
- unmappedPaths: string[];
13
- /** Candidate leaf -> origin in the unchanged legacy source (or built-in). */
14
- origins?: Record<string, ConfigOrigin>;
15
- };
16
-
17
- function modelRef(key: string): { provider: string; id: string; api: string } {
18
- const slash = key.indexOf("/");
19
- return { provider: key.slice(0, slash), id: key.slice(slash + 1), api: "openai-responses" };
20
- }
21
-
22
- /** Read-only analysis: never edits a source file or claims a lossy candidate is equivalent. */
23
- export function previewToolkitMigration(loaded: LoadedToolkitConfig): MigrationPreview {
24
- if (loaded.document?.format === "v2") return { status: "already-v2", reasons: ["The document already uses schemaVersion 2."], unmappedPaths: [] };
25
- if (loaded.document?.format === "invalid" || loaded.document?.format === "missing") {
26
- return { status: "unavailable", reasons: ["A readable legacy document is required; no candidate was produced."], unmappedPaths: [] };
27
- }
28
- const baseline = resolveToolkitConfig(loaded);
29
- const legacy = baseline.config;
30
- const { compatibility: _compatibility, diagnostics, ...defaults } = structuredClone(baseline.policy);
31
- const models: Record<string, unknown> = Object.create(null);
32
- const origins: Record<string, ConfigOrigin> = Object.create(null);
33
- const unmappedPaths = new Set(baseline.issues.map((issue) => issue.path));
34
- for (const [leaf, origin] of Object.entries(baseline.origins)) {
35
- if (leaf.startsWith("compatibility.")) continue;
36
- origins[leaf.startsWith("diagnostics.") ? leaf : `defaults.${leaf}`] = origin;
37
- }
38
- const keys = new Set([
39
- ...legacy.webSearch.models,
40
- ...Object.keys(legacy.webSearch.routes ?? {}),
41
- ...legacy.autoMode.models,
42
- ...legacy.compaction.gatewayContextModels,
43
- ]);
44
- for (const key of keys) {
45
- const resolved = resolveToolkitConfig(loaded, modelRef(key));
46
- const override: Record<string, unknown> = {};
47
- if (resolved.policy.webSearch.route !== defaults.webSearch.route) override.webSearch = resolved.policy.webSearch;
48
- if (resolved.policy.autoMode.available !== defaults.autoMode.available) override.autoMode = { available: resolved.policy.autoMode.available };
49
- if (resolved.policy.compatibility.transport !== "standard") override.compatibility = resolved.policy.compatibility;
50
- if (Object.keys(override).length > 0) {
51
- models[key] = override;
52
- for (const [feature, fields] of Object.entries(override)) {
53
- for (const field of Object.keys(fields as Record<string, unknown>)) {
54
- const leaf = `${feature}.${field}`;
55
- origins[`models[${JSON.stringify(key)}].${leaf}`] = resolved.origins[leaf];
56
- }
57
- }
58
- }
59
- }
60
- const candidate = { schemaVersion: 2, defaults, models, diagnostics };
61
- const reasons: string[] = [];
62
- if (loaded.warnings.length || baseline.issues.length) {
63
- reasons.push("Legacy warnings, unknown fields or normalized invalid values require review. Their original contents remain in the untouched source file.");
64
- }
65
- if (legacy.webSearch.enabled && legacy.webSearch.defaultRoute === undefined &&
66
- legacy.webSearch.models.some((key) => !Object.prototype.hasOwnProperty.call(legacy.webSearch.routes ?? {}, key))) {
67
- reasons.push("Legacy hosted allowlists ignore unsupported APIs and malformed payloads; explicit v2 hosted routes fail closed. This candidate is not behavior-equivalent on those paths.");
68
- }
69
- if (!legacy.webSearch.enabled && (legacy.webSearch.models.length || Object.keys(legacy.webSearch.routes ?? {}).length || legacy.webSearch.defaultRoute)) {
70
- reasons.push("Disabled legacy search contains dormant routes or a model list; simplified v2 policy does not retain that enable-later intent.");
71
- if (legacy.webSearch.models.length) unmappedPaths.add("webSearch.models");
72
- if (Object.keys(legacy.webSearch.routes ?? {}).length) unmappedPaths.add("webSearch.routes");
73
- if (legacy.webSearch.defaultRoute) unmappedPaths.add("webSearch.defaultRoute");
74
- }
75
- if (legacy.webSearch.models.length && (legacy.webSearch.defaultRoute !== undefined ||
76
- legacy.webSearch.models.some((key) => Object.hasOwn(legacy.webSearch.routes ?? {}, key)))) {
77
- unmappedPaths.add("webSearch.models");
78
- }
79
- if (!legacy.autoMode.enabled && legacy.autoMode.models.length) {
80
- reasons.push("Disabled legacy auto mode contains a dormant eligibility list; keep the original file for review.");
81
- unmappedPaths.add("autoMode.models");
82
- }
83
- if (!legacy.compaction.enabled && legacy.compaction.contextManagement === "remote") {
84
- reasons.push("Disabled legacy context management retains a dormant remote mode; the candidate selects Pi ownership.");
85
- unmappedPaths.add("compaction.contextManagement");
86
- }
87
- // Gateway affinity was previously context-mode gated for compaction, and not used by image.
88
- if (legacy.compaction.gatewayContextModels.length) {
89
- reasons.push("Gateway compatibility is now shared across features; review synthetic compaction/image affinity before using this candidate.");
90
- }
91
- const candidateChecks = [resolveV2Config(candidate, undefined), ...[...keys].map((key) => resolveV2Config(candidate, key))];
92
- if (candidateChecks.some((resolved) => resolved.issues.length)) reasons.push("The candidate has v2 validation issues; it cannot be applied as-is.");
93
- return {
94
- status: reasons.length ? "needs-review" : "ready",
95
- candidate,
96
- origins,
97
- unmappedPaths: [...unmappedPaths],
98
- reasons: reasons.length ? reasons : ["Recognized active policies map without a known semantic difference. Preview only; no source file was changed."],
99
- };
100
- }
1
+ import { resolveToolkitConfig } from "../config";
2
+ import type { LoadedToolkitConfig } from "../types";
3
+ import { RETIRED_AUTO_MODE_ISSUE, RETIRED_AUTO_MODE_MESSAGE, type ConfigOrigin } from "./policy";
4
+ import { resolveV2Config } from "./v2";
5
+
6
+ export type MigrationPreview = {
7
+ status: "ready" | "needs-review" | "already-v2" | "unavailable";
8
+ candidate?: Record<string, unknown>;
9
+ /** Controlled explanations, never arbitrary raw input values. */
10
+ reasons: string[];
11
+ /** Unknown names are masked; paths never expose unknown values. */
12
+ unmappedPaths: string[];
13
+ /** Candidate leaf -> origin in the unchanged legacy source (or built-in). */
14
+ origins?: Record<string, ConfigOrigin>;
15
+ };
16
+
17
+ function modelRef(key: string): { provider: string; id: string; api: string } {
18
+ const slash = key.indexOf("/");
19
+ return { provider: key.slice(0, slash), id: key.slice(slash + 1), api: "openai-responses" };
20
+ }
21
+
22
+ /** Read-only analysis: never edits a source file or claims a lossy candidate is equivalent. */
23
+ export function previewToolkitMigration(loaded: LoadedToolkitConfig): MigrationPreview {
24
+ if (loaded.document?.format === "v2") {
25
+ const retired = resolveToolkitConfig(loaded).issues.filter((issue) => issue.code === RETIRED_AUTO_MODE_ISSUE);
26
+ return { status: "already-v2", reasons: ["The document already uses schemaVersion 2.",
27
+ ...(retired.length ? [RETIRED_AUTO_MODE_MESSAGE] : [])], unmappedPaths: retired.map((issue) => issue.path) };
28
+ }
29
+ if (loaded.document?.format === "invalid" || loaded.document?.format === "missing") {
30
+ return { status: "unavailable", reasons: ["A readable legacy document is required; no candidate was produced."], unmappedPaths: [] };
31
+ }
32
+ const baseline = resolveToolkitConfig(loaded);
33
+ const legacy = baseline.config;
34
+ const { compatibility: _compatibility, diagnostics, ...defaults } = structuredClone(baseline.policy);
35
+ const models: Record<string, unknown> = Object.create(null);
36
+ const origins: Record<string, ConfigOrigin> = Object.create(null);
37
+ const unmappedPaths = new Set(baseline.issues.map((issue) => issue.path));
38
+ for (const [leaf, origin] of Object.entries(baseline.origins)) {
39
+ if (leaf.startsWith("compatibility.")) continue;
40
+ origins[leaf.startsWith("diagnostics.") ? leaf : `defaults.${leaf}`] = origin;
41
+ }
42
+ const keys = new Set([
43
+ ...legacy.webSearch.models,
44
+ ...Object.keys(legacy.webSearch.routes ?? {}),
45
+ ...legacy.compaction.gatewayContextModels,
46
+ ]);
47
+ for (const key of keys) {
48
+ const resolved = resolveToolkitConfig(loaded, modelRef(key));
49
+ const override: Record<string, unknown> = {};
50
+ if (resolved.policy.webSearch.route !== defaults.webSearch.route) override.webSearch = resolved.policy.webSearch;
51
+ if (resolved.policy.compatibility.transport !== "standard") override.compatibility = resolved.policy.compatibility;
52
+ if (Object.keys(override).length > 0) {
53
+ models[key] = override;
54
+ for (const [feature, fields] of Object.entries(override)) {
55
+ for (const field of Object.keys(fields as Record<string, unknown>)) {
56
+ const leaf = `${feature}.${field}`;
57
+ origins[`models[${JSON.stringify(key)}].${leaf}`] = resolved.origins[leaf];
58
+ }
59
+ }
60
+ }
61
+ }
62
+ const candidate = { schemaVersion: 2, defaults, models, diagnostics };
63
+ const reasons: string[] = [];
64
+ // Retired sections are never migrated; their presence is a controlled removal reason.
65
+ if (baseline.issues.some((issue) => issue.code === RETIRED_AUTO_MODE_ISSUE)) {
66
+ reasons.push(RETIRED_AUTO_MODE_MESSAGE + " No Auto Mode settings were migrated; review the removal before applying this candidate.");
67
+ unmappedPaths.add("autoMode");
68
+ }
69
+ if (loaded.warnings.length || baseline.issues.length) {
70
+ reasons.push("Legacy warnings, unknown fields or normalized invalid values require review. Their original contents remain in the untouched source file.");
71
+ }
72
+ if (legacy.webSearch.enabled && legacy.webSearch.defaultRoute === undefined &&
73
+ legacy.webSearch.models.some((key) => !Object.prototype.hasOwnProperty.call(legacy.webSearch.routes ?? {}, key))) {
74
+ reasons.push("Legacy hosted allowlists ignore unsupported APIs and malformed payloads; explicit v2 hosted routes fail closed. This candidate is not behavior-equivalent on those paths.");
75
+ }
76
+ if (!legacy.webSearch.enabled && (legacy.webSearch.models.length || Object.keys(legacy.webSearch.routes ?? {}).length || legacy.webSearch.defaultRoute)) {
77
+ reasons.push("Disabled legacy search contains dormant routes or a model list; simplified v2 policy does not retain that enable-later intent.");
78
+ if (legacy.webSearch.models.length) unmappedPaths.add("webSearch.models");
79
+ if (Object.keys(legacy.webSearch.routes ?? {}).length) unmappedPaths.add("webSearch.routes");
80
+ if (legacy.webSearch.defaultRoute) unmappedPaths.add("webSearch.defaultRoute");
81
+ }
82
+ if (legacy.webSearch.models.length && (legacy.webSearch.defaultRoute !== undefined ||
83
+ legacy.webSearch.models.some((key) => Object.hasOwn(legacy.webSearch.routes ?? {}, key)))) {
84
+ unmappedPaths.add("webSearch.models");
85
+ }
86
+ if (!legacy.compaction.enabled && legacy.compaction.contextManagement === "remote") {
87
+ reasons.push("Disabled legacy context management retains a dormant remote mode; the candidate selects Pi ownership.");
88
+ unmappedPaths.add("compaction.contextManagement");
89
+ }
90
+ // Gateway affinity was previously context-mode gated for compaction, and not used by image.
91
+ if (legacy.compaction.gatewayContextModels.length) {
92
+ reasons.push("Gateway compatibility is now shared across features; review synthetic compaction/image affinity before using this candidate.");
93
+ }
94
+ const candidateChecks = [resolveV2Config(candidate, undefined), ...[...keys].map((key) => resolveV2Config(candidate, key))];
95
+ if (candidateChecks.some((resolved) => resolved.issues.length)) reasons.push("The candidate has v2 validation issues; it cannot be applied as-is.");
96
+ return {
97
+ status: reasons.length ? "needs-review" : "ready",
98
+ candidate,
99
+ origins,
100
+ unmappedPaths: [...unmappedPaths],
101
+ reasons: reasons.length ? reasons : ["Recognized active policies map without a known semantic difference. Preview only; no source file was changed."],
102
+ };
103
+ }
@@ -1,28 +1,36 @@
1
- import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
- import type { ResolvedToolkitConfig } from "../config";
3
- import type { ConfigIssue } from "./policy";
4
- import { redactValue } from "../debug";
5
-
6
- const lastNotice = new WeakMap<object, string>();
7
-
8
- export function formatConfigIssues(issues: readonly ConfigIssue[], limit = 12): string {
9
- const lines = issues.slice(0, limit).map((issue) => `${issue.severity}: ${issue.path.slice(0, 220)} — ${issue.code}`);
10
- if (issues.length > limit) lines.push(`${issues.length - limit} more issue(s); inspect the configuration file.`);
11
- return String(redactValue(lines.join("\n")));
12
- }
13
-
14
- /** Per-session bounded notice, independent of feature enablement/debug. Never logs raw config. */
15
- export function notifyConfigIssues(ctx: ExtensionContext, resolved: ResolvedToolkitConfig): void {
16
- const owner = ctx.sessionManager ?? ctx;
17
- if (resolved.issues.length === 0) {
18
- lastNotice.delete(owner);
19
- return;
20
- }
21
- if (!ctx.hasUI || typeof ctx.ui?.notify !== "function") return;
22
- const message = formatConfigIssues(resolved.issues, 4);
23
- const fingerprint = `${resolved.source ?? "defaults"}\n${resolved.modelKey ?? ""}\n${message}`;
24
- if (lastNotice.get(owner) === fingerprint) return;
25
- lastNotice.set(owner, fingerprint);
26
- ctx.ui.notify(`Toolkit configuration:\n${message}\nUse /toolkit-config validate for details.`,
27
- resolved.issues.some((issue) => issue.severity === "error") ? "error" : "warning");
28
- }
1
+ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ import type { ResolvedToolkitConfig } from "../config";
3
+ import { RETIRED_AUTO_MODE_ISSUE, RETIRED_AUTO_MODE_MESSAGE, type ConfigIssue } from "./policy";
4
+ import { redactValue } from "../debug";
5
+
6
+ const lastNotice = new WeakMap<object, string>();
7
+
8
+ /** Controlled human text for a known code; never built from user-supplied configuration values. */
9
+ function issueExplanation(issue: ConfigIssue): string {
10
+ return issue.code === RETIRED_AUTO_MODE_ISSUE
11
+ ? RETIRED_AUTO_MODE_MESSAGE
12
+ : issue.code;
13
+ }
14
+
15
+ export function formatConfigIssues(issues: readonly ConfigIssue[], limit = 12): string {
16
+ const lines = issues.slice(0, limit).map((issue) =>
17
+ `${issue.severity}: ${issue.path.slice(0, 220)} — ${issueExplanation(issue)}`);
18
+ if (issues.length > limit) lines.push(`${issues.length - limit} more issue(s); inspect the configuration file.`);
19
+ return String(redactValue(lines.join("\n")));
20
+ }
21
+
22
+ /** Per-session bounded notice, independent of feature enablement/debug. Never logs raw config. */
23
+ export function notifyConfigIssues(ctx: ExtensionContext, resolved: ResolvedToolkitConfig): void {
24
+ const owner = ctx.sessionManager ?? ctx;
25
+ if (resolved.issues.length === 0) {
26
+ lastNotice.delete(owner);
27
+ return;
28
+ }
29
+ if (!ctx.hasUI || typeof ctx.ui?.notify !== "function") return;
30
+ const message = formatConfigIssues(resolved.issues, 4);
31
+ const fingerprint = `${resolved.source ?? "defaults"}\n${resolved.modelKey ?? ""}\n${message}`;
32
+ if (lastNotice.get(owner) === fingerprint) return;
33
+ lastNotice.set(owner, fingerprint);
34
+ ctx.ui.notify(`Toolkit configuration:\n${message}\nUse /toolkit-config validate for details.`,
35
+ resolved.issues.some((issue) => issue.severity === "error") ? "error" : "warning");
36
+ }
@@ -1,14 +1,12 @@
1
1
  import {
2
- DEFAULT_AUTO_MODE_CONFIG,
3
2
  DEFAULT_COMPACTION_CONFIG,
4
3
  DEFAULT_IMAGE_GENERATION_MODEL,
5
- type AutoModeConfig,
6
4
  type LeaveManagedModePolicy,
7
5
  type NativeFallbackConfig,
8
6
  type RemoteV2ContextSource,
9
7
  } from "../types";
10
8
 
11
- export type ConfigFeature = "context" | "webSearch" | "imageGeneration" | "autoMode" | "compatibility" | "responsesWebSocket" | "diagnostics";
9
+ export type ConfigFeature = "context" | "webSearch" | "imageGeneration" | "compatibility" | "responsesWebSocket" | "diagnostics";
12
10
  export type SearchRoute = "unmanaged" | "local" | "hosted" | "standalone-alpha";
13
11
  export type DiagnosticsConfig = {
14
12
  level: "error" | "warn" | "info" | "debug";
@@ -33,17 +31,11 @@ export type ContextPolicy = {
33
31
  reminderThresholdPercent: number;
34
32
  };
35
33
  };
36
- export type AutoModePolicy = Omit<AutoModeConfig, "enabled" | "models" | "reviewerModel" | "classifier"> & {
37
- available: boolean;
38
- reviewerModel: string | null;
39
- classifier: Omit<AutoModeConfig["classifier"], "model"> & { model: string | null };
40
- };
41
34
  export type EffectiveToolkitPolicy = {
42
35
  context: ContextPolicy;
43
36
  webSearch: { route: SearchRoute };
44
37
  imageGeneration: { enabled: boolean; defaultModel: string; allowedModels: string[] };
45
38
  responsesWebSocket: { enabled: boolean };
46
- autoMode: AutoModePolicy;
47
39
  compatibility: { transport: "standard" | "codex-gateway" };
48
40
  diagnostics: DiagnosticsConfig;
49
41
  };
@@ -61,6 +53,14 @@ export type ConfigIssue = {
61
53
  /** Issues for a different model do not invalidate the selected model. */
62
54
  modelKey?: string;
63
55
  };
56
+ /**
57
+ * Stable code for a configuration section that was removed from the Toolkit. A retired section is
58
+ * ignored in any shape and must never invalidate another feature, so it is reported as a warning.
59
+ */
60
+ export const RETIRED_AUTO_MODE_ISSUE = "retired.autoMode" as const;
61
+ /** Controlled explanation of the retirement; never contains user-supplied values. */
62
+ export const RETIRED_AUTO_MODE_MESSAGE =
63
+ "Auto Mode has been removed; these settings are ignored and tool calls are no longer reviewed by it.";
64
64
  export type ResolvedToolkitPolicy = {
65
65
  policy: EffectiveToolkitPolicy;
66
66
  origins: Record<string, ConfigOrigin>;
@@ -75,14 +75,12 @@ export type ConfigDocumentSnapshot = {
75
75
  issues: ConfigIssue[];
76
76
  };
77
77
  export const CONFIG_FEATURES: readonly ConfigFeature[] = [
78
- "context", "webSearch", "imageGeneration", "autoMode", "compatibility", "responsesWebSocket", "diagnostics",
78
+ "context", "webSearch", "imageGeneration", "compatibility", "responsesWebSocket", "diagnostics",
79
79
  ];
80
80
 
81
81
  /** Independent per-operation defaults, preserving the existing shipped policy. */
82
82
  export function createPolicyDefaults(): EffectiveToolkitPolicy {
83
83
  const context = DEFAULT_COMPACTION_CONFIG;
84
- const auto = structuredClone(DEFAULT_AUTO_MODE_CONFIG);
85
- const { enabled: _enabled, models: _models, reviewerModel, classifier, ...autoOptions } = auto;
86
84
  return {
87
85
  context: {
88
86
  mode: "remote-compaction",
@@ -105,12 +103,6 @@ export function createPolicyDefaults(): EffectiveToolkitPolicy {
105
103
  allowedModels: [DEFAULT_IMAGE_GENERATION_MODEL],
106
104
  },
107
105
  responsesWebSocket: { enabled: false },
108
- autoMode: {
109
- ...autoOptions,
110
- available: false,
111
- reviewerModel: reviewerModel ?? null,
112
- classifier: { ...classifier, model: classifier.model ?? null },
113
- },
114
106
  compatibility: { transport: "standard" },
115
107
  diagnostics: {
116
108
  level: "info",