Skip to content

Commit 393a926

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/upload-file-sandbox
2 parents 3e82be7 + 98a82b0 commit 393a926

File tree

38 files changed

+302
-167
lines changed

38 files changed

+302
-167
lines changed

.changeset/chilled-zebras-taste.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/great-students-appear.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"create-llama": patch
3+
---
4+
5+
docs: chroma env variables

.changeset/hungry-chairs-tie.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.github/workflows/e2e.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
python-version: ["3.11"]
2020
os: [macos-latest, windows-latest, ubuntu-22.04]
2121
frameworks: ["fastapi"]
22-
datasources: ["--no-files", "--example-file"]
22+
datasources: ["--no-files", "--example-file", "--llamacloud"]
2323
defaults:
2424
run:
2525
shell: bash

.github/workflows/release.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ jobs:
1717

1818
- uses: pnpm/action-setup@v3
1919

20+
- name: Install uv
21+
uses: astral-sh/setup-uv@v3
22+
2023
- name: Setup Node.js
2124
uses: actions/setup-node@v4
2225
with:

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,36 @@
11
# create-llama
22

3+
## 0.2.19
4+
5+
### Patch Changes
6+
7+
- 3d41488: feat: use selected llamacloud for multiagent
8+
9+
## 0.2.18
10+
11+
### Patch Changes
12+
13+
- 75e1f61: Fix cannot query public document from llamacloud
14+
- 88220f1: fix workflow doesn't stop when user presses stop generation button
15+
- 75e1f61: Fix typescript templates cannot upload file to llamacloud
16+
- 88220f1: Bump [email protected]
17+
18+
## 0.2.17
19+
20+
### Patch Changes
21+
22+
- cd3fcd0: bump: use LlamaIndexTS 0.6.18
23+
- 6335de1: Fix using LlamaCloud selector does not use the configured values in the environment (Python)
24+
25+
## 0.2.16
26+
27+
### Patch Changes
28+
29+
- 0e78ba4: Fix: programmatically ensure index for LlamaCloud
30+
- 0e78ba4: Fix .env not loaded on poetry run generate
31+
- 7f4ac22: Don't need to run generate script for LlamaCloud
32+
- 5263bde: Use selected LlamaCloud index in multi-agent template
33+
334
## 0.2.15
435

536
### Patch Changes

e2e/shared/streaming_template.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ const userMessage =
2727
dataSource !== "--no-files" ? "Physical standard for letters" : "Hello";
2828

2929
test.describe(`Test streaming template ${templateFramework} ${dataSource} ${templateUI} ${appType} ${templatePostInstallAction}`, async () => {
30+
const isNode18 = process.version.startsWith("v18");
31+
const isLlamaCloud = dataSource === "--llamacloud";
32+
// llamacloud is using File API which is not supported on node 18
33+
if (isNode18 && isLlamaCloud) {
34+
test.skip(true, "Skipping tests for Node 18 and LlamaCloud data source");
35+
}
36+
3037
let port: number;
3138
let externalPort: number;
3239
let cwd: string;

helpers/env-variables.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const getVectorDBEnvs = (
6565
{
6666
name: "PG_CONNECTION_STRING",
6767
description:
68-
"For generating a connection URI, see https://docs.timescale.com/use-timescale/latest/services/create-a-service\nThe PostgreSQL connection string.",
68+
"For generating a connection URI, see https://supabase.com/vector\nThe PostgreSQL connection string.",
6969
},
7070
];
7171

@@ -182,11 +182,11 @@ const getVectorDBEnvs = (
182182
},
183183
{
184184
name: "CHROMA_HOST",
185-
description: "The API endpoint for your Chroma database",
185+
description: "The hostname for your Chroma database. Eg: localhost",
186186
},
187187
{
188188
name: "CHROMA_PORT",
189-
description: "The port for your Chroma database",
189+
description: "The port for your Chroma database. Eg: 8000",
190190
},
191191
];
192192
// TS Version doesn't support config local storage path

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "create-llama",
3-
"version": "0.2.15",
3+
"version": "0.2.19",
44
"description": "Create LlamaIndex-powered apps with one command",
55
"keywords": [
66
"rag",

templates/components/engines/typescript/agent/chat.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
2+
BaseChatEngine,
23
BaseToolWithCall,
3-
ChatEngine,
44
OpenAIAgent,
55
QueryEngineTool,
66
} from "llamaindex";
@@ -45,7 +45,7 @@ export async function createChatEngine(documentIds?: string[], params?: any) {
4545
const agent = new OpenAIAgent({
4646
tools,
4747
systemPrompt: process.env.SYSTEM_PROMPT,
48-
}) as unknown as ChatEngine;
48+
}) as unknown as BaseChatEngine;
4949

5050
return agent;
5151
}

