Repository navigation
Expand file tree
/
Copy pathplugin.js
More file actions
98 lines (97 loc) · 4.12 KB
/
Copy pathplugin.js
File metadata and controls
98 lines (97 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import { ACCOUNT_MARKER, PROVIDER_ID, modelsConfig } from "./src/models.js";
import { findMuseBinary, readAccount, requireSubscription } from "./src/account.js";
import { QUOTA_INSTRUCTIONS, SESSION_HEADER } from "./src/quota-policy.js";
import { createRuntime } from "./src/runtime.js";
import { selectedProfile } from "./src/state.js";
import { createMuseTools } from "./src/tools.js";
export default async function MuseCodePlugin({ directory, client }) {
const runtime = createRuntime({ directory, notify: async (body) => { await client?.tui?.showToast({ body }); } });
const selected = async () => selectedProfile(await runtime.store.read(), directory);
const authorize = async (profile) => {
const login = await runtime.beginLogin(profile.id);
return {
url: login.url, method: "auto",
instructions: `Approve code ${login.code} in your Meta account using the browser. Do not enter your password in OpenCode.`,
async callback() { return (await runtime.awaitLogin(login.id)).granted ? { type: "success", key: ACCOUNT_MARKER } : { type: "failed" }; },
};
};
return {
tool: createMuseTools(runtime),
async config(config) {
const rows = await runtime.refreshProfile(await selected()).then((snapshot) => snapshot.models).catch(() => []);
const existing = config.provider?.[PROVIDER_ID] || {};
config.provider ||= {};
config.provider[PROVIDER_ID] = {
...existing,
name: "Muse Code (Meta subscription)",
npm: "@ai-sdk/openai",
options: { baseURL: "https://api.meta.ai/v1", timeout: false, setCacheKey: true, ...existing.options },
models: { ...modelsConfig(rows), ...existing.models },
};
},
async "chat.message"(input, output) {
if ((input.model?.providerID || output.message.model?.providerID) !== PROVIDER_ID) return;
output.message.tools = { ...output.message.tools, task: false };
},
async "chat.headers"(input, output) {
if (input.model.providerID !== PROVIDER_ID) return;
output.headers[SESSION_HEADER] = input.sessionID;
},
async "experimental.chat.system.transform"(input, output) {
if (input.model.providerID !== PROVIDER_ID) return;
output.system.push(QUOTA_INSTRUCTIONS);
},
async "experimental.provider.small_model"({ provider }, output) {
if (provider.id !== PROVIDER_ID || output.model) return;
const model = provider.models["muse-spark-1.3"] || provider.models["muse-spark-1.2"];
if (!model) return;
output.model = { ...model, options: { ...model.options, reasoningEffort: "low", reasoningSummary: "concise" } };
},
auth: {
provider: PROVIDER_ID,
async loader(getAuth) {
const auth = await getAuth();
if (auth?.type !== "api" || auth.key !== ACCOUNT_MARKER) return {};
return {
apiKey: ACCOUNT_MARKER,
fetch: runtime.fetch,
};
},
methods: [
{
type: "oauth",
label: "Meta account (subscription)",
async authorize() {
return authorize(await selected());
},
},
{
type: "oauth",
label: "Use the existing Muse Code account",
async authorize() {
await findMuseBinary();
requireSubscription(await readAccount(runtime.options(await selected())));
return {
url: "https://dev.meta.ai/docs/muse-code/auth",
method: "auto",
instructions: "Connecting the Meta account already signed in to Muse Code.",
async callback() {
requireSubscription(await readAccount(runtime.options(await selected())));
return { type: "success", key: ACCOUNT_MARKER };
},
};
},
},
{
type: "oauth",
label: "Add a Muse account (isolated profile)",
prompts: [{ type: "text", key: "label", message: "Account label", placeholder: "Personal / Work" }],
async authorize(inputs) { return authorize(await runtime.addProfile(inputs?.label)); },
},
],
},
async dispose() {
await runtime.dispose();
},
};
}