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.
Merge pull request langchain-ai#183 from langchain-ai/brace/custom-as…
…sistants feat: Custom assistants
- Loading branch information
Showing
43 changed files
with
2,357 additions
and
648 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], | ||
}, | ||
}; | ||
}; |
Oops, something went wrong.