-
Notifications
You must be signed in to change notification settings - Fork 184
feat: implement csv upload #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 15 commits
a9d2177
ff8bed6
2e43ba1
778bdfa
2e47af8
5d19019
cc45225
667c122
f3c1e54
14c0b2e
c24e60a
beaf4b4
2eb2803
bafb1d7
04cc7ce
5068e28
d473867
b3f3ce4
ce2de2d
b0e25b3
3d3d94c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"create-llama": patch | ||
--- | ||
|
||
Add CSV upload |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,35 +6,74 @@ import { | |
type AIStreamCallbacksAndOptions, | ||
} from "ai"; | ||
import { | ||
MessageContent, | ||
Metadata, | ||
NodeWithScore, | ||
Response, | ||
ToolCallLLMMessageOptions, | ||
} from "llamaindex"; | ||
|
||
import { AgentStreamChatResponse } from "llamaindex/agent/base"; | ||
import { appendImageData, appendSourceData } from "./stream-helper"; | ||
import { | ||
UploadedCsv, | ||
appendCsvData, | ||
appendImageData, | ||
appendSourceData, | ||
} from "./stream-helper"; | ||
|
||
type LlamaIndexResponse = | ||
| AgentStreamChatResponse<ToolCallLLMMessageOptions> | ||
| Response; | ||
|
||
type ParserOptions = { | ||
image_url?: string; | ||
export type DataParserOptions = { | ||
imageUrl?: string; | ||
uploadedCsv?: UploadedCsv; | ||
}; | ||
|
||
export const convertMessageContent = ( | ||
textMessage: string, | ||
additionalData?: DataParserOptions, | ||
): MessageContent => { | ||
if (additionalData?.imageUrl) { | ||
return [ | ||
{ | ||
type: "text", | ||
text: textMessage, | ||
}, | ||
{ | ||
type: "image_url", | ||
image_url: { | ||
url: additionalData?.imageUrl, | ||
}, | ||
}, | ||
]; | ||
} | ||
|
||
if (additionalData?.uploadedCsv) { | ||
const csvContent = | ||
"Use the following CSV data:\n" + | ||
"```csv\n" + | ||
additionalData.uploadedCsv.content + | ||
"\n```"; | ||
Comment on lines
+55
to
+58
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use template literals for better performance and readability in CSV content handling. - "Use the following CSV data:\n" +
- "```csv\n" +
- additionalData.uploadedCsv.content +
- "\n```";
+ `Use the following CSV data:\n\`\`\`csv\n${additionalData.uploadedCsv.content}\n\`\`\`` |
||
return `${csvContent}\n\n${textMessage}`; | ||
} | ||
|
||
return textMessage; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The updates to - const csvContent =
- "Use the following CSV data:\n" +
- "```csv\n" +
- additionalData.uploadedCsv.content +
- "\n```";
+ const csvContent = `Use the following CSV data:\n\`\`\`csv\n${additionalData.uploadedCsv.content}\n\`\`\``; |
||
}; | ||
|
||
function createParser( | ||
res: AsyncIterable<LlamaIndexResponse>, | ||
data: StreamData, | ||
opts?: ParserOptions, | ||
opts?: DataParserOptions, | ||
) { | ||
const it = res[Symbol.asyncIterator](); | ||
const trimStartOfStream = trimStartOfStreamHelper(); | ||
|
||
let sourceNodes: NodeWithScore<Metadata>[] | undefined; | ||
return new ReadableStream<string>({ | ||
start() { | ||
appendImageData(data, opts?.image_url); | ||
appendImageData(data, opts?.imageUrl); | ||
appendCsvData(data, opts?.uploadedCsv); | ||
}, | ||
async pull(controller): Promise<void> { | ||
const { value, done } = await it.next(); | ||
|
@@ -72,7 +111,7 @@ export function LlamaIndexStream( | |
data: StreamData, | ||
opts?: { | ||
callbacks?: AIStreamCallbacksAndOptions; | ||
parserOptions?: ParserOptions; | ||
parserOptions?: DataParserOptions; | ||
}, | ||
): ReadableStream<Uint8Array> { | ||
return createParser(response, data, opts?.parserOptions) | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -17,6 +17,20 @@ export function appendImageData(data: StreamData, imageUrl?: string) { | |||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
export type UploadedCsv = { | ||||||||||||||||||||||||||||||||||||
content: string; | ||||||||||||||||||||||||||||||||||||
filename: string; | ||||||||||||||||||||||||||||||||||||
filesize: number; | ||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
export function appendCsvData(data: StreamData, uploadedCsv?: UploadedCsv) { | ||||||||||||||||||||||||||||||||||||
if (!uploadedCsv) return; | ||||||||||||||||||||||||||||||||||||
data.appendMessageAnnotation({ | ||||||||||||||||||||||||||||||||||||
type: "csv", | ||||||||||||||||||||||||||||||||||||
data: uploadedCsv, | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Function to append CSV data to a stream. Ensure it handles empty or null + if (!uploadedCsv || !uploadedCsv.content.trim()) return; Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
export function appendSourceData( | ||||||||||||||||||||||||||||||||||||
data: StreamData, | ||||||||||||||||||||||||||||||||||||
sourceNodes?: NodeWithScore<Metadata>[], | ||||||||||||||||||||||||||||||||||||
|
@@ -65,6 +79,15 @@ export function appendToolData( | |||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
export function createStreamTimeout(stream: StreamData) { | ||||||||||||||||||||||||||||||||||||
const timeout = Number(process.env.STREAM_TIMEOUT ?? 1000 * 60 * 5); // default to 5 minutes | ||||||||||||||||||||||||||||||||||||
const t = setTimeout(() => { | ||||||||||||||||||||||||||||||||||||
appendEventData(stream, `Stream timed out after ${timeout / 1000} seconds`); | ||||||||||||||||||||||||||||||||||||
stream.close(); | ||||||||||||||||||||||||||||||||||||
marcusschiesser marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||
}, timeout); | ||||||||||||||||||||||||||||||||||||
return t; | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
Comment on lines
+85
to
+92
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Define the default timeout value as a constant for better readability and maintainability. + const DEFAULT_TIMEOUT = 1000 * 60 * 5; // 5 minutes
const timeout = Number(process.env.STREAM_TIMEOUT ?? DEFAULT_TIMEOUT); Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
export function createCallbackManager(stream: StreamData) { | ||||||||||||||||||||||||||||||||||||
const callbackManager = new CallbackManager(); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,35 +6,74 @@ import { | |
type AIStreamCallbacksAndOptions, | ||
} from "ai"; | ||
import { | ||
MessageContent, | ||
Metadata, | ||
NodeWithScore, | ||
Response, | ||
ToolCallLLMMessageOptions, | ||
} from "llamaindex"; | ||
|
||
import { AgentStreamChatResponse } from "llamaindex/agent/base"; | ||
import { appendImageData, appendSourceData } from "./stream-helper"; | ||
import { | ||
UploadedCsv, | ||
appendCsvData, | ||
appendImageData, | ||
appendSourceData, | ||
} from "./stream-helper"; | ||
|
||
type LlamaIndexResponse = | ||
| AgentStreamChatResponse<ToolCallLLMMessageOptions> | ||
| Response; | ||
|
||
type ParserOptions = { | ||
image_url?: string; | ||
export type DataParserOptions = { | ||
imageUrl?: string; | ||
uploadedCsv?: UploadedCsv; | ||
}; | ||
|
||
export const convertMessageContent = ( | ||
textMessage: string, | ||
additionalData?: DataParserOptions, | ||
): MessageContent => { | ||
if (additionalData?.imageUrl) { | ||
return [ | ||
{ | ||
type: "text", | ||
text: textMessage, | ||
}, | ||
{ | ||
type: "image_url", | ||
image_url: { | ||
url: additionalData?.imageUrl, | ||
}, | ||
}, | ||
]; | ||
} | ||
|
||
if (additionalData?.uploadedCsv) { | ||
const csvContent = | ||
"Use the following CSV data:\n" + | ||
"```csv\n" + | ||
additionalData.uploadedCsv.content + | ||
"\n```"; | ||
Comment on lines
+55
to
+58
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use template literals for better performance and readability in CSV content handling. - "Use the following CSV data:\n" +
- "```csv\n" +
- additionalData.uploadedCsv.content +
- "\n```";
+ `Use the following CSV data:\n\`\`\`csv\n${additionalData.uploadedCsv.content}\n\`\`\`` |
||
return `${csvContent}\n\n${textMessage}`; | ||
} | ||
|
||
return textMessage; | ||
leehuwuj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
|
||
function createParser( | ||
res: AsyncIterable<LlamaIndexResponse>, | ||
data: StreamData, | ||
opts?: ParserOptions, | ||
opts?: DataParserOptions, | ||
) { | ||
const it = res[Symbol.asyncIterator](); | ||
const trimStartOfStream = trimStartOfStreamHelper(); | ||
|
||
let sourceNodes: NodeWithScore<Metadata>[] | undefined; | ||
return new ReadableStream<string>({ | ||
start() { | ||
appendImageData(data, opts?.image_url); | ||
appendImageData(data, opts?.imageUrl); | ||
appendCsvData(data, opts?.uploadedCsv); | ||
}, | ||
async pull(controller): Promise<void> { | ||
const { value, done } = await it.next(); | ||
|
@@ -72,7 +111,7 @@ export function LlamaIndexStream( | |
data: StreamData, | ||
opts?: { | ||
callbacks?: AIStreamCallbacksAndOptions; | ||
parserOptions?: ParserOptions; | ||
parserOptions?: DataParserOptions; | ||
}, | ||
): ReadableStream<Uint8Array> { | ||
return createParser(response, data, opts?.parserOptions) | ||
|
Uh oh!
There was an error while loading. Please reload this page.