目录

Continue

VS Code Extension

通过配置创建新的 Extension,用于区别于 Continue 。

{
  "name": "continue",
  "icon": "media/icon.png",
  "version": "0.9.218",
  "displayName": "LNSoft Continue",
  "description": "The leading open-source AI code assistant",
  "publisher": "LNSoft Continue"
}

入口

VS Code 扩展的起点是 activate.tsactivateExtension 这里的函数将注册所有命令,并将 Continue GUI 作为 webview 加载到 IDE 的侧边栏中。

配置

目录:extensions/vscode

package.json

package.json 由开发者手动创建和维护,主要用于定义项目的配置信息。

  • configuration
  • commands
  • keybindings
  • menus
  • views

package-lock.json

package-lock.json 由 npm 自动生成和更新,主要用于锁定依赖的具体版本,确保安装一致性。

国际化

可以通过使用 package.nls.json 文件来支持多语言。package.nls.json 文件包含了所有需要本地化的字符串,并且可以为不同的语言创建相应的翻译文件,如 package.nls.zh-cn.json

  • 步骤
    • 在 package.json 中使用占位符: 在 package.json 文件中,用占位符(%占位符%)替换需要本地化的字符串。
    • 创建 package.nls.json 文件: 在扩展的根目录下创建 package.nls.json 文件,定义占位符和默认语言的映射。默认语言(通常是英文)的字符串。
    • 创建语言特定的翻译文件: 为每种语言创建一个翻译文件(package.nls.<language>.json),如 package.nls.zh-cn.json,并提供相应的翻译。

package.json

