mirror of
https://gitee.com/zhangsken/opencode.git
synced 2026-10-16 10:30:01 +08:00
feat(tui): group MCP integrations in connection dialog
This commit is contained in:
@@ -2133,6 +2133,7 @@ export type SessionMessagesResponse = {
|
||||
export type IntegrationInfo = {
|
||||
id: string
|
||||
name: string
|
||||
metadata?: { [x: string]: any }
|
||||
methods: Array<IntegrationMethod>
|
||||
connections: Array<ConnectionInfo>
|
||||
}
|
||||
|
||||
@@ -361,6 +361,7 @@ const layer = Layer.effect(
|
||||
Info.make({
|
||||
id: entry.ref.id,
|
||||
name: entry.ref.name,
|
||||
...(entry.ref.metadata === undefined ? {} : { metadata: entry.ref.metadata }),
|
||||
methods: entry.methods,
|
||||
connections,
|
||||
})
|
||||
|
||||
@@ -228,6 +228,7 @@ export const layer = (options?: Options) =>
|
||||
.transform((draft) => {
|
||||
draft.update(integrationID, (ref) => {
|
||||
ref.name = name
|
||||
ref.metadata = { source: "mcp" }
|
||||
})
|
||||
draft.method.update({
|
||||
integrationID,
|
||||
|
||||
@@ -52,10 +52,21 @@ describe("Integration", () => {
|
||||
const openai = Integration.ID.make("openai")
|
||||
|
||||
yield* integrations
|
||||
.transform((editor) => editor.update(openai, (integration) => (integration.name = "OpenAI")))
|
||||
.transform((editor) =>
|
||||
editor.update(openai, (integration) => {
|
||||
integration.name = "OpenAI"
|
||||
integration.metadata = { source: "plugin", featured: true }
|
||||
}),
|
||||
)
|
||||
.pipe(Scope.provide(scope))
|
||||
expect(yield* integrations.get(openai)).toEqual(
|
||||
Integration.Info.make({ id: openai, name: "OpenAI", methods: [], connections: [] }),
|
||||
Integration.Info.make({
|
||||
id: openai,
|
||||
name: "OpenAI",
|
||||
metadata: { source: "plugin", featured: true },
|
||||
methods: [],
|
||||
connections: [],
|
||||
}),
|
||||
)
|
||||
|
||||
yield* Scope.close(scope, Exit.void)
|
||||
|
||||
@@ -59,11 +59,13 @@ export interface Ref extends Schema.Schema.Type<typeof Ref> {}
|
||||
export const Ref = Schema.Struct({
|
||||
id: ID,
|
||||
name: Schema.String,
|
||||
metadata: optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
}).annotate({ identifier: "Integration.Ref" })
|
||||
|
||||
export const Info = Schema.Struct({
|
||||
id: ID,
|
||||
name: Schema.String,
|
||||
metadata: optional(Schema.Record(Schema.String, Schema.Any)),
|
||||
methods: Schema.Array(Method),
|
||||
connections: Schema.Array(Connection.Info),
|
||||
}).annotate({ identifier: "Integration.Info" })
|
||||
|
||||
@@ -45,6 +45,7 @@ const SUBMIT = Symbol("submit")
|
||||
export function integrationOptions(list: IntegrationInfo[]) {
|
||||
return list.toSorted(
|
||||
(a, b) =>
|
||||
Number(b.metadata?.source === "mcp") - Number(a.metadata?.source === "mcp") ||
|
||||
(INTEGRATION_PRIORITY[a.id] ?? 99) - (INTEGRATION_PRIORITY[b.id] ?? 99) ||
|
||||
a.name.localeCompare(b.name) ||
|
||||
a.id.localeCompare(b.id),
|
||||
@@ -103,6 +104,7 @@ export function DialogIntegration(
|
||||
let category = "Services"
|
||||
if (integration.id in INTEGRATION_PRIORITY) category = "Popular"
|
||||
if (provider) category = "Web search"
|
||||
if (integration.metadata?.source === "mcp") category = "MCP"
|
||||
return {
|
||||
title: integration.name,
|
||||
value: integration.id,
|
||||
|
||||
@@ -24,6 +24,16 @@ describe("integrationOptions", () => {
|
||||
]).map((item) => item.id),
|
||||
).toEqual(["openai", "anthropic", "mistral", "custom-z"])
|
||||
})
|
||||
|
||||
test("keeps MCP integrations above popular integrations without relying on their IDs", () => {
|
||||
expect(
|
||||
integrationOptions([
|
||||
integration({ id: "openai", name: "OpenAI" }),
|
||||
integration({ id: "linear", name: "Linear", metadata: { source: "mcp" } }),
|
||||
integration({ id: "github", name: "GitHub", metadata: { source: "mcp" } }),
|
||||
]).map((item) => item.id),
|
||||
).toEqual(["github", "linear", "openai"])
|
||||
})
|
||||
})
|
||||
|
||||
describe("connectMethods", () => {
|
||||
|
||||
Reference in New Issue
Block a user