@gravity-ui/aikit 2.4.0 → 2.5.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 (51) hide show
  1. package/build/cjs/package.json +1 -1
  2. package/build/cjs/utils/aiAgentContext/AIAgentContext.d.ts +22 -0
  3. package/build/cjs/utils/aiAgentContext/AIAgentContext.js +48 -0
  4. package/build/cjs/utils/aiAgentContext/AIAgentContext.js.map +1 -0
  5. package/build/cjs/utils/aiAgentContext/AIData.d.ts +17 -0
  6. package/build/cjs/utils/aiAgentContext/AIData.js +43 -0
  7. package/build/cjs/utils/aiAgentContext/AIData.js.map +1 -0
  8. package/build/cjs/utils/aiAgentContext/buildAIContextSystemPrompt.d.ts +7 -0
  9. package/build/cjs/utils/aiAgentContext/buildAIContextSystemPrompt.js +21 -0
  10. package/build/cjs/utils/aiAgentContext/buildAIContextSystemPrompt.js.map +1 -0
  11. package/build/cjs/utils/aiAgentContext/index.d.ts +5 -0
  12. package/build/cjs/utils/aiAgentContext/index.js +17 -0
  13. package/build/cjs/utils/aiAgentContext/index.js.map +1 -0
  14. package/build/cjs/utils/aiAgentContext/templateStrings.d.ts +4 -0
  15. package/build/cjs/utils/aiAgentContext/templateStrings.js +37 -0
  16. package/build/cjs/utils/aiAgentContext/templateStrings.js.map +1 -0
  17. package/build/cjs/utils/aiAgentContext/toYamlLike.d.ts +7 -0
  18. package/build/cjs/utils/aiAgentContext/toYamlLike.js +108 -0
  19. package/build/cjs/utils/aiAgentContext/toYamlLike.js.map +1 -0
  20. package/build/cjs/utils/aiAgentContext/types.d.ts +87 -0
  21. package/build/cjs/utils/aiAgentContext/types.js +3 -0
  22. package/build/cjs/utils/aiAgentContext/types.js.map +1 -0
  23. package/build/cjs/utils/index.d.ts +1 -0
  24. package/build/cjs/utils/index.js +1 -0
  25. package/build/cjs/utils/index.js.map +1 -1
  26. package/build/esm/package.json +1 -1
  27. package/build/esm/utils/aiAgentContext/AIAgentContext.d.ts +22 -0
  28. package/build/esm/utils/aiAgentContext/AIAgentContext.js +44 -0
  29. package/build/esm/utils/aiAgentContext/AIAgentContext.js.map +1 -0
  30. package/build/esm/utils/aiAgentContext/AIData.d.ts +17 -0
  31. package/build/esm/utils/aiAgentContext/AIData.js +39 -0
  32. package/build/esm/utils/aiAgentContext/AIData.js.map +1 -0
  33. package/build/esm/utils/aiAgentContext/buildAIContextSystemPrompt.d.ts +7 -0
  34. package/build/esm/utils/aiAgentContext/buildAIContextSystemPrompt.js +18 -0
  35. package/build/esm/utils/aiAgentContext/buildAIContextSystemPrompt.js.map +1 -0
  36. package/build/esm/utils/aiAgentContext/index.d.ts +5 -0
  37. package/build/esm/utils/aiAgentContext/index.js +7 -0
  38. package/build/esm/utils/aiAgentContext/index.js.map +1 -0
  39. package/build/esm/utils/aiAgentContext/templateStrings.d.ts +4 -0
  40. package/build/esm/utils/aiAgentContext/templateStrings.js +32 -0
  41. package/build/esm/utils/aiAgentContext/templateStrings.js.map +1 -0
  42. package/build/esm/utils/aiAgentContext/toYamlLike.d.ts +7 -0
  43. package/build/esm/utils/aiAgentContext/toYamlLike.js +105 -0
  44. package/build/esm/utils/aiAgentContext/toYamlLike.js.map +1 -0
  45. package/build/esm/utils/aiAgentContext/types.d.ts +87 -0
  46. package/build/esm/utils/aiAgentContext/types.js +2 -0
  47. package/build/esm/utils/aiAgentContext/types.js.map +1 -0
  48. package/build/esm/utils/index.d.ts +1 -0
  49. package/build/esm/utils/index.js +1 -0
  50. package/build/esm/utils/index.js.map +1 -1
  51. package/package.json +11 -1
