@curaious/uno-converse 0.1.15 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,12 @@
1
+ import { ReactNode, ReactElement } from 'react';
2
+ import { AxiosInstance } from 'axios';
3
+
4
+ interface Agent {
5
+ id: string;
6
+ agent_id: string;
7
+ name: string;
8
+ version: number;
9
+ }
1
10
  declare enum Role {
2
11
  User = "user",
3
12
  Developer = "developer",
@@ -276,12 +285,6 @@ type GetHeadersFn = () => Record<string, string> | Promise<Record<string, string
276
285
  interface UseConversationOptions {
277
286
  /** The namespace for conversations */
278
287
  namespace: string;
279
- /** Base URL of the Uno Agent Server (e.g., 'https://api.example.com/api/agent-server') */
280
- baseUrl: string;
281
- /** Project Name used to fetch the project ID */
282
- projectName: string;
283
- /** Optional function to get custom headers for requests (e.g., for authentication) */
284
- getHeaders?: GetHeadersFn;
285
288
  /** Auto-load conversations on mount (default: true) */
286
289
  autoLoad?: boolean;
287
290
  }
@@ -289,10 +292,6 @@ interface UseConversationOptions {
289
292
  * Return type for the useConversation hook
290
293
  */
291
294
  interface UseConversationReturn {
292
- /** The fetched project ID */
293
- projectId: string;
294
- /** Whether the project ID is being fetched */
295
- projectLoading: boolean;
296
295
  /** List of all conversations */
297
296
  conversations: Conversation[];
298
297
  /** Whether conversations are being loaded */
@@ -348,11 +347,6 @@ interface UseConversationReturn {
348
347
  * startNewChat,
349
348
  * } = useConversation({
350
349
  * namespace: 'my-app',
351
- * projectName: 'my-project',
352
- * baseUrl: 'https://my-uno-server.com/api/agent-server',
353
- * getHeaders: () => ({
354
- * 'Authorization': `Bearer ${getToken()}`,
355
- * }),
356
350
  * });
357
351
  *
358
352
  * const handleSend = async (text: string) => {
@@ -378,6 +372,132 @@ interface UseConversationReturn {
378
372
  */
379
373
  declare function useConversation(options: UseConversationOptions): UseConversationReturn;
380
374
 
375
+ /**
376
+ * Options for the useAgent hook
377
+ */
378
+ interface UseAgentOptions {
379
+ /** The name of the agent */
380
+ name: string;
381
+ }
382
+ /**
383
+ * Return type for the useAgent hook
384
+ */
385
+ interface UseAgentReturn {
386
+ agent: Agent | null;
387
+ /** Whether the agent is being loaded */
388
+ agentLoading: boolean;
389
+ }
390
+ declare function useAgent(options: UseAgentOptions): UseAgentReturn;
391
+
392
+ /**
393
+ * Options for the useProject hook
394
+ */
395
+ interface UseProjectOptions {
396
+ /** Base URL of the Uno Agent Server (e.g., 'https://api.example.com/api/agent-server') */
397
+ baseUrl: string;
398
+ /** Project Name used to fetch the project ID */
399
+ projectName: string;
400
+ /** Optional function to get custom headers for requests (e.g., for authentication) */
401
+ getHeaders?: GetHeadersFn;
402
+ /** Auto-load conversations on mount (default: true) */
403
+ autoLoad?: boolean;
404
+ }
405
+ /**
406
+ * Return type for the useProject hook
407
+ */
408
+ interface UseProjectReturn {
409
+ /** The fetched project ID */
410
+ projectId: string;
411
+ /** Whether the project ID is being fetched */
412
+ projectLoading: boolean;
413
+ /** Axios instance configured with baseUrl and custom headers */
414
+ axiosInstance: AxiosInstance;
415
+ /** Function to build query params with project_id automatically added */
416
+ buildParams: (params?: Record<string, string>) => Record<string, string>;
417
+ /** Function to get request headers (combines default + custom headers) */
418
+ getRequestHeaders: () => Promise<Record<string, string>>;
419
+ /** Base URL used for the axios instance */
420
+ baseUrl: string;
421
+ }
422
+
423
+ /**
424
+ * Context value for ProjectProvider
425
+ */
426
+ interface ProjectContextValue extends UseProjectReturn {
427
+ }
428
+ /**
429
+ * Props for ProjectProvider component
430
+ */
431
+ interface ProjectProviderProps {
432
+ /** Base URL of the Uno Agent Server (e.g., 'https://api.example.com/api/agent-server') */
433
+ baseUrl: string;
434
+ /** Project Name used to fetch the project ID */
435
+ projectName: string;
436
+ /** Optional function to get custom headers for requests (e.g., for authentication) */
437
+ getHeaders?: UseProjectOptions['getHeaders'];
438
+ /** Auto-load project on mount (default: true) */
439
+ autoLoad?: boolean;
440
+ /** Child components */
441
+ children: ReactNode;
442
+ }
443
+ /**
444
+ * ProjectProvider component that manages project state using React Context.
445
+ *
446
+ * This provider wraps the useProject hook and makes the project state available
447
+ * to all child components through context.
448
+ *
449
+ * @example
450
+ * ```tsx
451
+ * import { ProjectProvider, useProjectContext } from '@praveen001/uno-converse';
452
+ *
453
+ * function App() {
454
+ * return (
455
+ * <ProjectProvider
456
+ * baseUrl="https://api.example.com/api/agent-server"
457
+ * projectName="my-project"
458
+ * getHeaders={() => ({
459
+ * 'Authorization': `Bearer ${getToken()}`,
460
+ * })}
461
+ * >
462
+ * <YourApp />
463
+ * </ProjectProvider>
464
+ * );
465
+ * }
466
+ *
467
+ * function YourApp() {
468
+ * const { projectId, projectLoading } = useProjectContext();
469
+ *
470
+ * if (projectLoading) {
471
+ * return <div>Loading project...</div>;
472
+ * }
473
+ *
474
+ * return <div>Project ID: {projectId}</div>;
475
+ * }
476
+ * ```
477
+ */
478
+ declare const ProjectProvider: ({ baseUrl, projectName, getHeaders, autoLoad, children, }: ProjectProviderProps) => ReactElement;
479
+ /**
480
+ * Hook to access the project context.
481
+ *
482
+ * Must be used within a ProjectProvider component.
483
+ *
484
+ * @throws {Error} If used outside of ProjectProvider
485
+ *
486
+ * @example
487
+ * ```tsx
488
+ * function MyComponent() {
489
+ * const { projectId, projectLoading } = useProjectContext();
490
+ *
491
+ * return (
492
+ * <div>
493
+ * {projectLoading ? 'Loading...' : `Project ID: ${projectId}`}
494
+ * </div>
495
+ * );
496
+ * }
497
+ * ```
498
+ */
499
+ declare const useProjectContext: () => ProjectContextValue;
500
+
381
501
  /**
382
502
  * Callback invoked when the conversation state changes
383
503
  */
@@ -469,5 +589,5 @@ interface SSEStreamOptions {
469
589
  */
470
590
  declare function streamSSE(url: string, requestOptions: RequestInit, callbacks: SSEStreamOptions, abortSignal?: AbortSignal): Promise<void>;
471
591
 
472
- export { ChunkProcessor, ChunkType, ContentType, MessageType, Role, isEasyMessage, isFunctionCallMessage, isFunctionCallOutputMessage, isImageGenerationCallMessage, isInputMessage, isReasoningMessage, streamSSE, useConversation };
473
- export type { ChunkOutputItemData, ChunkResponseData, ChunkResponseUsage, ChunkRunData, Conversation, ConversationMessage, ConverseConfig, EasyInputContentUnion, EasyMessage, FunctionCallApprovalResponseMessage, FunctionCallMessage, FunctionCallOutputContentUnion, FunctionCallOutputMessage, GetHeadersFn, ImageGenerationCallMessage, InputContentUnion, InputImageContent, InputMessage, InputTextContent, MessageUnion, OnChangeCallback, OutputContentUnion, OutputMessage, OutputMessageUnion, OutputTextContent, ReasoningMessage, ResponseChunk, SSEStreamOptions, SummaryTextContent, Thread, Usage, UseConversationOptions, UseConversationReturn };
592
+ export { ChunkProcessor, ChunkType, ContentType, MessageType, ProjectProvider, Role, isEasyMessage, isFunctionCallMessage, isFunctionCallOutputMessage, isImageGenerationCallMessage, isInputMessage, isReasoningMessage, streamSSE, useAgent, useConversation, useProjectContext };
593
+ export type { ChunkOutputItemData, ChunkResponseData, ChunkResponseUsage, ChunkRunData, Conversation, ConversationMessage, ConverseConfig, EasyInputContentUnion, EasyMessage, FunctionCallApprovalResponseMessage, FunctionCallMessage, FunctionCallOutputContentUnion, FunctionCallOutputMessage, GetHeadersFn, ImageGenerationCallMessage, InputContentUnion, InputImageContent, InputMessage, InputTextContent, MessageUnion, OnChangeCallback, OutputContentUnion, OutputMessage, OutputMessageUnion, OutputTextContent, ProjectContextValue, ProjectProviderProps, ReasoningMessage, ResponseChunk, SSEStreamOptions, SummaryTextContent, Thread, Usage, UseAgentOptions, UseAgentReturn, UseConversationOptions, UseConversationReturn };
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
+ import { useState, useRef, useEffect, useMemo, useCallback, createContext, useContext } from 'react';
2
+ import { jsx } from 'react/jsx-runtime';
1
3
  import axios from 'axios';
2
- import { useMemo, useState, useRef, useCallback, useEffect } from 'react';
3
4
 
4
5
  // Message Roles
5
6
  var Role;
@@ -398,6 +399,203 @@ async function streamSSE(url, requestOptions, callbacks, abortSignal) {
398
399
  }
399
400
  }
400
401
 
402
+ function useProject(options) {
403
+ const { projectName, baseUrl, getHeaders, autoLoad = true } = options;
404
+ // Project state
405
+ const [projectId, setProjectId] = useState('');
406
+ const [projectLoading, setProjectLoading] = useState(false);
407
+ // Use ref to store current projectId for interceptor access
408
+ const projectIdRef = useRef('');
409
+ // Update ref whenever projectId changes
410
+ useEffect(() => {
411
+ projectIdRef.current = projectId;
412
+ }, [projectId]);
413
+ // Create axios instance with request interceptor for custom headers and project_id
414
+ const axiosInstance = useMemo(() => {
415
+ const instance = axios.create({
416
+ baseURL: baseUrl,
417
+ headers: {
418
+ 'Content-Type': 'application/json',
419
+ },
420
+ });
421
+ // Add request interceptor to inject custom headers and project_id
422
+ instance.interceptors.request.use(async (config) => {
423
+ // Add custom headers if getHeaders function is provided
424
+ if (getHeaders) {
425
+ const customHeaders = await getHeaders();
426
+ Object.assign(config.headers, customHeaders);
427
+ }
428
+ // Automatically add project_id to query params if available
429
+ const currentProjectId = projectIdRef.current;
430
+ if (currentProjectId) {
431
+ if (config.params) {
432
+ config.params = {
433
+ ...config.params,
434
+ project_id: currentProjectId,
435
+ };
436
+ }
437
+ else {
438
+ config.params = { project_id: currentProjectId };
439
+ }
440
+ }
441
+ return config;
442
+ });
443
+ return instance;
444
+ }, [baseUrl, getHeaders]);
445
+ // ============================================
446
+ // API Helper Functions
447
+ // ============================================
448
+ /**
449
+ * Build query params (project_id is automatically added by axios interceptor)
450
+ */
451
+ const buildParams = useCallback((params) => {
452
+ return params || {};
453
+ }, []);
454
+ /**
455
+ * Get headers for streaming requests (combines default + custom headers)
456
+ */
457
+ const getRequestHeaders = useCallback(async () => {
458
+ const headers = {
459
+ 'Content-Type': 'application/json',
460
+ };
461
+ // Add custom headers if getHeaders function is provided
462
+ if (getHeaders) {
463
+ const customHeaders = await getHeaders();
464
+ Object.assign(headers, customHeaders);
465
+ }
466
+ return headers;
467
+ }, [getHeaders]);
468
+ // ============================================
469
+ // Project Management
470
+ // ============================================
471
+ /**
472
+ * Fetch the project ID using the project name
473
+ */
474
+ const fetchProjectId = useCallback(async () => {
475
+ if (!projectName) {
476
+ return;
477
+ }
478
+ setProjectLoading(true);
479
+ try {
480
+ const response = await axiosInstance.get('/project/id', {
481
+ params: { name: projectName },
482
+ });
483
+ const id = typeof response.data === 'string' ? response.data : response.data.data;
484
+ setProjectId(id || '');
485
+ }
486
+ catch (error) {
487
+ console.error('Failed to fetch project ID:', error);
488
+ throw error;
489
+ }
490
+ finally {
491
+ setProjectLoading(false);
492
+ }
493
+ }, [axiosInstance, projectName]);
494
+ // ============================================
495
+ // Effects for auto-loading
496
+ // ============================================
497
+ // Fetch project ID on mount
498
+ useEffect(() => {
499
+ if (autoLoad && projectName) {
500
+ fetchProjectId();
501
+ }
502
+ }, [autoLoad, projectName, fetchProjectId]);
503
+ return {
504
+ // Project state
505
+ projectId,
506
+ projectLoading,
507
+ // API client
508
+ axiosInstance,
509
+ buildParams,
510
+ getRequestHeaders,
511
+ baseUrl,
512
+ };
513
+ }
514
+
515
+ // Create the context with undefined as default to ensure it's used within provider
516
+ const ProjectContext = createContext(undefined);
517
+ /**
518
+ * ProjectProvider component that manages project state using React Context.
519
+ *
520
+ * This provider wraps the useProject hook and makes the project state available
521
+ * to all child components through context.
522
+ *
523
+ * @example
524
+ * ```tsx
525
+ * import { ProjectProvider, useProjectContext } from '@praveen001/uno-converse';
526
+ *
527
+ * function App() {
528
+ * return (
529
+ * <ProjectProvider
530
+ * baseUrl="https://api.example.com/api/agent-server"
531
+ * projectName="my-project"
532
+ * getHeaders={() => ({
533
+ * 'Authorization': `Bearer ${getToken()}`,
534
+ * })}
535
+ * >
536
+ * <YourApp />
537
+ * </ProjectProvider>
538
+ * );
539
+ * }
540
+ *
541
+ * function YourApp() {
542
+ * const { projectId, projectLoading } = useProjectContext();
543
+ *
544
+ * if (projectLoading) {
545
+ * return <div>Loading project...</div>;
546
+ * }
547
+ *
548
+ * return <div>Project ID: {projectId}</div>;
549
+ * }
550
+ * ```
551
+ */
552
+ const ProjectProvider = ({ baseUrl, projectName, getHeaders, autoLoad = true, children, }) => {
553
+ // Use the useProject hook to manage project state
554
+ const projectState = useProject({
555
+ baseUrl,
556
+ projectName,
557
+ getHeaders,
558
+ autoLoad,
559
+ });
560
+ // Memoize the context value to prevent unnecessary re-renders
561
+ const contextValue = useMemo(() => projectState, [
562
+ projectState.projectId,
563
+ projectState.projectLoading,
564
+ projectState.axiosInstance,
565
+ projectState.buildParams,
566
+ projectState.getRequestHeaders,
567
+ projectState.baseUrl,
568
+ ]);
569
+ return (jsx(ProjectContext.Provider, { value: contextValue, children: children }));
570
+ };
571
+ /**
572
+ * Hook to access the project context.
573
+ *
574
+ * Must be used within a ProjectProvider component.
575
+ *
576
+ * @throws {Error} If used outside of ProjectProvider
577
+ *
578
+ * @example
579
+ * ```tsx
580
+ * function MyComponent() {
581
+ * const { projectId, projectLoading } = useProjectContext();
582
+ *
583
+ * return (
584
+ * <div>
585
+ * {projectLoading ? 'Loading...' : `Project ID: ${projectId}`}
586
+ * </div>
587
+ * );
588
+ * }
589
+ * ```
590
+ */
591
+ const useProjectContext = () => {
592
+ const context = useContext(ProjectContext);
593
+ if (context === undefined) {
594
+ throw new Error('useProjectContext must be used within a ProjectProvider');
595
+ }
596
+ return context;
597
+ };
598
+
401
599
  /**
402
600
  * Simple ID generator for message IDs
403
601
  */
@@ -420,11 +618,6 @@ function generateId() {
420
618
  * startNewChat,
421
619
  * } = useConversation({
422
620
  * namespace: 'my-app',
423
- * projectName: 'my-project',
424
- * baseUrl: 'https://my-uno-server.com/api/agent-server',
425
- * getHeaders: () => ({
426
- * 'Authorization': `Bearer ${getToken()}`,
427
- * }),
428
621
  * });
429
622
  *
430
623
  * const handleSend = async (text: string) => {
@@ -449,28 +642,9 @@ function generateId() {
449
642
  * ```
450
643
  */
451
644
  function useConversation(options) {
452
- const { namespace, projectName, baseUrl, getHeaders, autoLoad = true } = options;
453
- // Create axios instance with request interceptor for custom headers
454
- const axiosInstance = useMemo(() => {
455
- const instance = axios.create({
456
- baseURL: baseUrl,
457
- headers: {
458
- 'Content-Type': 'application/json',
459
- },
460
- });
461
- // Add request interceptor to inject custom headers
462
- if (getHeaders) {
463
- instance.interceptors.request.use(async (config) => {
464
- const customHeaders = await getHeaders();
465
- Object.assign(config.headers, customHeaders);
466
- return config;
467
- });
468
- }
469
- return instance;
470
- }, [baseUrl, getHeaders]);
471
- // Project state
472
- const [projectId, setProjectId] = useState('');
473
- const [projectLoading, setProjectLoading] = useState(false);
645
+ const { namespace, autoLoad = true } = options;
646
+ // Get project context (axios instance, projectId, etc.)
647
+ const { axiosInstance, projectId, projectLoading, buildParams, getRequestHeaders, baseUrl, } = useProjectContext();
474
648
  // Conversation list state
475
649
  const [conversations, setConversations] = useState([]);
476
650
  const [conversationsLoading, setConversationsLoading] = useState(false);
@@ -493,59 +667,7 @@ function useConversation(options) {
493
667
  // ============================================
494
668
  // API Helper Functions
495
669
  // ============================================
496
- /**
497
- * Build query params with project_id if available
498
- */
499
- const buildParams = useCallback((params) => {
500
- const result = {};
501
- if (projectId) {
502
- result.project_id = projectId;
503
- }
504
- if (params) {
505
- Object.assign(result, params);
506
- }
507
- return result;
508
- }, [projectId]);
509
- /**
510
- * Get headers for streaming requests (combines default + custom headers)
511
- */
512
- const getRequestHeaders = useCallback(async () => {
513
- const headers = {
514
- 'Content-Type': 'application/json',
515
- };
516
- // Add custom headers if getHeaders function is provided
517
- if (getHeaders) {
518
- const customHeaders = await getHeaders();
519
- Object.assign(headers, customHeaders);
520
- }
521
- return headers;
522
- }, [getHeaders]);
523
- // ============================================
524
- // Project Management
525
- // ============================================
526
- /**
527
- * Fetch the project ID using the project name
528
- */
529
- const fetchProjectId = useCallback(async () => {
530
- if (!projectName) {
531
- return;
532
- }
533
- setProjectLoading(true);
534
- try {
535
- const response = await axiosInstance.get('/project/id', {
536
- params: { name: projectName },
537
- });
538
- const id = typeof response.data === 'string' ? response.data : response.data.data;
539
- setProjectId(id || '');
540
- }
541
- catch (error) {
542
- console.error('Failed to fetch project ID:', error);
543
- throw error;
544
- }
545
- finally {
546
- setProjectLoading(false);
547
- }
548
- }, [axiosInstance, projectName]);
670
+ // Note: buildParams and getRequestHeaders are now provided by ProjectProvider
549
671
  // ============================================
550
672
  // Conversation Management
551
673
  // ============================================
@@ -790,12 +912,6 @@ function useConversation(options) {
790
912
  // ============================================
791
913
  // Effects for auto-loading
792
914
  // ============================================
793
- // Fetch project ID on mount
794
- useEffect(() => {
795
- if (autoLoad && projectName) {
796
- fetchProjectId();
797
- }
798
- }, [autoLoad, projectName, fetchProjectId]);
799
915
  // Load conversations after project ID is fetched
800
916
  useEffect(() => {
801
917
  if (autoLoad && projectId) {
@@ -822,9 +938,6 @@ function useConversation(options) {
822
938
  ? [...messages, streamingMessage]
823
939
  : messages;
824
940
  return {
825
- // Project state
826
- projectId,
827
- projectLoading,
828
941
  // Conversation list state
829
942
  conversations,
830
943
  conversationsLoading,
@@ -856,5 +969,43 @@ function useConversation(options) {
856
969
  };
857
970
  }
858
971
 
859
- export { ChunkProcessor, ChunkType, ContentType, MessageType, Role, isEasyMessage, isFunctionCallMessage, isFunctionCallOutputMessage, isImageGenerationCallMessage, isInputMessage, isReasoningMessage, streamSSE, useConversation };
972
+ function useAgent(options) {
973
+ const { name } = options;
974
+ // Get project context (axios instance, projectId, etc.)
975
+ const { axiosInstance, projectId, buildParams, } = useProjectContext();
976
+ // Agents state
977
+ const [agent, setAgent] = useState(null);
978
+ const [agentLoading, setAgentLoading] = useState(false);
979
+ // ============================================
980
+ // Agent Management
981
+ // ============================================
982
+ /**
983
+ * Fetch the agent
984
+ */
985
+ const loadAgent = useCallback(async () => {
986
+ setAgentLoading(true);
987
+ try {
988
+ const response = await axiosInstance.get('/agent-configs/by-name', {
989
+ params: buildParams({ name }),
990
+ });
991
+ setAgent(response.data.data);
992
+ }
993
+ catch (error) {
994
+ console.error('Failed to load agent:', error);
995
+ throw error;
996
+ }
997
+ finally {
998
+ setAgentLoading(false);
999
+ }
1000
+ }, [axiosInstance, name]);
1001
+ // Fetch agent after project is fetched
1002
+ useEffect(() => {
1003
+ if (projectId) {
1004
+ loadAgent();
1005
+ }
1006
+ }, [projectId, loadAgent]);
1007
+ return { agent, agentLoading };
1008
+ }
1009
+
1010
+ export { ChunkProcessor, ChunkType, ContentType, MessageType, ProjectProvider, Role, isEasyMessage, isFunctionCallMessage, isFunctionCallOutputMessage, isImageGenerationCallMessage, isInputMessage, isReasoningMessage, streamSSE, useAgent, useConversation, useProjectContext };
860
1011
  //# sourceMappingURL=index.js.map