@docyrus/docyrus 0.0.64 → 0.0.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import type { ExtensionAPI, ExtensionContext, ToolInfo } from "@mariozechner/pi-coding-agent";
2
2
  import type { McpExtensionState } from "./state.js";
3
- import { Type } from "@sinclair/typebox";
3
+ import { Type } from "typebox";
4
4
  import { showStatus, showTools, reconnectServers, authenticateServer, openMcpPanel } from "./commands.js";
5
5
  import { loadMcpConfig } from "./config.js";
6
6
  import { buildProxyDescription, createDirectToolExecutor, resolveDirectTools } from "./direct-tools.js";
@@ -65,7 +65,7 @@
65
65
  "dependencies": {
66
66
  "@modelcontextprotocol/ext-apps": "^1.2.2",
67
67
  "@modelcontextprotocol/sdk": "^1.25.1",
68
- "@sinclair/typebox": "^0.32.0",
68
+ "typebox": "^1.1.24",
69
69
  "zod": "^3.25.0 || ^4.0.0"
70
70
  },
71
71
  "devDependencies": {
@@ -1,5 +1,9 @@
1
- import type { ExtensionAPI, ExtensionContext, ModelSelectEvent, ThinkingLevel } from "@mariozechner/pi-coding-agent";
1
+ import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
2
2
  import { CustomEditor, ModelSelectorComponent, SettingsManager } from "@mariozechner/pi-coding-agent";
3
+
4
+ // Mirrors @mariozechner/pi-agent-core's ThinkingLevel (including "off"), defined locally so this
5
+ // extension can be loaded by pi without pulling an additional direct dep. Keep in sync with pi-agent-core.
6
+ type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
3
7
  import path from "node:path";
4
8
  import os from "node:os";
5
9
  import fs from "node:fs/promises";
@@ -1148,13 +1152,28 @@ function setEditor(pi: ExtensionAPI, ctx: ExtensionContext, history: PromptEntry
1148
1152
  requestEditorRender = () => editor.requestRenderNow();
1149
1153
  editor.modeLabelProvider = () => runtime.currentMode;
1150
1154
  // Keep the mode label color stable (match footer/status bar).
1151
- editor.modeLabelColor = (text: string) => ctx.ui.theme.fg("dim", text);
1155
+ // ctx can go stale after session replacement or reload; swallow the stale
1156
+ // assertion in the render-path callbacks so the last TUI frame doesn't crash.
1157
+ editor.modeLabelColor = (text: string) => {
1158
+ try {
1159
+ return ctx.ui.theme.fg("dim", text);
1160
+ } catch {
1161
+ return text;
1162
+ }
1163
+ };
1152
1164
  const borderColor = (text: string) => {
1153
- const isBashMode = editor.getText().trimStart().startsWith("!");
1154
- if (isBashMode) {
1155
- return ctx.ui.theme.getBashModeBorderColor()(text);
1165
+ // ctx can go stale after session replacement or reload; a final TUI render
1166
+ // can still fire from timers and calls into ctx.ui.* throw. Fall back to
1167
+ // the raw text instead of crashing the editor on the way out.
1168
+ try {
1169
+ const isBashMode = editor.getText().trimStart().startsWith("!");
1170
+ if (isBashMode) {
1171
+ return ctx.ui.theme.getBashModeBorderColor()(text);
1172
+ }
1173
+ return getModeBorderColor(ctx, pi, runtime.currentMode)(text);
1174
+ } catch {
1175
+ return text;
1156
1176
  }
1157
- return getModeBorderColor(ctx, pi, runtime.currentMode)(text);
1158
1177
  };
1159
1178
 
1160
1179
  editor.borderColor = borderColor;
@@ -1267,7 +1286,7 @@ export default function(pi: ExtensionAPI) {
1267
1286
  applyEditor(pi, ctx);
1268
1287
  });
1269
1288
 
1270
- pi.on("model_select", async(event: ModelSelectEvent, ctx) => {
1289
+ pi.on("model_select", async(event, ctx) => {
1271
1290
  // Always track the last observed model for overlay/store correctness.
1272
1291
  lastObservedModel = { provider: event.model.provider, modelId: event.model.id };
1273
1292
 
@@ -31,7 +31,7 @@
31
31
  */
32
32
  import { DynamicBorder, copyToClipboard, getMarkdownTheme, keyHint, type ExtensionAPI, type ExtensionContext, type Theme } from "@mariozechner/pi-coding-agent";
33
33
  import { StringEnum } from "@mariozechner/pi-ai";
34
- import { Type } from "@sinclair/typebox";
34
+ import { Type } from "typebox";
35
35
  import path from "node:path";
36
36
  import fs from "node:fs/promises";
37
37
  import { existsSync, readFileSync, readdirSync } from "node:fs";
package/server-loader.js CHANGED
@@ -18792,6 +18792,14 @@ var AUTH_DIR_PATH = (0, import_node_path3.join)((0, import_node_os.homedir)(), D
18792
18792
  var AUTH_FILE_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "auth.json");
18793
18793
  var CONFIG_FILE_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "config.json");
18794
18794
  var TENANT_OPENAPI_ROOT_PATH = (0, import_node_path3.join)(AUTH_DIR_PATH, "tenans");
18795
+ var DOCYRUS_PI_AGENT_GLOBAL_ROOT_PATH = (0, import_node_path3.join)(
18796
+ AUTH_DIR_PATH,
18797
+ DOCYRUS_PI_DIR_NAME,
18798
+ DOCYRUS_PI_AGENT_DIR_NAME
18799
+ );
18800
+ function getDocyrusPiAgentGlobalRootPath() {
18801
+ return DOCYRUS_PI_AGENT_GLOBAL_ROOT_PATH;
18802
+ }
18795
18803
  var DEFAULT_ENVIRONMENT_ID = "live";
18796
18804
  var DEFAULT_ENVIRONMENTS = [
18797
18805
  {
@@ -18815,9 +18823,6 @@ var DEFAULT_ENVIRONMENTS = [
18815
18823
  apiBaseUrl: "https://localhost:3366"
18816
18824
  }
18817
18825
  ];
18818
- function resolveDocyrusPiAgentRootPath(settingsRootPath) {
18819
- return (0, import_node_path3.join)(settingsRootPath, DOCYRUS_PI_DIR_NAME, DOCYRUS_PI_AGENT_DIR_NAME);
18820
- }
18821
18826
  function normalizeApiBaseUrl(apiBaseUrl) {
18822
18827
  const trimmed = apiBaseUrl.trim();
18823
18828
  if (!trimmed) {
@@ -41021,6 +41026,61 @@ function createCustomOpenAiProviderConfig(params) {
41021
41026
  ]
41022
41027
  };
41023
41028
  }
41029
+ var DEEPSEEK_BASE_URL = "https://api.deepseek.com";
41030
+ var DEEPSEEK_MODELS = [
41031
+ {
41032
+ id: "deepseek-v4-flash",
41033
+ name: "DeepSeek V4 Flash",
41034
+ cost: {
41035
+ input: 0.14,
41036
+ output: 0.28,
41037
+ cacheRead: 0.028,
41038
+ cacheWrite: 0
41039
+ }
41040
+ },
41041
+ {
41042
+ id: "deepseek-v4-pro",
41043
+ name: "DeepSeek V4 Pro",
41044
+ cost: {
41045
+ input: 1.74,
41046
+ output: 3.48,
41047
+ cacheRead: 0.145,
41048
+ cacheWrite: 0
41049
+ }
41050
+ }
41051
+ ];
41052
+ function createDeepseekProviderConfig() {
41053
+ return {
41054
+ baseUrl: DEEPSEEK_BASE_URL,
41055
+ apiKey: "env:DEEPSEEK_API_KEY",
41056
+ api: "openai-completions",
41057
+ models: DEEPSEEK_MODELS.map((model) => ({
41058
+ id: model.id,
41059
+ name: model.name,
41060
+ reasoning: true,
41061
+ input: ["text"],
41062
+ contextWindow: 1e6,
41063
+ maxTokens: 384e3,
41064
+ cost: {
41065
+ input: model.cost.input,
41066
+ output: model.cost.output,
41067
+ cacheRead: model.cost.cacheRead,
41068
+ cacheWrite: model.cost.cacheWrite
41069
+ },
41070
+ compat: {
41071
+ thinkingFormat: "deepseek",
41072
+ requiresReasoningContentOnAssistantMessages: true,
41073
+ reasoningEffortMap: {
41074
+ minimal: "high",
41075
+ low: "high",
41076
+ medium: "high",
41077
+ high: "high",
41078
+ xhigh: "max"
41079
+ }
41080
+ }
41081
+ }))
41082
+ };
41083
+ }
41024
41084
  function createAzureProviderConfig(params) {
41025
41085
  const providerConfig = {
41026
41086
  baseUrl: params.baseUrl,
@@ -41112,7 +41172,7 @@ async function resolveKnowledgeProviderFromAgentRuntime(params) {
41112
41172
  }
41113
41173
  };
41114
41174
  }
41115
- const agentRootPath = resolveDocyrusPiAgentRootPath(params.settingsRootPath);
41175
+ const agentRootPath = params.piAgentRootPath ?? getDocyrusPiAgentGlobalRootPath();
41116
41176
  const authState = readJsonFile((0, import_node_path12.join)(agentRootPath, "auth.json")) || {};
41117
41177
  const envStore = new AgentEnvStore((0, import_node_path12.join)(agentRootPath, "env.json"));
41118
41178
  const envState = await envStore.readState();
@@ -42709,6 +42769,20 @@ async function saveCustomOpenAiConfig(params) {
42709
42769
  }));
42710
42770
  params.settingsManager.setDefaultModelAndProvider("custom-openai", params.modelId.trim());
42711
42771
  }
42772
+ async function saveDeepseekConfig(params) {
42773
+ const apiKey = params.apiKey.trim();
42774
+ const modelId = params.modelId?.trim() || DEEPSEEK_MODELS[0].id;
42775
+ params.authStorage.set("deepseek", {
42776
+ type: "api_key",
42777
+ key: apiKey
42778
+ });
42779
+ await params.envStore.removeMany(["DEEPSEEK_API_KEY"]);
42780
+ await params.envStore.setMany({
42781
+ DEEPSEEK_API_KEY: apiKey
42782
+ });
42783
+ await upsertModelsProvider(params.modelsJsonPath, "deepseek", createDeepseekProviderConfig());
42784
+ params.settingsManager.setDefaultModelAndProvider("deepseek", modelId);
42785
+ }
42712
42786
  async function saveAzureConfig(params) {
42713
42787
  const modelId = params.modelId.trim();
42714
42788
  const useCustomModel = params.useCustomModel ?? false;
@@ -42786,6 +42860,12 @@ async function clearProviderConfig(params) {
42786
42860
  ]);
42787
42861
  await removeModelsProvider(params.modelsJsonPath, "custom-openai");
42788
42862
  }
42863
+ if (params.providerId === "deepseek") {
42864
+ await params.envStore.removeMany([
42865
+ "DEEPSEEK_API_KEY"
42866
+ ]);
42867
+ await removeModelsProvider(params.modelsJsonPath, "deepseek");
42868
+ }
42789
42869
  if (params.providerId === "azure-openai-responses") {
42790
42870
  await params.envStore.removeMany([
42791
42871
  "AZURE_OPENAI_API_KEY",
@@ -42830,6 +42910,7 @@ var PROVIDER_LABELS = {
42830
42910
  mistral: "Mistral",
42831
42911
  minimax: "MiniMax",
42832
42912
  "minimax-cn": "MiniMax CN",
42913
+ deepseek: "DeepSeek",
42833
42914
  huggingface: "Hugging Face",
42834
42915
  opencode: "OpenCode",
42835
42916
  "opencode-go": "OpenCode Go",
@@ -42843,6 +42924,7 @@ var PROVIDER_LABELS = {
42843
42924
  var PROVIDER_HINTS = {
42844
42925
  anthropic: "recommended",
42845
42926
  "custom-openai": "custom base URL + API key",
42927
+ deepseek: "API key (OpenAI-compatible preset)",
42846
42928
  "azure-openai-responses": "API key + base URL/resource + deployment",
42847
42929
  "amazon-bedrock": "AWS profile or access key pair",
42848
42930
  "openai-codex": "browser auth",
@@ -42885,6 +42967,8 @@ function getApiKeyProviderOptions(providerIds) {
42885
42967
  flow3 = "azure-openai-responses";
42886
42968
  } else if (providerId === "amazon-bedrock") {
42887
42969
  flow3 = "amazon-bedrock";
42970
+ } else if (providerId === "deepseek") {
42971
+ flow3 = "deepseek";
42888
42972
  }
42889
42973
  return {
42890
42974
  id: providerId,
@@ -42899,6 +42983,12 @@ function getApiKeyProviderOptions(providerIds) {
42899
42983
  hint: toHint("custom-openai"),
42900
42984
  flow: "custom-openai"
42901
42985
  });
42986
+ baseProviders.push({
42987
+ id: "deepseek",
42988
+ label: toLabel("deepseek"),
42989
+ hint: toHint("deepseek"),
42990
+ flow: "deepseek"
42991
+ });
42902
42992
  const deduped = /* @__PURE__ */ new Map();
42903
42993
  for (const provider of baseProviders) {
42904
42994
  deduped.set(provider.id, provider);
@@ -42960,6 +43050,23 @@ function getProviderFormFields(params) {
42960
43050
  placeholder: "gpt-4o"
42961
43051
  }
42962
43052
  ];
43053
+ case "deepseek":
43054
+ return [
43055
+ {
43056
+ name: "apiKey",
43057
+ title: `${provider.label} API key`,
43058
+ required: true,
43059
+ component: "password"
43060
+ },
43061
+ {
43062
+ name: "modelId",
43063
+ title: "Model",
43064
+ required: true,
43065
+ component: "select",
43066
+ options: DEEPSEEK_MODELS.map((model) => ({ label: model.name, value: model.id })),
43067
+ defaultValue: DEEPSEEK_MODELS[0].id
43068
+ }
43069
+ ];
42963
43070
  case "azure-openai-responses":
42964
43071
  return [
42965
43072
  {
@@ -43208,6 +43315,15 @@ async function applyProviderLogin(params) {
43208
43315
  });
43209
43316
  return { providerId: provider.id, preferredModelId: params.input.modelId };
43210
43317
  }
43318
+ case "deepseek": {
43319
+ const modelId = params.input.modelId ?? DEEPSEEK_MODELS[0].id;
43320
+ await saveDeepseekConfig({
43321
+ ...params,
43322
+ apiKey: params.input.apiKey,
43323
+ modelId
43324
+ });
43325
+ return { providerId: provider.id, preferredModelId: modelId };
43326
+ }
43211
43327
  case "azure-openai-responses": {
43212
43328
  const baseUrl = params.input.baseUrl ?? (params.input.resourceName ? `https://${params.input.resourceName}.openai.azure.com/openai` : void 0);
43213
43329
  if (!baseUrl) {
@@ -47732,25 +47848,11 @@ function setProcessArgValue(flag, value2) {
47732
47848
  }
47733
47849
  process.argv.push(flag, value2);
47734
47850
  }
47735
- function buildTools(profile, cwd, pi) {
47851
+ function buildTools(profile) {
47736
47852
  if (profile === "agent") {
47737
- return [
47738
- pi.createReadTool(cwd),
47739
- pi.createBashTool(cwd),
47740
- pi.createGrepTool(cwd),
47741
- pi.createFindTool(cwd),
47742
- pi.createLsTool(cwd)
47743
- ];
47853
+ return ["read", "bash", "grep", "find", "ls"];
47744
47854
  }
47745
- return [
47746
- pi.createReadTool(cwd),
47747
- pi.createBashTool(cwd),
47748
- pi.createEditTool(cwd),
47749
- pi.createWriteTool(cwd),
47750
- pi.createGrepTool(cwd),
47751
- pi.createFindTool(cwd),
47752
- pi.createLsTool(cwd)
47753
- ];
47855
+ return ["read", "bash", "edit", "write", "grep", "find", "ls"];
47754
47856
  }
47755
47857
  function resolveRequestedModel(params) {
47756
47858
  const { request, modelRegistry } = params;
@@ -47862,7 +47964,7 @@ async function main() {
47862
47964
  resourceLoader,
47863
47965
  settingsManager,
47864
47966
  sessionManager,
47865
- tools: buildTools(request.profile, cwd, pi),
47967
+ tools: buildTools(request.profile),
47866
47968
  model: requestedModel,
47867
47969
  thinkingLevel: request.thinking
47868
47970
  });
@@ -47922,7 +48024,7 @@ async function main() {
47922
48024
  resourceLoader,
47923
48025
  settingsManager,
47924
48026
  sessionManager,
47925
- tools: buildTools(request.profile, cwd, pi),
48027
+ tools: buildTools(request.profile),
47926
48028
  model: requestedModel,
47927
48029
  thinkingLevel: request.thinking
47928
48030
  });
@@ -47957,7 +48059,7 @@ async function main() {
47957
48059
  resourceLoader,
47958
48060
  settingsManager,
47959
48061
  sessionManager: resumedSessionManager,
47960
- tools: buildTools(request.profile, resumeCwd, pi),
48062
+ tools: buildTools(request.profile),
47961
48063
  model: requestedModel,
47962
48064
  thinkingLevel: request.thinking
47963
48065
  });