mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-03 05:56:26 +00:00
Reapply "refactor: move runtime state to SQLite"
This reverts commit 694ca50e97.
This commit is contained in:
@@ -4,6 +4,7 @@ import path from "node:path";
|
||||
import {
|
||||
clearRuntimeAuthProfileStoreSnapshots,
|
||||
ensureAuthProfileStore,
|
||||
saveAuthProfileStore,
|
||||
} from "openclaw/plugin-sdk/agent-runtime";
|
||||
import type {
|
||||
OpenClawConfig,
|
||||
@@ -14,7 +15,7 @@ import type {
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createTestPluginApi } from "openclaw/plugin-sdk/plugin-test-api";
|
||||
import { afterAll, afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { setGitHubCopilotDeviceFlowFetchGuardForTesting } from "./login.js";
|
||||
import { _setGitHubCopilotDeviceFlowFetchGuardForTesting } from "./login.js";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
githubCopilotLoginCommand: vi.fn(),
|
||||
@@ -64,7 +65,7 @@ type GithubCopilotTestModelCatalogProvider = {
|
||||
afterEach(async () => {
|
||||
vi.clearAllMocks();
|
||||
vi.unstubAllGlobals();
|
||||
setGitHubCopilotDeviceFlowFetchGuardForTesting(null);
|
||||
_setGitHubCopilotDeviceFlowFetchGuardForTesting(null);
|
||||
clearRuntimeAuthProfileStoreSnapshots();
|
||||
await Promise.all(tempDirs.splice(0).map((dir) => fs.rm(dir, { recursive: true, force: true })));
|
||||
});
|
||||
@@ -80,7 +81,23 @@ async function createAgentDir() {
|
||||
return dir;
|
||||
}
|
||||
|
||||
function registerProviderForTest() {
|
||||
function seedGithubCopilotTokenProfile(agentDir: string, token = "existing-token") {
|
||||
saveAuthProfileStore(
|
||||
{
|
||||
version: 1,
|
||||
profiles: {
|
||||
"github-copilot:github": {
|
||||
type: "token",
|
||||
provider: "github-copilot",
|
||||
token,
|
||||
},
|
||||
},
|
||||
},
|
||||
agentDir,
|
||||
);
|
||||
}
|
||||
|
||||
function _registerProvider() {
|
||||
return registerProviderWithPluginConfig({});
|
||||
}
|
||||
|
||||
@@ -259,19 +276,7 @@ describe("github-copilot plugin", () => {
|
||||
const provider = registerProviderWithPluginConfig({});
|
||||
const method = provider.auth[0];
|
||||
const agentDir = await createAgentDir();
|
||||
await fs.writeFile(
|
||||
path.join(agentDir, "auth-profiles.json"),
|
||||
JSON.stringify({
|
||||
version: 1,
|
||||
profiles: {
|
||||
"github-copilot:github": {
|
||||
type: "token",
|
||||
provider: "github-copilot",
|
||||
token: "existing-token",
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
seedGithubCopilotTokenProfile(agentDir);
|
||||
const prompter = {
|
||||
confirm: vi.fn(async () => false),
|
||||
note: vi.fn(),
|
||||
@@ -316,20 +321,8 @@ describe("github-copilot plugin", () => {
|
||||
const provider = registerProviderWithPluginConfig({});
|
||||
const method = provider.auth[0];
|
||||
const agentDir = await createAgentDir();
|
||||
await fs.writeFile(
|
||||
path.join(agentDir, "auth-profiles.json"),
|
||||
JSON.stringify({
|
||||
version: 1,
|
||||
profiles: {
|
||||
"github-copilot:github": {
|
||||
type: "token",
|
||||
provider: "github-copilot",
|
||||
token: "existing-token",
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
const fetchMock = vi.fn(async (input: unknown, _init?: RequestInit) => {
|
||||
seedGithubCopilotTokenProfile(agentDir);
|
||||
const fetchMock = vi.fn(async (input: unknown) => {
|
||||
const target =
|
||||
typeof input === "string"
|
||||
? input
|
||||
@@ -359,7 +352,7 @@ describe("github-copilot plugin", () => {
|
||||
throw new Error(`unexpected fetch in github-copilot refresh test: ${target}`);
|
||||
});
|
||||
vi.stubGlobal("fetch", fetchMock);
|
||||
setGitHubCopilotDeviceFlowFetchGuardForTesting(async (params) => ({
|
||||
_setGitHubCopilotDeviceFlowFetchGuardForTesting(async (params) => ({
|
||||
response: await fetchMock(params.url, params.init),
|
||||
finalUrl: params.url,
|
||||
release: async () => {},
|
||||
@@ -596,19 +589,7 @@ describe("github-copilot plugin", () => {
|
||||
const method = provider.auth[0];
|
||||
const agentDir = await createAgentDir();
|
||||
const runtime = { error: vi.fn(), exit: vi.fn() };
|
||||
await fs.writeFile(
|
||||
path.join(agentDir, "auth-profiles.json"),
|
||||
JSON.stringify({
|
||||
version: 1,
|
||||
profiles: {
|
||||
"github-copilot:github": {
|
||||
type: "token",
|
||||
provider: "github-copilot",
|
||||
token: "existing-token",
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
seedGithubCopilotTokenProfile(agentDir);
|
||||
|
||||
const result = await method.runNonInteractive({
|
||||
authChoice: "github-copilot",
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { createProviderUsageFetch, makeResponse } from "openclaw/plugin-sdk/test-env";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { buildCopilotModelDefinition, getDefaultCopilotModelIds } from "./models-defaults.js";
|
||||
import { deriveCopilotApiBaseUrlFromToken, resolveCopilotApiToken } from "./token.js";
|
||||
import { fetchCopilotUsage } from "./usage.js";
|
||||
@@ -13,16 +16,6 @@ vi.mock("openclaw/plugin-sdk/provider-model-shared", () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
const jsonStoreMocks = vi.hoisted(() => ({
|
||||
loadJsonFile: vi.fn(),
|
||||
saveJsonFile: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("openclaw/plugin-sdk/json-store", () => ({
|
||||
loadJsonFile: jsonStoreMocks.loadJsonFile,
|
||||
saveJsonFile: jsonStoreMocks.saveJsonFile,
|
||||
}));
|
||||
|
||||
vi.mock("openclaw/plugin-sdk/state-paths", () => ({
|
||||
resolveStateDir: () => "/tmp/openclaw-state",
|
||||
}));
|
||||
@@ -324,12 +317,12 @@ describe("fetchCopilotUsage", () => {
|
||||
});
|
||||
|
||||
describe("github-copilot token", () => {
|
||||
const cachePath = "/tmp/openclaw-state/credentials/github-copilot.token.json";
|
||||
|
||||
beforeEach(() => {
|
||||
jsonStoreMocks.loadJsonFile.mockClear();
|
||||
jsonStoreMocks.saveJsonFile.mockClear();
|
||||
});
|
||||
function makeCopilotEnv(): NodeJS.ProcessEnv {
|
||||
return {
|
||||
...process.env,
|
||||
OPENCLAW_STATE_DIR: fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-copilot-token-")),
|
||||
};
|
||||
}
|
||||
|
||||
it("derives baseUrl from token", () => {
|
||||
expect(deriveCopilotApiBaseUrlFromToken("token;proxy-ep=proxy.example.com;")).toBe(
|
||||
@@ -341,32 +334,35 @@ describe("github-copilot token", () => {
|
||||
});
|
||||
|
||||
it("uses cache when token is still valid", async () => {
|
||||
const now = Date.now();
|
||||
jsonStoreMocks.loadJsonFile.mockReturnValue({
|
||||
token: "cached;proxy-ep=proxy.example.com;",
|
||||
expiresAt: now + 60 * 60 * 1000,
|
||||
updatedAt: now,
|
||||
integrationId: "vscode-chat",
|
||||
const env = makeCopilotEnv();
|
||||
const fetchImpl = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
status: 200,
|
||||
json: async () => ({
|
||||
token: "cached;proxy-ep=proxy.example.com;",
|
||||
expires_at: Math.floor(Date.now() / 1000) + 3600,
|
||||
}),
|
||||
});
|
||||
|
||||
const fetchImpl = vi.fn();
|
||||
const res = await resolveCopilotApiToken({
|
||||
const first = await resolveCopilotApiToken({
|
||||
githubToken: "gh",
|
||||
cachePath,
|
||||
loadJsonFileImpl: jsonStoreMocks.loadJsonFile,
|
||||
saveJsonFileImpl: jsonStoreMocks.saveJsonFile,
|
||||
env,
|
||||
fetchImpl: fetchImpl as unknown as typeof fetch,
|
||||
});
|
||||
const second = await resolveCopilotApiToken({
|
||||
githubToken: "gh",
|
||||
env,
|
||||
fetchImpl: fetchImpl as unknown as typeof fetch,
|
||||
});
|
||||
|
||||
expect(res.token).toBe("cached;proxy-ep=proxy.example.com;");
|
||||
expect(res.baseUrl).toBe("https://api.example.com");
|
||||
expect(res.source).toContain("cache:");
|
||||
expect(fetchImpl).not.toHaveBeenCalled();
|
||||
expect(fetchImpl).toHaveBeenCalledTimes(1);
|
||||
expect(first.source).toContain("fetched:");
|
||||
expect(second.token).toBe("cached;proxy-ep=proxy.example.com;");
|
||||
expect(second.baseUrl).toBe("https://api.example.com");
|
||||
expect(second.source).toContain("cache:sqlite:");
|
||||
});
|
||||
|
||||
it("fetches and stores token when cache is missing", async () => {
|
||||
jsonStoreMocks.loadJsonFile.mockReturnValue(undefined);
|
||||
|
||||
const env = makeCopilotEnv();
|
||||
const fetchImpl = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
status: 200,
|
||||
@@ -378,19 +374,13 @@ describe("github-copilot token", () => {
|
||||
|
||||
const res = await resolveCopilotApiToken({
|
||||
githubToken: "gh",
|
||||
cachePath,
|
||||
loadJsonFileImpl: jsonStoreMocks.loadJsonFile,
|
||||
saveJsonFileImpl: jsonStoreMocks.saveJsonFile,
|
||||
env,
|
||||
fetchImpl: fetchImpl as unknown as typeof fetch,
|
||||
});
|
||||
|
||||
expect(res.token).toBe("fresh;proxy-ep=https://proxy.contoso.test;");
|
||||
expect(res.baseUrl).toBe("https://api.contoso.test");
|
||||
const [, calledInit] = fetchImpl.mock.calls[0] ?? [];
|
||||
expect(((calledInit as RequestInit).headers as Record<string, string>)["Accept-Encoding"]).toBe(
|
||||
"identity",
|
||||
);
|
||||
expect(jsonStoreMocks.saveJsonFile).toHaveBeenCalledTimes(1);
|
||||
expect(fetchImpl).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -515,9 +505,6 @@ describe("fetchCopilotModelCatalog", () => {
|
||||
expect(((calledInit as RequestInit).headers as Record<string, string>).Authorization).toBe(
|
||||
"Bearer tid=test",
|
||||
);
|
||||
expect(((calledInit as RequestInit).headers as Record<string, string>)["Accept-Encoding"]).toBe(
|
||||
"identity",
|
||||
);
|
||||
|
||||
expect(out.map((m) => m.id)).toEqual([
|
||||
"gpt-5.5",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { StreamFn } from "openclaw/plugin-sdk/agent-core";
|
||||
import type { Context } from "openclaw/plugin-sdk/llm";
|
||||
import type { ProviderWrapStreamFnContext } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import type { Context } from "openclaw/plugin-sdk/provider-ai";
|
||||
import { buildCopilotIdeHeaders, COPILOT_INTEGRATION_ID } from "openclaw/plugin-sdk/provider-auth";
|
||||
import {
|
||||
applyAnthropicEphemeralCacheControlMarkers,
|
||||
|
||||
Reference in New Issue
Block a user