File size: 4,851 Bytes
5f40163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import type { MCPConfig } from "@openhands/typescript-client";
export type { MCPConfig } from "@openhands/typescript-client";
import type { SkillCategoryId } from "@openhands/extensions/skills";

export const ProviderOptions = {
  github: "github",
  gitlab: "gitlab",
  bitbucket: "bitbucket",
  bitbucket_data_center: "bitbucket_data_center",
  azure_devops: "azure_devops",
  forgejo: "forgejo",
} as const;

export type Provider = keyof typeof ProviderOptions;

export type ProviderToken = {
  token: string;
  host: string | null;
};

export type SettingsChoiceValue = boolean | number | string;

export type SettingsChoice = {
  label: string;
  value: SettingsChoiceValue;
};

export type SettingsValue =
  | boolean
  | number
  | string
  | null
  | SettingsValue[]
  | { [key: string]: SettingsValue };

export type SettingsValueType =
  | "string"
  | "integer"
  | "number"
  | "boolean"
  | "array"
  | "object";

export type SettingProminence = "critical" | "major" | "minor";

export type SettingsFieldSchema = {
  key: string;
  label: string;
  description?: string | null;
  section: string;
  section_label: string;
  value_type: SettingsValueType;
  default?: SettingsValue;
  choices: SettingsChoice[];
  depends_on: string[];
  prominence: SettingProminence;
  secret: boolean;
  required: boolean;
};

export type SettingsSectionSchema = {
  key: string;
  label: string;
  fields: SettingsFieldSchema[];
};

export type SettingsSchema = {
  model_name: string;
  sections: SettingsSectionSchema[];
};

export type SkillType = "repo" | "knowledge" | "agentskills";

export type SkillInfo = {
  name: string;
  type: SkillType;
  source: string | null;
  description?: string | null;
  triggers?: string[];
  /**
   * Topical category from the bundled `@openhands/extensions` catalog.
   * Always absent for user/project skills: the agent-server's `/api/skills` response drops SKILL.md frontmatter metadata, so a local `category` cannot reach us.
   */
  category?: SkillCategoryId | null;
  version?: string;
  license?: string | null;
  compatibility?: string | null;
  metadata?: Record<string, string> | null;
  allowed_tools?: string[] | null;
  is_agentskills_format?: boolean;
  disable_model_invocation?: boolean;
  content?: string;
};

export type SettingsScope = "personal";

/**
 * Agent kind stored on ``Settings.agent_settings.agent_kind``.
 *
 * - ``"openhands"`` (default): the conversation runs through OpenHands' built-in
 *   LLM-driven Agent. The other agent_settings fields (``llm``, ``condenser``,
 *   ``mcp_config``, ``tools``) apply.
 * - ``"acp"``: the conversation is driven by an external ACP subprocess
 *   (Claude Code / Codex / Gemini CLI / Custom). The LLM / condenser
 *   settings are inert; ``mcp_config`` and ``acp_command`` / ``acp_args`` /
 *   ``acp_model`` /
 *   ``acp_server`` apply instead. Provider credentials are supplied through the
 *   Secrets panel (``request.secrets``), never through a per-agent env channel.
 */
export type AgentKind = "openhands" | "acp";

export type Settings = {
  llm_model: string;
  llm_base_url: string;
  agent: string;
  language: string;
  llm_api_key: string | null;
  /** Cloud-shape "an LLM key is on file for this user". */
  llm_api_key_set: boolean;
  /**
   * Agent-server-shape "an LLM key is on file". The local agent-server
   * uses `_is_set` in its `/api/settings` payload; Cloud uses `_set`.
   * Surfacing both so onboarding-skip logic can treat the two backends
   * uniformly.
   */
  llm_api_key_is_set?: boolean;
  search_api_key_set: boolean;
  confirmation_mode: boolean;
  security_analyzer: string | null;
  max_iterations: number | null;
  remote_runtime_resource_factor: number | null;
  provider_tokens_set: Partial<Record<Provider, string | null>>;
  enable_default_condenser: boolean;
  condenser_max_size: number | null;
  enable_sound_notifications: boolean;
  enable_proactive_conversation_starters: boolean;
  enable_solvability_analysis: boolean;
  user_consents_to_analytics: boolean | null;
  search_api_key?: string;
  is_new_user?: boolean;
  mcp_config?: MCPConfig;
  /** Deny-list over user- and project-authored skills. */
  disabled_skills?: string[];
  /**
   * Allow-list over the bundled `@openhands/extensions` catalog. `undefined`
   * means "never migrated", the only signal `migrateSkillEnablement` has, so
   * it is deliberately absent from `DEFAULT_SETTINGS`.
   */
  enabled_skills?: string[];
  max_budget_per_task: number | null;
  email?: string;
  email_verified?: boolean;
  git_user_name?: string;
  git_user_email?: string;
  title_llm_profile?: string | null;
  agent_settings_schema?: SettingsSchema | null;
  agent_settings?: Record<string, SettingsValue> | null;
  conversation_settings_schema?: SettingsSchema | null;
  conversation_settings?: Record<string, SettingsValue> | null;
};