@@ -1 +1 @@
1
- {"version":"2.4.0","type":"commonjs","sideEffects":["*.css","*.scss"]}
1
+ {"version":"2.5.0","type":"commonjs","sideEffects":["*.css","*.scss"]}
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import type { AIAgentContextAPI, AIAgentContextValue } from "./types.js";
3
+ declare const AIAgentContext: React.Context<AIAgentContextValue<unknown> | null>;
4
+ /** Raw context — internal use only, not exported from the package. */
5
+ export { AIAgentContext as _AIAgentContext };
6
+ /**
7
+ * Provider that manages the AI data registry.
8
+ * Wrap your app or chat area with this to enable AIData collection.
9
+ */
10
+ export declare function AIAgentContextProvider({ children }: {
11
+ children: React.ReactNode;
12
+ }): import("react/jsx-runtime").JSX.Element;
13
+ /**
14
+ * Hook for consumers to access registered AI data.
15
+ * Returns { getData } where getData() returns the current list of all entries.
16
+ * If no AIAgentContextProvider exists above, getData() returns [].
17
+ *
18
+ * Generic `T` is the **expected** shape of `data` for this consumer — not validated
19
+ * or guaranteed at runtime. The registry is populated by arbitrary `AIData`
20
+ * registrations; entries may not match `T`.
21
+ */
22
+ export declare function useAIAgentContext<T = unknown>(): AIAgentContextAPI<T>;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._AIAgentContext = void 0;
4
+ exports.AIAgentContextProvider = AIAgentContextProvider;
5
+ exports.useAIAgentContext = useAIAgentContext;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const react_1 = require("react");
8
+ const AIAgentContext = (0, react_1.createContext)(null);
9
+ exports._AIAgentContext = AIAgentContext;
10
+ /**
11
+ * Provider that manages the AI data registry.
12
+ * Wrap your app or chat area with this to enable AIData collection.
13
+ */
14
+ function AIAgentContextProvider({ children }) {
15
+ const registryRef = (0, react_1.useRef)(new Map());
16
+ const contextValue = (0, react_1.useMemo)(() => ({
17
+ register: (id, getter) => {
18
+ registryRef.current.set(id, getter);
19
+ },
20
+ unregister: (id) => {
21
+ registryRef.current.delete(id);
22
+ },
23
+ getData: () => Array.from(registryRef.current.values()).map((getter) => {
24
+ const { label, data } = getter();
25
+ return { label, data };
26
+ }),
27
+ }), []);
28
+ return (0, jsx_runtime_1.jsx)(AIAgentContext.Provider, { value: contextValue, children: children });
29
+ }
30
+ /**
31
+ * Hook for consumers to access registered AI data.
32
+ * Returns { getData } where getData() returns the current list of all entries.
33
+ * If no AIAgentContextProvider exists above, getData() returns [].
34
+ *
35
+ * Generic `T` is the **expected** shape of `data` for this consumer — not validated
36
+ * or guaranteed at runtime. The registry is populated by arbitrary `AIData`
37
+ * registrations; entries may not match `T`.
38
+ */
39
+ function useAIAgentContext() {
40
+ const ctx = (0, react_1.useContext)(AIAgentContext);
41
+ const getData = (0, react_1.useCallback)(() => {
42
+ if (!ctx)
43
+ return [];
44
+ return ctx.getData();
45
+ }, [ctx]);
46
+ return (0, react_1.useMemo)(() => ({ getData }), [getData]);
47
+ }
48
+ //# sourceMappingURL=AIAgentContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AIAgentContext.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/AIAgentContext.tsx"],"names":[],"mappings":";;;AAaA,wDAqBC;AAWD,8CASC;;AAtDD,iCAAqF;AAIrF,MAAM,cAAc,GAAG,IAAA,qBAAa,EAA6B,IAAI,CAAC,CAAC;AAG7C,yCAAe;AAEzC;;;GAGG;AACH,SAAgB,sBAAsB,CAAC,EAAC,QAAQ,EAA8B;IAC1E,MAAM,WAAW,GAAG,IAAA,cAAM,EAAC,IAAI,GAAG,EAA6B,CAAC,CAAC;IAEjE,MAAM,YAAY,GAAG,IAAA,eAAO,EACxB,GAAG,EAAE,CAAC,CAAC;QACH,QAAQ,EAAE,CAAC,EAAU,EAAE,MAAyB,EAAE,EAAE;YAChD,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,UAAU,EAAE,CAAC,EAAU,EAAE,EAAE;YACvB,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,GAAkB,EAAE,CACzB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACpD,MAAM,EAAC,KAAK,EAAE,IAAI,EAAC,GAAG,MAAM,EAAE,CAAC;YAC/B,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,CAAC;QACzB,CAAC,CAAC;KACT,CAAC,EACF,EAAE,CACL,CAAC;IAEF,OAAO,uBAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,YAAG,QAAQ,GAA2B,CAAC;AAC9F,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,iBAAiB;IAC7B,MAAM,GAAG,GAAG,IAAA,kBAAU,EAAC,cAAc,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAG,IAAA,mBAAW,EAAC,GAAqB,EAAE;QAC/C,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,OAAO,GAAG,CAAC,OAAO,EAAsB,CAAC;IAC7C,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,OAAO,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,CAAC,EAAC,OAAO,EAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;AACjD,CAAC","sourcesContent":["import React, {createContext, useCallback, useContext, useMemo, useRef} from 'react';\n\nimport type {AIAgentContextAPI, AIAgentContextValue, AIDataEntry, AIDataProps} from './types';\n\nconst AIAgentContext = createContext<AIAgentContextValue | null>(null);\n\n/** Raw context — internal use only, not exported from the package. */\nexport {AIAgentContext as _AIAgentContext};\n\n/**\n * Provider that manages the AI data registry.\n * Wrap your app or chat area with this to enable AIData collection.\n */\nexport function AIAgentContextProvider({children}: {children: React.ReactNode}) {\n const registryRef = useRef(new Map<string, () => AIDataProps>());\n\n const contextValue = useMemo<AIAgentContextValue>(\n () => ({\n register: (id: string, getter: () => AIDataProps) => {\n registryRef.current.set(id, getter);\n },\n unregister: (id: string) => {\n registryRef.current.delete(id);\n },\n getData: (): AIDataEntry[] =>\n Array.from(registryRef.current.values()).map((getter) => {\n const {label, data} = getter();\n return {label, data};\n }),\n }),\n [],\n );\n\n return <AIAgentContext.Provider value={contextValue}>{children}</AIAgentContext.Provider>;\n}\n\n/**\n * Hook for consumers to access registered AI data.\n * Returns { getData } where getData() returns the current list of all entries.\n * If no AIAgentContextProvider exists above, getData() returns [].\n *\n * Generic `T` is the **expected** shape of `data` for this consumer — not validated\n * or guaranteed at runtime. The registry is populated by arbitrary `AIData`\n * registrations; entries may not match `T`.\n */\nexport function useAIAgentContext<T = unknown>(): AIAgentContextAPI<T> {\n const ctx = useContext(AIAgentContext);\n\n const getData = useCallback((): AIDataEntry<T>[] => {\n if (!ctx) return [];\n return ctx.getData() as AIDataEntry<T>[];\n }, [ctx]);\n\n return useMemo(() => ({getData}), [getData]);\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import type { AIDataProps } from "./types.js";
2
+ /**
3
+ * Hook to register data in the AI agent context.
4
+ *
5
+ * Registration happens in `useEffect`, so `getData()` is only meaningful
6
+ * **after mount** of components that register data. Do not call `getData()`
7
+ * synchronously during render or in `useLayoutEffect` in the same commit.
8
+ *
9
+ * Uses a ref + getter pattern: the registry stores `() => propsRef.current`
10
+ * so `getData()` always reads the latest props without re-registering on every render.
11
+ */
12
+ export declare function useProvideAIData<T>(props: AIDataProps<T>): void;
13
+ /**
14
+ * Component that registers data in the AI agent context.
15
+ * Pure side-effect — renders nothing.
16
+ */
17
+ export declare function AIData<T>(props: AIDataProps<T>): null;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useProvideAIData = useProvideAIData;
4
+ exports.AIData = AIData;
5
+ const react_1 = require("react");
6
+ const AIAgentContext_1 = require("./AIAgentContext.js");
7
+ /**
8
+ * Hook to register data in the AI agent context.
9
+ *
10
+ * Registration happens in `useEffect`, so `getData()` is only meaningful
11
+ * **after mount** of components that register data. Do not call `getData()`
12
+ * synchronously during render or in `useLayoutEffect` in the same commit.
13
+ *
14
+ * Uses a ref + getter pattern: the registry stores `() => propsRef.current`
15
+ * so `getData()` always reads the latest props without re-registering on every render.
16
+ */
17
+ function useProvideAIData(props) {
18
+ const ctx = (0, react_1.useContext)(AIAgentContext_1._AIAgentContext);
19
+ const id = (0, react_1.useId)();
20
+ const propsRef = (0, react_1.useRef)(props);
21
+ propsRef.current = props;
22
+ (0, react_1.useEffect)(() => {
23
+ if (!ctx) {
24
+ // eslint-disable-next-line no-console
25
+ console.warn('useProvideAIData must be used inside AIAgentContextProvider');
26
+ return;
27
+ }
28
+ ctx.register(id, () => propsRef.current);
29
+ // eslint-disable-next-line consistent-return
30
+ return () => {
31
+ ctx.unregister(id);
32
+ };
33
+ }, [ctx, id]);
34
+ }
35
+ /**
36
+ * Component that registers data in the AI agent context.
37
+ * Pure side-effect — renders nothing.
38
+ */
39
+ function AIData(props) {
40
+ useProvideAIData(props);
41
+ return null;
42
+ }
43
+ //# sourceMappingURL=AIData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AIData.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/AIData.ts"],"names":[],"mappings":";;AAeA,4CAqBC;AAMD,wBAGC;AA7CD,iCAA2D;AAE3D,wDAAiD;AAGjD;;;;;;;;;GASG;AACH,SAAgB,gBAAgB,CAAI,KAAqB;IACrD,MAAM,GAAG,GAAG,IAAA,kBAAU,EAAC,gCAAe,CAAC,CAAC;IACxC,MAAM,EAAE,GAAG,IAAA,aAAK,GAAE,CAAC;IACnB,MAAM,QAAQ,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAC;IAC/B,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;IAEzB,IAAA,iBAAS,EAAC,GAAG,EAAE;QACX,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YAE5E,OAAO;QACX,CAAC;QAED,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAEzC,6CAA6C;QAC7C,OAAO,GAAG,EAAE;YACR,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvB,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAgB,MAAM,CAAI,KAAqB;IAC3C,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["import {useContext, useEffect, useId, useRef} from 'react';\n\nimport {_AIAgentContext} from './AIAgentContext';\nimport type {AIDataProps} from './types';\n\n/**\n * Hook to register data in the AI agent context.\n *\n * Registration happens in `useEffect`, so `getData()` is only meaningful\n * **after mount** of components that register data. Do not call `getData()`\n * synchronously during render or in `useLayoutEffect` in the same commit.\n *\n * Uses a ref + getter pattern: the registry stores `() => propsRef.current`\n * so `getData()` always reads the latest props without re-registering on every render.\n */\nexport function useProvideAIData<T>(props: AIDataProps<T>): void {\n const ctx = useContext(_AIAgentContext);\n const id = useId();\n const propsRef = useRef(props);\n propsRef.current = props;\n\n useEffect(() => {\n if (!ctx) {\n // eslint-disable-next-line no-console\n console.warn('useProvideAIData must be used inside AIAgentContextProvider');\n\n return;\n }\n\n ctx.register(id, () => propsRef.current);\n\n // eslint-disable-next-line consistent-return\n return () => {\n ctx.unregister(id);\n };\n }, [ctx, id]);\n}\n\n/**\n * Component that registers data in the AI agent context.\n * Pure side-effect — renders nothing.\n */\nexport function AIData<T>(props: AIDataProps<T>): null {\n useProvideAIData(props);\n return null;\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { AIDataEntry, BuildAIContextOptions } from "./types.js";
2
+ /**
3
+ * Formats AI data entries into a system prompt string.
4
+ * Uses YAML-like format by default, can be overridden via options.formatData.
5
+ * Uses prompt builder to build the system prompt from **Template Literal**. See `createDefaultSystemPromptBuilder` for more details.
6
+ */
7
+ export declare function buildAIContextSystemPrompt<T = unknown>(entries: AIDataEntry<T>[], options?: BuildAIContextOptions<T>): string;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildAIContextSystemPrompt = buildAIContextSystemPrompt;
4
+ const templateStrings_1 = require("./templateStrings.js");
5
+ const toYamlLike_1 = require("./toYamlLike.js");
6
+ /**
7
+ * Formats AI data entries into a system prompt string.
8
+ * Uses YAML-like format by default, can be overridden via options.formatData.
9
+ * Uses prompt builder to build the system prompt from **Template Literal**. See `createDefaultSystemPromptBuilder` for more details.
10
+ */
11
+ function buildAIContextSystemPrompt(entries, options = {}) {
12
+ var _a, _b;
13
+ if (entries.length === 0)
14
+ return '';
15
+ const builder = (0, templateStrings_1.createDefaultSystemPromptBuilder)(entries, {
16
+ formatData: (_a = options.formatData) !== null && _a !== void 0 ? _a : toYamlLike_1.toYamlLike,
17
+ });
18
+ const template = (_b = options.template) !== null && _b !== void 0 ? _b : templateStrings_1.DEFAULT_SYSTEM_PROMPT_TEMPLATE;
19
+ return builder(...template);
20
+ }
21
+ //# sourceMappingURL=buildAIContextSystemPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildAIContextSystemPrompt.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/buildAIContextSystemPrompt.ts"],"names":[],"mappings":";;AASA,gEAaC;AAtBD,0DAAmG;AACnG,gDAAwC;AAGxC;;;;GAIG;AACH,SAAgB,0BAA0B,CACtC,OAAyB,EACzB,UAAoC,EAAE;;IAEtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,OAAO,GAAG,IAAA,kDAAgC,EAAI,OAAO,EAAE;QACzD,UAAU,EAAE,MAAA,OAAO,CAAC,UAAU,mCAAI,uBAAU;KAC/C,CAAC,CAAC;IAEH,MAAM,QAAQ,GAA2B,MAAA,OAAO,CAAC,QAAQ,mCAAI,gDAA8B,CAAC;IAE5F,OAAO,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;AAChC,CAAC","sourcesContent":["import {DEFAULT_SYSTEM_PROMPT_TEMPLATE, createDefaultSystemPromptBuilder} from './templateStrings';\nimport {toYamlLike} from './toYamlLike';\nimport type {AIDataEntry, BuildAIContextOptions, PromptBuilderParams} from './types';\n\n/**\n * Formats AI data entries into a system prompt string.\n * Uses YAML-like format by default, can be overridden via options.formatData.\n * Uses prompt builder to build the system prompt from **Template Literal**. See `createDefaultSystemPromptBuilder` for more details.\n */\nexport function buildAIContextSystemPrompt<T = unknown>(\n entries: AIDataEntry<T>[],\n options: BuildAIContextOptions<T> = {},\n): string {\n if (entries.length === 0) return '';\n\n const builder = createDefaultSystemPromptBuilder<T>(entries, {\n formatData: options.formatData ?? toYamlLike,\n });\n\n const template: PromptBuilderParams<T> = options.template ?? DEFAULT_SYSTEM_PROMPT_TEMPLATE;\n\n return builder(...template);\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export { AIAgentContextProvider, useAIAgentContext } from "./AIAgentContext.js";
2
+ export { AIData, useProvideAIData } from "./AIData.js";
3
+ export { buildAIContextSystemPrompt } from "./buildAIContextSystemPrompt.js";
4
+ export { AIPrompt, DEFAULT_SYSTEM_PROMPT_TEMPLATE } from "./templateStrings.js";
5
+ export type { AIDataProps, AIDataEntry, AIAgentContextAPI, BuildAIContextOptions, PromptBuilder, PromptBuilderParams, PromptBuilderExpression, PromptBuilderExpressionOptions, } from "./types.js";
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_SYSTEM_PROMPT_TEMPLATE = exports.AIPrompt = exports.buildAIContextSystemPrompt = exports.useProvideAIData = exports.AIData = exports.useAIAgentContext = exports.AIAgentContextProvider = void 0;
4
+ // Components
5
+ var AIAgentContext_1 = require("./AIAgentContext.js");
6
+ Object.defineProperty(exports, "AIAgentContextProvider", { enumerable: true, get: function () { return AIAgentContext_1.AIAgentContextProvider; } });
7
+ Object.defineProperty(exports, "useAIAgentContext", { enumerable: true, get: function () { return AIAgentContext_1.useAIAgentContext; } });
8
+ var AIData_1 = require("./AIData.js");
9
+ Object.defineProperty(exports, "AIData", { enumerable: true, get: function () { return AIData_1.AIData; } });
10
+ Object.defineProperty(exports, "useProvideAIData", { enumerable: true, get: function () { return AIData_1.useProvideAIData; } });
11
+ // Utilities
12
+ var buildAIContextSystemPrompt_1 = require("./buildAIContextSystemPrompt.js");
13
+ Object.defineProperty(exports, "buildAIContextSystemPrompt", { enumerable: true, get: function () { return buildAIContextSystemPrompt_1.buildAIContextSystemPrompt; } });
14
+ var templateStrings_1 = require("./templateStrings.js");
15
+ Object.defineProperty(exports, "AIPrompt", { enumerable: true, get: function () { return templateStrings_1.AIPrompt; } });
16
+ Object.defineProperty(exports, "DEFAULT_SYSTEM_PROMPT_TEMPLATE", { enumerable: true, get: function () { return templateStrings_1.DEFAULT_SYSTEM_PROMPT_TEMPLATE; } });
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/index.ts"],"names":[],"mappings":";;;AAAA,aAAa;AACb,sDAA2E;AAAnE,wHAAA,sBAAsB,OAAA;AAAE,mHAAA,iBAAiB,OAAA;AACjD,sCAAkD;AAA1C,gGAAA,MAAM,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AAEhC,YAAY;AACZ,8EAAwE;AAAhE,wIAAA,0BAA0B,OAAA;AAClC,wDAA2E;AAAnE,2GAAA,QAAQ,OAAA;AAAE,iIAAA,8BAA8B,OAAA","sourcesContent":["// Components\nexport {AIAgentContextProvider, useAIAgentContext} from './AIAgentContext';\nexport {AIData, useProvideAIData} from './AIData';\n\n// Utilities\nexport {buildAIContextSystemPrompt} from './buildAIContextSystemPrompt';\nexport {AIPrompt, DEFAULT_SYSTEM_PROMPT_TEMPLATE} from './templateStrings';\n\n// Types\nexport type {\n AIDataProps,\n AIDataEntry,\n AIAgentContextAPI,\n BuildAIContextOptions,\n PromptBuilder,\n PromptBuilderParams,\n PromptBuilderExpression,\n PromptBuilderExpressionOptions,\n} from './types';\n"]}
@@ -0,0 +1,4 @@
1
+ import { AIDataEntry, AnyDepthArray, PromptBuilder, PromptBuilderExpression, PromptBuilderExpressionOptions, PromptBuilderParams } from "./types.js";
2
+ export declare function AIPrompt<T = unknown>(templateParts: TemplateStringsArray, ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<T>)[]): PromptBuilderParams<T>;
3
+ export declare function createDefaultSystemPromptBuilder<T = unknown>(entries: AIDataEntry<T>[], options: PromptBuilderExpressionOptions<T>): PromptBuilder<T>;
4
+ export declare const DEFAULT_SYSTEM_PROMPT_TEMPLATE: [templateParts: string[], ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<any>)[]];
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_SYSTEM_PROMPT_TEMPLATE = void 0;
4
+ exports.AIPrompt = AIPrompt;
5
+ exports.createDefaultSystemPromptBuilder = createDefaultSystemPromptBuilder;
6
+ function AIPrompt(templateParts, ...functions) {
7
+ return [[...templateParts.raw], ...functions];
8
+ }
9
+ function createDefaultSystemPromptBuilder(entries, options) {
10
+ return (templateParts, ...functions) => {
11
+ const out = [];
12
+ for (let i = 0; i < templateParts.length; i++) {
13
+ const part = templateParts[i];
14
+ out.push(part);
15
+ const fn = functions[i];
16
+ if (fn) {
17
+ const result = typeof fn === 'function' ? fn(entries, options) : fn;
18
+ if (typeof result === 'string') {
19
+ out.push(result);
20
+ }
21
+ if (Array.isArray(result)) {
22
+ // @ts-expect-error - we know that the result is an array of strings, but TS can't handle it (Type instantiation is excessively deep and possibly infinite.)
23
+ out.push(result.flat(Infinity).join('\n\n'));
24
+ }
25
+ }
26
+ }
27
+ return out.join('');
28
+ };
29
+ }
30
+ exports.DEFAULT_SYSTEM_PROMPT_TEMPLATE = AIPrompt `Meta information provided by the user about the current page they are on:
31
+
32
+ ${(entries, options) => entries.map((entry) => {
33
+ const formatted = options.formatData(entry.data);
34
+ return [`### ${entry.label}`, formatted];
35
+ })}
36
+ `;
37
+ //# sourceMappingURL=templateStrings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateStrings.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/templateStrings.ts"],"names":[],"mappings":";;;AASA,4BAKC;AAED,4EAgCC;AAvCD,SAAgB,QAAQ,CACpB,aAAmC,EACnC,GAAG,SAA0E;IAE7E,OAAO,CAAC,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC;AAClD,CAAC;AAED,SAAgB,gCAAgC,CAC5C,OAAyB,EACzB,OAA0C;IAE1C,OAAO,CACH,aAAuB,EACvB,GAAG,SAA0E,EACvE,EAAE;QACR,MAAM,GAAG,GAAG,EAAE,CAAC;QAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEf,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAExB,IAAI,EAAE,EAAE,CAAC;gBACL,MAAM,MAAM,GAAG,OAAO,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEpE,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC7B,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACrB,CAAC;gBAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBACxB,4JAA4J;oBAC5J,GAAG,CAAC,IAAI,CAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/D,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC;AACN,CAAC;AAEY,QAAA,8BAA8B,GAAG,QAAQ,CAAK;;EAEzD,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CACnB,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;IAClB,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEjD,OAAO,CAAC,OAAO,KAAK,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC,CAAC;CACL,CAAC","sourcesContent":["import {\n AIDataEntry,\n AnyDepthArray,\n PromptBuilder,\n PromptBuilderExpression,\n PromptBuilderExpressionOptions,\n PromptBuilderParams,\n} from './types';\n\nexport function AIPrompt<T = unknown>(\n templateParts: TemplateStringsArray,\n ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<T>)[]\n): PromptBuilderParams<T> {\n return [[...templateParts.raw], ...functions];\n}\n\nexport function createDefaultSystemPromptBuilder<T = unknown>(\n entries: AIDataEntry<T>[],\n options: PromptBuilderExpressionOptions<T>,\n): PromptBuilder<T> {\n return (\n templateParts: string[],\n ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<T>)[]\n ): string => {\n const out = [];\n\n for (let i = 0; i < templateParts.length; i++) {\n const part = templateParts[i];\n out.push(part);\n\n const fn = functions[i];\n\n if (fn) {\n const result = typeof fn === 'function' ? fn(entries, options) : fn;\n\n if (typeof result === 'string') {\n out.push(result);\n }\n\n if (Array.isArray(result)) {\n // @ts-expect-error - we know that the result is an array of strings, but TS can't handle it (Type instantiation is excessively deep and possibly infinite.)\n out.push((result.flat(Infinity) as string[]).join('\\n\\n'));\n }\n }\n }\n\n return out.join('');\n };\n}\n\nexport const DEFAULT_SYSTEM_PROMPT_TEMPLATE = AIPrompt<any>`Meta information provided by the user about the current page they are on:\n\n${(entries, options) =>\n entries.map((entry) => {\n const formatted = options.formatData(entry.data);\n\n return [`### ${entry.label}`, formatted];\n })}\n`;\n"]}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Simple YAML-like serializer for plain JS values.
3
+ * Handles: string, number, boolean, null/undefined, arrays, plain objects.
4
+ * Falls back to String() for unsupported types.
5
+ * Internal helper — not exported from the package.
6
+ */
7
+ export declare function toYamlLike(data: unknown, indent?: number): string;
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toYamlLike = toYamlLike;
4
+ const CIRCULAR_REF = '[Circular]';
5
+ function indentLines(text, spaces) {
6
+ const prefix = ' '.repeat(spaces);
7
+ return text
8
+ .split('\n')
9
+ .map((line) => `${prefix}${line}`)
10
+ .join('\n');
11
+ }
12
+ function isComplexValue(val) {
13
+ if (val === null || val === undefined) {
14
+ return false;
15
+ }
16
+ if (Array.isArray(val)) {
17
+ return val.length > 0;
18
+ }
19
+ if (typeof val === 'object') {
20
+ return Object.keys(val).length > 0;
21
+ }
22
+ if (typeof val === 'string') {
23
+ return val.includes('\n');
24
+ }
25
+ return false;
26
+ }
27
+ function withVisitedObject(value, visited, serialize) {
28
+ if (visited.has(value)) {
29
+ return CIRCULAR_REF;
30
+ }
31
+ visited.add(value);
32
+ try {
33
+ return serialize();
34
+ }
35
+ finally {
36
+ visited.delete(value);
37
+ }
38
+ }
39
+ function isVisitedReference(val, visited) {
40
+ return typeof val === 'object' && val !== null && visited.has(val);
41
+ }
42
+ function formatKeyValue(key, val, keyPrefix, indent, visited) {
43
+ if (isVisitedReference(val, visited)) {
44
+ return `${keyPrefix}${key}: ${CIRCULAR_REF}`;
45
+ }
46
+ if (isComplexValue(val)) {
47
+ return `${keyPrefix}${key}:\n${toYamlLikeInternal(val, indent + 2, visited)}`;
48
+ }
49
+ return `${keyPrefix}${key}: ${toYamlLikeInternal(val, indent + 2, visited)}`;
50
+ }
51
+ /**
52
+ * Simple YAML-like serializer for plain JS values.
53
+ * Handles: string, number, boolean, null/undefined, arrays, plain objects.
54
+ * Falls back to String() for unsupported types.
55
+ * Internal helper — not exported from the package.
56
+ */
57
+ function toYamlLike(data, indent = 0) {
58
+ return toYamlLikeInternal(data, indent, new Set());
59
+ }
60
+ function toYamlLikeInternal(data, indent, visited) {
61
+ if (data === null || data === undefined)
62
+ return 'null';
63
+ if (typeof data === 'string') {
64
+ if (data.includes('\n')) {
65
+ return `|\n${indentLines(data, indent + 2)}`;
66
+ }
67
+ return data;
68
+ }
69
+ if (typeof data === 'number' || typeof data === 'boolean') {
70
+ return String(data);
71
+ }
72
+ if (Array.isArray(data)) {
73
+ if (data.length === 0)
74
+ return '[]';
75
+ return withVisitedObject(data, visited, () => data
76
+ .map((item) => {
77
+ const prefix = `${' '.repeat(indent)}- `;
78
+ if (typeof item === 'object' && item !== null && !Array.isArray(item)) {
79
+ return withVisitedObject(item, visited, () => {
80
+ const entries = Object.entries(item);
81
+ if (entries.length === 0)
82
+ return `${prefix}{}`;
83
+ const [firstKey, firstVal] = entries[0];
84
+ const firstLine = formatKeyValue(firstKey, firstVal, `${' '.repeat(indent)}- `, indent, visited);
85
+ const rest = entries
86
+ .slice(1)
87
+ .map(([key, val]) => formatKeyValue(key, val, ' '.repeat(indent + 2), indent + 2, visited))
88
+ .join('\n');
89
+ return rest ? `${firstLine}\n${rest}` : firstLine;
90
+ });
91
+ }
92
+ return `${prefix}${toYamlLikeInternal(item, indent + 2, visited)}`;
93
+ })
94
+ .join('\n'));
95
+ }
96
+ if (typeof data === 'object') {
97
+ return withVisitedObject(data, visited, () => {
98
+ const entries = Object.entries(data);
99
+ if (entries.length === 0)
100
+ return '{}';
101
+ return entries
102
+ .map(([key, val]) => formatKeyValue(key, val, ' '.repeat(indent), indent, visited))
103
+ .join('\n');
104
+ });
105
+ }
106
+ return String(data);
107
+ }
108
+ //# sourceMappingURL=toYamlLike.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toYamlLike.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/toYamlLike.ts"],"names":[],"mappings":"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","sourcesContent":["const CIRCULAR_REF = '[Circular]';\n\nfunction indentLines(text: string, spaces: number): string {\n const prefix = ' '.repeat(spaces);\n return text\n .split('\\n')\n .map((line) => `${prefix}${line}`)\n .join('\\n');\n}\n\nfunction isComplexValue(val: unknown): boolean {\n if (val === null || val === undefined) {\n return false;\n }\n if (Array.isArray(val)) {\n return val.length > 0;\n }\n if (typeof val === 'object') {\n return Object.keys(val).length > 0;\n }\n if (typeof val === 'string') {\n return val.includes('\\n');\n }\n return false;\n}\n\nfunction withVisitedObject<T extends object>(\n value: T,\n visited: Set<object>,\n serialize: () => string,\n): string {\n if (visited.has(value)) {\n return CIRCULAR_REF;\n }\n visited.add(value);\n try {\n return serialize();\n } finally {\n visited.delete(value);\n }\n}\n\nfunction isVisitedReference(val: unknown, visited: Set<object>): val is object {\n return typeof val === 'object' && val !== null && visited.has(val);\n}\n\nfunction formatKeyValue(\n key: string,\n val: unknown,\n keyPrefix: string,\n indent: number,\n visited: Set<object>,\n): string {\n if (isVisitedReference(val, visited)) {\n return `${keyPrefix}${key}: ${CIRCULAR_REF}`;\n }\n if (isComplexValue(val)) {\n return `${keyPrefix}${key}:\\n${toYamlLikeInternal(val, indent + 2, visited)}`;\n }\n return `${keyPrefix}${key}: ${toYamlLikeInternal(val, indent + 2, visited)}`;\n}\n\n/**\n * Simple YAML-like serializer for plain JS values.\n * Handles: string, number, boolean, null/undefined, arrays, plain objects.\n * Falls back to String() for unsupported types.\n * Internal helper — not exported from the package.\n */\nexport function toYamlLike(data: unknown, indent = 0): string {\n return toYamlLikeInternal(data, indent, new Set());\n}\n\nfunction toYamlLikeInternal(data: unknown, indent: number, visited: Set<object>): string {\n if (data === null || data === undefined) return 'null';\n\n if (typeof data === 'string') {\n if (data.includes('\\n')) {\n return `|\\n${indentLines(data, indent + 2)}`;\n }\n return data;\n }\n\n if (typeof data === 'number' || typeof data === 'boolean') {\n return String(data);\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) return '[]';\n\n return withVisitedObject(data, visited, () =>\n data\n .map((item) => {\n const prefix = `${' '.repeat(indent)}- `;\n if (typeof item === 'object' && item !== null && !Array.isArray(item)) {\n return withVisitedObject(item, visited, () => {\n const entries = Object.entries(item);\n if (entries.length === 0) return `${prefix}{}`;\n const [firstKey, firstVal] = entries[0];\n const firstLine = formatKeyValue(\n firstKey,\n firstVal,\n `${' '.repeat(indent)}- `,\n indent,\n visited,\n );\n const rest = entries\n .slice(1)\n .map(([key, val]) =>\n formatKeyValue(\n key,\n val,\n ' '.repeat(indent + 2),\n indent + 2,\n visited,\n ),\n )\n .join('\\n');\n return rest ? `${firstLine}\\n${rest}` : firstLine;\n });\n }\n return `${prefix}${toYamlLikeInternal(item, indent + 2, visited)}`;\n })\n .join('\\n'),\n );\n }\n\n if (typeof data === 'object') {\n return withVisitedObject(data, visited, () => {\n const entries = Object.entries(data as Record<string, unknown>);\n if (entries.length === 0) return '{}';\n\n return entries\n .map(([key, val]) => formatKeyValue(key, val, ' '.repeat(indent), indent, visited))\n .join('\\n');\n });\n }\n\n return String(data);\n}\n"]}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Props for AIData component and useProvideAIData hook
3
+ */
4
+ export interface AIDataProps<T = unknown> {
5
+ /** Human-readable description of what this data represents */
6
+ label: string;
7
+ /** The actual data to expose to the AI agent */
8
+ data: T;
9
+ }
10
+ /**
11
+ * Entry returned by getData()
12
+ */
13
+ export interface AIDataEntry<T = unknown> {
14
+ /** Human-readable description of what this data represents */
15
+ label: string;
16
+ /** The actual data */
17
+ data: T;
18
+ }
19
+ /**
20
+ * Public API returned by useAIAgentContext()
21
+ */
22
+ export interface AIAgentContextAPI<T = unknown> {
23
+ /** Returns the current list of all registered data entries */
24
+ getData: () => AIDataEntry<T>[];
25
+ }
26
+ export type AnyDepthArray<T> = Array<T | AnyDepthArray<T>>;
27
+ /**
28
+ * Expression for a prompt builder, used to build the part of system prompt.
29
+ * Returns the string part of the system prompt.
30
+ */
31
+ export type PromptBuilderExpression<T = unknown> = (entries: AIDataEntry<T>[], options: PromptBuilderExpressionOptions<T>) => string | AnyDepthArray<string>;
32
+ export interface PromptBuilderExpressionOptions<T = unknown> {
33
+ formatData: (data: T) => string;
34
+ }
35
+ /**
36
+ * Prompt builder **Tagged Template Literal** function.
37
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
38
+ */
39
+ export type PromptBuilder<T = unknown> = (templateParts: string[], ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<T>)[]) => string;
40
+ export type PromptBuilderParams<T = unknown> = Parameters<PromptBuilder<T>>;
41
+ /**
42
+ * Options for buildAIContextSystemPrompt
43
+ */
44
+ export interface BuildAIContextOptions<T = unknown> {
45
+ /**
46
+ * System prompt **template literal**. Use this, if you want to customize the system prompt or create on the fly.
47
+ * If not provided, a default system prompt template literal will be used (see example below).
48
+ *
49
+ * Use `AIPrompt` helper function to create a valid template.
50
+ *
51
+ * If you ever worked with styled-components, this is similar to the `styled` function.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * // Like in styled-components, use backticks to create a template literal.
56
+ * AIPrompt`Meta information provided by the user about the current page they are on:
57
+ *
58
+ * ${(entries, options) => entries.map((entry) =>
59
+ * // Each function inside the template literal has access to the entries and options from context:
60
+ * `### ${entry.label}\n${options.formatData(entry.data)}`
61
+ * )}
62
+ * `
63
+ *
64
+ * ```
65
+ */
66
+ template?: PromptBuilderParams<T>;
67
+ /**
68
+ * Custom data formatter.
69
+ * This function is used to convert JS objects to a LLM-readable string.
70
+ *
71
+ * Defaults to YAML-like serializer.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * formatData: (data) => JSON.stringify(data, null, 2)
76
+ * ```
77
+ */
78
+ formatData?: (data: unknown) => string;
79
+ }
80
+ /**
81
+ * Internal context value. Not exported to consumers.
82
+ */
83
+ export interface AIAgentContextValue<T = unknown> {
84
+ register: (id: string, getter: () => AIDataProps<T>) => void;
85
+ unregister: (id: string) => void;
86
+ getData: () => AIDataEntry<T>[];
87
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Props for AIData component and useProvideAIData hook\n */\nexport interface AIDataProps<T = unknown> {\n /** Human-readable description of what this data represents */\n label: string;\n /** The actual data to expose to the AI agent */\n data: T;\n}\n\n/**\n * Entry returned by getData()\n */\nexport interface AIDataEntry<T = unknown> {\n /** Human-readable description of what this data represents */\n label: string;\n /** The actual data */\n data: T;\n}\n\n/**\n * Public API returned by useAIAgentContext()\n */\nexport interface AIAgentContextAPI<T = unknown> {\n /** Returns the current list of all registered data entries */\n getData: () => AIDataEntry<T>[];\n}\n\nexport type AnyDepthArray<T> = Array<T | AnyDepthArray<T>>;\n\n/**\n * Expression for a prompt builder, used to build the part of system prompt.\n * Returns the string part of the system prompt.\n */\nexport type PromptBuilderExpression<T = unknown> = (\n entries: AIDataEntry<T>[],\n options: PromptBuilderExpressionOptions<T>,\n) => string | AnyDepthArray<string>;\n\nexport interface PromptBuilderExpressionOptions<T = unknown> {\n formatData: (data: T) => string;\n}\n\n/**\n * Prompt builder **Tagged Template Literal** function.\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates\n */\nexport type PromptBuilder<T = unknown> = (\n templateParts: string[],\n ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<T>)[]\n) => string;\n\nexport type PromptBuilderParams<T = unknown> = Parameters<PromptBuilder<T>>;\n\n/**\n * Options for buildAIContextSystemPrompt\n */\nexport interface BuildAIContextOptions<T = unknown> {\n /**\n * System prompt **template literal**. Use this, if you want to customize the system prompt or create on the fly.\n * If not provided, a default system prompt template literal will be used (see example below).\n *\n * Use `AIPrompt` helper function to create a valid template.\n *\n * If you ever worked with styled-components, this is similar to the `styled` function.\n *\n * @example\n * ```ts\n * // Like in styled-components, use backticks to create a template literal.\n * AIPrompt`Meta information provided by the user about the current page they are on:\n *\n * ${(entries, options) => entries.map((entry) =>\n * // Each function inside the template literal has access to the entries and options from context:\n * `### ${entry.label}\\n${options.formatData(entry.data)}`\n * )}\n * `\n *\n * ```\n */\n template?: PromptBuilderParams<T>;\n /**\n * Custom data formatter.\n * This function is used to convert JS objects to a LLM-readable string.\n *\n * Defaults to YAML-like serializer.\n *\n * @example\n * ```ts\n * formatData: (data) => JSON.stringify(data, null, 2)\n * ```\n */\n formatData?: (data: unknown) => string;\n}\n\n/**\n * Internal context value. Not exported to consumers.\n */\nexport interface AIAgentContextValue<T = unknown> {\n register: (id: string, getter: () => AIDataProps<T>) => void;\n unregister: (id: string) => void;\n getData: () => AIDataEntry<T>[];\n}\n"]}
@@ -3,4 +3,5 @@ export * from "./messageUtils.js";
3
3
  export * from "./validation.js";
