forked from langchain-ai/open-canvas
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a48a906
commit 6b021b1
Showing
30 changed files
with
841 additions
and
492 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { | ||
OpenCanvasGraphAnnotation, | ||
OpenCanvasGraphReturnType, | ||
} from "../../state"; | ||
import { LangGraphRunnableConfig } from "@langchain/langgraph"; | ||
import { | ||
getFormattedReflections, | ||
getModelFromConfig, | ||
getModelNameAndProviderFromConfig, | ||
optionallyGetSystemPromptFromConfig, | ||
} from "@/agent/utils"; | ||
import { ARTIFACT_TOOL_SCHEMA } from "./schemas"; | ||
import { ArtifactV3 } from "@/types"; | ||
import { createArtifactContent, formatNewArtifactPrompt } from "./utils"; | ||
|
||
/** | ||
* Generate a new artifact based on the user's query. | ||
*/ | ||
export const generateArtifact = async ( | ||
state: typeof OpenCanvasGraphAnnotation.State, | ||
config: LangGraphRunnableConfig | ||
): Promise<OpenCanvasGraphReturnType> => { | ||
const { modelName } = getModelNameAndProviderFromConfig(config); | ||
const smallModel = await getModelFromConfig(config, 0.5); | ||
|
||
const modelWithArtifactTool = smallModel.bindTools( | ||
[ | ||
{ | ||
name: "generate_artifact", | ||
schema: ARTIFACT_TOOL_SCHEMA, | ||
}, | ||
], | ||
{ tool_choice: "generate_artifact" } | ||
); | ||
|
||
const memoriesAsString = await getFormattedReflections(config); | ||
const formattedNewArtifactPrompt = formatNewArtifactPrompt( | ||
memoriesAsString, | ||
modelName | ||
); | ||
|
||
const userSystemPrompt = optionallyGetSystemPromptFromConfig(config); | ||
const fullSystemPrompt = userSystemPrompt | ||
? `${userSystemPrompt}\n${formattedNewArtifactPrompt}` | ||
: formattedNewArtifactPrompt; | ||
|
||
const response = await modelWithArtifactTool.invoke( | ||
[{ role: "system", content: fullSystemPrompt }, ...state.messages], | ||
{ runName: "generate_artifact" } | ||
); | ||
|
||
const newArtifactContent = createArtifactContent(response.tool_calls?.[0]); | ||
const newArtifact: ArtifactV3 = { | ||
currentIndex: 1, | ||
contents: [newArtifactContent], | ||
}; | ||
|
||
return { | ||
artifact: newArtifact, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { PROGRAMMING_LANGUAGES } from "@/types"; | ||
import { z } from "zod"; | ||
|
||
export const ARTIFACT_TOOL_SCHEMA = z.object({ | ||
type: z | ||
.enum(["code", "text"]) | ||
.describe("The content type of the artifact generated."), | ||
language: z | ||
.enum( | ||
PROGRAMMING_LANGUAGES.map((lang) => lang.language) as [ | ||
string, | ||
...string[], | ||
] | ||
) | ||
.optional() | ||
.describe( | ||
"The language/programming language of the artifact generated.\n" + | ||
"If generating code, it should be one of the options, or 'other'.\n" + | ||
"If not generating code, the language should ALWAYS be 'other'." | ||
), | ||
isValidReact: z | ||
.boolean() | ||
.optional() | ||
.describe( | ||
"Whether or not the generated code is valid React code. Only populate this field if generating code." | ||
), | ||
artifact: z.string().describe("The content of the artifact to generate."), | ||
title: z | ||
.string() | ||
.describe( | ||
"A short title to give to the artifact. Should be less than 5 words." | ||
), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { NEW_ARTIFACT_PROMPT } from "../../prompts"; | ||
import { ArtifactCodeV3, ArtifactMarkdownV3 } from "@/types"; | ||
import { ToolCall } from "@langchain/core/messages/tool"; | ||
|
||
export const formatNewArtifactPrompt = ( | ||
memoriesAsString: string, | ||
modelName: string | ||
): string => { | ||
return NEW_ARTIFACT_PROMPT.replace("{reflections}", memoriesAsString).replace( | ||
"{disableChainOfThought}", | ||
modelName.includes("claude") | ||
? "\n\nIMPORTANT: Do NOT preform chain of thought beforehand. Instead, go STRAIGHT to generating the tool response. This is VERY important." | ||
: "" | ||
); | ||
}; | ||
|
||
export const createArtifactContent = ( | ||
toolCall: ToolCall | undefined | ||
): ArtifactCodeV3 | ArtifactMarkdownV3 => { | ||
const toolArgs = toolCall?.args; | ||
const artifactType = toolArgs?.type; | ||
|
||
if (artifactType === "code") { | ||
return { | ||
index: 1, | ||
type: "code", | ||
title: toolArgs?.title, | ||
code: toolArgs?.artifact, | ||
language: toolArgs?.language, | ||
}; | ||
} | ||
|
||
return { | ||
index: 1, | ||
type: "text", | ||
title: toolArgs?.title, | ||
fullMarkdown: toolArgs?.artifact, | ||
}; | ||
}; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { | ||
OpenCanvasGraphAnnotation, | ||
OpenCanvasGraphReturnType, | ||
} from "../../state"; | ||
import { LangGraphRunnableConfig } from "@langchain/langgraph"; | ||
import { optionallyUpdateArtifactMeta } from "./update-meta"; | ||
import { buildPrompt, createNewArtifactContent, validateState } from "./utils"; | ||
import { | ||
getFormattedReflections, | ||
getModelFromConfig, | ||
optionallyGetSystemPromptFromConfig, | ||
} from "@/agent/utils"; | ||
import { isArtifactMarkdownContent } from "@/lib/artifact_content_types"; | ||
|
||
export const rewriteArtifact = async ( | ||
state: typeof OpenCanvasGraphAnnotation.State, | ||
config: LangGraphRunnableConfig | ||
): Promise<OpenCanvasGraphReturnType> => { | ||
const smallModelWithConfig = (await getModelFromConfig(config)).withConfig({ | ||
runName: "rewrite_artifact_model_call", | ||
}); | ||
const memoriesAsString = await getFormattedReflections(config); | ||
const { currentArtifactContent, recentHumanMessage } = validateState(state); | ||
|
||
const artifactMetaToolCall = await optionallyUpdateArtifactMeta( | ||
state, | ||
config | ||
); | ||
const artifactType = artifactMetaToolCall?.args?.type; | ||
const isNewType = artifactType !== currentArtifactContent.type; | ||
|
||
const artifactContent = isArtifactMarkdownContent(currentArtifactContent) | ||
? currentArtifactContent.fullMarkdown | ||
: currentArtifactContent.code; | ||
|
||
const formattedPrompt = buildPrompt({ | ||
artifactContent, | ||
memoriesAsString, | ||
isNewType, | ||
artifactMetaToolCall, | ||
}); | ||
|
||
const userSystemPrompt = optionallyGetSystemPromptFromConfig(config); | ||
const fullSystemPrompt = userSystemPrompt | ||
? `${userSystemPrompt}\n${formattedPrompt}` | ||
: formattedPrompt; | ||
|
||
const newArtifactResponse = await smallModelWithConfig.invoke([ | ||
{ role: "system", content: fullSystemPrompt }, | ||
recentHumanMessage, | ||
]); | ||
|
||
const newArtifactContent = createNewArtifactContent({ | ||
artifactType, | ||
state, | ||
currentArtifactContent, | ||
artifactMetaToolCall, | ||
newContent: newArtifactResponse.content as string, | ||
}); | ||
|
||
return { | ||
artifact: { | ||
...state.artifact, | ||
currentIndex: state.artifact.contents.length + 1, | ||
contents: [...state.artifact.contents, newArtifactContent], | ||
}, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { PROGRAMMING_LANGUAGES } from "@/types"; | ||
import { z } from "zod"; | ||
|
||
export const OPTIONALLY_UPDATE_ARTIFACT_META_SCHEMA = z.object({ | ||
type: z.enum(["text", "code"]).describe("The type of the artifact content."), | ||
title: z | ||
.string() | ||
.optional() | ||
.describe( | ||
"The new title to give the artifact. ONLY update this if the user is making a request which changes the subject/topic of the artifact." | ||
), | ||
language: z | ||
.enum( | ||
PROGRAMMING_LANGUAGES.map((lang) => lang.language) as [ | ||
string, | ||
...string[], | ||
] | ||
) | ||
.describe( | ||
"The language of the code artifact. This should be populated with the programming language if the user is requesting code to be written, or 'other', in all other cases." | ||
), | ||
}); |
Oops, something went wrong.