templates/components/llamaindex/typescript/documents/upload.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,26 @@ export async function uploadDocument(
1616
// trigger LlamaCloudIndex API to upload the file and run the pipeline
1717
const projectId = await index.getProjectId();
1818
const pipelineId = await index.getPipelineId();
19-
return [
20-
await LLamaCloudFileService.addFileToPipeline(
21-
projectId,
22-
pipelineId,
23-
new File([fileBuffer], filename, { type: mimeType }),
24-
{ private: "true" },
25-
),
26-
];
19+
try {
20+
return [
21+
await LLamaCloudFileService.addFileToPipeline(
22+
projectId,
23+
pipelineId,
24+
new File([fileBuffer], filename, { type: mimeType }),
25+
{ private: "true" },
26+
),
27+
];
28+
} catch (error) {
29+
if (
30+
error instanceof ReferenceError &&
31+
error.message.includes("File is not defined")
32+
) {
33+
throw new Error(
34+
"File class is not supported in the current Node.js version. Please use Node.js 20 or higher.",
35+
);
36+
}
37+
throw error;
38+
}
2739
}
2840

2941
// run the pipeline for other vector store indexes

templates/components/llamaindex/typescript/streaming/annotations.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,26 @@ function getValidAnnotation(annotation: JSONValue): Annotation {
172172
}
173173
return { type: annotation.type, data: annotation.data };
174174
}
175+
176+
// validate and get all annotations of a specific type or role from the frontend messages
177+
export function getAnnotations<
178+
T extends Annotation["data"] = Annotation["data"],
179+
>(
180+
messages: Message[],
181+
options?: {
182+
role?: Message["role"]; // message role
183+
type?: Annotation["type"]; // annotation type
184+
},
185+
): {
186+
type: string;
187+
data: T;
188+
}[] {
189+
const messagesByRole = options?.role
190+
? messages.filter((msg) => msg.role === options?.role)
191+
: messages;
192+
const annotations = getAllAnnotations(messagesByRole);
193+
const annotationsByType = options?.type
194+
? annotations.filter((a) => a.type === options.type)
195+
: annotations;
196+
return annotationsByType as { type: string; data: T }[];
197+
}