{
  "name": "continue",
  "icon": "media/icon.png",
  "version": "0.9.191",
  "contributes": {
    "commands": [
      {
        "command": "continue.focusContinueInputWithoutClear",
        "category": "Continue",
        "title": "%focusContinueInputWithoutClear%",
        "group": "Continue"
      },
      {
        "command": "continue.toggleFullScreen",
        "category": "Continue",
        "title": "%toggleFullScreen%",
        "icon": "$(fullscreen)",
        "group": "Continue"
      },
      {
        "command": "continue.newSession",
        "category": "Continue",
        "title": "%newSession%",
        "icon": "$(add)",
        "group": "Continue"
      },
      {
        "command": "continue.viewHistory",
        "category": "Continue",
        "title": "%viewHistory%",
        "icon": "$(history)",
        "group": "Continue"
      },
      {
        "command": "continue.writeCommentsForCode",
        "category": "Continue",
        "title": "%writeCommentsForCode%",
        "group": "Continue"
      },
      {
        "command": "continue.writeDocstringForCode",
        "category": "Continue",
        "title": "%writeDocstringForCode%",
        "group": "Continue"
      },
      {
        "command": "continue.fixCode",
        "category": "Continue",
        "title": "%fixCode%",
        "group": "Continue"
      },
      {
        "command": "continue.optimizeCode",
        "category": "Continue",
        "title": "%optimizeCode%",
        "group": "Continue"
      }
    ]
}

package.nls.json

{
  "newSession": "New Session",
  "toggleFullScreen": "Toggle Full Screen",
  "viewHistory": "View History",
  "fixCode": "Fix this Code",
  "optimizeCode": "Optimize this Code",
  "writeDocstringForCode": "Write a Docstring for this Code",
  "writeCommentsForCode": "Write Comments for this Code",
  "focusContinueInputWithoutClear": "Add Highlighted Code to Context"
}

package.nls.zh-cn.json

{
  "newSession": "新会话",
  "toggleFullScreen": "切换全屏",
  "viewHistory": "查看历史记录",
  "fixCode": "修复代码",
  "optimizeCode": "优化代码",
  "writeDocstringForCode": "为此代码编写文档字符串",
  "writeCommentsForCode": "为此代码编写注释",
  "focusContinueInputWithoutClear": "将高亮显示的代码添加到上下文"
}

GUI

主界面

左边是主界面,不同的元素使用不同的颜色区分;右边是主界面中元素对应的组件或配置(颜色一致),通过 缩进 方式表示他们之间的包含关系。

路由

路径 组件
/ GUI
/index.html GUI
/history History
/stats Stats
/help Help
/help HelpPage
/settings SettingsPage
/addModel AddNewModel
/addModel/provider/:providerName ConfigureProvider
/monaco MonacoPage
/onboarding Onboarding
/localOnboarding LocalOnboarding
/migration MigrationPage
/apiKeysOnboarding ApiKeysOnboarding
/apiKeyAutocompleteOnboarding ApiKeyAutocompleteOnboarding

标题 & 图标

extensions/vscode/package.json

{
  "contributes": {
    "viewsContainers": {
      "activitybar": [
        {
          "id": "continue",
          "title": "Continue",
          "icon": "media/sidebar-icon.png"
        }
      ]
    },
    "views": {
      "continue": [
        {
          "type": "webview",
          "id": "continue.continueGUIView",
          "name": "",
          "visibility": "visible"
        }
      ]
    }
  }
}

在 Visual Studio Code 扩展中,viewsContainers 配置用于在活动栏(Activity Bar)中添加自定义视图容器。

菜单

通过编辑配置文件 package.json

WebView View/Title

{
  "contributes": {
    "menus": {
      "view/title": [
        {
          "command": "continue.newSession",
          "group": "navigation@1",
          "when": "view == continue.continueGUIView"
        },
        {
          "command": "continue.toggleFullScreen",
          "group": "navigation@1",
          "when": "view == continue.continueGUIView"
        },
        {
          "command": "continue.viewHistory",
          "group": "navigation@1",
          "when": "view == continue.continueGUIView"
        }
      ]
    }
  }
}

上下文菜单

{
  "contributes": {
    "menus": {
      "continue.continueSubMenu": [
        {
          "command": "continue.focusContinueInputWithoutClear",
          "group": "Continue",
          "when": "editorHasSelection"
        },
        {
          "command": "continue.writeCommentsForCode",
          "group": "Continue",
          "when": "editorHasSelection"
        },
        {
          "command": "continue.writeDocstringForCode",
          "group": "Continue",
          "when": "editorHasSelection"
        },
        {
          "command": "continue.fixCode",
          "group": "Continue",
          "when": "editorHasSelection"
        },
        {
          "command": "continue.optimizeCode",
          "group": "Continue",
          "when": "editorHasSelection"
        },
        {
          "command": "continue.fixGrammar",
          "group": "Continue",
          "when": "editorHasSelection && editorLangId == 'markdown'"
        }
      ]
    }
  }
}

Tab AutoComplete

getTabCompletion core/autocomplete/completionProvider.ts

使用 Ollama 设置

~/.continue/config.json 文件中配置。

{
  "tabAutocompleteModel": {
    "title": "Tab Autocomplete",
    "provider": "ollama",
    "model": "codeqwen:7b",
    "apiKey": ""
  }
}

Tab AutoComplete 选项

默认 Tab AutoComplete 选项配置在代码:core/util/parameters.ts

{
  "tabAutocompleteOptions": {
    "multilineCompletions": "auto",
    "maxPromptTokens": 400
  }
}
  • multilineCompletions 控制是否提供多行代码的自动补全
    • "always": 默认。总是在多行代码上提供自动补全
    • "never": 从不在多行代码上提供自动补全
    • "auto": 根据代码上下文自动决定是否提供多行代码的自动补全
  • maxPromptTokens 要使用的提示 Token 的最大数量。数字越小,完成速度越快,但上下文越少。

使用什么样的模型

建议用于自动完成的模型是使用高度特定的提示格式进行训练的,这使它们能够响应完成代码的请求。出色的自动完成不需要庞大的模型。大多数最先进的自动完成模型的参数不超过 10B,超过这个数字并不能显着提高性能。

模型 大小
deepseek-coder:1.3b-base 1.3B
starcoder2:3b 3B
deepseek-coder:6.7b-base 6.7B
codeqwen:7b 7B
deepseek-coder-v2:16b 16B
codestral:22b 22B

支持编程语言

您需要支持编程语言,可以通过编辑代码:core/autocomplete/languages.ts

// TypeScript
export const Typescript = {
  name: "TypeScript",
  topLevelKeywords: ["function", "class", "module", "export", "import"],
  singleLineComment: "//",
  endOfLine: [";"],
};

// Python
export const Python = {
  name: "Python",
  // """"#" is for .ipynb files, where we add '"""' surrounding markdown blocks.
  // This stops the model from trying to complete the start of a new markdown block
  topLevelKeywords: ["def", "class", '"""#'],
  singleLineComment: "#",
  endOfLine: [],
};

// ...

export const LANGUAGES: { [extension: string]: AutocompleteLanguageInfo } = {
  ts: Typescript,
  js: Typescript,
  tsx: Typescript,
  jsx: Typescript,
  ipynb: Python,
  py: Python,
  pyi: Python,
  java: Java,
  cpp: Cpp,
  cxx: Cpp,
  h: Cpp,
  hpp: Cpp,
  cs: CSharp,
  c: C,
  scala: Scala,
  sc: Scala,
  go: Go,
  rs: Rust,
  hs: Haskell,
  php: PHP,
  rb: Ruby,
  rails: RubyOnRails,
  swift: Swift,
  kt: Kotlin,
  clj: Clojure,
  cljs: Clojure,
  cljc: Clojure,
  jl: Julia,
  fs: FSharp,
  fsi: FSharp,
  fsx: FSharp,
  fsscript: FSharp,
  r: R,
  R: R,
  dart: Dart,
  sol: Solidity,
  yaml: YAML,
  yml: YAML,
  md: Markdown,
};

Embedding Model

在配置文件 ~/.continue/config.json 中配置 transformers.js 模型,并不能生效,目前没有指定模型的功能。

{
  "embeddingsProvider": {
    "provider": "transformers.js",
    "model": "bge-small-zh-v1.5"  // 无效
  },
}

可以通过文件 core/indexing/embeddings/TransformersJsEmbeddingsProvider.ts 修改来指定中文模型 bge-small-zh-v1.5

  static model: string = "bge-small-zh-v1.5";

两处都要修改

transformers.js 支持的模型

Slash Command

Slash 命令接口,定义在 core/index.d.ts 中,需要您定义一个 name(用于调用命令的文本),一个 description(在 slash 命令菜单中显示的文本)和一个在调用命令时将被调用的 run 函数。run 函数是一个异步生成器,它产生要在聊天中显示的内容。run 函数传递了一个 ContinueSDK 对象,可以用它与 IDE 交互,调用 LLM,并查看聊天历史,以及其他一些实用程序。

export interface SlashCommand {
  name: string;
  description: string;
  params?: { [key: string]: any };
  run: (sdk: ContinueSDK) => AsyncGenerator<string | undefined>;
}

core/commands/slash 中有许多示例的斜杠命令,我们建议从中借鉴。一旦您在此文件夹中创建了新的 SlashCommand,请确保完成以下操作:

  • 将您的命令添加到 core/commands/slash/index.ts 中的数组中
  • 将您的命令添加到 config_schema.json 中的列表中。这样可以确保智能感知在用户编辑 config.json 时显示您的提供程序可用的命令。如果您的命令接受任何参数,您还应该按照现有示例将它们添加到 JSON 模式中。

编写内建 Slash Command:翻译中文(/tr)

增加文件 core/commands/slash/translate.ts,并在其中添加以下内容:

import { SlashCommand } from "../../index.js";
import { stripImages } from "../../llm/countTokens.js";

const TranslateChineseCommand: SlashCommand = {
  name: "tr",
  description: "Translate to Chinese",
  run: async function* ({ ide, llm, input }) {
    if (input.trim() === "") {
      yield "Please enter the text you want to translate into Chinese.";
      return;
    }

    // input = '/tr hello world' => 'hello world'
    input = input.replace("/tr", "").trim();

    const prompt = `The text the user wants to translate is:

"${input}"

Please translate into Chinese. Your output should contain only the corresponding Chinese, without any explanation or other output.`;

    for await (const chunk of llm.streamChat([
      { role: "user", content: prompt },
    ])) {
      yield stripImages(chunk.content);
    }
  },
};

export default TranslateChineseCommand;

修改文件 core/commands/slash/index.ts,并在其中添加以下内容:

//...
import TranslateChineseCommand from "./translate.js";

export default [
  //...
  TranslateChineseCommand,
];

LLM Providers

Adding an LLM Provider

Continue 支持十几种不同的 LLM “providers”,使得在 OpenAI、Ollama、Together、LM Studio、Msty 等平台上运行模型变得容易。你可以在这里找到所有现有的 providers,如果你发现缺少某个 provider,可以按照以下步骤添加:

  1. 在 core/llm/llms 目录中创建一个新文件。文件名应为 provider 的名称,并且应导出一个扩展自 BaseLLM 的类。这个类应包含以下最小实现。我们建议查看现有的 providers 以获取更多详细信息。LlamaCpp Provider 是一个很好的简单示例。
    • providerName - 你的 provider 的标识符
    • 至少一个 _streamComplete 或 _streamChat - 这是向 API 发出请求并返回流响应的函数。你只需要实现其中一个,因为 Continue 可以在 “chat” 和 “raw completion” 之间自动转换。
  2. 将你的 provider 添加到 core/llm/llms/index.ts 中的 LLMs 数组中。
  3. 如果你的 provider 支持图像,将其添加到 core/llm/index.ts 中的 PROVIDER_SUPPORTS_IMAGES 数组中。
  4. 将必要的 JSON Schema 类型添加到 config_schema.json 中。这确保了当用户编辑 config.json 时,Intellisense 会显示你的 provider 可用的选项。
  5. 在 docs/docs/reference/Model Providers 中为你的 provider 添加一个文档页面。这应该展示在 config.json 中配置你的 provider 的示例,并解释可用的选项。

Context Providers

ContextProvider 是一个 Continue 插件,可以通过输入 @ 来快速选择文档作为语言模型的上下文。 IContextProvider 接口在 core/index.d.ts 中定义,但所有内置上下文提供程序都扩展于 BaseContextProvider

export interface IContextProvider {
  get description(): ContextProviderDescription;

  getContextItems(
    query: string,
    extras: ContextProviderExtras,
  ): Promise<ContextItem[]>;

  loadSubmenuItems(args: LoadSubmenuItemsArgs): Promise<ContextSubmenuItem[]>;
}
export abstract class BaseContextProvider implements IContextProvider {
  options: { [key: string]: any };

  constructor(options: { [key: string]: any }) {
    this.options = options;
  }

  static description: ContextProviderDescription;

  get description(): ContextProviderDescription {
    return (this.constructor as any).description;
  }

  // Maybe just include the chat message in here. Should never have to go back to the context provider once you have the information.
  abstract getContextItems(
    query: string,
    extras: ContextProviderExtras,
  ): Promise<ContextItem[]>;

  async loadSubmenuItems(
    args: LoadSubmenuItemsArgs,
  ): Promise<ContextSubmenuItem[]> {
    return [];
  }
}

在定义上下文提供程序之前,请确定要创建哪种 "type"

编写您的上下文提供程序,请确保完成以下操作:

Prompt files

Prompt (.prompt) 文件是构建和与他人共享 LLM 提示的简单方法。该格式的灵感来自 HumanLoops 的 .prompt 文件。保存在目录 extensions/vscode/.prompts 里。

语法

Preamble

--- 分隔符上方的所有内容,可让您指定模型参数。它使用 YAML 语法,目前支持以下参数:

  • temperature
  • topP
  • topK
  • minP
  • presencePenalty
  • frequencyPenalty
  • mirostat
  • stop
  • maxTokens
  • name
  • description

如果不需要任何这些参数,则可以省略 “Preamble”,并且不需要包含 --- 分隔符。

Body

--- 分隔符下方的所有内容,包含您的提示。正文可以只是文本。

要添加系统消息,以 <system></system> 标签开始正文,并将系统消息放入其中。

Body 支持使用 Handlebars 语法 进行模板化。当前可用的变量如下:

  • input:侧边栏输入框中的全文,与斜杠命令一起发送
  • currentFile:IDE 中当前打开的文件(目前只支持打开一个文件时有用)
Context providers

.prompt 文件的 Body 还支持您通过引用上下文提供程序的名称添加到配置中的 Context providers

如果您想要使用 url 上下文提供程序来包含 https://github.com/continuedev/continue 的内容,您将使用},其中第二部分是上下文提供程序的参数,用空格分隔。

文本生成 SQL 语句

n2sql.prompt 文件

temperature: 0.5
maxTokens: 1024
name: n2sql
description: 文本生成 SQL 语句
---
<system>
你是一名数据库专家。根据以下表结构帮助用户编写 SQL 语句。
CREATE TABLE yxdsj_wshbb_gdfw_day(
  prov_name varchar(200) DEFAULT NULL COMMENT '省公司名称',
  city_name varchar(200) DEFAULT NULL COMMENT '地市公司名称',
  county_name varchar(200) DEFAULT NULL COMMENT '区县公司名称',
  tousu int(11) DEFAULT NULL COMMENT '投诉数量',
  yijian int(11) DEFAULT NULL COMMENT '意见数量',
  acpt_time varchar(200) DEFAULT NULL COMMENT '受理时间',
  tousu_bwhl  varchar(200) DEFAULT NULL COMMENT '投诉百万户量',
  yijian_bwhl  varchar(200) DEFAULT NULL COMMENT '意见百万户量'
)
</system>

}

