22
33import fs from 'fs' ;
44import path from 'path' ;
5- import { TrieveSDK , Topic , ChunkMetadata } from 'trieve-ts-sdk' ;
5+ import {
6+ TrieveSDK ,
7+ Topic ,
8+ ChunkMetadata ,
9+ UpdateDatasetReqPayload ,
10+ } from 'trieve-ts-sdk' ;
611import { program } from 'commander' ;
712import chalk from 'chalk' ;
813import inquirer from 'inquirer' ;
@@ -108,6 +113,10 @@ function getConfigOrEnv(key: string, envVar: string): string | undefined {
108113function ensureTrieveConfig ( ) {
109114 const apiKey = getConfigOrEnv ( 'TRIEVE_API_KEY' , 'TRIEVE_API_KEY' ) ;
110115 const datasetId = getConfigOrEnv ( 'TRIEVE_DATASET_ID' , 'TRIEVE_DATASET_ID' ) ;
116+ const organizationId = getConfigOrEnv (
117+ 'TRIEVE_ORGANIZATION_ID' ,
118+ 'TRIEVE_ORGANIZATION_ID' ,
119+ ) ;
111120
112121 if ( ! apiKey ) {
113122 console . error (
@@ -125,7 +134,15 @@ function ensureTrieveConfig() {
125134 console . log ( chalk . cyan ( 'trieve-cli configure' ) ) ;
126135 process . exit ( 1 ) ;
127136 }
128- return { apiKey, datasetId } ;
137+ if ( ! organizationId ) {
138+ console . error (
139+ chalk . red ( 'Error: TRIEVE_ORGANIZATION_ID is not set in env or config.' ) ,
140+ ) ;
141+ console . log ( chalk . yellow ( 'Run the following command to set it:' ) ) ;
142+ console . log ( chalk . cyan ( 'trieve-cli configure' ) ) ;
143+ process . exit ( 1 ) ;
144+ }
145+ return { apiKey, datasetId, organizationId } ;
129146}
130147
131148const uploadFile = async (
@@ -217,10 +234,11 @@ async function checkFileUploadStatus(
217234 groupTrackingId : string ,
218235) : Promise < boolean > {
219236 try {
220- const { apiKey, datasetId } = ensureTrieveConfig ( ) ;
237+ const { apiKey, datasetId, organizationId } = ensureTrieveConfig ( ) ;
221238 const trieveClient : TrieveSDK = new TrieveSDK ( {
222239 apiKey,
223240 datasetId,
241+ organizationId,
224242 } ) ;
225243
226244 const response = await trieveClient . getChunksGroupByTrackingId ( {
@@ -388,7 +406,6 @@ async function askQuestion(question: string): Promise<void> {
388406 'default-user-' + Math . random ( ) . toString ( 36 ) . substring ( 2 , 15 ) ;
389407
390408 const topicData = await trieveClient . createTopic ( {
391- first_user_message : question ,
392409 name : topicName ,
393410 owner_id : ownerId ,
394411 } ) ;
@@ -411,7 +428,7 @@ async function askQuestion(question: string): Promise<void> {
411428 let fullResponse = '' ;
412429 let parsedChunks : ChunkMetadata [ ] = [ ] ;
413430 let isCollapsed = true ;
414- let isChunkSection = true ; // Initially assume we're receiving chunks
431+ let isChunkSection = false ; // Initially assume we're receiving chunks
415432 let actualAnswer = '' ;
416433
417434 // Set up keyboard interaction for collapsible chunks
@@ -425,12 +442,22 @@ async function askQuestion(question: string): Promise<void> {
425442 key : { name : string ; ctrl ?: boolean ; sequence ?: string } ,
426443 ) => {
427444 // Handle both key.name and raw sequence for better compatibility
428- if ( key . name === 'j' || key . sequence === 'j' ) {
445+ if ( str === 'j' || key . name === 'j' || key . sequence === 'j' ) {
429446 isCollapsed = ! isCollapsed ;
430447 // Clear console and redisplay with updated collapse state
431448 console . clear ( ) ;
432449
433450 if ( parsedChunks . length > 0 ) {
451+ // Show the answer first (if available)
452+ if ( actualAnswer ) {
453+ console . log ( actualAnswer ) ;
454+ }
455+
456+ // Add a separator between answer and chunks
457+ console . log (
458+ chalk . dim ( '─' . repeat ( 40 ) + ' References ' + '─' . repeat ( 40 ) ) ,
459+ ) ;
460+
434461 if ( isCollapsed ) {
435462 console . log (
436463 chalk . cyan (
@@ -440,12 +467,7 @@ async function askQuestion(question: string): Promise<void> {
440467 } else {
441468 console . log ( formatChunksCollapsible ( parsedChunks ) ) ;
442469 }
443-
444- // Add a separator between chunks and answer
445- console . log ( chalk . dim ( '─' . repeat ( 40 ) + ' Answer ' + '─' . repeat ( 40 ) ) ) ;
446- }
447-
448- if ( actualAnswer ) {
470+ } else if ( actualAnswer ) {
449471 console . log ( actualAnswer ) ;
450472 }
451473 } else if ( key . name === 'c ' && key . ctrl ) {
@@ -475,21 +497,8 @@ async function askQuestion(question: string): Promise<void> {
475497 if ( chunksJson ) {
476498 parsedChunks = JSON . parse ( chunksJson ) ;
477499
478- // Only show a collapsed summary initially
479- if ( isCollapsed ) {
480- console . log (
481- chalk . cyan (
482- `📚 Found ${ parsedChunks . length } reference chunks (press 'j' to expand)` ,
483- ) ,
484- ) ;
485- } else {
486- console . log ( formatChunksCollapsible ( parsedChunks ) ) ;
487- }
488-
489- // Add a separator between chunks and answer
490- console . log (
491- chalk . dim ( '─' . repeat ( 40 ) + ' Answer ' + '─' . repeat ( 40 ) ) ,
492- ) ;
500+ // Don't display chunks immediately, we'll show them after the answer
501+ // Just save them for later display
493502 }
494503 } catch ( e ) {
495504 console . error ( chalk . red ( '❌ Error parsing chunks:' ) , e ) ;
@@ -519,11 +528,18 @@ async function askQuestion(question: string): Promise<void> {
519528 console . log ( chalk . green ( '✅ Response complete' ) ) ;
520529
521530 if ( parsedChunks . length > 0 ) {
531+ // Add a separator between answer and chunks at the end
532+ console. log ( chalk . dim ( '─' . repeat ( 40 ) + ' References ' + '─' . repeat ( 40 ) ) ) ;
522533 console . log (
523534 chalk . blue (
524535 `📚 ${ parsedChunks . length } reference chunks used (press 'j' to ${ isCollapsed ? 'expand' : 'collapse' } )` ,
525536 ) ,
526537 ) ;
538+
539+ // If not collapsed, show the chunks again
540+ if ( ! isCollapsed ) {
541+ console . log ( formatChunksCollapsible ( parsedChunks ) ) ;
542+ }
527543 }
528544
529545 console . log (
@@ -601,6 +617,66 @@ program
601617 }
602618 } ) ;
603619
620+ // -t "Always use the search tool here when the user asks a question about some information you're supposed to have or some files."
621+ // -q "Write this as a maximum 5 word query with the keywords you think would be useful"
622+
623+ program
624+ . command ( 'update-tool-config' )
625+ . description ( 'Update the tool configuration for a dataset' )
626+ . requiredOption (
627+ '-t, --tool-description <toolDescription>' ,
628+ 'Description that tells the LLM when it should use the search tool to retrieve information from your dataset' ,
629+ "Always use the search tool here when the user asks a question about some information you're supposed to have or some files." ,
630+ )
631+ . requiredOption (
632+ '-q, --query-description <queryDescription>' ,
633+ 'Description of how the LLM should write its search queries to retrieve relevant information from your dataset' ,
634+ 'Write this as a maximum 5 word query with the keywords you think would be useful' ,
635+ )
636+ . action ( async ( options ) => {
637+ try {
638+ console . log ( chalk . blue ( '🔧 Updating tool configuration...' ) ) ;
639+
640+ const { apiKey, datasetId, organizationId } = ensureTrieveConfig ( ) ;
641+
642+ // Initialize SDK with apiKey and datasetId from config
643+ const trieveClient : TrieveSDK = new TrieveSDK ( {
644+ apiKey,
645+ datasetId,
646+ organizationId,
647+ } ) ;
648+
649+ const updatePayload : UpdateDatasetReqPayload = {
650+ dataset_id : datasetId ,
651+ server_configuration : {
652+ TOOL_CONFIGURATION : {
653+ query_tool_options : {
654+ tool_description : options . toolDescription ,
655+ query_parameter_description : options . queryDescription ,
656+ price_filter_description :
657+ 'The price or page range filter to use for the search' ,
658+
659+ max_price_option_description :
660+ 'The maximum price or page to filter by' ,
661+
662+ min_price_option_description :
663+ 'The minimum price or page to filter by' ,
664+ } ,
665+ } ,
666+ } ,
667+ } ;
668+
669+ await trieveClient . updateDataset ( updatePayload ) ;
670+
671+ console . log ( chalk . green ( '✅ Tool configuration updated successfully!' ) ) ;
672+ } catch ( error ) {
673+ console . error (
674+ chalk . red ( '❌ Failed to update tool configuration:' ) ,
675+ error instanceof Error ? error . message : error ,
676+ ) ;
677+ }
678+ } ) ;
679+
604680program
605681 . command ( 'configure' )
606682 . description ( 'Set up or update your Trieve CLI configuration' )
@@ -618,6 +694,12 @@ program
618694 message : 'Enter your TRIEVE_DATASET_ID:' ,
619695 default : ( config . get ( 'TRIEVE_DATASET_ID' ) as string ) || '' ,
620696 } ,
697+ {
698+ type : 'input' ,
699+ name : 'TRIEVE_ORGANIZATION_ID' ,
700+ message : 'Enter your TRIEVE_ORGANIZATION_ID:' ,
701+ default : ( config . get ( 'TRIEVE_ORGANIZATION_ID' ) as string ) || '' ,
702+ } ,
621703 {
622704 type : 'input' ,
623705 name : 'userId' ,
@@ -627,6 +709,7 @@ program
627709 ] ) ;
628710 config . set ( 'TRIEVE_API_KEY' , answers . TRIEVE_API_KEY ) ;
629711 config . set ( 'TRIEVE_DATASET_ID' , answers . TRIEVE_DATASET_ID ) ;
712+ config . set ( 'TRIEVE_ORGANIZATION_ID' , answers . TRIEVE_ORGANIZATION_ID ) ;
630713 config . set ( 'userId' , answers . userId ) ;
631714 console . log ( chalk . green ( '✅ Configuration saved!' ) ) ;
632715 } ) ;
@@ -685,6 +768,7 @@ ${chalk.yellow('Examples:')}
685768 $ ${ chalk . green ( 'trieve-cli check-upload-status --tracking-id <tracking-id>' ) }
686769 $ ${ chalk . green ( 'trieve-cli ask "What is the capital of France?"' ) }
687770 $ ${ chalk . green ( 'trieve-cli ask' ) }
771+ $ ${ chalk . green ( 'trieve-cli update-tool-config -t "Use this tool to search for information about our products and services" -q "Write specific search queries to find relevant information from our knowledge base"' ) }
688772` ,
689773) ;
690774
0 commit comments