templates/components/llamaindex/typescript/streaming/events.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export function createCallbackManager(stream: StreamData) {
7575
callbackManager.on("retrieve-end", (data) => {
7676
const { nodes, query } = data.detail;
7777
appendSourceData(stream, nodes);
78-
appendEventData(stream, `Retrieving context for query: '${query}'`);
78+
appendEventData(stream, `Retrieving context for query: '${query.query}'`);
7979
appendEventData(
8080
stream,
8181
`Retrieved ${nodes.length} sources to use as context for the query`,

templates/components/multiagent/python/app/api/routers/chat.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import logging
22

3-
from app.api.routers.events import EventCallbackHandler
43
from app.api.routers.models import (
54
ChatData,
65
)
@@ -23,13 +22,12 @@ async def chat(
2322
last_message_content = data.get_last_message_content()
2423
messages = data.get_history_messages(include_agent_messages=True)
2524

26-
event_handler = EventCallbackHandler()
2725
# The chat API supports passing private document filters and chat params
2826
# but agent workflow does not support them yet
2927
# ignore chat params and use all documents for now
3028
# TODO: generate filters based on doc_ids
31-
# TODO: use chat params
32-
engine = get_chat_engine(chat_history=messages)
29+
params = data.data or {}
30+
engine = get_chat_engine(chat_history=messages, params=params)
3331

3432
event_handler = engine.run(input=last_message_content, streaming=True)
3533
return VercelStreamResponse(

templates/components/multiagent/python/app/api/routers/vercel_response.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import asyncio
12
import json
23
import logging
3-
from abc import ABC
44
from typing import AsyncGenerator, List
55

66
from aiostream import stream
@@ -13,7 +13,7 @@
1313
logger = logging.getLogger("uvicorn")
1414

1515

16-
class VercelStreamResponse(StreamingResponse, ABC):
16+
class VercelStreamResponse(StreamingResponse):
1717
"""
1818
Base class to convert the response from the chat engine to the streaming format expected by Vercel
1919
"""
@@ -23,26 +23,34 @@ class VercelStreamResponse(StreamingResponse, ABC):
2323

2424
def __init__(self, request: Request, chat_data: ChatData, *args, **kwargs):
2525
self.request = request
26-
27-
stream = self._create_stream(request, chat_data, *args, **kwargs)
28-
content = self.content_generator(stream)
29-
26+
self.chat_data = chat_data
27+
content = self.content_generator(*args, **kwargs)
3028
super().__init__(content=content)
3129

32-
async def content_generator(self, stream):
30+
async def content_generator(self, event_handler, events):
31+
logger.info("Starting content_generator")
32+
stream = self._create_stream(
33+
self.request, self.chat_data, event_handler, events
34+
)
3335
is_stream_started = False
34-
35-
async with stream.stream() as streamer:
36-
async for output in streamer:
37-
if not is_stream_started:
38-
is_stream_started = True
39-
# Stream a blank message to start the stream
40-
yield self.convert_text("")
41-
42-
yield output
43-
44-
if await self.request.is_disconnected():
45-
break
36+
try:
37+
async with stream.stream() as streamer:
38+
async for output in streamer:
39+
if not is_stream_started:
40+
is_stream_started = True
41+
# Stream a blank message to start the stream
42+
yield self.convert_text("")
43+
44+
yield output
45+
except asyncio.CancelledError:
46+
logger.info("Stopping workflow")
47+
await event_handler.cancel_run()
48+
except Exception as e:
49+
logger.error(
50+
f"Unexpected error in content_generator: {str(e)}", exc_info=True
51+
)
52+
finally:
53+
logger.info("The stream has been stopped!")
4654

4755
def _create_stream(
4856
self,

templates/components/multiagent/python/app/engine/engine.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ def get_chat_engine(
1818
agent_type = os.getenv("EXAMPLE_TYPE", "").lower()
1919
match agent_type:
2020
case "choreography":
21-
agent = create_choreography(chat_history)
21+
agent = create_choreography(chat_history, **kwargs)
2222
case "orchestrator":
23-
agent = create_orchestrator(chat_history)
23+
agent = create_orchestrator(chat_history, **kwargs)
2424
case _:
25-
agent = create_workflow(chat_history)
25+
agent = create_workflow(chat_history, **kwargs)
2626

2727
logger.info(f"Using agent pattern: {agent_type}")
2828

templates/components/multiagent/python/app/examples/choreography.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
from llama_index.core.chat_engine.types import ChatMessage
99

1010

11-
def create_choreography(chat_history: Optional[List[ChatMessage]] = None):
12-
researcher = create_researcher(chat_history)
11+
def create_choreography(chat_history: Optional[List[ChatMessage]] = None, **kwargs):
12+
researcher = create_researcher(chat_history, **kwargs)
1313
publisher = create_publisher(chat_history)
1414
reviewer = FunctionCallingAgent(
1515
name="reviewer",
@@ -21,12 +21,14 @@ def create_choreography(chat_history: Optional[List[ChatMessage]] = None):
2121
name="writer",
2222
agents=[researcher, reviewer, publisher],
2323
description="expert in writing blog posts, needs researched information and images to write a blog post",
24-
system_prompt=dedent("""
24+
system_prompt=dedent(
25+
"""
2526
You are an expert in writing blog posts. You are given a task to write a blog post. Before starting to write the post, consult the researcher agent to get the information you need. Don't make up any information yourself.
2627
After creating a draft for the post, send it to the reviewer agent to receive feedback and make sure to incorporate the feedback from the reviewer.
2728
You can consult the reviewer and researcher a maximum of two times. Your output should contain only the blog post.
2829
Finally, always request the publisher to create a document (PDF, HTML) and publish the blog post.
29-
"""),
30+
"""
31+
),
3032
# TODO: add chat_history support to AgentCallingAgent
3133
# chat_history=chat_history,
3234
)

templates/components/multiagent/python/app/examples/orchestrator.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,32 @@
88
from llama_index.core.chat_engine.types import ChatMessage
99

1010

11-
def create_orchestrator(chat_history: Optional[List[ChatMessage]] = None):
12-
researcher = create_researcher(chat_history)
11+
def create_orchestrator(chat_history: Optional[List[ChatMessage]] = None, **kwargs):
12+
researcher = create_researcher(chat_history, **kwargs)
1313
writer = FunctionCallingAgent(
1414
name="writer",
1515
description="expert in writing blog posts, need information and images to write a post",
16-
system_prompt=dedent("""
16+
system_prompt=dedent(
17+
"""
1718
You are an expert in writing blog posts.
1819
You are given a task to write a blog post. Do not make up any information yourself.
1920
If you don't have the necessary information to write a blog post, reply "I need information about the topic to write the blog post".
2021
If you need to use images, reply "I need images about the topic to write the blog post". Do not use any dummy images made up by you.
2122
If you have all the information needed, write the blog post.
22-
"""),
23+
"""
24+
),
2325
chat_history=chat_history,
2426
)
2527
reviewer = FunctionCallingAgent(
2628
name="reviewer",
2729
description="expert in reviewing blog posts, needs a written blog post to review",
28-
system_prompt=dedent("""
30+
system_prompt=dedent(
31+
"""
2932
You are an expert in reviewing blog posts. You are given a task to review a blog post. Review the post and fix any issues found yourself. You must output a final blog post.
3033
A post must include at least one valid image. If not, reply "I need images about the topic to write the blog post". An image URL starting with "example" or "your website" is not valid.
3134
Especially check for logical inconsistencies and proofread the post for grammar and spelling errors.
32-
"""),
35+
"""
36+
),
3337
chat_history=chat_history,
3438
)
3539
publisher = create_publisher(chat_history)

0 commit comments

Comments
 (0)