feat: Create a shared package (#89)

* feat: Create a shared package

* formatting
This commit is contained in:
Brace Sproul 2025-06-08 12:10:52 -07:00 • committed by GitHub
parent 46a74dd0cb
commit a0b8aaa075
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
42 changed files with 273 additions and 36 deletions

View file

@ -28,6 +28,7 @@
"@langchain/langgraph-sdk": "^0.0.78",
"@langchain/openai": "^0.5.10",
"@octokit/rest": "^22.0.0",
"@open-swe/shared": "workspace:*",
"diff": "^8.0.1",
"langchain": "^0.3.26",
"langsmith": "^0.3.29",

View file

@ -1,5 +1,9 @@
import { END, START, StateGraph } from "@langchain/langgraph";
import { GraphAnnotation, GraphConfiguration, GraphState } from "./types.js";
import {
GraphAnnotation,
GraphConfiguration,
GraphState,
} from "@open-swe/shared/open-swe/types";
import {
initialize,
generateAction,

View file

@ -3,7 +3,12 @@ import {
isToolMessage,
ToolMessage,
} from "@langchain/core/messages";
import { GraphConfig, GraphState, GraphUpdate, PlanItem } from "../types.js";
import {
GraphConfig,
GraphState,
GraphUpdate,
PlanItem,
} from "@open-swe/shared/open-swe/types";
import { formatPlanPromptWithSummaries } from "../utils/plan-prompt.js";
import {
getMessageContentString,

View file

@ -1,4 +1,9 @@
import { GraphConfig, GraphState, GraphUpdate, PlanItem } from "../types.js";
import {
GraphConfig,
GraphState,
GraphUpdate,
PlanItem,
} from "@open-swe/shared/open-swe/types";
import { loadModel, Task } from "../utils/load-model.js";
import {
getMessageContentString,

View file

@ -1,4 +1,8 @@
import { GraphState, GraphConfig, GraphUpdate } from "../types.js";
import {
GraphState,
GraphConfig,
GraphUpdate,
} from "@open-swe/shared/open-swe/types";
import { loadModel, Task } from "../utils/load-model.js";
import {
shellTool,
@ -12,7 +16,7 @@ import { createLogger, LogLevel } from "../utils/logger.js";
import { getCurrentPlanItem } from "../utils/current-task.js";
import { getMessageContentString } from "../utils/message/content.js";
import { getActivePlanItems } from "../utils/task-plan.js";
import { SANDBOX_ROOT_DIR } from "../constants.js";
import { SANDBOX_ROOT_DIR } from "@open-swe/shared/constants";
const logger = createLogger(LogLevel.INFO, "GenerateMessageNode");

View file

@ -1,5 +1,9 @@
import { createLogger, LogLevel } from "../utils/logger.js";
import { GraphState, GraphConfig, GraphUpdate } from "../types.js";
import {
GraphState,
GraphConfig,
GraphUpdate,
} from "@open-swe/shared/open-swe/types";
import {
checkoutBranch,
cloneRepo,
@ -9,7 +13,7 @@ import {
pullLatestChanges,
} from "../utils/git.js";
import { daytonaClient } from "../utils/sandbox.js";
import { SNAPSHOT_NAME } from "../constants.js";
import { SNAPSHOT_NAME } from "@open-swe/shared/constants";
import { getGitHubTokensFromConfig } from "../utils/github-tokens.js";
import { getCodebaseTree } from "../utils/tree.js";

View file

@ -1,5 +1,5 @@
import { Command, END, interrupt } from "@langchain/langgraph";
import { GraphState, GraphUpdate } from "../types.js";
import { GraphState, GraphUpdate } from "@open-swe/shared/open-swe/types";
import {
ActionRequest,
HumanInterrupt,

View file

@ -1,4 +1,9 @@
import { GraphConfig, GraphState, GraphUpdate, PlanItem } from "../types.js";
import {
GraphConfig,
GraphState,
GraphUpdate,
PlanItem,
} from "@open-swe/shared/open-swe/types";
import {
checkoutBranchAndCommit,
createPullRequest,

View file

@ -1,6 +1,11 @@
import { z } from "zod";
import { createLogger, LogLevel } from "../utils/logger.js";
import { GraphConfig, GraphState, GraphUpdate, PlanItem } from "../types.js";
import {
GraphConfig,
GraphState,
GraphUpdate,
PlanItem,
} from "@open-swe/shared/open-swe/types";
import { loadModel, Task } from "../utils/load-model.js";
import { formatPlanPrompt } from "../utils/plan-prompt.js";
import { Command } from "@langchain/langgraph";

View file

@ -1,5 +1,5 @@
import { isAIMessage, ToolMessage } from "@langchain/core/messages";
import { GraphState, GraphUpdate } from "../types.js";
import { GraphState, GraphUpdate } from "@open-swe/shared/open-swe/types";
import { HumanInterrupt, HumanResponse } from "@langchain/langgraph/prebuilt";
import { END, interrupt, Command } from "@langchain/langgraph";
import { stopSandbox, startSandbox } from "../utils/sandbox.js";

View file

@ -1,4 +1,9 @@
import { GraphState, GraphConfig, GraphUpdate, PlanItem } from "../types.js";
import {
GraphState,
GraphConfig,
GraphUpdate,
PlanItem,
} from "@open-swe/shared/open-swe/types";
import { loadModel, Task } from "../utils/load-model.js";
import { z } from "zod";
import { tool } from "@langchain/core/tools";

View file

@ -1,5 +1,10 @@
import { v4 as uuidv4 } from "uuid";
import { GraphConfig, GraphState, GraphUpdate, PlanItem } from "../types.js";
import {
GraphConfig,
GraphState,
GraphUpdate,
PlanItem,
} from "@open-swe/shared/open-swe/types";
import { loadModel, Task } from "../utils/load-model.js";
import { AIMessage, BaseMessage } from "@langchain/core/messages";
import { formatPlanPrompt } from "../utils/plan-prompt.js";

View file

@ -5,7 +5,7 @@ import {
} from "@langchain/core/messages";
import { createLogger, LogLevel } from "../utils/logger.js";
import { applyPatchTool, shellTool } from "../tools/index.js";
import { GraphState, GraphConfig } from "../types.js";
import { GraphState, GraphConfig } from "@open-swe/shared/open-swe/types";
import {
checkoutBranchAndCommit,
getChangedFilesStatus,

View file

@ -11,7 +11,10 @@ import {
PlannerGraphStateObj,
PlannerGraphUpdate,
} from "./types.js";
import { GraphConfig, GraphConfiguration } from "../../types.js";
import {
GraphConfig,
GraphConfiguration,
} from "@open-swe/shared/open-swe/types";
import {
generateAction,
generatePlan,

View file

@ -1,14 +1,14 @@
import { loadModel, Task } from "../../../utils/load-model.js";
import { shellTool } from "../../../tools/index.js";
import { PlannerGraphState, PlannerGraphUpdate } from "../types.js";
import { GraphConfig } from "../../../types.js";
import { GraphConfig } from "@open-swe/shared/open-swe/types";
import { createLogger, LogLevel } from "../../../utils/logger.js";
import { getMessageContentString } from "../../../utils/message/content.js";
import { getUserRequest } from "../../../utils/user-request.js";
import { isHumanMessage } from "@langchain/core/messages";
import { formatFollowupMessagePrompt } from "../utils/followup-prompt.js";
import { getRepoAbsolutePath } from "../../../utils/git.js";
import { SANDBOX_ROOT_DIR } from "../../../constants.js";
import { SANDBOX_ROOT_DIR } from "@open-swe/shared/constants";
const logger = createLogger(LogLevel.INFO, "GeneratePlanningMessageNode");

View file

@ -4,7 +4,7 @@ import {
ToolMessage,
} from "@langchain/core/messages";
import { sessionPlanTool } from "../../../tools/index.js";
import { GraphConfig } from "../../../types.js";
import { GraphConfig } from "@open-swe/shared/open-swe/types";
import { loadModel, Task } from "../../../utils/load-model.js";
import { PlannerGraphState, PlannerGraphUpdate } from "../types.js";
import { getUserRequest } from "../../../utils/user-request.js";

View file

@ -1,5 +1,5 @@
import { z } from "zod";
import { GraphConfig } from "../../../types.js";
import { GraphConfig } from "@open-swe/shared/open-swe/types";
import { PlannerGraphState, PlannerGraphUpdate } from "../types.js";
import { loadModel, Task } from "../../../utils/load-model.js";
import { getMessageString } from "../../../utils/message/content.js";

View file

@ -1,6 +1,6 @@
import { isAIMessage, ToolMessage } from "@langchain/core/messages";
import { shellTool } from "../../../tools/index.js";
import { GraphConfig } from "../../../types.js";
import { GraphConfig } from "@open-swe/shared/open-swe/types";
import { PlannerGraphState, PlannerGraphUpdate } from "../types.js";
import { createLogger, LogLevel } from "../../../utils/logger.js";
import { zodSchemaToString } from "../../../utils/zod-to-string.js";

View file

@ -2,7 +2,7 @@ import "@langchain/langgraph/zod";
import { z } from "zod";
import { addMessages, Messages } from "@langchain/langgraph";
import { BaseMessage } from "@langchain/core/messages";
import { GraphAnnotation } from "../../types.js";
import { GraphAnnotation } from "@open-swe/shared/open-swe/types";
export const PlannerGraphStateObj = GraphAnnotation.extend({
plannerMessages: z

View file

@ -1,4 +1,4 @@
import { TaskPlan } from "../../../types.js";
import { TaskPlan } from "@open-swe/shared/open-swe/types";
const followupMessagePrompt = `
The user is sending a followup request for you to generate a plan for. You are provided with the following context to aid in your new plan context gathering steps:

View file

@ -1,13 +1,13 @@
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { applyPatch } from "diff";
import { GraphState } from "../types.js";
import { GraphState } from "@open-swe/shared/open-swe/types";
import { readFile, writeFile } from "../utils/read-write.js";
import { getCurrentTaskInput } from "@langchain/langgraph";
import { fixGitPatch } from "../utils/diff.js";
import { createLogger, LogLevel } from "../utils/logger.js";
import { daytonaClient } from "../utils/sandbox.js";
import { SANDBOX_ROOT_DIR } from "../constants.js";
import { SANDBOX_ROOT_DIR } from "@open-swe/shared/constants";
const logger = createLogger(LogLevel.INFO, "ApplyPatchTool");

View file

@ -1,12 +1,12 @@
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { Sandbox } from "@daytonaio/sdk";
import { GraphState } from "../types.js";
import { GraphState } from "@open-swe/shared/open-swe/types";
import { getCurrentTaskInput } from "@langchain/langgraph";
import { getSandboxErrorFields } from "../utils/sandbox-error-fields.js";
import { createLogger, LogLevel } from "../utils/logger.js";
import { daytonaClient } from "../utils/sandbox.js";
import { SANDBOX_ROOT_DIR, TIMEOUT_SEC } from "../constants.js";
import { SANDBOX_ROOT_DIR, TIMEOUT_SEC } from "@open-swe/shared/constants";
const logger = createLogger(LogLevel.INFO, "ShellTool");

View file

@ -1,4 +1,4 @@
import { PlanItem } from "../types.js";
import { PlanItem } from "@open-swe/shared/open-swe/types";
export function getCurrentPlanItem(plan: PlanItem[]): PlanItem {
return (

View file

@ -1,8 +1,8 @@
import { Octokit } from "@octokit/rest";
import { Sandbox } from "@daytonaio/sdk";
import { createLogger, LogLevel } from "./logger.js";
import { GraphConfig, TargetRepository } from "../types.js";
import { TIMEOUT_SEC, SANDBOX_ROOT_DIR } from "../constants.js";
import { GraphConfig, TargetRepository } from "@open-swe/shared/open-swe/types";
import { TIMEOUT_SEC, SANDBOX_ROOT_DIR } from "@open-swe/shared/constants";
import { getSandboxErrorFields } from "./sandbox-error-fields.js";
import { ExecuteResponse } from "@daytonaio/sdk/dist/types/ExecuteResponse.js";

View file

@ -1,4 +1,4 @@
import { GraphConfig } from "../types.js";
import { GraphConfig } from "@open-swe/shared/open-swe/types";
export function getGitHubTokensFromConfig(config: GraphConfig): {
githubToken: string;

View file

@ -1,5 +1,5 @@
import { initChatModel } from "langchain/chat_models/universal";
import { GraphConfig } from "../types.js";
import { GraphConfig } from "@open-swe/shared/open-swe/types";
export enum Task {
PLANNER = "planner",

View file

@ -1,4 +1,4 @@
import { PlanItem } from "../types.js";
import { PlanItem } from "@open-swe/shared/open-swe/types";
export const PLAN_PROMPT = `## Completed Tasks
{COMPLETED_TASKS}

View file

@ -1,5 +1,10 @@
import { v4 as uuidv4 } from "uuid";
import { PlanItem, Task, TaskPlan, PlanRevision } from "../types.js";
import {
PlanItem,
Task,
TaskPlan,
PlanRevision,
} from "@open-swe/shared/open-swe/types";
/**
* Creates a new task with the provided plan items.

View file

@ -1,9 +1,9 @@
import { getCurrentTaskInput } from "@langchain/langgraph";
import { GraphState } from "../types.js";
import { GraphState } from "@open-swe/shared/open-swe/types";
import { daytonaClient } from "./sandbox.js";
import { createLogger, LogLevel } from "./logger.js";
import path from "node:path";
import { SANDBOX_ROOT_DIR, TIMEOUT_SEC } from "../constants.js";
import { SANDBOX_ROOT_DIR, TIMEOUT_SEC } from "@open-swe/shared/constants";
const logger = createLogger(LogLevel.INFO, "Tree");

View file

@ -3,7 +3,8 @@
"author": "LangChain",
"private": true,
"workspaces": [
"apps/*"
"apps/*",
"packages/*"
],
"scripts": {
"dev": "turbo dev",

View file

View file

@ -0,0 +1,4 @@
node_modules
.next
.git
.env

28
packages/shared/.gitignore vendored Normal file
View file

@ -0,0 +1,28 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# LangGraph API
.langgraph_api
.env

View file

@ -0,0 +1,4 @@
{
"tabWidth": 2,
"useTabs": false
}

View file

@ -0,0 +1,28 @@
import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";
export default tseslint.config(
{ ignores: ["dist"] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.node,
},
rules: {
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/no-unused-vars": [
"error",
{
args: "none",
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
},
],
"no-console": ["error"],
},
},
);

View file

@ -0,0 +1,59 @@
{
"name": "@open-swe/shared",
"homepage": "https://github.com/langchain-ai/open-swe/blob/main/README.md",
"repository": {
"type": "git",
"url": "https://github.com/langchain-ai/open-swe.git"
},
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"clean": "rm -rf ./dist .turbo || true",
"build": "yarn clean && tsc",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"format": "prettier --write .",
"format:check": "prettier --check ."
},
"dependencies": {
"@langchain/core": "^0.3.56",
"@langchain/langgraph": "^0.2.73",
"zod": "^3.23.8"
},
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^9.19.0",
"@tsconfig/recommended": "^1.0.8",
"@types/node": "^22.13.5",
"dotenv": "^16.4.7",
"eslint": "^9.19.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-no-instanceof": "^1.0.1",
"eslint-plugin-prettier": "^4.2.1",
"prettier": "^3.5.2",
"typescript": "~5.7.2",
"typescript-eslint": "^8.22.0"
},
"packageManager": "yarn@3.5.1",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.js"
},
"./*": {
"types": "./dist/*.d.ts",
"import": "./dist/*.js",
"require": "./dist/*.js"
},
"./package.json": "./package.json"
},
"files": [
"dist/**/*"
]
}

View file

@ -0,0 +1,2 @@
// no-op file
export {};

View file

@ -0,0 +1,25 @@
{
"extends": "@tsconfig/recommended",
"compilerOptions": {
"target": "ES2021",
"lib": ["ES2023"],
"module": "NodeNext",
"moduleResolution": "nodenext",
"esModuleInterop": true,
"noImplicitReturns": true,
"declaration": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"useDefineForClassFields": true,
"strictPropertyInitialization": false,
"allowJs": true,
"strict": true,
"strictFunctionTypes": false,
"outDir": "dist",
"types": ["jest", "node"],
"resolveJsonModule": true
},
"include": ["src/**/*.ts", "src/*.ts"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,11 @@
{
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["dist/**"]
},
"dev": {
"dependsOn": ["^dev"]
}
}
}

View file

@ -1918,6 +1918,7 @@ __metadata:
"@langchain/langgraph-sdk": ^0.0.78
"@langchain/openai": ^0.5.10
"@octokit/rest": ^22.0.0
"@open-swe/shared": "workspace:*"
"@tsconfig/recommended": ^1.0.8
"@types/jest": ^29.5.0
"@types/node": ^22.13.5
@ -1940,6 +1941,29 @@ __metadata:
languageName: unknown
linkType: soft
"@open-swe/shared@workspace:*, @open-swe/shared@workspace:packages/shared":
version: 0.0.0-use.local
resolution: "@open-swe/shared@workspace:packages/shared"
dependencies:
"@eslint/eslintrc": ^3.1.0
"@eslint/js": ^9.19.0
"@langchain/core": ^0.3.56
"@langchain/langgraph": ^0.2.73
"@tsconfig/recommended": ^1.0.8
"@types/node": ^22.13.5
dotenv: ^16.4.7
eslint: ^9.19.0
eslint-config-prettier: ^8.8.0
eslint-plugin-import: ^2.27.5
eslint-plugin-no-instanceof: ^1.0.1
eslint-plugin-prettier: ^4.2.1
prettier: ^3.5.2
typescript: ~5.7.2
typescript-eslint: ^8.22.0
zod: ^3.23.8
languageName: unknown
linkType: soft
"@open-swe/web@workspace:apps/web":
version: 0.0.0-use.local
resolution: "@open-swe/web@workspace:apps/web"