feat: Add script to get trace URLs (#552)

* feat: Add script to get trace URLs

* fix lint

* cr
This commit is contained in:
Brace Sproul 2025-07-28 17:41:49 -07:00 • committed by GitHub
parent e44b33de95
commit 9f5a957726
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 111 additions and 0 deletions

View file

@ -20,6 +20,7 @@
"test:int": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.config.js --testPathPattern=int.test.ts",
"test:single": "NODE_OPTIONS=--experimental-vm-modules yarn run jest --config jest.config.js --testTimeout 100000",
"eval:single": "NODE_OPTIONS=--experimental-vm-modules yarn run vitest --config ls.vitest.config.ts --run",
"get-trace-urls": "tsx scripts/get-trace-urls.ts",
"postinstall": "turbo build"
},
"dependencies": {

View file

@ -0,0 +1,110 @@
/* eslint-disable no-console */
import "dotenv/config";
import { Client } from "@langchain/langgraph-sdk";
import { ManagerGraphState } from "@open-swe/shared/open-swe/manager/types";
import { PlannerGraphState } from "@open-swe/shared/open-swe/planner/types";
interface TraceUrls {
managerTraceUrl: string;
plannerTraceUrl: string;
programmerTraceUrl: string;
}
/**
* Get the trace URLs for a given manager thread ID.
* @param managerThreadId The ID of the manager thread.
* @returns The trace URLs for the manager, planner, and programmer.
*/
async function getTraceUrls(managerThreadId: string): Promise<TraceUrls> {
const {
LANGGRAPH_API_URL: apiUrl,
LANGCHAIN_API_KEY: apiKey,
LANGSMITH_WORKSPACE_ID: orgId,
LANGSMITH_PROJECT_ID: projectId,
} = process.env;
const missing = [apiUrl, apiKey, orgId, projectId]
.map((val, i) =>
!val
? [
"LANGGRAPH_API_URL",
"LANGCHAIN_API_KEY",
"LANGSMITH_WORKSPACE_ID",
"LANGSMITH_PROJECT_ID",
][i]
: null,
)
.filter(Boolean);
if (missing.length) {
throw new Error(
`Missing required environment variables: ${missing.join(", ")}`,
);
}
const client = new Client({
apiUrl: apiUrl!,
apiKey: apiKey!,
defaultHeaders: {
"x-auth-scheme": "langsmith",
},
});
const constructUrl = (runId: string) =>
`https://smith.langchain.com/o/${orgId}/projects/p/${projectId}/r/${runId}`;
const [managerRuns, managerState] = await Promise.all([
client.runs.list(managerThreadId),
client.threads.getState<ManagerGraphState>(managerThreadId),
]);
const managerRunId = managerRuns?.[0]?.run_id;
if (!managerRunId) {
throw new Error("Unable to find run ID for manager thread.");
}
const result: TraceUrls = {
managerTraceUrl: constructUrl(managerRunId),
plannerTraceUrl: "",
programmerTraceUrl: "",
};
const plannerSession = managerState.values.plannerSession;
if (!plannerSession?.runId || !plannerSession?.threadId) {
return result;
}
result.plannerTraceUrl = constructUrl(plannerSession.runId);
const plannerState = await client.threads.getState<PlannerGraphState>(
plannerSession.threadId,
);
const programmerSession = plannerState.values.programmerSession;
if (programmerSession?.runId && programmerSession?.threadId) {
result.programmerTraceUrl = constructUrl(programmerSession.runId);
}
return result;
}
// Make script executable
if (import.meta.url === `file://${process.argv[1]}`) {
const managerThreadId = process.argv[2];
if (!managerThreadId) {
console.error("Usage: yarn get-trace-urls <manager-thread-id>");
process.exit(1);
}
getTraceUrls(managerThreadId)
.then((urls) => {
console.log("\n🔗 Trace URLs:");
console.log(`Manager: ${urls.managerTraceUrl}`);
console.log(`Planner: ${urls.plannerTraceUrl || "Not available"}`);
console.log(`Programmer: ${urls.programmerTraceUrl || "Not available"}`);
})
.catch((error) => {
console.error("❌ Error:", error.message);
process.exit(1);
});
}