Skip to content
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

azure-dynamic-sessions[major]: Add new package #5788

Merged
merged 25 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/core_docs/docs/integrations/platforms/microsoft.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,21 @@ See a [usage example for the Azure Files](/docs/integrations/document_loaders/we
```typescript
import { AzureBlobStorageFileLoader } from "@langchain/community/document_loaders/web/azure_blob_storage_file";
```

## Tools

### Azure Container Apps Dynamic Sessions

> [Azure Container Apps dynamic sessions](https://learn.microsoft.com/azure/container-apps/sessions) provide fast access to secure sandboxed environments that are ideal for running code or applications that require strong isolation from other workloads.

<IntegrationInstallTooltip></IntegrationInstallTooltip>

```bash npm2yarn
npm install @langchain/azure-dynamic-sessions
```

See a [usage example](/docs/integrations/tools/azure_dynamic_sessions).

```typescript
import { SessionsPythonREPLTool } from "@langchain/azure-dynamic-sessions";
```
42 changes: 42 additions & 0 deletions docs/core_docs/docs/integrations/tools/azure_dynamic_sessions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Azure Container Apps Dynamic Sessions

> [Azure Container Apps dynamic sessions](https://learn.microsoft.com/azure/container-apps/sessions) provide fast access to secure sandboxed environments that are ideal for running code or applications that require strong isolation from other workloads.

You can learn more about Azure Container Apps dynamic sessions and its code interpretation capabilities on [this page](https://learn.microsoft.com/azure/container-apps/sessions). If you don't have an Azure account, you can [create a free account](https://azure.microsoft.com/free/) to get started.

## Setup

You'll first need to install the [`@langchain/azure-dynamic-sessions`](https://www.npmjs.com/package/@langchain/azure-dynamic-sessions) package:

import IntegrationInstallTooltip from "@mdx_components/integration_install_tooltip.mdx";

<IntegrationInstallTooltip></IntegrationInstallTooltip>

```bash npm2yarn
npm install @langchain/azure-dynamic-sessions
```

You'll also need to have a code interpreter session pool instance running. You can deploy a version using [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) following [this guide](https://learn.microsoft.com/azure/container-apps/sessions-code-interpreter).

Once you have your instance running, you need to make sure you have properly set up the Azure Entra authentication for it. You can find the instructions on how to do that [here](https://learn.microsoft.com/azure/container-apps/sessions?tabs=azure-cli#authentication).

After you've added the role for your identity, you need to retrieve the **session pool management endpoint**. You can find it in the Azure Portal, under the "Overview" section of your instance. Then you need to set the following environment variable:

import CodeBlock from "@theme/CodeBlock";
import EnvVars from "@examples/tools/azure_dynamic_sessions/.env.example";

<CodeBlock language="text">{EnvVars}</CodeBlock>

## Usage example

Below is a simple example that creates a new Python code interpreter session, invoke the tool and prints the result.

import Example from "@examples/tools/azure_dynamic_sessions/azure_dynamic_sessions.ts";

<CodeBlock language="typescript">{Example}</CodeBlock>

Here is a complete example where we use an Azure OpenAI chat model to call the Python code interpreter session tool to execute the code and get the result:

import AgentExample from "@examples/tools/azure_dynamic_sessions/azure_dynamic_sessions-agent.ts";

<CodeBlock language="typescript">{AgentExample}</CodeBlock>
2 changes: 2 additions & 0 deletions examples/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ AZURE_OPENAI_API_COMPLETIONS_DEPLOYMENT_NAME=ADD_YOURS_HERE # Azure Portal -> Co
AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME=ADD_YOURS_HERE # Azure Portal -> Cognitive Services -> OpenAI -> Choose your instance -> Go to Azure OpenAI Studio -> Deployments
AZURE_OPENAI_API_VERSION=ADD_YOURS_HERE # Azure Portal -> Cognitive Services -> OpenAI -> Choose your instance -> Go to Azure OpenAI Studio -> Completions/Chat -> Choose Deployment -> View Code
AZURE_OPENAI_BASE_PATH=ADD_YOURS_HERE # Azure Portal -> Cognitive Services -> OpenAI -> Choose your instance -> Endpoint (optional)
AZURE_OPENAI_BASE_PATH=ADD_YOURS_HERE # Azure Portal -> Cognitive Services -> OpenAI -> Choose your instance -> Endpoint (optional)
AZURE_CONTAINER_APP_SESSION_POOL_MANAGEMENT_ENDPOINT=ADD_YOURS_HERE # Azure Portal -> Container App Session Pools -> Choose your app -> Pool management endpoint -> Copy the URL
CONNERY_RUNNER_URL=ADD_YOURS_HERE
CONNERY_RUNNER_API_KEY=ADD_YOURS_HERE
ELASTIC_URL=ADD_YOURS_HERE # http://127.0.0.1:9200
Expand Down
1 change: 1 addition & 0 deletions examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@gomomento/sdk": "^1.51.1",
"@google/generative-ai": "^0.7.0",
"@langchain/anthropic": "workspace:*",
"@langchain/azure-dynamic-sessions": "workspace:^",
"@langchain/azure-openai": "workspace:*",
"@langchain/cloudflare": "workspace:*",
"@langchain/cohere": "workspace:*",
Expand Down
1 change: 1 addition & 0 deletions examples/src/tools/azure_dynamic_sessions/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
AZURE_CONTAINER_APP_SESSION_POOL_MANAGEMENT_ENDPOINT=<your_endpoint>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { ChatPromptTemplate } from "@langchain/core/prompts";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there! 👋 I noticed that the recent code changes in azure_dynamic_sessions-agent.ts explicitly access an environment variable using process.env. I've flagged this for your review to ensure it aligns with our environment variable usage guidelines. Keep up the great work! 🚀

import { pull } from "langchain/hub";
import { AgentExecutor, createToolCallingAgent } from "langchain/agents";
import { SessionsPythonREPLTool } from "@langchain/azure-dynamic-sessions";
import { AzureChatOpenAI } from "@langchain/openai";

const tools = [
new SessionsPythonREPLTool({
poolManagementEndpoint:
process.env.AZURE_CONTAINER_APP_SESSION_POOL_MANAGEMENT_ENDPOINT || "",
}),
];

// Note: you need a model deployment that supports function calling,
// like `gpt-35-turbo` version `1106`.
const llm = new AzureChatOpenAI({
temperature: 0,
});

// Get the prompt to use - you can modify this!
// If you want to see the prompt in full, you can at:
// https://smith.langchain.com/hub/jacob/tool-calling-agent
const prompt = await pull<ChatPromptTemplate>("jacob/tool-calling-agent");

const agent = await createToolCallingAgent({
llm,
tools,
prompt,
});

const agentExecutor = new AgentExecutor({
agent,
tools,
});

const result = await agentExecutor.invoke({
input:
"Create a Python program that prints the Python version and return the result.",
});

console.log(result);
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { SessionsPythonREPLTool } from "@langchain/azure-dynamic-sessions";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey team, I've flagged a change in the PR for the azure_dynamic_sessions.ts file that explicitly accesses an environment variable via process.env. Please review this change to ensure it aligns with our environment variable usage guidelines.


const tool = new SessionsPythonREPLTool({
poolManagementEndpoint:
process.env.AZURE_CONTAINER_APP_SESSION_POOL_MANAGEMENT_ENDPOINT || "",
});

const result = await tool.invoke("print('Hello, World!')\n1+2");

console.log(result);

// {
// stdout: "Hello, World!\n",
// stderr: "",
// result: 3,
// }
2 changes: 2 additions & 0 deletions libs/langchain-azure-dynamic-sessions/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Azure Container App Session Pool Management Endpoint
AZURE_CONTAINER_APP_SESSION_POOL_MANAGEMENT_ENDPOINT=<your-endpoint>
66 changes: 66 additions & 0 deletions libs/langchain-azure-dynamic-sessions/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
module.exports = {
extends: [
"airbnb-base",
"eslint:recommended",
"prettier",
"plugin:@typescript-eslint/recommended",
],
parserOptions: {
ecmaVersion: 12,
parser: "@typescript-eslint/parser",
project: "./tsconfig.json",
sourceType: "module",
},
plugins: ["@typescript-eslint", "no-instanceof"],
ignorePatterns: [
".eslintrc.cjs",
"scripts",
"node_modules",
"dist",
"dist-cjs",
"*.js",
"*.cjs",
"*.d.ts",
],
rules: {
"no-process-env": 2,
"no-instanceof/no-instanceof": 2,
"@typescript-eslint/explicit-module-boundary-types": 0,
"@typescript-eslint/no-empty-function": 0,
"@typescript-eslint/no-shadow": 0,
"@typescript-eslint/no-empty-interface": 0,
"@typescript-eslint/no-use-before-define": ["error", "nofunc"],
"@typescript-eslint/no-unused-vars": ["warn", { args: "none" }],
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error",
camelcase: 0,
"class-methods-use-this": 0,
"import/extensions": [2, "ignorePackages"],
"import/no-extraneous-dependencies": [
"error",
{ devDependencies: ["**/*.test.ts"] },
],
"import/no-unresolved": 0,
"import/prefer-default-export": 0,
"keyword-spacing": "error",
"max-classes-per-file": 0,
"max-len": 0,
"no-await-in-loop": 0,
"no-bitwise": 0,
"no-console": 0,
"no-restricted-syntax": 0,
"no-shadow": 0,
"no-continue": 0,
"no-void": 0,
"no-underscore-dangle": 0,
"no-use-before-define": 0,
"no-useless-constructor": 0,
"no-return-await": 0,
"consistent-return": 0,
"no-else-return": 0,
"func-names": 0,
"no-lonely-if": 0,
"prefer-rest-params": 0,
"new-cap": ["error", { properties: false, capIsNew: false }],
},
};
7 changes: 7 additions & 0 deletions libs/langchain-azure-dynamic-sessions/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
index.cjs
index.js
index.d.ts
index.d.cts
node_modules
dist
.yarn
19 changes: 19 additions & 0 deletions libs/langchain-azure-dynamic-sessions/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "https://json.schemastore.org/prettierrc",
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "always",
"requirePragma": false,
"insertPragma": false,
"proseWrap": "preserve",
"htmlWhitespaceSensitivity": "css",
"vueIndentScriptAndStyle": false,
"endOfLine": "lf"
}
10 changes: 10 additions & 0 deletions libs/langchain-azure-dynamic-sessions/.release-it.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"github": {
"release": true,
"autoGenerate": true,
"tokenRef": "GITHUB_TOKEN_RELEASE"
},
"npm": {
"versionArgs": ["--workspaces-update=false"]
}
}
21 changes: 21 additions & 0 deletions libs/langchain-azure-dynamic-sessions/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License

Copyright (c) 2023 LangChain

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
60 changes: 60 additions & 0 deletions libs/langchain-azure-dynamic-sessions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# @langchain/azure-dynamic-sessions

This package contains the [Azure Container Apps dynamic sessions](https://learn.microsoft.com/azure/container-apps/sessions) tool integration.

Learn more about how to use this tool in the [LangChain documentation](https://js.langchain.com/docs/integrations/tools/azure_dynamic_sessions).

## Installation

```bash npm2yarn
npm install @langchain/azure-dynamic-sessions
```

This package, along with the main LangChain package, depends on [`@langchain/core`](https://npmjs.com/package/@langchain/core/).
If you are using this package with other LangChain packages, you should make sure that all of the packages depend on the same instance of @langchain/core.
You can do so by adding appropriate fields to your project's `package.json` like this:

```json
{
"name": "your-project",
"version": "0.0.0",
"dependencies": {
"@langchain/azure-openai": "^0.0.4",
"langchain": "0.0.207"
},
"resolutions": {
"@langchain/core": "0.1.5"
},
"overrides": {
"@langchain/core": "0.1.5"
},
"pnpm": {
"overrides": {
"@langchain/core": "0.1.5"
}
}
}
```

The field you need depends on the package manager you're using, but we recommend adding a field for the common `yarn`, `npm`, and `pnpm` to maximize compatibility.

## Tool usage

```typescript
import { SessionsPythonREPLTool } from "@langchain/azure-dynamic-sessions";

const tool = new SessionsPythonREPLTool({
poolManagementEndpoint:
process.env.AZURE_CONTAINER_APP_SESSION_POOL_MANAGEMENT_ENDPOINT || "",
});

const result = await tool.invoke("print('Hello, World!')\n1+2");

console.log(result);

// {
// stdout: "Hello, World!\n",
// stderr: "",
// result: 3,
// }
```
21 changes: 21 additions & 0 deletions libs/langchain-azure-dynamic-sessions/jest.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: "ts-jest/presets/default-esm",
testEnvironment: "./jest.env.cjs",
modulePathIgnorePatterns: ["dist/", "docs/"],
moduleNameMapper: {
"^(\\.{1,2}/.*)\\.js$": "$1",
},
transform: {
"^.+\\.tsx?$": ["@swc/jest"],
},
transformIgnorePatterns: [
"/node_modules/",
"\\.pnp\\.[^\\/]+$",
"./scripts/jest-setup-after-env.js",
],
setupFiles: ["dotenv/config"],
testTimeout: 20_000,
passWithNoTests: true,
collectCoverageFrom: ["src/**/*.ts"],
};
12 changes: 12 additions & 0 deletions libs/langchain-azure-dynamic-sessions/jest.env.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const { TestEnvironment } = require("jest-environment-node");

class AdjustedTestEnvironmentToSupportFloat32Array extends TestEnvironment {
constructor(config, context) {
// Make `instanceof Float32Array` return true in tests
// to avoid https://github.com/xenova/transformers.js/issues/57 and https://github.com/jestjs/jest/issues/2549
super(config, context);
this.global.Float32Array = Float32Array;
}
}

module.exports = AdjustedTestEnvironmentToSupportFloat32Array;
22 changes: 22 additions & 0 deletions libs/langchain-azure-dynamic-sessions/langchain.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";

/**
* @param {string} relativePath
* @returns {string}
*/
function abs(relativePath) {
return resolve(dirname(fileURLToPath(import.meta.url)), relativePath);
}

export const config = {
internals: [/node\:/, /@langchain\/core\//],
entrypoints: {
index: "index",
},
requiresOptionalDependency: [],
tsConfigPath: resolve("./tsconfig.json"),
cjsSource: "./dist-cjs",
cjsDestination: "./dist",
abs,
};
Loading
Loading