4
4
  export * from "./messageTypeRegistry.js";
5
5
  export * from "./clipboardUtils.js";
6
+ export * from "./aiAgentContext/index.js";
6
7
  export * from "./toolset/index.js";
@@ -7,5 +7,6 @@ tslib_1.__exportStar(require("./messageUtils.js"), exports);
7
7
  tslib_1.__exportStar(require("./validation.js"), exports);
8
8
  tslib_1.__exportStar(require("./messageTypeRegistry.js"), exports);
9
9
  tslib_1.__exportStar(require("./clipboardUtils.js"), exports);
10
+ tslib_1.__exportStar(require("./aiAgentContext/index.js"), exports);
10
11
  tslib_1.__exportStar(require("./toolset/index.js"), exports);
11
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../src","sources":["utils/index.ts"],"names":[],"mappings":";;;AAAA,mBAAmB;AACnB,yDAA4B;AAC5B,4DAA+B;AAC/B,0DAA6B;AAC7B,mEAAsC;AACtC,8DAAiC;AACjC,6DAA0B","sourcesContent":["// Export utilities\nexport * from './chatUtils';\nexport * from './messageUtils';\nexport * from './validation';\nexport * from './messageTypeRegistry';\nexport * from './clipboardUtils';\nexport * from './toolset';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../src","sources":["utils/index.ts"],"names":[],"mappings":";;;AAAA,mBAAmB;AACnB,yDAA4B;AAC5B,4DAA+B;AAC/B,0DAA6B;AAC7B,mEAAsC;AACtC,8DAAiC;AACjC,oEAAiC;AACjC,6DAA0B","sourcesContent":["// Export utilities\nexport * from './chatUtils';\nexport * from './messageUtils';\nexport * from './validation';\nexport * from './messageTypeRegistry';\nexport * from './clipboardUtils';\nexport * from './aiAgentContext';\nexport * from './toolset';\n"]}
@@ -1 +1 @@
1
- {"version":"2.4.0","type":"module","sideEffects":["*.css","*.scss"]}
1
+ {"version":"2.5.0","type":"module","sideEffects":["*.css","*.scss"]}
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import type { AIAgentContextAPI, AIAgentContextValue } from "./types.js";
3
+ declare const AIAgentContext: React.Context<AIAgentContextValue<unknown> | null>;
4
+ /** Raw context — internal use only, not exported from the package. */
5
+ export { AIAgentContext as _AIAgentContext };
6
+ /**
7
+ * Provider that manages the AI data registry.
8
+ * Wrap your app or chat area with this to enable AIData collection.
9
+ */
10
+ export declare function AIAgentContextProvider({ children }: {
11
+ children: React.ReactNode;
12
+ }): import("react/jsx-runtime").JSX.Element;
13
+ /**
14
+ * Hook for consumers to access registered AI data.
15
+ * Returns { getData } where getData() returns the current list of all entries.
16
+ * If no AIAgentContextProvider exists above, getData() returns [].
17
+ *
18
+ * Generic `T` is the **expected** shape of `data` for this consumer — not validated
19
+ * or guaranteed at runtime. The registry is populated by arbitrary `AIData`
20
+ * registrations; entries may not match `T`.
21
+ */
22
+ export declare function useAIAgentContext<T = unknown>(): AIAgentContextAPI<T>;
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useCallback, useContext, useMemo, useRef } from 'react';
3
+ const AIAgentContext = createContext(null);
4
+ /** Raw context — internal use only, not exported from the package. */
5
+ export { AIAgentContext as _AIAgentContext };
6
+ /**
7
+ * Provider that manages the AI data registry.
8
+ * Wrap your app or chat area with this to enable AIData collection.
9
+ */
10
+ export function AIAgentContextProvider({ children }) {
11
+ const registryRef = useRef(new Map());
12
+ const contextValue = useMemo(() => ({
13
+ register: (id, getter) => {
14
+ registryRef.current.set(id, getter);
15
+ },
16
+ unregister: (id) => {
17
+ registryRef.current.delete(id);
18
+ },
19
+ getData: () => Array.from(registryRef.current.values()).map((getter) => {
20
+ const { label, data } = getter();
21
+ return { label, data };
22
+ }),
23
+ }), []);
24
+ return _jsx(AIAgentContext.Provider, { value: contextValue, children: children });
25
+ }
26
+ /**
27
+ * Hook for consumers to access registered AI data.
28
+ * Returns { getData } where getData() returns the current list of all entries.
29
+ * If no AIAgentContextProvider exists above, getData() returns [].
30
+ *
31
+ * Generic `T` is the **expected** shape of `data` for this consumer — not validated
32
+ * or guaranteed at runtime. The registry is populated by arbitrary `AIData`
33
+ * registrations; entries may not match `T`.
34
+ */
35
+ export function useAIAgentContext() {
36
+ const ctx = useContext(AIAgentContext);
37
+ const getData = useCallback(() => {
38
+ if (!ctx)
39
+ return [];
40
+ return ctx.getData();
41
+ }, [ctx]);
42
+ return useMemo(() => ({ getData }), [getData]);
43
+ }
44
+ //# sourceMappingURL=AIAgentContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AIAgentContext.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/AIAgentContext.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAC,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAC,MAAM,OAAO,CAAC;AAIrF,MAAM,cAAc,GAAG,aAAa,CAA6B,IAAI,CAAC,CAAC;AAEvE,sEAAsE;AACtE,OAAO,EAAC,cAAc,IAAI,eAAe,EAAC,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAC,QAAQ,EAA8B;IAC1E,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,GAAG,EAA6B,CAAC,CAAC;IAEjE,MAAM,YAAY,GAAG,OAAO,CACxB,GAAG,EAAE,CAAC,CAAC;QACH,QAAQ,EAAE,CAAC,EAAU,EAAE,MAAyB,EAAE,EAAE;YAChD,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,UAAU,EAAE,CAAC,EAAU,EAAE,EAAE;YACvB,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,GAAkB,EAAE,CACzB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACpD,MAAM,EAAC,KAAK,EAAE,IAAI,EAAC,GAAG,MAAM,EAAE,CAAC;YAC/B,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,CAAC;QACzB,CAAC,CAAC;KACT,CAAC,EACF,EAAE,CACL,CAAC;IAEF,OAAO,KAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,YAAG,QAAQ,GAA2B,CAAC;AAC9F,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB;IAC7B,MAAM,GAAG,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAG,WAAW,CAAC,GAAqB,EAAE;QAC/C,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,OAAO,GAAG,CAAC,OAAO,EAAsB,CAAC;IAC7C,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAC,OAAO,EAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;AACjD,CAAC","sourcesContent":["import React, {createContext, useCallback, useContext, useMemo, useRef} from 'react';\n\nimport type {AIAgentContextAPI, AIAgentContextValue, AIDataEntry, AIDataProps} from './types';\n\nconst AIAgentContext = createContext<AIAgentContextValue | null>(null);\n\n/** Raw context — internal use only, not exported from the package. */\nexport {AIAgentContext as _AIAgentContext};\n\n/**\n * Provider that manages the AI data registry.\n * Wrap your app or chat area with this to enable AIData collection.\n */\nexport function AIAgentContextProvider({children}: {children: React.ReactNode}) {\n const registryRef = useRef(new Map<string, () => AIDataProps>());\n\n const contextValue = useMemo<AIAgentContextValue>(\n () => ({\n register: (id: string, getter: () => AIDataProps) => {\n registryRef.current.set(id, getter);\n },\n unregister: (id: string) => {\n registryRef.current.delete(id);\n },\n getData: (): AIDataEntry[] =>\n Array.from(registryRef.current.values()).map((getter) => {\n const {label, data} = getter();\n return {label, data};\n }),\n }),\n [],\n );\n\n return <AIAgentContext.Provider value={contextValue}>{children}</AIAgentContext.Provider>;\n}\n\n/**\n * Hook for consumers to access registered AI data.\n * Returns { getData } where getData() returns the current list of all entries.\n * If no AIAgentContextProvider exists above, getData() returns [].\n *\n * Generic `T` is the **expected** shape of `data` for this consumer — not validated\n * or guaranteed at runtime. The registry is populated by arbitrary `AIData`\n * registrations; entries may not match `T`.\n */\nexport function useAIAgentContext<T = unknown>(): AIAgentContextAPI<T> {\n const ctx = useContext(AIAgentContext);\n\n const getData = useCallback((): AIDataEntry<T>[] => {\n if (!ctx) return [];\n return ctx.getData() as AIDataEntry<T>[];\n }, [ctx]);\n\n return useMemo(() => ({getData}), [getData]);\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import type { AIDataProps } from "./types.js";
2
+ /**
3
+ * Hook to register data in the AI agent context.
4
+ *
5
+ * Registration happens in `useEffect`, so `getData()` is only meaningful
6
+ * **after mount** of components that register data. Do not call `getData()`
7
+ * synchronously during render or in `useLayoutEffect` in the same commit.
8
+ *
9
+ * Uses a ref + getter pattern: the registry stores `() => propsRef.current`
10
+ * so `getData()` always reads the latest props without re-registering on every render.
11
+ */
12
+ export declare function useProvideAIData<T>(props: AIDataProps<T>): void;
13
+ /**
14
+ * Component that registers data in the AI agent context.
15
+ * Pure side-effect — renders nothing.
16
+ */
17
+ export declare function AIData<T>(props: AIDataProps<T>): null;
@@ -0,0 +1,39 @@
1
+ import { useContext, useEffect, useId, useRef } from 'react';
2
+ import { _AIAgentContext } from "./AIAgentContext.js";
3
+ /**
4
+ * Hook to register data in the AI agent context.
5
+ *
6
+ * Registration happens in `useEffect`, so `getData()` is only meaningful
7
+ * **after mount** of components that register data. Do not call `getData()`
8
+ * synchronously during render or in `useLayoutEffect` in the same commit.
9
+ *
10
+ * Uses a ref + getter pattern: the registry stores `() => propsRef.current`
11
+ * so `getData()` always reads the latest props without re-registering on every render.
12
+ */
13
+ export function useProvideAIData(props) {
14
+ const ctx = useContext(_AIAgentContext);
15
+ const id = useId();
16
+ const propsRef = useRef(props);
17
+ propsRef.current = props;
18
+ useEffect(() => {
19
+ if (!ctx) {
20
+ // eslint-disable-next-line no-console
21
+ console.warn('useProvideAIData must be used inside AIAgentContextProvider');
22
+ return;
23
+ }
24
+ ctx.register(id, () => propsRef.current);
25
+ // eslint-disable-next-line consistent-return
26
+ return () => {
27
+ ctx.unregister(id);
28
+ };
29
+ }, [ctx, id]);
30
+ }
31
+ /**
32
+ * Component that registers data in the AI agent context.
33
+ * Pure side-effect — renders nothing.
34
+ */
35
+ export function AIData(props) {
36
+ useProvideAIData(props);
37
+ return null;
38
+ }
39
+ //# sourceMappingURL=AIData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AIData.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/AIData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAC,MAAM,OAAO,CAAC;AAE3D,OAAO,EAAC,eAAe,EAAC,4BAAyB;AAGjD;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAI,KAAqB;IACrD,MAAM,GAAG,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IACxC,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;IAEzB,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YAE5E,OAAO;QACX,CAAC;QAED,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAEzC,6CAA6C;QAC7C,OAAO,GAAG,EAAE;YACR,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvB,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAI,KAAqB;IAC3C,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["import {useContext, useEffect, useId, useRef} from 'react';\n\nimport {_AIAgentContext} from './AIAgentContext';\nimport type {AIDataProps} from './types';\n\n/**\n * Hook to register data in the AI agent context.\n *\n * Registration happens in `useEffect`, so `getData()` is only meaningful\n * **after mount** of components that register data. Do not call `getData()`\n * synchronously during render or in `useLayoutEffect` in the same commit.\n *\n * Uses a ref + getter pattern: the registry stores `() => propsRef.current`\n * so `getData()` always reads the latest props without re-registering on every render.\n */\nexport function useProvideAIData<T>(props: AIDataProps<T>): void {\n const ctx = useContext(_AIAgentContext);\n const id = useId();\n const propsRef = useRef(props);\n propsRef.current = props;\n\n useEffect(() => {\n if (!ctx) {\n // eslint-disable-next-line no-console\n console.warn('useProvideAIData must be used inside AIAgentContextProvider');\n\n return;\n }\n\n ctx.register(id, () => propsRef.current);\n\n // eslint-disable-next-line consistent-return\n return () => {\n ctx.unregister(id);\n };\n }, [ctx, id]);\n}\n\n/**\n * Component that registers data in the AI agent context.\n * Pure side-effect — renders nothing.\n */\nexport function AIData<T>(props: AIDataProps<T>): null {\n useProvideAIData(props);\n return null;\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { AIDataEntry, BuildAIContextOptions } from "./types.js";
2
+ /**
3
+ * Formats AI data entries into a system prompt string.
4
+ * Uses YAML-like format by default, can be overridden via options.formatData.
5
+ * Uses prompt builder to build the system prompt from **Template Literal**. See `createDefaultSystemPromptBuilder` for more details.
6
+ */
7
+ export declare function buildAIContextSystemPrompt<T = unknown>(entries: AIDataEntry<T>[], options?: BuildAIContextOptions<T>): string;
@@ -0,0 +1,18 @@
1
+ import { DEFAULT_SYSTEM_PROMPT_TEMPLATE, createDefaultSystemPromptBuilder } from "./templateStrings.js";
2
+ import { toYamlLike } from "./toYamlLike.js";
3
+ /**
4
+ * Formats AI data entries into a system prompt string.
5
+ * Uses YAML-like format by default, can be overridden via options.formatData.
6
+ * Uses prompt builder to build the system prompt from **Template Literal**. See `createDefaultSystemPromptBuilder` for more details.
7
+ */
8
+ export function buildAIContextSystemPrompt(entries, options = {}) {
9
+ var _a, _b;
10
+ if (entries.length === 0)
11
+ return '';
12
+ const builder = createDefaultSystemPromptBuilder(entries, {
13
+ formatData: (_a = options.formatData) !== null && _a !== void 0 ? _a : toYamlLike,
14
+ });
15
+ const template = (_b = options.template) !== null && _b !== void 0 ? _b : DEFAULT_SYSTEM_PROMPT_TEMPLATE;
16
+ return builder(...template);
17
+ }
18
+ //# sourceMappingURL=buildAIContextSystemPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildAIContextSystemPrompt.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/buildAIContextSystemPrompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,8BAA8B,EAAE,gCAAgC,EAAC,6BAA0B;AACnG,OAAO,EAAC,UAAU,EAAC,wBAAqB;AAGxC;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACtC,OAAyB,EACzB,UAAoC,EAAE;;IAEtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,OAAO,GAAG,gCAAgC,CAAI,OAAO,EAAE;QACzD,UAAU,EAAE,MAAA,OAAO,CAAC,UAAU,mCAAI,UAAU;KAC/C,CAAC,CAAC;IAEH,MAAM,QAAQ,GAA2B,MAAA,OAAO,CAAC,QAAQ,mCAAI,8BAA8B,CAAC;IAE5F,OAAO,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;AAChC,CAAC","sourcesContent":["import {DEFAULT_SYSTEM_PROMPT_TEMPLATE, createDefaultSystemPromptBuilder} from './templateStrings';\nimport {toYamlLike} from './toYamlLike';\nimport type {AIDataEntry, BuildAIContextOptions, PromptBuilderParams} from './types';\n\n/**\n * Formats AI data entries into a system prompt string.\n * Uses YAML-like format by default, can be overridden via options.formatData.\n * Uses prompt builder to build the system prompt from **Template Literal**. See `createDefaultSystemPromptBuilder` for more details.\n */\nexport function buildAIContextSystemPrompt<T = unknown>(\n entries: AIDataEntry<T>[],\n options: BuildAIContextOptions<T> = {},\n): string {\n if (entries.length === 0) return '';\n\n const builder = createDefaultSystemPromptBuilder<T>(entries, {\n formatData: options.formatData ?? toYamlLike,\n });\n\n const template: PromptBuilderParams<T> = options.template ?? DEFAULT_SYSTEM_PROMPT_TEMPLATE;\n\n return builder(...template);\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export { AIAgentContextProvider, useAIAgentContext } from "./AIAgentContext.js";
2
+ export { AIData, useProvideAIData } from "./AIData.js";
3
+ export { buildAIContextSystemPrompt } from "./buildAIContextSystemPrompt.js";
4
+ export { AIPrompt, DEFAULT_SYSTEM_PROMPT_TEMPLATE } from "./templateStrings.js";
5
+ export type { AIDataProps, AIDataEntry, AIAgentContextAPI, BuildAIContextOptions, PromptBuilder, PromptBuilderParams, PromptBuilderExpression, PromptBuilderExpressionOptions, } from "./types.js";
@@ -0,0 +1,7 @@
1
+ // Components
2
+ export { AIAgentContextProvider, useAIAgentContext } from "./AIAgentContext.js";
3
+ export { AIData, useProvideAIData } from "./AIData.js";
4
+ // Utilities
5
+ export { buildAIContextSystemPrompt } from "./buildAIContextSystemPrompt.js";
6
+ export { AIPrompt, DEFAULT_SYSTEM_PROMPT_TEMPLATE } from "./templateStrings.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/index.ts"],"names":[],"mappings":"AAAA,aAAa;AACb,OAAO,EAAC,sBAAsB,EAAE,iBAAiB,EAAC,4BAAyB;AAC3E,OAAO,EAAC,MAAM,EAAE,gBAAgB,EAAC,oBAAiB;AAElD,YAAY;AACZ,OAAO,EAAC,0BAA0B,EAAC,wCAAqC;AACxE,OAAO,EAAC,QAAQ,EAAE,8BAA8B,EAAC,6BAA0B","sourcesContent":["// Components\nexport {AIAgentContextProvider, useAIAgentContext} from './AIAgentContext';\nexport {AIData, useProvideAIData} from './AIData';\n\n// Utilities\nexport {buildAIContextSystemPrompt} from './buildAIContextSystemPrompt';\nexport {AIPrompt, DEFAULT_SYSTEM_PROMPT_TEMPLATE} from './templateStrings';\n\n// Types\nexport type {\n AIDataProps,\n AIDataEntry,\n AIAgentContextAPI,\n BuildAIContextOptions,\n PromptBuilder,\n PromptBuilderParams,\n PromptBuilderExpression,\n PromptBuilderExpressionOptions,\n} from './types';\n"]}
@@ -0,0 +1,4 @@
1
+ import { AIDataEntry, AnyDepthArray, PromptBuilder, PromptBuilderExpression, PromptBuilderExpressionOptions, PromptBuilderParams } from "./types.js";
2
+ export declare function AIPrompt<T = unknown>(templateParts: TemplateStringsArray, ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<T>)[]): PromptBuilderParams<T>;
3
+ export declare function createDefaultSystemPromptBuilder<T = unknown>(entries: AIDataEntry<T>[], options: PromptBuilderExpressionOptions<T>): PromptBuilder<T>;
4
+ export declare const DEFAULT_SYSTEM_PROMPT_TEMPLATE: [templateParts: string[], ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<any>)[]];
@@ -0,0 +1,32 @@
1
+ export function AIPrompt(templateParts, ...functions) {
2
+ return [[...templateParts.raw], ...functions];
3
+ }
4
+ export function createDefaultSystemPromptBuilder(entries, options) {
5
+ return (templateParts, ...functions) => {
6
+ const out = [];
7
+ for (let i = 0; i < templateParts.length; i++) {
8
+ const part = templateParts[i];
9
+ out.push(part);
10
+ const fn = functions[i];
11
+ if (fn) {
12
+ const result = typeof fn === 'function' ? fn(entries, options) : fn;
13
+ if (typeof result === 'string') {
14
+ out.push(result);
15
+ }
16
+ if (Array.isArray(result)) {
17
+ // @ts-expect-error - we know that the result is an array of strings, but TS can't handle it (Type instantiation is excessively deep and possibly infinite.)
18
+ out.push(result.flat(Infinity).join('\n\n'));
19
+ }
20
+ }
21
+ }
22
+ return out.join('');
23
+ };
24
+ }
25
+ export const DEFAULT_SYSTEM_PROMPT_TEMPLATE = AIPrompt `Meta information provided by the user about the current page they are on:
26
+
27
+ ${(entries, options) => entries.map((entry) => {
28
+ const formatted = options.formatData(entry.data);
29
+ return [`### ${entry.label}`, formatted];
30
+ })}
31
+ `;
32
+ //# sourceMappingURL=templateStrings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateStrings.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/templateStrings.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,QAAQ,CACpB,aAAmC,EACnC,GAAG,SAA0E;IAE7E,OAAO,CAAC,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC5C,OAAyB,EACzB,OAA0C;IAE1C,OAAO,CACH,aAAuB,EACvB,GAAG,SAA0E,EACvE,EAAE;QACR,MAAM,GAAG,GAAG,EAAE,CAAC;QAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEf,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAExB,IAAI,EAAE,EAAE,CAAC;gBACL,MAAM,MAAM,GAAG,OAAO,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAEpE,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC7B,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACrB,CAAC;gBAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBACxB,4JAA4J;oBAC5J,GAAG,CAAC,IAAI,CAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/D,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC;AACN,CAAC;AAED,MAAM,CAAC,MAAM,8BAA8B,GAAG,QAAQ,CAAK;;EAEzD,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CACnB,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;IAClB,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEjD,OAAO,CAAC,OAAO,KAAK,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC,CAAC;CACL,CAAC","sourcesContent":["import {\n AIDataEntry,\n AnyDepthArray,\n PromptBuilder,\n PromptBuilderExpression,\n PromptBuilderExpressionOptions,\n PromptBuilderParams,\n} from './types';\n\nexport function AIPrompt<T = unknown>(\n templateParts: TemplateStringsArray,\n ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<T>)[]\n): PromptBuilderParams<T> {\n return [[...templateParts.raw], ...functions];\n}\n\nexport function createDefaultSystemPromptBuilder<T = unknown>(\n entries: AIDataEntry<T>[],\n options: PromptBuilderExpressionOptions<T>,\n): PromptBuilder<T> {\n return (\n templateParts: string[],\n ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<T>)[]\n ): string => {\n const out = [];\n\n for (let i = 0; i < templateParts.length; i++) {\n const part = templateParts[i];\n out.push(part);\n\n const fn = functions[i];\n\n if (fn) {\n const result = typeof fn === 'function' ? fn(entries, options) : fn;\n\n if (typeof result === 'string') {\n out.push(result);\n }\n\n if (Array.isArray(result)) {\n // @ts-expect-error - we know that the result is an array of strings, but TS can't handle it (Type instantiation is excessively deep and possibly infinite.)\n out.push((result.flat(Infinity) as string[]).join('\\n\\n'));\n }\n }\n }\n\n return out.join('');\n };\n}\n\nexport const DEFAULT_SYSTEM_PROMPT_TEMPLATE = AIPrompt<any>`Meta information provided by the user about the current page they are on:\n\n${(entries, options) =>\n entries.map((entry) => {\n const formatted = options.formatData(entry.data);\n\n return [`### ${entry.label}`, formatted];\n })}\n`;\n"]}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Simple YAML-like serializer for plain JS values.
3
+ * Handles: string, number, boolean, null/undefined, arrays, plain objects.
4
+ * Falls back to String() for unsupported types.
5
+ * Internal helper — not exported from the package.
6
+ */
7
+ export declare function toYamlLike(data: unknown, indent?: number): string;
@@ -0,0 +1,105 @@
1
+ const CIRCULAR_REF = '[Circular]';
2
+ function indentLines(text, spaces) {
3
+ const prefix = ' '.repeat(spaces);
4
+ return text
5
+ .split('\n')
6
+ .map((line) => `${prefix}${line}`)
7
+ .join('\n');
8
+ }
9
+ function isComplexValue(val) {
10
+ if (val === null || val === undefined) {
11
+ return false;
12
+ }
13
+ if (Array.isArray(val)) {
14
+ return val.length > 0;
15
+ }
16
+ if (typeof val === 'object') {
17
+ return Object.keys(val).length > 0;
18
+ }
19
+ if (typeof val === 'string') {
20
+ return val.includes('\n');
21
+ }
22
+ return false;
23
+ }
24
+ function withVisitedObject(value, visited, serialize) {
25
+ if (visited.has(value)) {
26
+ return CIRCULAR_REF;
27
+ }
28
+ visited.add(value);
29
+ try {
30
+ return serialize();
31
+ }
32
+ finally {
33
+ visited.delete(value);
34
+ }
35
+ }
36
+ function isVisitedReference(val, visited) {
37
+ return typeof val === 'object' && val !== null && visited.has(val);
38
+ }
39
+ function formatKeyValue(key, val, keyPrefix, indent, visited) {
40
+ if (isVisitedReference(val, visited)) {
41
+ return `${keyPrefix}${key}: ${CIRCULAR_REF}`;
42
+ }
43
+ if (isComplexValue(val)) {
44
+ return `${keyPrefix}${key}:\n${toYamlLikeInternal(val, indent + 2, visited)}`;
45
+ }
46
+ return `${keyPrefix}${key}: ${toYamlLikeInternal(val, indent + 2, visited)}`;
47
+ }
48
+ /**
49
+ * Simple YAML-like serializer for plain JS values.
50
+ * Handles: string, number, boolean, null/undefined, arrays, plain objects.
51
+ * Falls back to String() for unsupported types.
52
+ * Internal helper — not exported from the package.
53
+ */
54
+ export function toYamlLike(data, indent = 0) {
55
+ return toYamlLikeInternal(data, indent, new Set());
56
+ }
57
+ function toYamlLikeInternal(data, indent, visited) {
58
+ if (data === null || data === undefined)
59
+ return 'null';
60
+ if (typeof data === 'string') {
61
+ if (data.includes('\n')) {
62
+ return `|\n${indentLines(data, indent + 2)}`;
63
+ }
64
+ return data;
65
+ }
66
+ if (typeof data === 'number' || typeof data === 'boolean') {
67
+ return String(data);
68
+ }
69
+ if (Array.isArray(data)) {
70
+ if (data.length === 0)
71
+ return '[]';
72
+ return withVisitedObject(data, visited, () => data
73
+ .map((item) => {
74
+ const prefix = `${' '.repeat(indent)}- `;
75
+ if (typeof item === 'object' && item !== null && !Array.isArray(item)) {
76
+ return withVisitedObject(item, visited, () => {
77
+ const entries = Object.entries(item);
78
+ if (entries.length === 0)
79
+ return `${prefix}{}`;
80
+ const [firstKey, firstVal] = entries[0];
81
+ const firstLine = formatKeyValue(firstKey, firstVal, `${' '.repeat(indent)}- `, indent, visited);
82
+ const rest = entries
83
+ .slice(1)
84
+ .map(([key, val]) => formatKeyValue(key, val, ' '.repeat(indent + 2), indent + 2, visited))
85
+ .join('\n');
86
+ return rest ? `${firstLine}\n${rest}` : firstLine;
87
+ });
88
+ }
89
+ return `${prefix}${toYamlLikeInternal(item, indent + 2, visited)}`;
90
+ })
91
+ .join('\n'));
92
+ }
93
+ if (typeof data === 'object') {
94
+ return withVisitedObject(data, visited, () => {
95
+ const entries = Object.entries(data);
96
+ if (entries.length === 0)
97
+ return '{}';
98
+ return entries
99
+ .map(([key, val]) => formatKeyValue(key, val, ' '.repeat(indent), indent, visited))
100
+ .join('\n');
101
+ });
102
+ }
103
+ return String(data);
104
+ }
105
+ //# sourceMappingURL=toYamlLike.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toYamlLike.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/toYamlLike.ts"],"names":[],"mappings":"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","sourcesContent":["const CIRCULAR_REF = '[Circular]';\n\nfunction indentLines(text: string, spaces: number): string {\n const prefix = ' '.repeat(spaces);\n return text\n .split('\\n')\n .map((line) => `${prefix}${line}`)\n .join('\\n');\n}\n\nfunction isComplexValue(val: unknown): boolean {\n if (val === null || val === undefined) {\n return false;\n }\n if (Array.isArray(val)) {\n return val.length > 0;\n }\n if (typeof val === 'object') {\n return Object.keys(val).length > 0;\n }\n if (typeof val === 'string') {\n return val.includes('\\n');\n }\n return false;\n}\n\nfunction withVisitedObject<T extends object>(\n value: T,\n visited: Set<object>,\n serialize: () => string,\n): string {\n if (visited.has(value)) {\n return CIRCULAR_REF;\n }\n visited.add(value);\n try {\n return serialize();\n } finally {\n visited.delete(value);\n }\n}\n\nfunction isVisitedReference(val: unknown, visited: Set<object>): val is object {\n return typeof val === 'object' && val !== null && visited.has(val);\n}\n\nfunction formatKeyValue(\n key: string,\n val: unknown,\n keyPrefix: string,\n indent: number,\n visited: Set<object>,\n): string {\n if (isVisitedReference(val, visited)) {\n return `${keyPrefix}${key}: ${CIRCULAR_REF}`;\n }\n if (isComplexValue(val)) {\n return `${keyPrefix}${key}:\\n${toYamlLikeInternal(val, indent + 2, visited)}`;\n }\n return `${keyPrefix}${key}: ${toYamlLikeInternal(val, indent + 2, visited)}`;\n}\n\n/**\n * Simple YAML-like serializer for plain JS values.\n * Handles: string, number, boolean, null/undefined, arrays, plain objects.\n * Falls back to String() for unsupported types.\n * Internal helper — not exported from the package.\n */\nexport function toYamlLike(data: unknown, indent = 0): string {\n return toYamlLikeInternal(data, indent, new Set());\n}\n\nfunction toYamlLikeInternal(data: unknown, indent: number, visited: Set<object>): string {\n if (data === null || data === undefined) return 'null';\n\n if (typeof data === 'string') {\n if (data.includes('\\n')) {\n return `|\\n${indentLines(data, indent + 2)}`;\n }\n return data;\n }\n\n if (typeof data === 'number' || typeof data === 'boolean') {\n return String(data);\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) return '[]';\n\n return withVisitedObject(data, visited, () =>\n data\n .map((item) => {\n const prefix = `${' '.repeat(indent)}- `;\n if (typeof item === 'object' && item !== null && !Array.isArray(item)) {\n return withVisitedObject(item, visited, () => {\n const entries = Object.entries(item);\n if (entries.length === 0) return `${prefix}{}`;\n const [firstKey, firstVal] = entries[0];\n const firstLine = formatKeyValue(\n firstKey,\n firstVal,\n `${' '.repeat(indent)}- `,\n indent,\n visited,\n );\n const rest = entries\n .slice(1)\n .map(([key, val]) =>\n formatKeyValue(\n key,\n val,\n ' '.repeat(indent + 2),\n indent + 2,\n visited,\n ),\n )\n .join('\\n');\n return rest ? `${firstLine}\\n${rest}` : firstLine;\n });\n }\n return `${prefix}${toYamlLikeInternal(item, indent + 2, visited)}`;\n })\n .join('\\n'),\n );\n }\n\n if (typeof data === 'object') {\n return withVisitedObject(data, visited, () => {\n const entries = Object.entries(data as Record<string, unknown>);\n if (entries.length === 0) return '{}';\n\n return entries\n .map(([key, val]) => formatKeyValue(key, val, ' '.repeat(indent), indent, visited))\n .join('\\n');\n });\n }\n\n return String(data);\n}\n"]}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Props for AIData component and useProvideAIData hook
3
+ */
4
+ export interface AIDataProps<T = unknown> {
5
+ /** Human-readable description of what this data represents */
6
+ label: string;
7
+ /** The actual data to expose to the AI agent */
8
+ data: T;
9
+ }
10
+ /**
11
+ * Entry returned by getData()
12
+ */
13
+ export interface AIDataEntry<T = unknown> {
14
+ /** Human-readable description of what this data represents */
15
+ label: string;
16
+ /** The actual data */
17
+ data: T;
18
+ }
19
+ /**
20
+ * Public API returned by useAIAgentContext()
21
+ */
22
+ export interface AIAgentContextAPI<T = unknown> {
23
+ /** Returns the current list of all registered data entries */
24
+ getData: () => AIDataEntry<T>[];
25
+ }
26
+ export type AnyDepthArray<T> = Array<T | AnyDepthArray<T>>;
27
+ /**
28
+ * Expression for a prompt builder, used to build the part of system prompt.
29
+ * Returns the string part of the system prompt.
30
+ */
31
+ export type PromptBuilderExpression<T = unknown> = (entries: AIDataEntry<T>[], options: PromptBuilderExpressionOptions<T>) => string | AnyDepthArray<string>;
32
+ export interface PromptBuilderExpressionOptions<T = unknown> {
33
+ formatData: (data: T) => string;
34
+ }
35
+ /**
36
+ * Prompt builder **Tagged Template Literal** function.
37
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
38
+ */
39
+ export type PromptBuilder<T = unknown> = (templateParts: string[], ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<T>)[]) => string;
40
+ export type PromptBuilderParams<T = unknown> = Parameters<PromptBuilder<T>>;
41
+ /**
42
+ * Options for buildAIContextSystemPrompt
43
+ */
44
+ export interface BuildAIContextOptions<T = unknown> {
45
+ /**
46
+ * System prompt **template literal**. Use this, if you want to customize the system prompt or create on the fly.
47
+ * If not provided, a default system prompt template literal will be used (see example below).
48
+ *
49
+ * Use `AIPrompt` helper function to create a valid template.
50
+ *
51
+ * If you ever worked with styled-components, this is similar to the `styled` function.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * // Like in styled-components, use backticks to create a template literal.
56
+ * AIPrompt`Meta information provided by the user about the current page they are on:
57
+ *
58
+ * ${(entries, options) => entries.map((entry) =>
59
+ * // Each function inside the template literal has access to the entries and options from context:
60
+ * `### ${entry.label}\n${options.formatData(entry.data)}`
61
+ * )}
62
+ * `
63
+ *
64
+ * ```
65
+ */
66
+ template?: PromptBuilderParams<T>;
67
+ /**
68
+ * Custom data formatter.
69
+ * This function is used to convert JS objects to a LLM-readable string.
70
+ *
71
+ * Defaults to YAML-like serializer.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * formatData: (data) => JSON.stringify(data, null, 2)
76
+ * ```
77
+ */
78
+ formatData?: (data: unknown) => string;
79
+ }
80
+ /**
81
+ * Internal context value. Not exported to consumers.
82
+ */
83
+ export interface AIAgentContextValue<T = unknown> {
84
+ register: (id: string, getter: () => AIDataProps<T>) => void;
85
+ unregister: (id: string) => void;
86
+ getData: () => AIDataEntry<T>[];
87
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"../../../../src","sources":["utils/aiAgentContext/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Props for AIData component and useProvideAIData hook\n */\nexport interface AIDataProps<T = unknown> {\n /** Human-readable description of what this data represents */\n label: string;\n /** The actual data to expose to the AI agent */\n data: T;\n}\n\n/**\n * Entry returned by getData()\n */\nexport interface AIDataEntry<T = unknown> {\n /** Human-readable description of what this data represents */\n label: string;\n /** The actual data */\n data: T;\n}\n\n/**\n * Public API returned by useAIAgentContext()\n */\nexport interface AIAgentContextAPI<T = unknown> {\n /** Returns the current list of all registered data entries */\n getData: () => AIDataEntry<T>[];\n}\n\nexport type AnyDepthArray<T> = Array<T | AnyDepthArray<T>>;\n\n/**\n * Expression for a prompt builder, used to build the part of system prompt.\n * Returns the string part of the system prompt.\n */\nexport type PromptBuilderExpression<T = unknown> = (\n entries: AIDataEntry<T>[],\n options: PromptBuilderExpressionOptions<T>,\n) => string | AnyDepthArray<string>;\n\nexport interface PromptBuilderExpressionOptions<T = unknown> {\n formatData: (data: T) => string;\n}\n\n/**\n * Prompt builder **Tagged Template Literal** function.\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates\n */\nexport type PromptBuilder<T = unknown> = (\n templateParts: string[],\n ...functions: (string | AnyDepthArray<string> | PromptBuilderExpression<T>)[]\n) => string;\n\nexport type PromptBuilderParams<T = unknown> = Parameters<PromptBuilder<T>>;\n\n/**\n * Options for buildAIContextSystemPrompt\n */\nexport interface BuildAIContextOptions<T = unknown> {\n /**\n * System prompt **template literal**. Use this, if you want to customize the system prompt or create on the fly.\n * If not provided, a default system prompt template literal will be used (see example below).\n *\n * Use `AIPrompt` helper function to create a valid template.\n *\n * If you ever worked with styled-components, this is similar to the `styled` function.\n *\n * @example\n * ```ts\n * // Like in styled-components, use backticks to create a template literal.\n * AIPrompt`Meta information provided by the user about the current page they are on:\n *\n * ${(entries, options) => entries.map((entry) =>\n * // Each function inside the template literal has access to the entries and options from context:\n * `### ${entry.label}\\n${options.formatData(entry.data)}`\n * )}\n * `\n *\n * ```\n */\n template?: PromptBuilderParams<T>;\n /**\n * Custom data formatter.\n * This function is used to convert JS objects to a LLM-readable string.\n *\n * Defaults to YAML-like serializer.\n *\n * @example\n * ```ts\n * formatData: (data) => JSON.stringify(data, null, 2)\n * ```\n */\n formatData?: (data: unknown) => string;\n}\n\n/**\n * Internal context value. Not exported to consumers.\n */\nexport interface AIAgentContextValue<T = unknown> {\n register: (id: string, getter: () => AIDataProps<T>) => void;\n unregister: (id: string) => void;\n getData: () => AIDataEntry<T>[];\n}\n"]}
@@ -3,4 +3,5 @@ export * from "./messageUtils.js";
3
3
  export * from "./validation.js";