根据上面的输入生成 SQL 语句

起名字

name.prompt 文件

temperature: 0.5
maxTokens: 256
name: name
description: 起名字
---
<system>
你是一名起名字的专家
</system>

}

根据上面的输入起名字
- 起一个有意义的名字
- 提示至少三个名字
- 名字应该有创意

总结网页内容

url.prompt 文件

temperature: 0.5
maxTokens: 4096
name: url
description: 总结网页信息
---
<system>
你是一名专业的文学家,你需要总结网页的信息。
</system>

}

总结:

Quick Actions

快速操作使用 CodeLens 提供程序在代码中的函数上方添加交互元素。代码参考:extensions/vscode/src/lang-server/codeLens/providers/QuickActionsCodeLensProvider.ts

启用/禁用快速操作

要禁用快速操作,请打开设置菜单 (⌘ + ,),搜索"continue.enableQuickActions",然后切换复选框以禁用。

自定义快速操作

通过 ~/.continue/config.json 文件配置自定义快速操作。

单元测试

在选定的代码上方生成并插入单元测试的快速操作。

{
  "experimental": {
    "quickActions": [
      {
        "title": "Unit test",
        "prompt": "Write a unit test for this code. Do not change anything about the code itself.",
      }
    ]
  }
}

详细解释

将提示和代码发送到聊天面板,以提供详细解释。

{
  "experimental": {
    "quickActions": [
      {
        "title": "Detailed explanation",
        "prompt": "Explain the following code in detail, including all methods and properties.",
        "sendToChat": true
      }
    ]
  }
}

编程语言支持

对于您打开的文件的语言,您必须安装语言服务器协议(Language Server Protocol)扩展。

语言 扩展
JavaScript JavaScript and TypeScript Nightly
TypeScript JavaScript and TypeScript Nightly
Python Python
Java Language Support for Java(TM) by Red Hat
C/C++ C/C++
Rust rust-analyzer

参考资料