fix(session): propagate network context
This commit is contained in:
@@ -35,12 +35,18 @@ function appendParams(url: URL, params: Record<string, unknown> = {}): void {
|
||||
}
|
||||
}
|
||||
|
||||
function withNetworkParam(params: Record<string, unknown> | undefined, network: string): Record<string, unknown> {
|
||||
if (params?.network !== undefined || params?.network_name !== undefined || params?.name !== undefined) return params ?? {};
|
||||
return { ...(params ?? {}), network };
|
||||
}
|
||||
|
||||
export async function requestJson(ctx: RuntimeContext, request: RequestOptions): Promise<[unknown, number]> {
|
||||
const { method, path, params, body, requireAuth = true, requireProject = false, requireNetworkCtx = false, requireUsernameCtx = false } = request;
|
||||
if (requireNetworkCtx) requireNetwork(ctx);
|
||||
const network = requireNetworkCtx ? requireNetwork(ctx) : null;
|
||||
if (requireUsernameCtx) requireUsername(ctx);
|
||||
const url = new URL(`/api/v1${path}`, ctx.server.replace(/\/+$/, ""));
|
||||
appendParams(url, params);
|
||||
const requestParams = network && (params !== undefined || body === undefined) ? withNetworkParam(params, network) : params;
|
||||
appendParams(url, requestParams);
|
||||
const started = performance.now();
|
||||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), ctx.timeout * 1000);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"dev": "bun --watch src/server.ts",
|
||||
"build": "bun run check",
|
||||
"check": "bun run typecheck && bun run typecheck:opencode",
|
||||
"migrate:session-identity": "bun scripts/migrate-session-identity.ts",
|
||||
"pipeline:trigger": "bash scripts/trigger-gitea-pipeline.sh",
|
||||
"start": "bun src/server.ts",
|
||||
"start:prod": "bun run check && bun src/server.ts"
|
||||
|
||||
@@ -11,6 +11,7 @@ export type AgentAuthContext = {
|
||||
role: string;
|
||||
isSuperuser: boolean;
|
||||
projectId: string;
|
||||
network: string;
|
||||
projectRole: string;
|
||||
tokenExpiresAt?: string;
|
||||
};
|
||||
@@ -22,6 +23,7 @@ type AgentAuthContextResponse = {
|
||||
role?: unknown;
|
||||
is_superuser?: unknown;
|
||||
project_id?: unknown;
|
||||
network?: unknown;
|
||||
project_role?: unknown;
|
||||
token_expires_at?: unknown;
|
||||
};
|
||||
@@ -53,6 +55,7 @@ const normalizeAgentAuthContext = (
|
||||
typeof payload.role !== "string" ||
|
||||
typeof payload.is_superuser !== "boolean" ||
|
||||
typeof payload.project_id !== "string" ||
|
||||
typeof payload.network !== "string" ||
|
||||
typeof payload.project_role !== "string"
|
||||
) {
|
||||
return null;
|
||||
@@ -65,6 +68,7 @@ const normalizeAgentAuthContext = (
|
||||
role: payload.role,
|
||||
isSuperuser: payload.is_superuser,
|
||||
projectId: payload.project_id,
|
||||
network: payload.network,
|
||||
projectRole: payload.project_role,
|
||||
tokenExpiresAt:
|
||||
typeof payload.token_expires_at === "string"
|
||||
|
||||
@@ -17,6 +17,7 @@ export type SessionBinding = {
|
||||
export type SessionContext = {
|
||||
clientSessionId: string;
|
||||
accessToken?: string;
|
||||
network?: string;
|
||||
projectId?: string;
|
||||
tokenExpiresAt?: string;
|
||||
userId?: string;
|
||||
@@ -36,6 +37,7 @@ export class ChatSessionBridge {
|
||||
async resolve(context: {
|
||||
sessionId?: string;
|
||||
accessToken?: string;
|
||||
network?: string;
|
||||
projectId?: string;
|
||||
traceId?: string;
|
||||
tokenExpiresAt?: string;
|
||||
@@ -71,6 +73,7 @@ export class ChatSessionBridge {
|
||||
allowLearningWrite: true,
|
||||
clientSessionId: requestContext.clientSessionId,
|
||||
learningMode: "interactive",
|
||||
network: requestContext.network,
|
||||
projectId: requestContext.projectId,
|
||||
projectKey: requestContext.projectKey,
|
||||
sessionId,
|
||||
@@ -144,6 +147,7 @@ export class ChatSessionBridge {
|
||||
private buildRequestContext(context: {
|
||||
sessionId?: string;
|
||||
accessToken?: string;
|
||||
network?: string;
|
||||
projectId?: string;
|
||||
traceId?: string;
|
||||
tokenExpiresAt?: string;
|
||||
@@ -154,6 +158,7 @@ export class ChatSessionBridge {
|
||||
clientSessionId: sessionId || this.createClientSessionId(),
|
||||
accessToken: context.accessToken,
|
||||
actorKey: toActorKey(context.userId),
|
||||
network: context.network,
|
||||
projectId: context.projectId,
|
||||
projectKey: toProjectKey(context.projectId),
|
||||
tokenExpiresAt: context.tokenExpiresAt,
|
||||
|
||||
@@ -525,6 +525,7 @@ export const buildChatRouter = (
|
||||
const { binding, requestContext, created } = await sessionBridge.resolve({
|
||||
sessionId: requestedSessionId,
|
||||
accessToken,
|
||||
network: authContext.network,
|
||||
projectId,
|
||||
traceId,
|
||||
tokenExpiresAt: authContext.tokenExpiresAt,
|
||||
|
||||
@@ -9,6 +9,7 @@ export type RuntimeSessionContext = {
|
||||
clientSessionId: string;
|
||||
learningMode?: "interactive" | "review";
|
||||
memoryListReadScopes?: Partial<Record<"user" | "workspace", boolean>>;
|
||||
network?: string;
|
||||
projectId?: string;
|
||||
projectKey: string;
|
||||
sessionId: string;
|
||||
|
||||
+9
-1
@@ -101,11 +101,19 @@ app.post("/internal/tools/tjwater-cli-call", async (req, res) => {
|
||||
const timeoutSec =
|
||||
typeof req.body?.timeout === "number" && req.body.timeout > 0 ? req.body.timeout : 120;
|
||||
|
||||
if (!context.network) {
|
||||
res.status(400).json({
|
||||
message: "runtime network missing; refresh chat context",
|
||||
detail: sessionId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const authJson = JSON.stringify({
|
||||
server: config.TJWATER_API_BASE_URL,
|
||||
access_token: context.accessToken,
|
||||
project_id: context.projectId,
|
||||
network:"tjwater",
|
||||
network: context.network,
|
||||
});
|
||||
|
||||
const cliArgs = ["--auth-stdin", ...command.split(/\s+/).filter(Boolean)];
|
||||
|
||||
@@ -14,6 +14,7 @@ describe("runtime session context", () => {
|
||||
allowLearningWrite: true,
|
||||
clientSessionId: "chat-session-1",
|
||||
learningMode: "interactive",
|
||||
network: "fengyang",
|
||||
projectId: "project-id-1",
|
||||
projectKey: "project-1",
|
||||
sessionId: "runtime-session-1",
|
||||
@@ -24,6 +25,7 @@ describe("runtime session context", () => {
|
||||
|
||||
expect(runtimeContext?.accessToken).toBe("token-1");
|
||||
expect(runtimeContext?.clientSessionId).toBe("chat-session-1");
|
||||
expect(runtimeContext?.network).toBe("fengyang");
|
||||
expect(runtimeContext?.sessionId).toBe("runtime-session-1");
|
||||
|
||||
removeRuntimeSessionContext("runtime-session-1");
|
||||
|
||||
Reference in New Issue
Block a user