4
4
  export * from "./messageTypeRegistry.js";
5
5
  export * from "./clipboardUtils.js";
6
+ export * from "./aiAgentContext/index.js";
6
7
  export * from "./toolset/index.js";
@@ -4,5 +4,6 @@ export * from "./messageUtils.js";
4
4
  export * from "./validation.js";
5
5
  export * from "./messageTypeRegistry.js";
6
6
  export * from "./clipboardUtils.js";
7
+ export * from "./aiAgentContext/index.js";
7
8
  export * from "./toolset/index.js";
8
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../../../src","sources":["utils/index.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,+BAA4B;AAC5B,kCAA+B;AAC/B,gCAA6B;AAC7B,yCAAsC;AACtC,oCAAiC;AACjC,mCAA0B","sourcesContent":["// Export utilities\nexport * from './chatUtils';\nexport * from './messageUtils';\nexport * from './validation';\nexport * from './messageTypeRegistry';\nexport * from './clipboardUtils';\nexport * from './toolset';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"../../../src","sources":["utils/index.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,+BAA4B;AAC5B,kCAA+B;AAC/B,gCAA6B;AAC7B,yCAAsC;AACtC,oCAAiC;AACjC,0CAAiC;AACjC,mCAA0B","sourcesContent":["// Export utilities\nexport * from './chatUtils';\nexport * from './messageUtils';\nexport * from './validation';\nexport * from './messageTypeRegistry';\nexport * from './clipboardUtils';\nexport * from './aiAgentContext';\nexport * from './toolset';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/aikit",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Gravity UI base kit for building ai assistant chats",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -98,6 +98,16 @@
98
98
  "default": "./build/cjs/utils/clipboardUtils.js"
99
99
  }
100
100
  },
101
+ "./utils/aiAgentContext": {
102
+ "import": {
103
+ "types": "./build/esm/utils/aiAgentContext/index.d.ts",
104
+ "default": "./build/esm/utils/aiAgentContext/index.js"
105
+ },
106
+ "require": {
107
+ "types": "./build/cjs/utils/aiAgentContext/index.d.ts",
108
+ "default": "./build/cjs/utils/aiAgentContext/index.js"
109
+ }
110
+ },
101
111
  "./utils/toolset": {
102
112
  "import": {
103
113
  "types": "./build/esm/utils/toolset/index.d.ts",