diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 00000000..d9005572
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @format
+ */
+
+const OFF = 0;
+const WARNING = 1;
+const ERROR = 2;
+
+module.exports = {
+ root: true,
+ env: {
+ browser: true,
+ commonjs: true,
+ jest: true,
+ node: true,
+ },
+ parser: "@babel/eslint-parser",
+ parserOptions: {
+ allowImportExportEverywhere: true,
+ },
+ extends: ["airbnb", "prettier"],
+ plugins: ["react-hooks", "header"],
+ ignorePatterns: [
+ "build",
+ "docs/api",
+ "node_modules",
+ "docs/_static",
+ "static",
+ ],
+ rules: {
+ // Ignore certain webpack alias because it can't be resolved
+ "import/no-unresolved": [
+ ERROR,
+ { ignore: ["^@theme", "^@docusaurus", "^@generated"] },
+ ],
+ "import/extensions": OFF,
+ "react/jsx-filename-extension": OFF,
+ "react-hooks/rules-of-hooks": ERROR,
+ "react/prop-types": OFF, // PropTypes aren't used much these days.
+ "react/function-component-definition": [
+ WARNING,
+ {
+ namedComponents: "function-declaration",
+ unnamedComponents: "arrow-function",
+ },
+ ],
+ "no-unused-vars": WARNING,
+ "import/prefer-default-export": WARNING,
+ "react/jsx-props-no-spreading": OFF,
+ "no-empty-pattern": WARNING,
+ },
+};
diff --git a/.github/workflows/format-lint.yml b/.github/workflows/format-lint.yml
new file mode 100644
index 00000000..1705d740
--- /dev/null
+++ b/.github/workflows/format-lint.yml
@@ -0,0 +1,52 @@
+# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
+
+name: CI (Lint/Format)
+
+on:
+ push:
+ branches: ["main"]
+ pull_request:
+ workflow_dispatch: # Allows triggering the workflow manually in GitHub UI
+
+
+# If another push to the same PR or branch happens while this workflow is still running,
+# cancel the earlier run in favor of the next run.
+#
+# There's no point in testing an outdated version of the code. GitHub only allows
+# a limited number of job runners to be active at the same time, so it's better to cancel
+# pointless jobs early so that more useful jobs can run sooner.
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ lint:
+ name: Check linting
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Use Node.js 18.x
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18.x
+ cache: "yarn"
+ - name: Install dependencies
+ run: yarn install --immutable --mode=skip-build
+ - name: Check linting
+ run: yarn run lint
+
+ format:
+ name: Check formatting
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Use Node.js 18.x
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18.x
+ cache: "yarn"
+ - name: Install dependencies
+ run: yarn install --immutable --mode=skip-build
+ - name: Check formatting
+ run: yarn run format:check
diff --git a/docs/evaluation/faq/evaluator-implementations.mdx b/docs/evaluation/faq/evaluator-implementations.mdx
index ef023b00..80d3476d 100644
--- a/docs/evaluation/faq/evaluator-implementations.mdx
+++ b/docs/evaluation/faq/evaluator-implementations.mdx
@@ -53,10 +53,10 @@ Three QA evaluators you can load are: `"qa"`, `"context_qa"`, `"cot_qa"`. Based
- The `"qa"` evaluator ([reference](https://api.python.langchain.com/en/latest/evaluation/langchain.evaluation.qa.eval_chain.QAEvalChain.html#langchain-evaluation-qa-eval-chain-qaevalchain)) instructs an llm to directly grade a response as "correct" or "incorrect" based on the reference answer.
- The `"context_qa"` evaluator ([reference](https://api.python.langchain.com/en/latest/evaluation/langchain.evaluation.qa.eval_chain.ContextQAEvalChain.html#langchain.evaluation.qa.eval_chain.ContextQAEvalChain)) instructs the LLM chain to use reference "context" (provided throught the example outputs) in determining correctness. This is useful if you have a larger corpus of grounding docs but don't have ground truth answers to a query.
- The `"cot_qa"` evaluator ([reference](https://api.python.langchain.com/en/latest/evaluation/langchain.evaluation.qa.eval_chain.CotQAEvalChain.html#langchain.evaluation.qa.eval_chain.CotQAEvalChain)) is similar to the "context_qa" evaluator, except it instructs the LLMChain to use chain of thought "reasoning" before determining a final verdict. This tends to lead to responses that better correlate with human labels, for a slightly higher token and runtime cost.
- {" "}
-
- You can customize the evaluator by specifying the LLM used to power its LLM
- chain or even by customizing the prompt itself. Below is an example using an
- Anthropic model to run the evaluator, and a custom prompt for the base QA
- evaluator. Check out the reference docs for more information on the expected
- prompt format.
-
+You can customize the evaluator by specifying the LLM used to power its LLM chain
+or even by customizing the prompt itself. Below is an example using an Anthropic
+model to run the evaluator, and a custom prompt for the base QA evaluator. Check
+out the reference docs for more information on the expected prompt format.
+
+ ]}
+ groupId="client-language"
+/>
## Criteria Evaluators (No Labels)
diff --git a/docs/tracing/faq/logging_and_viewing.mdx b/docs/tracing/faq/logging_and_viewing.mdx
index adbce104..6a338b1b 100644
--- a/docs/tracing/faq/logging_and_viewing.mdx
+++ b/docs/tracing/faq/logging_and_viewing.mdx
@@ -52,6 +52,7 @@ Additionally, you will need to set `LANGCHAIN_TRACING_V2='true'` if you plan to
- LangChain (Python or JS)
- `@traceable` decorator or `wrap_openai` method in the Python SDK
+
:::
(
-
-);
+export function ClientInstallationCodeTabs() {
+ return (
+
+ );
+}
diff --git a/src/components/Hub.js b/src/components/Hub.js
index 01018c14..be330e4f 100644
--- a/src/components/Hub.js
+++ b/src/components/Hub.js
@@ -10,39 +10,41 @@ import {
ShellBlock,
} from "./InstructionsWithCode";
-export const HubInstallationCodeTabs = () => (
-
-);
+export function HubInstallationCodeTabs() {
+ return (
+
+ );
+}
-export const HubPullCodeTabs = ({}) => {
+export function HubPullCodeTabs() {
const pyBlock = `from langchain import hub
# pull a chat prompt
@@ -94,9 +96,9 @@ console.log(result);`;
);
-};
+}
-export const HubPushCodeTabs = ({}) => {
+export function HubPushCodeTabs() {
const pyBlock = `from langchain import hub
from langchain.prompts.chat import ChatPromptTemplate
@@ -131,4 +133,4 @@ await hub.push("/my-first-prompt", prompt);`;
);
-};
+}
diff --git a/src/components/InstructionsWithCode.js b/src/components/InstructionsWithCode.js
index 18eb769a..7a017f29 100644
--- a/src/components/InstructionsWithCode.js
+++ b/src/components/InstructionsWithCode.js
@@ -7,7 +7,7 @@ export function LangChainPyBlock(content) {
return {
value: "langchain-py",
label: "LangChain (Python)",
- content: content,
+ content,
language: "python",
};
}
@@ -16,7 +16,7 @@ export function LangChainJSBlock(content) {
return {
value: "langchain-js",
label: "LangChain (JS)",
- content: content,
+ content,
language: "typescript",
};
}
@@ -25,7 +25,7 @@ export function TypeScriptBlock(content) {
return {
value: "typescript",
label: "TypeScript SDK",
- content: content,
+ content,
language: "typescript",
};
}
@@ -34,7 +34,7 @@ export function PythonBlock(content) {
return {
value: "python",
label: "Python SDK",
- content: content,
+ content,
language: "python",
};
}
@@ -43,27 +43,35 @@ export function APIBlock(content) {
return {
value: "api",
label: "API (Using Python Requests)",
- content: content,
+ content,
language: "python",
};
}
export function ShellBlock(content, value = "shell", label = "Shell") {
return {
- value: value,
- label: label,
- content: content,
+ value,
+ label,
+ content,
};
}
-export const CodeTabs = ({ tabs, groupId }) => (
-
- {tabs.map((tab, index) => (
-
-
- {tab.content}
-
-
- ))}
-
-);
+export function CodeTabs({ tabs, groupId }) {
+ return (
+
+ {tabs.map((tab, index) => {
+ const key = `${groupId}-${index}`;
+ return (
+
+
+ {tab.content}
+
+
+ );
+ })}
+
+ );
+}
diff --git a/src/components/QuickStart.js b/src/components/QuickStart.js
index e4163740..b10d08ed 100644
--- a/src/components/QuickStart.js
+++ b/src/components/QuickStart.js
@@ -1,3 +1,7 @@
+import CodeBlock from "@theme/CodeBlock";
+import React from "react";
+import TabItem from "@theme/TabItem";
+import Tabs from "@theme/Tabs";
import {
CodeTabs,
PythonBlock,
@@ -5,11 +9,6 @@ import {
TypeScriptBlock,
} from "./InstructionsWithCode";
-import CodeBlock from "@theme/CodeBlock";
-import React from "react";
-import TabItem from "@theme/TabItem";
-import Tabs from "@theme/Tabs";
-
export const TypeScriptSDKTracingCode = () =>
`import { OpenAI } from "openai";
import { traceable } from "langsmith/traceable";
@@ -28,13 +27,16 @@ const pipeline = traceable(async (user_input) => {
await pipeline("Hello, world!")
// Out: Hello there! How can I assist you today?`;
-export const TypeScriptSDKTracingCodeBlock = () => (
- {TypeScriptSDKTracingCode()}
-);
+export function TypeScriptSDKTracingCodeBlock() {
+ return (
+ {TypeScriptSDKTracingCode()}
+ );
+}
-export const PythonAPITracingCodeBlock = () => (
-
- {`import openai
+export function PythonAPITracingCodeBlock() {
+ return (
+
+ {`import openai
import requests
from datetime import datetime
from uuid import uuid4
@@ -95,8 +97,9 @@ chat_completion = client.chat.completions.create(model="gpt-3.5-turbo", messages
# End runs
patch_run(child_run_id, chat_completion.dict())
patch_run(parent_run_id, {"answer": chat_completion.choices[0].message.content})`}
-
-);
+
+ );
+}
export const PythonSDKTracingCode = () =>
`import openai
@@ -114,69 +117,75 @@ def pipeline(user_input: str):
pipeline("Hello, world!")
# Out: Hello there! How can I assist you today?`;
-export const PythonSDKTracingCodeBlock = () => (
- {PythonSDKTracingCode()}
-);
-
-export const LangChainInstallationCodeTabs = () => (
-
-);
-
-export const ConfigureSDKEnvironmentCodeTabs = ({}) => (
- {PythonSDKTracingCode()};
+}
+
+export function LangChainInstallationCodeTabs() {
+ return (
+
+ );
+}
+
+export function ConfigureSDKEnvironmentCodeTabs({}) {
+ return (
+
# The below examples use the OpenAI API, though it's not necessary in general
export OPENAI_API_KEY=`),
- ]}
- groupId="client-language"
- />
-);
-
-export const ConfigureEnvironmentCodeTabs = ({}) => (
-
+ );
+}
+
+export function ConfigureEnvironmentCodeTabs({}) {
+ return (
+
# The below examples use the OpenAI API, though it's not necessary in general
export OPENAI_API_KEY=`),
- ]}
- groupId="client-language"
- />
-);
+ ]}
+ groupId="client-language"
+ />
+ );
+}
-export const LangChainQuickStartCodeTabs = ({}) => {
+export function LangChainQuickStartCodeTabs({}) {
const simpleTSBlock = `import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
@@ -242,7 +251,7 @@ chain.invoke({"question": question, "context": context})`}
);
-};
+}
const TraceableQuickStart = PythonBlock(`from typing import Any, Iterable\n
import openai
@@ -272,21 +281,24 @@ for tok in my_chat_bot("Summarize this morning's meetings."):
print(tok, end="")
# See an example run at: https://smith.langchain.com/public/3e853ad8-77ce-404d-ad4c-05726851ad0f/r`);
-export const TraceableQuickStartCodeBlock = ({}) => (
-
- {TraceableQuickStart.content}
-
-);
-
-export const TraceableThreadingCodeBlock = ({}) => (
-
- {`import asyncio
+export function TraceableQuickStartCodeBlock({}) {
+ return (
+
+ {TraceableQuickStart.content}
+
+ );
+}
+
+export function TraceableThreadingCodeBlock({}) {
+ return (
+
+ {`import asyncio
import datetime
from concurrent.futures import ThreadPoolExecutor
from typing import Any, Dict, List\n
@@ -350,18 +362,20 @@ async def nested_chain(text: str, run_tree: RunTree, **kwargs: Any) -> str:
)
return "\\n".join([future.result() for future in futures])\n\n
asyncio.run(nested_chain("Summarize meeting"))`}
-
-);
-
-export const RunTreeQuickStartCodeTabs = ({}) => (
-
+ );
+}
+
+export function RunTreeQuickStartCodeTabs({}) {
+ return (
+
-);
+ ]}
+ groupId="client-language"
+ />
+ );
+}
diff --git a/src/components/RunTree.js b/src/components/RunTree.js
index af782c68..893e057d 100644
--- a/src/components/RunTree.js
+++ b/src/components/RunTree.js
@@ -1,10 +1,11 @@
import React from "react";
import { CodeTabs, PythonBlock, TypeScriptBlock } from "./InstructionsWithCode";
-export const RunTreeExampleCodeTabs = () => (
-
-);
+ ]}
+ groupId="client-language"
+ />
+ );
+}
diff --git a/src/components/TracingFaq.js b/src/components/TracingFaq.js
index 20a2f2f3..63c81354 100644
--- a/src/components/TracingFaq.js
+++ b/src/components/TracingFaq.js
@@ -3,7 +3,7 @@ import React from "react";
import TabItem from "@theme/TabItem";
import Tabs from "@theme/Tabs";
-export const AccessRunIdBlock = ({}) => {
+export function AccessRunIdBlock({}) {
const callbackPythonBlock = `from langchain import chat_models, prompts, callbacks
chain = (
prompts.ChatPromptTemplate.from_template("Say hi to {name}")
@@ -110,4 +110,4 @@ console.log(response.__run);`;
);
-};
+}
diff --git a/src/hooks/useColorScheme.js b/src/hooks/useColorScheme.js
index a75af787..fb958ebf 100644
--- a/src/hooks/useColorScheme.js
+++ b/src/hooks/useColorScheme.js
@@ -9,6 +9,6 @@ export function useColorScheme() {
mode: systemMode,
isDarkMode,
isLightMode: !isDarkMode,
- setMode: setMode,
+ setMode,
};
}
diff --git a/src/theme/ColorModeToggle/index.js b/src/theme/ColorModeToggle/index.js
index 06eb6194..42c4ad37 100644
--- a/src/theme/ColorModeToggle/index.js
+++ b/src/theme/ColorModeToggle/index.js
@@ -14,9 +14,5 @@ export default function ColorModeToggleWrapper(props) {
setMode(value);
}, [value]);
- return (
- <>
-
- >
- );
+ return ;
}
diff --git a/src/theme/SearchBar.js b/src/theme/SearchBar.js
index 44aeba03..42d4a946 100644
--- a/src/theme/SearchBar.js
+++ b/src/theme/SearchBar.js
@@ -2,9 +2,5 @@ import React from "react";
import SearchBar from "@theme-original/SearchBar";
export default function SearchBarWrapper(props) {
- return (
- <>
-
- >
- );
+ return ;
}