@byfriends/sdk 0.3.0 → 0.3.2

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.
package/dist/index.d.mts CHANGED
@@ -65,9 +65,6 @@ declare interface AgentAPI {
65
65
  setPermission: (payload: SetPermissionPayload) => void;
66
66
  setModel: (payload: SetModelPayload) => SetModelResult;
67
67
  getModel: (payload: EmptyPayload) => string;
68
- enterPlan: (payload: EmptyPayload) => void;
69
- cancelPlan: (payload: CancelPlanPayload) => void;
70
- clearPlan: (payload: EmptyPayload) => void;
71
68
  beginCompaction: (payload: BeginCompactionPayload) => void;
72
69
  cancelCompaction: (payload: EmptyPayload) => void;
73
70
  registerTool: (payload: RegisterToolPayload) => void;
@@ -81,7 +78,6 @@ declare interface AgentAPI {
81
78
  getContext: (payload: EmptyPayload) => AgentContextData;
82
79
  getConfig: (payload: EmptyPayload) => AgentConfigData;
83
80
  getPermission: (payload: EmptyPayload) => PermissionData;
84
- getPlan: (payload: EmptyPayload) => PlanData;
85
81
  getUsage: (payload: EmptyPayload) => UsageStatus;
86
82
  getTools: (payload: EmptyPayload) => readonly ToolInfo[];
87
83
  getBackground: (payload: GetBackgroundPayload) => readonly BackgroundTaskInfo[];
@@ -178,15 +174,6 @@ declare interface AgentRecordEvents {
178
174
  };
179
175
  'permission.record_approval_result': PermissionApprovalResultRecord;
180
176
  'full_compaction.begin': CompactionBeginData;
181
- 'plan_mode.enter': {
182
- id: string;
183
- };
184
- 'plan_mode.cancel': {
185
- id?: string;
186
- };
187
- 'plan_mode.exit': {
188
- id?: string;
189
- };
190
177
  'tools.register_user_tool': UserToolRegistration;
191
178
  'tools.unregister_user_tool': {
192
179
  name: string;
@@ -260,9 +247,6 @@ declare class AgentRecords {
260
247
  export declare type AgentReplayRecord = {
261
248
  type: 'message';
262
249
  message: ContextMessage;
263
- } | {
264
- type: 'plan_updated';
265
- enabled: boolean;
266
250
  } | {
267
251
  type: 'config_updated';
268
252
  config: AgentConfigUpdateData;
@@ -1149,8 +1133,8 @@ declare const ByfConfigPatchSchema: z.ZodObject<{
1149
1133
  defaultThinking: z.ZodOptional<z.ZodBoolean>;
1150
1134
  defaultPermissionMode: z.ZodOptional<z.ZodEnum<{
1151
1135
  auto: "auto";
1152
- yolo: "yolo";
1153
1136
  manual: "manual";
1137
+ yolo: "yolo";
1154
1138
  }>>;
1155
1139
  permission: z.ZodOptional<z.ZodObject<{
1156
1140
  rules: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -1190,19 +1174,19 @@ declare const ByfConfigPatchSchema: z.ZodObject<{
1190
1174
  timeout: z.ZodOptional<z.ZodNumber>;
1191
1175
  }, z.core.$strict>>>;
1192
1176
  services: z.ZodOptional<z.ZodObject<{
1193
- byfSearch: z.ZodOptional<z.ZodObject<{
1194
- baseUrl: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1195
- apiKey: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1196
- oauth: z.ZodOptional<z.ZodOptional<z.ZodObject<{
1197
- storage: z.ZodEnum<{
1198
- file: "file";
1199
- keyring: "keyring";
1177
+ webSearch: z.ZodOptional<z.ZodObject<{
1178
+ providers: z.ZodArray<z.ZodObject<{
1179
+ type: z.ZodEnum<{
1180
+ exa: "exa";
1181
+ brave: "brave";
1182
+ firecrawl: "firecrawl";
1200
1183
  }>;
1201
- key: z.ZodString;
1202
- }, z.core.$strip>>>;
1203
- customHeaders: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
1184
+ apiKeys: z.ZodArray<z.ZodString>;
1185
+ baseUrl: z.ZodOptional<z.ZodString>;
1186
+ priority: z.ZodNumber;
1187
+ }, z.core.$strip>>;
1204
1188
  }, z.core.$strip>>;
1205
- byfFetch: z.ZodOptional<z.ZodObject<{
1189
+ fetchUrl: z.ZodOptional<z.ZodObject<{
1206
1190
  baseUrl: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1207
1191
  apiKey: z.ZodOptional<z.ZodOptional<z.ZodString>>;
1208
1192
  oauth: z.ZodOptional<z.ZodOptional<z.ZodObject<{
@@ -1287,8 +1271,8 @@ declare const ByfConfigSchema: z.ZodObject<{
1287
1271
  defaultThinking: z.ZodOptional<z.ZodBoolean>;
1288
1272
  defaultPermissionMode: z.ZodOptional<z.ZodEnum<{
1289
1273
  auto: "auto";
1290
- yolo: "yolo";
1291
1274
  manual: "manual";
1275
+ yolo: "yolo";
1292
1276
  }>>;
1293
1277
  permission: z.ZodOptional<z.ZodObject<{
1294
1278
  rules: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -1328,19 +1312,19 @@ declare const ByfConfigSchema: z.ZodObject<{
1328
1312
  timeout: z.ZodOptional<z.ZodNumber>;
1329
1313
  }, z.core.$strict>>>;
1330
1314
  services: z.ZodOptional<z.ZodObject<{
1331
- byfSearch: z.ZodOptional<z.ZodObject<{
1332
- baseUrl: z.ZodOptional<z.ZodString>;
1333
- apiKey: z.ZodOptional<z.ZodString>;
1334
- oauth: z.ZodOptional<z.ZodObject<{
1335
- storage: z.ZodEnum<{
1336
- file: "file";
1337
- keyring: "keyring";
1315
+ webSearch: z.ZodOptional<z.ZodObject<{
1316
+ providers: z.ZodArray<z.ZodObject<{
1317
+ type: z.ZodEnum<{
1318
+ exa: "exa";
1319
+ brave: "brave";
1320
+ firecrawl: "firecrawl";
1338
1321
  }>;
1339
- key: z.ZodString;
1322
+ apiKeys: z.ZodArray<z.ZodString>;
1323
+ baseUrl: z.ZodOptional<z.ZodString>;
1324
+ priority: z.ZodNumber;
1340
1325
  }, z.core.$strip>>;
1341
- customHeaders: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1342
1326
  }, z.core.$strip>>;
1343
- byfFetch: z.ZodOptional<z.ZodObject<{
1327
+ fetchUrl: z.ZodOptional<z.ZodObject<{
1344
1328
  baseUrl: z.ZodOptional<z.ZodString>;
1345
1329
  apiKey: z.ZodOptional<z.ZodString>;
1346
1330
  oauth: z.ZodOptional<z.ZodObject<{
@@ -1406,9 +1390,6 @@ declare class ByfCore implements PromisableMethods<CoreAPI> {
1406
1390
  setThinking({ sessionId, ...payload }: SessionAgentPayload<SetThinkingPayload>): void | Promise<void>;
1407
1391
  setPermission({ sessionId, ...payload }: SessionAgentPayload<SetPermissionPayload>): void | Promise<void>;
1408
1392
  getModel({ sessionId, ...payload }: SessionAgentPayload<EmptyPayload>): string | Promise<string>;
1409
- enterPlan({ sessionId, ...payload }: SessionAgentPayload<EmptyPayload>): void | Promise<void>;
1410
- cancelPlan({ sessionId, ...payload }: SessionAgentPayload<CancelPlanPayload>): void | Promise<void>;
1411
- clearPlan({ sessionId, ...payload }: SessionAgentPayload<EmptyPayload>): void | Promise<void>;
1412
1393
  beginCompaction({ sessionId, ...payload }: SessionAgentPayload<BeginCompactionPayload>): void | Promise<void>;
1413
1394
  cancelCompaction({ sessionId, ...payload }: SessionAgentPayload<EmptyPayload>): void | Promise<void>;
1414
1395
  registerTool({ sessionId, ...payload }: SessionAgentPayload<RegisterToolPayload>): void | Promise<void>;
@@ -1422,7 +1403,6 @@ declare class ByfCore implements PromisableMethods<CoreAPI> {
1422
1403
  getContext({ sessionId, ...payload }: SessionAgentPayload<EmptyPayload>): AgentContextData | Promise<AgentContextData>;
1423
1404
  getConfig({ sessionId, ...payload }: SessionAgentPayload<EmptyPayload>): AgentConfigData | Promise<AgentConfigData>;
1424
1405
  getPermission({ sessionId, ...payload }: SessionAgentPayload<EmptyPayload>): PermissionData | Promise<PermissionData>;
1425
- getPlan({ sessionId, ...payload }: SessionAgentPayload<EmptyPayload>): Promise<null> | null;
1426
1406
  getUsage({ sessionId, ...payload }: SessionAgentPayload<EmptyPayload>): UsageStatus | Promise<UsageStatus>;
1427
1407
  getTools({ sessionId, ...payload }: SessionAgentPayload<EmptyPayload>): readonly ToolInfo[] | Promise<readonly ToolInfo[]>;
1428
1408
  getBackground({ sessionId, ...payload }: SessionAgentPayload<GetBackgroundPayload>): readonly BackgroundTaskInfo[] | Promise<readonly BackgroundTaskInfo[]>;
@@ -1514,7 +1494,7 @@ export declare class ByfHarness {
1514
1494
  get sessions(): ReadonlyMap<string, Session>;
1515
1495
  get interactiveAgentId(): string;
1516
1496
  set interactiveAgentId(agentId: string);
1517
- track(event: string, properties?: Record<string, unknown>): void;
1497
+ track(_event: string, _properties?: Record<string, unknown>): void;
1518
1498
  createSession(options: CreateSessionOptions): Promise<Session>;
1519
1499
  resumeSession(input: ResumeSessionInput): Promise<Session>;
1520
1500
  forkSession(input: ForkSessionInput): Promise<Session>;
@@ -1539,6 +1519,7 @@ export declare interface ByfHarnessOptions {
1539
1519
  readonly identity?: HostIdentity | undefined;
1540
1520
  readonly homeDir?: string | undefined;
1541
1521
  readonly configPath?: string | undefined;
1522
+ readonly runtime?: RuntimeConfig | undefined;
1542
1523
  readonly autoLoadConfig?: boolean | undefined;
1543
1524
  readonly uiMode?: string;
1544
1525
  readonly skillDirs?: readonly string[];
@@ -1621,10 +1602,6 @@ declare interface CancelPayload {
1621
1602
  readonly turnId?: number;
1622
1603
  }
1623
1604
 
1624
- declare interface CancelPlanPayload {
1625
- readonly id?: string;
1626
- }
1627
-
1628
1605
  /** Top-level catalog: `{ [providerId]: ProviderEntry }` (e.g. models.dev/api.json). */
1629
1606
  export declare type Catalog = Record<string, CatalogProviderEntry>;
1630
1607
 
@@ -3531,15 +3508,6 @@ declare type PermissionRuleDecision = 'allow' | 'deny' | 'ask';
3531
3508
  */
3532
3509
  declare type PermissionRuleScope = 'turn-override' | 'session-runtime' | 'project' | 'user';
3533
3510
 
3534
- declare type PlanData = null;
3535
-
3536
- export declare interface PlanInfo {
3537
- readonly id: string;
3538
- readonly exists: boolean;
3539
- readonly content: string;
3540
- readonly path: string;
3541
- }
3542
-
3543
3511
  declare type PreparedSystemPromptContext = Pick<SystemPromptContext, 'cwd' | 'agentsMd'>;
3544
3512
 
3545
3513
  declare interface PrepareToolExecutionResult {
@@ -3959,7 +3927,6 @@ export declare interface ResumedAgentState {
3959
3927
  readonly context: AgentContextData;
3960
3928
  readonly replay: readonly AgentReplayRecord[];
3961
3929
  readonly permission: PermissionData;
3962
- readonly plan: PlanData;
3963
3930
  readonly usage: UsageStatus;
3964
3931
  readonly tools: readonly ToolInfo[];
3965
3932
  readonly toolStore?: Readonly<Record<string, unknown>>;
@@ -4097,8 +4064,6 @@ declare class SDKRpcClient {
4097
4064
  setModel(input: SetSessionModelRpcInput): Promise<SetSessionModelRpcResult>;
4098
4065
  setThinking(input: SetSessionThinkingRpcInput): Promise<void>;
4099
4066
  setPermission(input: SetSessionPermissionRpcInput): Promise<void>;
4100
- getPlan(input: SessionIdRpcInput): Promise<SessionPlan>;
4101
- clearPlan(input: SessionIdRpcInput): Promise<void>;
4102
4067
  compact(input: SessionIdRpcInput & CompactOptions): Promise<void>;
4103
4068
  cancelCompaction(input: SessionIdRpcInput): Promise<void>;
4104
4069
  getUsage(input: SessionIdRpcInput): Promise<SessionUsage>;
@@ -4145,6 +4110,7 @@ declare interface SDKRpcClientOptions {
4145
4110
  readonly homeDir?: string | undefined;
4146
4111
  readonly configPath?: string | undefined;
4147
4112
  readonly skillDirs?: readonly string[];
4113
+ readonly runtime?: RuntimeConfig | undefined;
4148
4114
  }
4149
4115
 
4150
4116
  declare type SDKSessionAPI = WithAgentId<SDKAgentAPI>;
@@ -4158,19 +4124,19 @@ declare interface ServicesConfig_2 {
4158
4124
  }
4159
4125
 
4160
4126
  declare const ServicesConfigSchema: z.ZodObject<{
4161
- byfSearch: z.ZodOptional<z.ZodObject<{
4162
- baseUrl: z.ZodOptional<z.ZodString>;
4163
- apiKey: z.ZodOptional<z.ZodString>;
4164
- oauth: z.ZodOptional<z.ZodObject<{
4165
- storage: z.ZodEnum<{
4166
- file: "file";
4167
- keyring: "keyring";
4127
+ webSearch: z.ZodOptional<z.ZodObject<{
4128
+ providers: z.ZodArray<z.ZodObject<{
4129
+ type: z.ZodEnum<{
4130
+ exa: "exa";
4131
+ brave: "brave";
4132
+ firecrawl: "firecrawl";
4168
4133
  }>;
4169
- key: z.ZodString;
4134
+ apiKeys: z.ZodArray<z.ZodString>;
4135
+ baseUrl: z.ZodOptional<z.ZodString>;
4136
+ priority: z.ZodNumber;
4170
4137
  }, z.core.$strip>>;
4171
- customHeaders: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
4172
4138
  }, z.core.$strip>>;
4173
- byfFetch: z.ZodOptional<z.ZodObject<{
4139
+ fetchUrl: z.ZodOptional<z.ZodObject<{
4174
4140
  baseUrl: z.ZodOptional<z.ZodString>;
4175
4141
  apiKey: z.ZodOptional<z.ZodString>;
4176
4142
  oauth: z.ZodOptional<z.ZodObject<{
@@ -4208,8 +4174,6 @@ export declare class Session {
4208
4174
  setModel(model: string): Promise<void>;
4209
4175
  setThinking(level: string): Promise<void>;
4210
4176
  setPermission(mode: PermissionMode): Promise<void>;
4211
- getPlan(): Promise<SessionPlan>;
4212
- clearPlan(): Promise<void>;
4213
4177
  compact(options?: CompactOptions): Promise<void>;
4214
4178
  cancelCompaction(): Promise<void>;
4215
4179
  getUsage(): Promise<SessionUsage>;
@@ -4385,8 +4349,6 @@ declare interface SessionOptions {
4385
4349
  readonly onClose?: (() => void | Promise<void>) | undefined;
4386
4350
  }
4387
4351
 
4388
- export declare type SessionPlan = PlanInfo | null;
4389
-
4390
4352
  declare interface SessionPromptRpcInput {
4391
4353
  readonly sessionId: string;
4392
4354
  readonly input: PromptInput;
package/dist/index.mjs CHANGED
@@ -46352,7 +46352,7 @@ var OpenAIResponsesChatProvider = class OpenAIResponsesChatProvider extends Base
46352
46352
  };
46353
46353
  //#endregion
46354
46354
  //#region ../kosong/src/providers/index.ts
46355
- function createProvider(config) {
46355
+ function createProvider$1(config) {
46356
46356
  switch (config.type) {
46357
46357
  case "anthropic": return new AnthropicChatProvider(config);
46358
46358
  case "openai-completions": return new OpenAICompletionsChatProvider(config);
@@ -58148,14 +58148,36 @@ function isRecord$4(value) {
58148
58148
  var mcp_config_default = "---\nname: mcp-config\ndescription: Configure MCP servers and handle MCP OAuth login.\n---\n\n# Interactive MCP server configuration\n\nThe user invoked this skill through `/mcp-config` or `/skill:mcp-config`.\nEither they want to log into an MCP server that asked for OAuth, or they\nwant to edit the `mcp.json` that lists MCP servers. The work is small and\nlocal — handle it on this turn yourself, no agents or planning todos.\n\nPick the flow from the user's message and your tool list:\n\n- An `mcp__<server>__authenticate` tool is in your list, the user says\n \"log in\" / \"auth\" / \"sign in\", they invoke `/mcp-config login\n <server>`, or they quote a `needs-auth` status → **Login**.\n- Add / edit / remove / list of an `mcp.json` entry → **Config edit**.\n- Bare `/mcp-config` with no `authenticate` tool in your list →\n **Config edit**. If there were a pending login, the authenticate tool\n would be in your list.\n\n## Login\n\nEach MCP server in `needs-auth` exposes one `mcp__<server>__authenticate`\ntool. Call it for the server the user means — its own description owns\nthe OAuth UX (printing the URL, blocking on the callback, reconnecting on\nsuccess). Surface its output verbatim, including the authorization URL\nunchanged; the URL contains state and PKCE parameters that break if\nedited.\n\nIf the user named a server that has no authenticate tool, say so in one\nsentence and stop — do **not** fall into config edit. They're trying to\nlog in to a server that isn't currently waiting for login; quietly\nrewriting `mcp.json` would be the wrong fix. If multiple authenticate\ntools exist and the user didn't name one, ask which.\n\n## Config edit\n\nConfig lives in two files; on key collision the project file overrides\nthe user-global one:\n\n- User-global: `~/.byf/mcp.json` (or `$BYF_HOME/mcp.json` if\n set). Use for servers you want everywhere.\n- Project-local: `<cwd>/.byf/mcp.json`. Mention once that stdio\n entries spawn commands at session start, so this should only live in\n trusted repos.\n\nBoth files wrap their entries the same way:\n\n```json\n{ \"mcpServers\": { \"<name>\": { /* entry */ } } }\n```\n\nA minimal stdio entry needs `command` (+ optional `args`, `env`, `cwd`).\nA minimal http entry needs `url`; add `bearerTokenEnvVar: \"ENV_NAME\"` for\nservers that authenticate with a static bearer token from the\nenvironment. Servers that use OAuth take no token field — the login flow\nabove handles them. `transport` is inferred from `command` vs `url`, so\nomit it. For less common fields (`enabled`, `startupTimeoutMs`,\n`toolTimeoutMs`, `enabledTools`, `disabledTools`, `headers`) the source of\ntruth is `McpServerStdioConfigSchema` / `McpServerHttpConfigSchema` in\n`packages/agent-core/src/config/schema.ts`.\n\nIf the user only wants to **see** what's configured, read both files,\nshow a merged view, and stop — no scope prompt, no write.\n\nFor changes, the flow is:\n\n1. **Pick a scope.** Infer it from the user's words when you can\n (project / repo / this checkout / cwd → project; global / everywhere /\n all projects → user-global). When the request is genuinely scope-less,\n use one `AskUserQuestion` to ask user-global vs project-local, defaulting\n to user-global. Use plain text for every other question — `AskUserQuestion`\n is a poor fit for free-form input. If the user dismisses the scope\n question, stop; you can't safely guess where they wanted the change.\n2. **Read and announce.** Read the target file (a missing or empty file\n is fine; you'll create `{ \"mcpServers\": {} }`). If JSON parsing fails,\n surface the error verbatim and stop — silently overwriting a broken\n file could destroy work. Then show the user the target path, what's\n currently in it, and the entry you're about to write or delete. This\n is for transparency, not a confirmation gate — the Edit/Write\n permission prompt is the real gate, and your message is what gives\n the user context when that prompt appears. In yolo / afk modes there\n is no prompt, which is those modes' explicit contract.\n3. **Write and tell them how to reload MCP servers.** Preserve unrelated\n entries and the `mcpServers` wrapper. MCP servers load at session\n start, so tell the user to start a new session (for example `/new`) or\n restart BYF for the change to take effect.\n\n## Secrets\n\nDon't store secrets (tokens, keys, passwords) as literals in\n`mcp.json` — it's a plain config file on disk. http servers should use\n`bearerTokenEnvVar` to reference an env var instead; if a stdio entry\nmust inline one in `env`, warn the user before writing.\n";
58149
58149
  //#endregion
58150
58150
  //#region ../agent-core/src/skill/builtin/mcp-config.ts
58151
- const PSEUDO_PATH = "builtin://mcp-config";
58152
- const parsed = parseSkillText({
58151
+ const PSEUDO_PATH$1 = "builtin://mcp-config";
58152
+ const parsed$1 = parseSkillText({
58153
58153
  skillMdPath: "/builtin/skills/mcp-config.md",
58154
58154
  skillDirName: "mcp-config",
58155
58155
  source: "builtin",
58156
58156
  text: mcp_config_default
58157
58157
  });
58158
58158
  const MCP_CONFIG_SKILL = {
58159
+ ...parsed$1,
58160
+ path: PSEUDO_PATH$1,
58161
+ dir: PSEUDO_PATH$1,
58162
+ metadata: {
58163
+ ...parsed$1.metadata,
58164
+ type: parsed$1.metadata.type ?? "inline",
58165
+ disableModelInvocation: true
58166
+ }
58167
+ };
58168
+ //#endregion
58169
+ //#region ../agent-core/src/skill/builtin/update-config.md
58170
+ var update_config_default = "---\nname: update-config\ndescription: Audit and fix ~/.byf/config.toml — remove deprecated fields, migrate legacy settings, and flag semantic conflicts.\n---\n\n# Audit and fix config.toml\n\nThe user invoked this skill via `/update-config` or `/skill:update-config`.\nThe goal is to bring `~/.byf/config.toml` in line with the current BYF schema:\nremove deprecated fields, migrate legacy settings, and point out semantic\nconflicts that a deterministic linter cannot catch. The work is small and\nlocal — handle it on this turn yourself, no agents or planning todos.\n\n## Read the config\n\n1. **Resolve the path.** Default: `~/.byf/config.toml` (or\n `$BYF_HOME/config.toml` if that env var is set). If the user passed a path\n as an argument, use that instead.\n2. **Read the file.** If it does not exist, say so and stop — there is nothing\n to update. If the TOML fails to parse, surface the parse error verbatim and\n **stop** — do not overwrite a broken file, that could destroy the user's\n work.\n3. **Never echo secrets.** `config.toml` stores `api_key` secret values, and\n `oauth` references (a `{ storage, key }` handle that points at a\n file/keyring entry — not the token itself). When you describe what you\n found or plan to change, state only that a credential is present or\n absent — never quote the `api_key` value itself, not even partially.\n\n## What to check for\n\nField-level validity (which keys exist, what types and enums are allowed) is\n**not** something to reproduce here. The single source of truth is\n`ByfConfigSchema` in `packages/agent-core/src/config/schema.ts` — read it when\nyou need to confirm whether a field is recognized and what values it accepts.\n\nThe checks below fall into three groups. Report findings from all three before\nmaking any change.\n\n### 1. Deprecated, renamed, and migrated fields\n\nThese are historical fields that the schema no longer accepts or has replaced.\nDelete them, except where the table says to rename or migrate:\n\n| Field | Action |\n|---|---|\n| `default_yolo` / `defaultYolo` (top-level) | Remove. Use `yolo` instead. |\n| `services.byf_search` | Remove. (Legacy service, superseded by `[services.web_search]`.) |\n| `services.byf_fetch` | Remove. Use `[services.fetch_url]` instead. |\n| `loop_control.max_steps_per_run` | **Rename** to `max_steps_per_turn`, preserving the value. First check whether `max_steps_per_turn` is already present: if so, the old key is a stale duplicate — just delete it; if not, write `max_steps_per_turn` with the old value, then delete `max_steps_per_run`. (The runtime auto-copies the value on read, but this skill edits the file directly and skips that roundtrip — so you must perform the rename yourself to avoid losing the limit.) |\n| `default_thinking` (top-level boolean) | Migrate — see below. |\n\n**`default_thinking` migration** (matches the runtime precedence in\n`byf-tui.ts`: a `[thinking]` block wins over `default_thinking`):\n\n- If `[thinking]` already has `mode` or `effort` set, `default_thinking` was\n never effective — just remove it.\n- Otherwise migrate by value: `true` → write `[thinking]` with\n `mode = \"on\"` and `effort = \"high\"`; `false` → `[thinking]` with\n `mode = \"off\"`. Then remove `default_thinking`.\n\n> **Raw-passthrough blind spot.** Fields stripped by the schema (like\n> `byf_search`, `byf_fetch`) survive inside `config.raw` and get written back\n> on every read→write roundtrip, so they linger in the file even though they\n> have no effect. Deleting them here is the only way to clear them — that is\n> the core value of this skill.\n\n### 2. Semantic conflicts (the part a linter cannot enumerate)\n\nLook for cross-field problems that require understanding intent:\n\n- A provider with **both** `api_key` and `oauth` configured — these are\n mutually exclusive; ask which one the user meant.\n- `thinking.mode = \"off\"` **and** a non-empty `thinking.effort` — the effort\n is ignored; suggest removing it or flipping the mode.\n- `models.<alias>.capabilities` containing a value not in the valid set. The\n valid set is the single source of truth: read `CAPABILITY_DEFINITIONS` (or\n the derived `VALID_CAPABILITIES`) in\n `packages/agent-core/src/providers/runtime-provider.ts`. Comparison is\n case-insensitive at runtime, so flag only genuine mismatches.\n- A model alias, `default_provider`, or `default_model` that points at a\n provider or model that does not exist — a dangling reference. Report it; do\n **not** delete it, the user may be mid-edit.\n\n### 3. Housekeeping\n\n- Top-level keys that are not in `ByfConfigSchema` (and not a deprecated key\n above) — likely typos or leftovers from an old version. Report them; only\n remove with user confirmation. Note that legitimate unknown keys (e.g.\n `theme`, `notifications`) are preserved by design through `config.raw`, so\n do not touch keys the user clearly added on purpose.\n- **Nested keys inside containers** (`[providers.<name>]`, `[models.<alias>]`,\n `[services]`, `[background]`, `[loop_control]`, `[thinking]`,\n `[permission]`). A key that the corresponding section of `ByfConfigSchema`\n does not recognize is silently dropped by the parser and has no effect — a\n common cause is a typo (e.g. `max_context_tokns` instead of\n `max_context_size`). Cross-check each sub-key against the schema and flag\n any mismatch; fix only with user confirmation. Note that `[permission]`\n still accepts the legacy `deny`/`allow`/`ask` array shorthand, so do not\n report those as unknown.\n\n## Make changes\n\nFor each change, show the user **what is currently there → what you plan to\nwrite** before editing. Then apply edits with Write/Edit. The Edit/Write\npermission prompt is the real safety gate — your summary is what gives the\nuser context when that prompt appears. There is no automatic backup; if the\nuser wants one, suggest they copy the file first.\n\nAfter editing, tell the user to start a new session (e.g. `/new`) or restart\nBYF for the config change to take effect.\n";
58171
+ //#endregion
58172
+ //#region ../agent-core/src/skill/builtin/update-config.ts
58173
+ const PSEUDO_PATH = "builtin://update-config";
58174
+ const parsed = parseSkillText({
58175
+ skillMdPath: "/builtin/skills/update-config.md",
58176
+ skillDirName: "update-config",
58177
+ source: "builtin",
58178
+ text: update_config_default
58179
+ });
58180
+ const UPDATE_CONFIG_SKILL = {
58159
58181
  ...parsed,
58160
58182
  path: PSEUDO_PATH,
58161
58183
  dir: PSEUDO_PATH,
@@ -58169,6 +58191,7 @@ const MCP_CONFIG_SKILL = {
58169
58191
  //#region ../agent-core/src/skill/builtin/index.ts
58170
58192
  function registerBuiltinSkills(registry) {
58171
58193
  registry.registerBuiltinSkill(MCP_CONFIG_SKILL);
58194
+ registry.registerBuiltinSkill(UPDATE_CONFIG_SKILL);
58172
58195
  }
58173
58196
  //#endregion
58174
58197
  //#region ../agent-core/src/skill/scanner.ts
@@ -58961,12 +58984,12 @@ function joinPath(parent, child, pathClass) {
58961
58984
  }
58962
58985
  //#endregion
58963
58986
  //#region ../agent-core/src/tools/builtin/file/glob.md
58964
- var glob_default = "Find files (and optionally directories) by glob pattern, sorted by modification time (most recent first).\n\nGood patterns:\n- `*.ts` files in the current directory matching an extension\n- `src/**/*.ts` recursive with a subdirectory anchor and extension\n- `test_*.py` files whose name starts with a literal prefix\n\nRejected patterns (no literal anchor):\n- `**`, `**/*`, `*/*` — pure wildcards. Add an extension or subdirectory to give the walk a concrete target.\n- Anything starting with `**/` (e.g. `**/*.md`, `**/main/*.py`). Anchor it with a top-level subdirectory like `src/**/*.md`.\n- `*.{ts,tsx}` — brace expansion is not supported. Issue two calls: `*.ts` and `*.tsx`.\n\nLarge-directory warning — avoid recursing into dependency/build output even with an anchor:\n- `node_modules/**/*.js`, `.venv/**/*.py`, `__pycache__/**`, `target/**` match technically but typically produce thousands of results that truncate at the match cap. Prefer specific subpaths like `node_modules/react/src/**/*.js`.\n";
58987
+ var glob_default = "Find files (and optionally directories) by glob pattern, sorted by modification time (most recent first).\n\nREJECTED patterns (no literal anchor will be rejected):\n- **Pure wildcards**: `**`, `**/*`, `*/*` — no literal anchor bounds the result. Add an extension or subdirectory to give the walk a concrete target.\n- **`**/` prefix**: Anything starting with `**/` (e.g. `**/*.py`, `**/main/*.ts`). The leading `**/` has no literal anchor in front of it. Anchor it with a top-level subdirectory like `src/**/*.ts`.\n- **Brace expansion**: `*.{ts,tsx}` is not supported. Split it into separate calls: `*.ts` and `*.tsx`.\n\nGood patterns:\n- `*.ts` — files in the current directory matching an extension\n- `src/**/*.ts` — recursive with a subdirectory anchor and extension\n- `test_*.py` — files whose name starts with a literal prefix\n\nLarge-directory warning — avoid recursing into dependency/build output even with an anchor:\n- `node_modules/**/*.js`, `.venv/**/*.py`, `__pycache__/**`, `target/**` match technically but typically produce thousands of results that truncate at the match cap. Prefer specific subpaths like `node_modules/react/src/**/*.js`.\n\nWhen you need to search the entire project, first use Glob to explore the top-level directory structure, then use an anchored pattern like `src/**/*.ts` or `packages/**/*.ts` to narrow the search.\n";
58965
58988
  //#endregion
58966
58989
  //#region ../agent-core/src/tools/builtin/file/glob.ts
58967
58990
  const GlobInputSchema = z.object({
58968
- pattern: z.string().describe("Glob pattern to match files/directories."),
58969
- path: z.string().optional().describe("Absolute path to the directory to search in. Defaults to the current working directory."),
58991
+ pattern: z.string().describe("Glob pattern to match files/directories. IMPORTANT: pattern MUST contain a literal anchor like a file extension (.ts) or a subdirectory name (src/). Patterns starting with **/ (e.g. **/*.py, **/main/*.ts), pure wildcards (**, **/*, */*, *), and brace expansion (*.{ts,tsx}) are REJECTED. Example: src/**/*.ts searches all .ts files under src/."),
58992
+ path: z.string().optional().describe("Absolute path to the directory to search in. Defaults to the current working directory. Explicit absolute paths outside the workspace are allowed (e.g. to search a dependency installed elsewhere); relative paths are resolved against the working directory and rejected if they escape it."),
58970
58993
  include_dirs: z.boolean().default(true).optional().describe("Whether to include directories in results. Defaults to true. Set false to return only files.")
58971
58994
  });
58972
58995
  const MAX_MATCHES = 1e3;
@@ -59008,7 +59031,7 @@ var GlobTool = class {
59008
59031
  workspace: this.workspace,
59009
59032
  operation: "search",
59010
59033
  policy: {
59011
- guardMode: "strict",
59034
+ guardMode: "absolute-outside-allowed",
59012
59035
  checkSensitive: false
59013
59036
  }
59014
59037
  });
@@ -59042,7 +59065,7 @@ var GlobTool = class {
59042
59065
  }
59043
59066
  return {
59044
59067
  isError: true,
59045
- output: `Pattern "${args.pattern}" is a pure wildcard (only \`*\`, \`?\`, \`**\`, \`/\`) and would enumerate every file under the search root — with no literal anchor to bound the result set, this typically exhausts your context on large trees. Add an extension ("${args.pattern === "**" || args.pattern === "**/*" ? "**/*.ts" : "**/*.md"}") or a subdirectory ("src/**/*.ts") to constrain the walk.\n\nAllowed roots for explicit path searches:\n${rootList}\n\nTop of ${this.workspace.workspaceDir}:\n${tree}`
59068
+ output: `Pattern "${args.pattern}" is a pure wildcard (only \`*\`, \`?\`, \`**\`, \`/\`) and would enumerate every file under the search root — with no literal anchor to bound the result set, this typically exhausts your context on large trees. Add an extension ("${args.pattern === "**" || args.pattern === "**/*" ? "**/*.ts" : "**/*.md"}") or a subdirectory ("src/**/*.ts") to constrain the walk.\n\nWorkspace roots:\n${rootList}\n\nTop of ${this.workspace.workspaceDir}:\n${tree}`
59046
59069
  };
59047
59070
  }
59048
59071
  if (containsBraceExpansion(args.pattern)) return {
@@ -59070,6 +59093,8 @@ var GlobTool = class {
59070
59093
  try {
59071
59094
  const seen = /* @__PURE__ */ new Set();
59072
59095
  const entries = [];
59096
+ const pathClass = this.kaos.pathClass();
59097
+ const filteredSensitive = [];
59073
59098
  const YIELD_SAFETY_CAP = MAX_MATCHES * 2;
59074
59099
  let yielded = 0;
59075
59100
  let truncated = false;
@@ -59085,6 +59110,10 @@ var GlobTool = class {
59085
59110
  break outer;
59086
59111
  }
59087
59112
  seen.add(filePath);
59113
+ if (isSensitiveFile(filePath, pathClass)) {
59114
+ filteredSensitive.push(filePath);
59115
+ continue;
59116
+ }
59088
59117
  let mtime = 0;
59089
59118
  let isDir = false;
59090
59119
  try {
@@ -59100,10 +59129,10 @@ var GlobTool = class {
59100
59129
  }
59101
59130
  entries.sort((a, b) => b.mtime - a.mtime);
59102
59131
  const paths = entries.map((e) => e.path);
59103
- const pathClass = this.kaos.pathClass();
59104
59132
  const relBase = searchRoots[0] ?? this.workspace.workspaceDir;
59105
59133
  const displayLines = paths.map((p) => relativizeIfUnder$1(p, relBase, pathClass));
59106
- if (entries.length === 0 && !truncated) return { output: "No matches found" };
59134
+ const filteredSome = filteredSensitive.length > 0;
59135
+ if (entries.length === 0 && !truncated) return { output: filteredSome ? `No non-sensitive matches found (filtered ${String(filteredSensitive.length)} sensitive file(s))` : "No matches found" };
59107
59136
  const lines = [];
59108
59137
  if (truncated) {
59109
59138
  lines.push(`[Truncated at ${String(MAX_MATCHES)} matches — use a more specific pattern]`);
@@ -59111,6 +59140,10 @@ var GlobTool = class {
59111
59140
  }
59112
59141
  lines.push(...displayLines);
59113
59142
  if (!truncated && entries.length === 1e3) lines.push(`Found ${String(entries.length)} matches`);
59143
+ if (filteredSome) {
59144
+ const displayedFiltered = filteredSensitive.map((p) => relativizeIfUnder$1(p, relBase, pathClass));
59145
+ lines.push(`Filtered ${String(filteredSensitive.length)} sensitive file(s): ${displayedFiltered.join(", ")}`);
59146
+ }
59114
59147
  return { output: lines.join("\n") };
59115
59148
  } catch (error) {
59116
59149
  if (error !== null && typeof error === "object" && "code" in error) {
@@ -65435,7 +65468,7 @@ function rewriteWindowsNullRedirect$1(command) {
65435
65468
  }
65436
65469
  //#endregion
65437
65470
  //#region ../agent-core/src/tools/builtin/state/todo-list.md
65438
- var todo_list_default = "Use this tool to maintain a structured TODO list as you work through a multi-step task.\n\nUse for multi-step tasks, tracking investigation progress, or planning a sequence of edits. Do not use for single-shot answers or trivial requests.\n\n**Avoid churn:**\n- Do not re-call this tool when nothing meaningful has changed since the last call — update the list only after real progress.\n- When unsure of the current state, call query mode first (omit `todos`) to check the list before deciding what to update.\n- If no available tool can move any task forward, tell the user where you are stuck instead of repeatedly re-ordering the same todos.\n\n**How to use:**\n- Call with `todos: [...]` to replace the full list. Statuses: pending / in_progress / done.\n- Call with no arguments to query the current list.\n- Call with `todos: []` to clear the list.\n- Keep titles short and actionable.\n- Update statuses as you make progress — mark one item in_progress at a time.\n";
65471
+ var todo_list_default = "Use this tool to maintain a structured TODO list as you work through a multi-step task.\n\nUse for multi-step tasks, tracking investigation progress, or planning a sequence of edits. Do not use for single-shot answers or trivial requests.\n\n**Update discipline:**\n- Update status immediately when you start or complete a subtask: mark it `in_progress` when you begin working on it, and `done` when finished.\n- Do not skip the `in_progress` state — the user should always see what you are currently working on.\n- Avoid redundant calls: do not re-call this tool when nothing meaningful has changed since the last call.\n- When unsure of the current state, call query mode first (omit `todos`) to check the list before deciding what to update.\n- If no available tool can move any task forward, tell the user where you are stuck instead of repeatedly re-ordering the same todos.\n\n**How to use:**\n- Call with `todos: [...]` to replace the full list. Statuses: pending / in_progress / done.\n- Call with no arguments to query the current list.\n- Call with `todos: []` to clear the list.\n- Keep titles short and actionable.\n- Update statuses as you make progress — mark one item in_progress at a time.\n";
65439
65472
  //#endregion
65440
65473
  //#region ../agent-core/src/tools/builtin/state/todo-list.ts
65441
65474
  /**
@@ -66810,7 +66843,7 @@ var ConfigState = class {
66810
66843
  return provider;
66811
66844
  }
66812
66845
  get provider() {
66813
- return createProvider(this.providerConfig);
66846
+ return createProvider$1(this.providerConfig);
66814
66847
  }
66815
66848
  get model() {
66816
66849
  if (this._modelAlias === void 0) throw new Error("Model not set");
@@ -70165,6 +70198,7 @@ const YoloOutsideWorkspacePermissionPolicy = {
70165
70198
  evaluate({ agent, mode, toolCallContext }) {
70166
70199
  if (mode !== "yolo") return void 0;
70167
70200
  const toolName = toolCallContext.toolCall.name;
70201
+ if (isDefaultAutoAllowTool(toolName)) return void 0;
70168
70202
  const toolAccess = FILE_ACCESS_TOOLS[toolName];
70169
70203
  if (toolAccess === void 0) return void 0;
70170
70204
  const [operation, displayOperation] = toolAccess;
@@ -70672,8 +70706,7 @@ var AgentRecords = class {
70672
70706
  tools: "tools",
70673
70707
  usage: "usage",
70674
70708
  background: "background",
70675
- full_compaction: "fullCompaction",
70676
- plan_mode: "planMode"
70709
+ full_compaction: "fullCompaction"
70677
70710
  }[recordType.split(".")[0]] ?? null;
70678
70711
  }
70679
70712
  async replay() {
@@ -82939,8 +82972,8 @@ var ToolManager = class {
82939
82972
  return (input) => withProviderRequestAuth(resolveAuth, (auth) => uploadVideo(input, { auth }));
82940
82973
  }
82941
82974
  get loopTools() {
82942
- const builtinNames = [...this.builtinTools.keys()].filter((name) => this.enabledTools.has(name)).sort();
82943
- const userNames = [...this.userTools.keys()].filter((name) => this.enabledTools.has(name)).sort();
82975
+ const builtinNames = [...this.builtinTools.keys()].filter((name) => this.enabledTools.has(name)).toSorted();
82976
+ const userNames = [...this.userTools.keys()].filter((name) => this.enabledTools.has(name)).toSorted();
82944
82977
  const mcpNames = [...this.mcpTools.keys()].filter((name) => this.isMcpToolEnabled(name));
82945
82978
  return [
82946
82979
  ...builtinNames.map((name) => this.builtinTools.get(name)),
@@ -83116,7 +83149,7 @@ function findImplicitBoundaries(prompt) {
83116
83149
  const index = prompt.indexOf(header);
83117
83150
  if (index !== -1) boundaries.push(index);
83118
83151
  }
83119
- return boundaries.sort((a, b) => a - b);
83152
+ return boundaries.toSorted((a, b) => a - b);
83120
83153
  }
83121
83154
  /**
83122
83155
  * Split prompt by implicit boundaries into blocks.
@@ -84541,15 +84574,6 @@ var Agent = class {
84541
84574
  getModel: () => {
84542
84575
  return this.config.modelAlias ?? "";
84543
84576
  },
84544
- enterPlan: async () => {
84545
- throw new ByfError(ErrorCodes.NOT_IMPLEMENTED, "Plan mode has been removed");
84546
- },
84547
- cancelPlan: async () => {
84548
- throw new ByfError(ErrorCodes.NOT_IMPLEMENTED, "Plan mode has been removed");
84549
- },
84550
- clearPlan: async () => {
84551
- throw new ByfError(ErrorCodes.NOT_IMPLEMENTED, "Plan mode has been removed");
84552
- },
84553
84577
  beginCompaction: (payload) => {
84554
84578
  this.fullCompaction.begin({
84555
84579
  source: "manual",
@@ -84584,7 +84608,6 @@ var Agent = class {
84584
84608
  getContext: () => this.context.data(),
84585
84609
  getConfig: () => this.config.data(),
84586
84610
  getPermission: () => this.permission.data(),
84587
- getPlan: async () => null,
84588
84611
  getUsage: () => this.usage.data(),
84589
84612
  getTools: () => this.tools.data(),
84590
84613
  getBackground: (payload) => this.background.list(payload.activeOnly ?? false, payload.limit)
@@ -84717,6 +84740,21 @@ function proxyWithExtraPayload(methods, extraPayload) {
84717
84740
  }, ...args);
84718
84741
  } });
84719
84742
  }
84743
+ /** The Zod `z.enum` literal inferred from registry keys. */
84744
+ const PROVIDER_TYPE_VALUES = Object.keys({
84745
+ exa: { defaultBaseUrl: "https://api.exa.ai/search" },
84746
+ brave: { defaultBaseUrl: "https://api.search.brave.com/res/v1/web/search" },
84747
+ firecrawl: { defaultBaseUrl: "https://api.firecrawl.dev/v2/search" }
84748
+ });
84749
+ const providerClassMap = /* @__PURE__ */ new Map();
84750
+ function registerProvider(type, cls) {
84751
+ providerClassMap.set(type, cls);
84752
+ }
84753
+ function createProvider(type, options) {
84754
+ const cls = providerClassMap.get(type);
84755
+ if (cls === void 0) throw new Error(`WebSearch provider type "${type}" is not registered. Did you import the provider module?`);
84756
+ return new cls(options);
84757
+ }
84720
84758
  //#endregion
84721
84759
  //#region ../agent-core/src/config/schema.ts
84722
84760
  const ProviderTypeSchema = z.enum([
@@ -84816,9 +84854,18 @@ const ByfServiceConfigSchema = z.object({
84816
84854
  oauth: OAuthRefSchema.optional(),
84817
84855
  customHeaders: StringRecordSchema.optional()
84818
84856
  });
84857
+ /** Provider type enum derived from webSearchProviderRegistry keys. */
84858
+ const WebSearchProviderTypeSchema = z.enum(PROVIDER_TYPE_VALUES);
84859
+ const WebSearchProviderConfigSchema = z.object({
84860
+ type: WebSearchProviderTypeSchema,
84861
+ apiKeys: z.array(z.string().min(1)).nonempty(),
84862
+ baseUrl: z.string().optional(),
84863
+ priority: z.number().int().positive()
84864
+ });
84865
+ const WebSearchConfigSchema = z.object({ providers: z.array(WebSearchProviderConfigSchema).nonempty() });
84819
84866
  const ServicesConfigSchema = z.object({
84820
- byfSearch: ByfServiceConfigSchema.optional(),
84821
- byfFetch: ByfServiceConfigSchema.optional()
84867
+ webSearch: WebSearchConfigSchema.optional(),
84868
+ fetchUrl: ByfServiceConfigSchema.optional()
84822
84869
  });
84823
84870
  const McpServerCommonFields = {
84824
84871
  enabled: z.boolean().optional(),
@@ -84884,8 +84931,8 @@ const LoopControlPatchSchema = LoopControlSchema.partial();
84884
84931
  const BackgroundConfigPatchSchema = BackgroundConfigSchema.partial();
84885
84932
  const ByfServiceConfigPatchSchema = ByfServiceConfigSchema.partial();
84886
84933
  const ServicesConfigPatchSchema = z.object({
84887
- byfSearch: ByfServiceConfigPatchSchema.optional(),
84888
- byfFetch: ByfServiceConfigPatchSchema.optional()
84934
+ webSearch: WebSearchConfigSchema.optional(),
84935
+ fetchUrl: ByfServiceConfigPatchSchema.optional()
84889
84936
  });
84890
84937
  const ByfConfigPatchSchema = z.object({
84891
84938
  providers: z.record(z.string(), ProviderConfigPatchSchema).optional(),
@@ -85133,10 +85180,15 @@ function transformServiceData(data) {
85133
85180
  const targetKey = snakeToCamel(key);
85134
85181
  if (targetKey === "oauth") out[targetKey] = isPlainObject$1(value) ? transformPlainObject(value) : value;
85135
85182
  else if (targetKey === "customHeaders") out[targetKey] = cloneObjectValue(value);
85183
+ else if (Array.isArray(value)) out[targetKey] = value.map((item) => isPlainObject$1(item) ? transformRecord(item, identity, snakeToCamel) : item);
85184
+ else if (isPlainObject$1(value)) out[targetKey] = transformPlainObject(value);
85136
85185
  else out[targetKey] = value;
85137
85186
  }
85138
85187
  return out;
85139
85188
  }
85189
+ function identity(v) {
85190
+ return v;
85191
+ }
85140
85192
  function transformLoopControlData(data) {
85141
85193
  const out = transformPlainObject(data);
85142
85194
  if (out["maxStepsPerTurn"] === void 0 && out["maxStepsPerRun"] !== void 0) out["maxStepsPerTurn"] = out["maxStepsPerRun"];
@@ -85156,11 +85208,11 @@ function configToTomlData(config) {
85156
85208
  delete out["default_yolo"];
85157
85209
  delete out["defaultYolo"];
85158
85210
  delete out["defaultPermissionMode"];
85211
+ delete out["default_thinking"];
85159
85212
  for (const key of [
85160
85213
  "defaultProvider",
85161
85214
  "defaultModel",
85162
85215
  "yolo",
85163
- "defaultThinking",
85164
85216
  "defaultPermissionMode",
85165
85217
  "mergeAllAvailableSkills",
85166
85218
  "extraSkillDirs"
@@ -85229,10 +85281,17 @@ function permissionRuleToToml(rule) {
85229
85281
  }
85230
85282
  function servicesToToml(services, rawServices) {
85231
85283
  const out = cloneRecord(rawServices);
85232
- if (services.byfSearch !== void 0) out["byf_search"] = serviceToToml(services.byfSearch);
85233
- else delete out["byf_search"];
85234
- if (services.byfFetch !== void 0) out["byf_fetch"] = serviceToToml(services.byfFetch);
85235
- else delete out["byf_fetch"];
85284
+ if (services.webSearch !== void 0 && services.webSearch.providers.length > 0) {
85285
+ const providersToml = services.webSearch.providers.map((p) => {
85286
+ const providerOut = {};
85287
+ for (const [key, value] of Object.entries(p)) setDefined(providerOut, camelToSnake(key), value);
85288
+ return providerOut;
85289
+ });
85290
+ out["web_search"] = out["web_search"] ?? {};
85291
+ out["web_search"]["providers"] = providersToml;
85292
+ } else delete out["web_search"];
85293
+ if (services.fetchUrl !== void 0) out["fetch_url"] = serviceToToml(services.fetchUrl);
85294
+ else delete out["fetch_url"];
85236
85295
  return out;
85237
85296
  }
85238
85297
  function serviceToToml(service) {
@@ -125212,11 +125271,15 @@ function createProxiedFetch(deps) {
125212
125271
  const proxyUrl = getProxyForUrl(url, envLookup, sysProxy);
125213
125272
  const noProxyMatch = noProxy !== void 0 && isNoProxyHost(hostname, noProxy);
125214
125273
  const controller = new AbortController();
125215
- const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
125274
+ const timeoutId = setTimeout(() => {
125275
+ controller.abort();
125276
+ }, REQUEST_TIMEOUT_MS);
125216
125277
  if (init?.signal) if (init.signal.aborted) {
125217
125278
  clearTimeout(timeoutId);
125218
125279
  controller.abort();
125219
- } else init.signal.addEventListener("abort", () => controller.abort(), { once: true });
125280
+ } else init.signal.addEventListener("abort", () => {
125281
+ controller.abort();
125282
+ }, { once: true });
125220
125283
  const mergedInit = {
125221
125284
  ...init,
125222
125285
  signal: controller.signal
@@ -125228,7 +125291,7 @@ function createProxiedFetch(deps) {
125228
125291
  return response;
125229
125292
  } catch (error) {
125230
125293
  clearTimeout(timeoutId);
125231
- if (isRetryableError(error) && proxyUrl && !noProxyMatch) return await retryViaProxy(input, init, proxyUrl, innerFetch);
125294
+ if (isRetryableError(error) && proxyUrl && !noProxyMatch) return retryViaProxy(input, init, proxyUrl, innerFetch);
125232
125295
  throw error;
125233
125296
  }
125234
125297
  };
@@ -125236,11 +125299,15 @@ function createProxiedFetch(deps) {
125236
125299
  }
125237
125300
  async function retryViaProxy(input, init, proxyUrl, innerFetch) {
125238
125301
  const controller = new AbortController();
125239
- const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
125302
+ const timeoutId = setTimeout(() => {
125303
+ controller.abort();
125304
+ }, REQUEST_TIMEOUT_MS);
125240
125305
  if (init?.signal) if (init.signal.aborted) {
125241
125306
  clearTimeout(timeoutId);
125242
125307
  controller.abort();
125243
- } else init.signal.addEventListener("abort", () => controller.abort(), { once: true });
125308
+ } else init.signal.addEventListener("abort", () => {
125309
+ controller.abort();
125310
+ }, { once: true });
125244
125311
  const dispatcher = new import_undici.ProxyAgent(proxyUrl);
125245
125312
  const retryInit = {
125246
125313
  ...init,
@@ -125390,82 +125457,188 @@ var RemoteFetchURLProvider = class {
125390
125457
  }
125391
125458
  };
125392
125459
  //#endregion
125393
- //#region ../agent-core/src/tools/providers/remote-web-search.ts
125394
- var RemoteWebSearchProvider = class {
125395
- tokenProvider;
125396
- apiKey;
125460
+ //#region ../agent-core/src/tools/providers/router.ts
125461
+ var AllProvidersFailedError = class extends Error {
125462
+ lastError;
125463
+ constructor(lastError) {
125464
+ super(`All search providers failed. Last error: ${lastError ?? "unknown"}`);
125465
+ this.lastError = lastError;
125466
+ this.name = "AllProvidersFailedError";
125467
+ }
125468
+ };
125469
+ var PriorityRouter = class {
125470
+ providers;
125471
+ constructor(providers) {
125472
+ this.providers = providers;
125473
+ }
125474
+ async search(query, options) {
125475
+ let lastError;
125476
+ for (const provider of this.providers) try {
125477
+ return await provider.search(query, options);
125478
+ } catch (error) {
125479
+ lastError = error instanceof Error ? error.message : String(error);
125480
+ }
125481
+ throw new AllProvidersFailedError(lastError);
125482
+ }
125483
+ };
125484
+ //#endregion
125485
+ //#region ../agent-core/src/tools/providers/exa.ts
125486
+ var ExaWebSearchProvider = class {
125487
+ apiKeys;
125397
125488
  baseUrl;
125398
- defaultHeaders;
125399
- customHeaders;
125400
125489
  fetchImpl;
125401
125490
  constructor(options) {
125402
- this.tokenProvider = options.tokenProvider;
125403
- this.apiKey = options.apiKey;
125404
- this.baseUrl = options.baseUrl;
125405
- this.defaultHeaders = options.defaultHeaders ?? {};
125406
- this.customHeaders = options.customHeaders ?? {};
125491
+ this.apiKeys = options.apiKeys;
125492
+ this.baseUrl = options.baseUrl ?? "https://api.exa.ai/search";
125407
125493
  this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
125408
125494
  }
125409
125495
  async search(query, options) {
125410
- const body = {
125411
- text_query: query,
125412
- limit: options?.limit ?? 5,
125413
- enable_page_crawling: options?.includeContent ?? false,
125414
- timeout_seconds: 30
125496
+ const limit = options?.limit ?? 5;
125497
+ const includeContent = options?.includeContent ?? false;
125498
+ const contents = {};
125499
+ if (includeContent) contents.text = { maxCharacters: 1e4 };
125500
+ else contents.highlights = {
125501
+ query,
125502
+ maxCharacters: 300
125415
125503
  };
125416
- const bodyJson = JSON.stringify(body);
125417
- const response = await this.post(bodyJson);
125418
- if (response.status === 401) {
125419
- const detail = await safeReadText(response);
125420
- throw new Error(`Remote search request failed: HTTP 401 (auth/unauthorized). ${detail}`.trim());
125421
- }
125422
- if (response.status !== 200) {
125423
- const detail = await safeReadText(response);
125424
- throw new Error(`Remote search request failed: HTTP ${String(response.status)}. ${detail}`.trim());
125425
- }
125426
- const json = await response.json();
125427
- return (Array.isArray(json.search_results) ? json.search_results : []).map((r) => {
125428
- const out = {
125429
- title: r.title ?? "",
125430
- url: r.url ?? "",
125431
- snippet: r.snippet ?? ""
125432
- };
125433
- if (typeof r.date === "string" && r.date.length > 0) out.date = r.date;
125434
- if (typeof r.content === "string" && r.content.length > 0) out.content = r.content;
125435
- return out;
125504
+ const body = JSON.stringify({
125505
+ query,
125506
+ numResults: limit,
125507
+ contents
125436
125508
  });
125509
+ let lastError;
125510
+ for (const apiKey of this.apiKeys) try {
125511
+ const response = await this.fetchImpl(this.baseUrl, {
125512
+ method: "POST",
125513
+ headers: {
125514
+ Authorization: `Bearer ${apiKey}`,
125515
+ "Content-Type": "application/json"
125516
+ },
125517
+ body
125518
+ });
125519
+ if (!response.ok) {
125520
+ const detail = (await response.text().catch(() => "")).slice(0, 200);
125521
+ throw new Error(`Exa search failed: HTTP ${response.status}${detail ? `: ${detail}` : ""}`);
125522
+ }
125523
+ const json = await response.json();
125524
+ return (Array.isArray(json.results) ? json.results : []).map((r) => {
125525
+ const out = {
125526
+ title: r.title ?? "",
125527
+ url: r.url ?? "",
125528
+ snippet: ""
125529
+ };
125530
+ if (includeContent && typeof r.text === "string") {
125531
+ out.snippet = r.text.slice(0, 300);
125532
+ if (r.text.length > 0) out.content = r.text;
125533
+ } else if (Array.isArray(r.highlights) && r.highlights.length > 0) out.snippet = r.highlights[0].slice(0, 300);
125534
+ if (typeof r.publishedDate === "string" && r.publishedDate.length > 0) out.date = r.publishedDate;
125535
+ return out;
125536
+ });
125537
+ } catch (error) {
125538
+ lastError = error instanceof Error ? error : new Error(String(error));
125539
+ }
125540
+ throw lastError ?? /* @__PURE__ */ new Error("Exa search failed: no API keys configured");
125437
125541
  }
125438
- async post(bodyJson) {
125439
- const accessToken = await this.resolveApiKey();
125440
- return this.fetchImpl(this.baseUrl, {
125441
- method: "POST",
125442
- headers: {
125443
- ...this.defaultHeaders,
125444
- Authorization: `Bearer ${accessToken}`,
125445
- "Content-Type": "application/json",
125446
- ...this.customHeaders
125447
- },
125448
- body: bodyJson
125449
- });
125542
+ };
125543
+ registerProvider("exa", ExaWebSearchProvider);
125544
+ //#endregion
125545
+ //#region ../agent-core/src/tools/providers/brave.ts
125546
+ var BraveWebSearchProvider = class {
125547
+ apiKeys;
125548
+ baseUrl;
125549
+ fetchImpl;
125550
+ constructor(options) {
125551
+ this.apiKeys = options.apiKeys;
125552
+ this.baseUrl = options.baseUrl ?? "https://api.search.brave.com/res/v1/web/search";
125553
+ this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
125450
125554
  }
125451
- async resolveApiKey() {
125452
- if (this.tokenProvider !== void 0) try {
125453
- return await this.tokenProvider.getAccessToken();
125555
+ async search(query, options) {
125556
+ const limit = options?.limit ?? 5;
125557
+ const url = new URL(this.baseUrl);
125558
+ url.searchParams.set("q", query);
125559
+ url.searchParams.set("count", String(limit));
125560
+ let lastError;
125561
+ for (const apiKey of this.apiKeys) try {
125562
+ const response = await this.fetchImpl(url.toString(), {
125563
+ method: "GET",
125564
+ headers: {
125565
+ "Accept": "application/json",
125566
+ "Accept-Encoding": "gzip",
125567
+ "X-Subscription-Token": apiKey
125568
+ }
125569
+ });
125570
+ if (!response.ok) {
125571
+ const detail = (await response.text().catch(() => "")).slice(0, 200);
125572
+ throw new Error(`Brave search failed: HTTP ${response.status}${detail ? `: ${detail}` : ""}`);
125573
+ }
125574
+ const json = await response.json();
125575
+ return (Array.isArray(json.web?.results) ? json.web.results : []).map((r) => {
125576
+ const out = {
125577
+ title: r.title ?? "",
125578
+ url: r.url ?? "",
125579
+ snippet: r.description ?? ""
125580
+ };
125581
+ if (typeof r.age === "string" && r.age.length > 0) out.date = r.age;
125582
+ return out;
125583
+ });
125454
125584
  } catch (error) {
125455
- if (this.apiKey !== void 0 && this.apiKey.length > 0) return this.apiKey;
125456
- throw error;
125585
+ lastError = error instanceof Error ? error : new Error(String(error));
125457
125586
  }
125458
- if (this.apiKey !== void 0 && this.apiKey.length > 0) return this.apiKey;
125459
- throw new Error("Remote search service is not configured: missing API key or token provider.");
125587
+ throw lastError ?? /* @__PURE__ */ new Error("Brave search failed: no API keys configured");
125460
125588
  }
125461
125589
  };
125462
- async function safeReadText(response) {
125463
- try {
125464
- return await response.text();
125465
- } catch {
125466
- return "";
125590
+ registerProvider("brave", BraveWebSearchProvider);
125591
+ //#endregion
125592
+ //#region ../agent-core/src/tools/providers/firecrawl.ts
125593
+ var FirecrawlWebSearchProvider = class {
125594
+ apiKeys;
125595
+ baseUrl;
125596
+ fetchImpl;
125597
+ constructor(options) {
125598
+ this.apiKeys = options.apiKeys;
125599
+ this.baseUrl = options.baseUrl ?? "https://api.firecrawl.dev/v2/search";
125600
+ this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
125467
125601
  }
125468
- }
125602
+ async search(query, options) {
125603
+ const limit = options?.limit ?? 5;
125604
+ const includeContent = options?.includeContent ?? false;
125605
+ const requestBody = {
125606
+ query,
125607
+ limit
125608
+ };
125609
+ if (includeContent) requestBody.scrapeOptions = { formats: ["markdown"] };
125610
+ const body = JSON.stringify(requestBody);
125611
+ let lastError;
125612
+ for (const apiKey of this.apiKeys) try {
125613
+ const response = await this.fetchImpl(this.baseUrl, {
125614
+ method: "POST",
125615
+ headers: {
125616
+ "Authorization": `Bearer ${apiKey}`,
125617
+ "Content-Type": "application/json"
125618
+ },
125619
+ body
125620
+ });
125621
+ if (!response.ok) {
125622
+ const detail = (await response.text().catch(() => "")).slice(0, 200);
125623
+ throw new Error(`Firecrawl search failed: HTTP ${response.status}${detail ? `: ${detail}` : ""}`);
125624
+ }
125625
+ const json = await response.json();
125626
+ return (Array.isArray(json.data?.web) ? json.data.web : []).map((r) => {
125627
+ const out = {
125628
+ title: r.title ?? "",
125629
+ url: r.url ?? "",
125630
+ snippet: r.description ?? ""
125631
+ };
125632
+ if (includeContent && typeof r.markdown === "string" && r.markdown.length > 0) out.content = r.markdown;
125633
+ return out;
125634
+ });
125635
+ } catch (error) {
125636
+ lastError = error instanceof Error ? error : new Error(String(error));
125637
+ }
125638
+ throw lastError ?? /* @__PURE__ */ new Error("Firecrawl search failed: no API keys configured");
125639
+ }
125640
+ };
125641
+ registerProvider("firecrawl", FirecrawlWebSearchProvider);
125469
125642
  //#endregion
125470
125643
  //#region ../agent-core/src/utils/environment.ts
125471
125644
  /**
@@ -125727,15 +125900,6 @@ var SessionAPIImpl = class {
125727
125900
  getModel({ agentId, ...payload }) {
125728
125901
  return this.getAgent(agentId).getModel(payload);
125729
125902
  }
125730
- enterPlan({ agentId, ...payload }) {
125731
- return this.getAgent(agentId).enterPlan(payload);
125732
- }
125733
- cancelPlan({ agentId, ...payload }) {
125734
- return this.getAgent(agentId).cancelPlan(payload);
125735
- }
125736
- clearPlan({ agentId, ...payload }) {
125737
- return this.getAgent(agentId).clearPlan(payload);
125738
- }
125739
125903
  beginCompaction({ agentId, ...payload }) {
125740
125904
  return this.getAgent(agentId).beginCompaction(payload);
125741
125905
  }
@@ -125776,9 +125940,6 @@ var SessionAPIImpl = class {
125776
125940
  getPermission({ agentId, ...payload }) {
125777
125941
  return this.getAgent(agentId).getPermission(payload);
125778
125942
  }
125779
- getPlan({ agentId, ...payload }) {
125780
- return this.getAgent(agentId).getPlan(payload);
125781
- }
125782
125943
  getUsage({ agentId, ...payload }) {
125783
125944
  return this.getAgent(agentId).getUsage(payload);
125784
125945
  }
@@ -126116,19 +126277,59 @@ function createRuntimeProviderAuthResolver(input, resolved = resolveRuntimeProvi
126116
126277
  function isAuthLoginRequired(error) {
126117
126278
  return isByfError(error) && error.code === ErrorCodes.AUTH_LOGIN_REQUIRED;
126118
126279
  }
126280
+ const CAPABILITY_DEFINITIONS = [
126281
+ {
126282
+ name: "image_in",
126283
+ returnKey: "image_in"
126284
+ },
126285
+ {
126286
+ name: "video_in",
126287
+ returnKey: "video_in"
126288
+ },
126289
+ {
126290
+ name: "audio_in",
126291
+ returnKey: "audio_in"
126292
+ },
126293
+ {
126294
+ name: "thinking",
126295
+ returnKey: "thinking"
126296
+ },
126297
+ {
126298
+ name: "always_thinking",
126299
+ returnKey: "thinking"
126300
+ },
126301
+ {
126302
+ name: "tool_use",
126303
+ returnKey: "tool_use"
126304
+ },
126305
+ {
126306
+ name: "thinking_effort",
126307
+ returnKey: "thinking_effort"
126308
+ },
126309
+ {
126310
+ name: "thinking_xhigh",
126311
+ returnKey: "thinking_xhigh"
126312
+ },
126313
+ {
126314
+ name: "thinking_max",
126315
+ returnKey: "thinking_max"
126316
+ }
126317
+ ];
126318
+ CAPABILITY_DEFINITIONS.map((d) => d.name);
126119
126319
  function resolveModelCapabilities(alias, provider) {
126120
126320
  const capabilities = new Set((alias.capabilities ?? []).map((capability) => capability.trim().toLowerCase()));
126121
126321
  const has = (capability) => capabilities.has(capability);
126122
- const providerCapability = createProvider(providerForCapabilityProbe(provider)).getCapability?.(provider.model) ?? UNKNOWN_CAPABILITY;
126322
+ const providerCapability = createProvider$1(providerForCapabilityProbe(provider)).getCapability?.(provider.model) ?? UNKNOWN_CAPABILITY;
126323
+ const returnKeyToNames = /* @__PURE__ */ new Map();
126324
+ for (const def of CAPABILITY_DEFINITIONS) {
126325
+ const names = returnKeyToNames.get(def.returnKey) ?? [];
126326
+ names.push(def.name);
126327
+ returnKeyToNames.set(def.returnKey, names);
126328
+ }
126329
+ const resolved = {};
126330
+ for (const [returnKey, names] of returnKeyToNames) resolved[returnKey] = names.some((n) => has(n)) || Boolean(providerCapability[returnKey]);
126123
126331
  return {
126124
- image_in: has("image_in") || providerCapability.image_in,
126125
- video_in: has("video_in") || providerCapability.video_in,
126126
- audio_in: has("audio_in") || providerCapability.audio_in,
126127
- thinking: has("thinking") || has("always_thinking") || providerCapability.thinking,
126128
- tool_use: has("tool_use") || providerCapability.tool_use,
126129
- thinking_effort: has("thinking_effort") || providerCapability.thinking_effort,
126130
- thinking_xhigh: has("thinking_xhigh") || providerCapability.thinking_xhigh,
126131
- thinking_max: has("thinking_max") || providerCapability.thinking_max,
126332
+ ...resolved,
126132
126333
  max_context_tokens: alias.maxContextSize
126133
126334
  };
126134
126335
  }
@@ -126936,15 +127137,6 @@ var ByfCore = class {
126936
127137
  getModel({ sessionId, ...payload }) {
126937
127138
  return this.sessionApi(sessionId).getModel(payload);
126938
127139
  }
126939
- enterPlan({ sessionId, ...payload }) {
126940
- return this.sessionApi(sessionId).enterPlan(payload);
126941
- }
126942
- cancelPlan({ sessionId, ...payload }) {
126943
- return this.sessionApi(sessionId).cancelPlan(payload);
126944
- }
126945
- clearPlan({ sessionId, ...payload }) {
126946
- return this.sessionApi(sessionId).clearPlan(payload);
126947
- }
126948
127140
  beginCompaction({ sessionId, ...payload }) {
126949
127141
  return this.sessionApi(sessionId).beginCompaction(payload);
126950
127142
  }
@@ -126984,9 +127176,6 @@ var ByfCore = class {
126984
127176
  getPermission({ sessionId, ...payload }) {
126985
127177
  return this.sessionApi(sessionId).getPermission(payload);
126986
127178
  }
126987
- getPlan({ sessionId, ...payload }) {
126988
- return this.sessionApi(sessionId).getPlan(payload);
126989
- }
126990
127179
  getUsage({ sessionId, ...payload }) {
126991
127180
  return this.sessionApi(sessionId).getUsage(payload);
126992
127181
  }
@@ -127074,8 +127263,8 @@ async function createRuntimeConfig(input) {
127074
127263
  systemProxy: () => detectSystemProxy()
127075
127264
  });
127076
127265
  const localFetcher = new LocalFetchURLProvider({ fetchImpl: proxiedFetch });
127077
- const searchService = input.config.services?.byfSearch;
127078
- const fetchService = input.config.services?.byfFetch;
127266
+ const fetchService = input.config.services?.fetchUrl;
127267
+ const webSearchConfig = input.config.services?.webSearch;
127079
127268
  return {
127080
127269
  kaos: localKaos,
127081
127270
  osEnv: await detectEnvironmentFromNode(),
@@ -127087,12 +127276,11 @@ async function createRuntimeConfig(input) {
127087
127276
  fetchImpl: proxiedFetch,
127088
127277
  ...serviceCredentials(fetchService, input.resolveOAuthTokenProvider)
127089
127278
  }),
127090
- webSearcher: searchService?.baseUrl === void 0 ? void 0 : new RemoteWebSearchProvider({
127091
- baseUrl: searchService.baseUrl,
127092
- defaultHeaders: input.byfRequestHeaders,
127093
- fetchImpl: proxiedFetch,
127094
- ...serviceCredentials(searchService, input.resolveOAuthTokenProvider)
127095
- })
127279
+ webSearcher: webSearchConfig === void 0 ? void 0 : new PriorityRouter([...webSearchConfig.providers].toSorted((a, b) => a.priority - b.priority).map((p) => createProvider(p.type, {
127280
+ apiKeys: p.apiKeys,
127281
+ baseUrl: p.baseUrl,
127282
+ fetchImpl: proxiedFetch
127283
+ })))
127096
127284
  };
127097
127285
  }
127098
127286
  function serviceCredentials(service, resolveOAuthTokenProvider) {
@@ -127127,7 +127315,6 @@ async function resumeSessionResult(summary, session, warning) {
127127
127315
  context,
127128
127316
  replay: agent.replayBuilder.buildResult(),
127129
127317
  permission,
127130
- plan: null,
127131
127318
  usage,
127132
127319
  tools: await api.getTools({ agentId }),
127133
127320
  toolStore: agent.tools.storeData(),
@@ -127228,7 +127415,8 @@ var SDKRpcClient = class {
127228
127415
  this.core = new ByfCore(coreRpc, {
127229
127416
  homeDir: options.homeDir,
127230
127417
  configPath: options.configPath,
127231
- skillDirs: options.skillDirs
127418
+ skillDirs: options.skillDirs,
127419
+ runtime: options.runtime
127232
127420
  });
127233
127421
  this.ready = sdkRpc(new ClientAPI(this)).then((rpc) => {
127234
127422
  this.rpc = rpc;
@@ -127327,18 +127515,6 @@ var SDKRpcClient = class {
127327
127515
  mode: input.mode
127328
127516
  });
127329
127517
  }
127330
- async getPlan(input) {
127331
- return (await this.getRpc()).getPlan({
127332
- sessionId: input.sessionId,
127333
- agentId: this.interactiveAgentId
127334
- });
127335
- }
127336
- async clearPlan(input) {
127337
- await (await this.getRpc()).clearPlan({
127338
- sessionId: input.sessionId,
127339
- agentId: this.interactiveAgentId
127340
- });
127341
- }
127342
127518
  async compact(input) {
127343
127519
  return (await this.getRpc()).beginCompaction({
127344
127520
  sessionId: input.sessionId,
@@ -127644,13 +127820,6 @@ var Session = class {
127644
127820
  mode
127645
127821
  });
127646
127822
  }
127647
- async getPlan() {
127648
- this.ensureOpen();
127649
- return null;
127650
- }
127651
- async clearPlan() {
127652
- this.ensureOpen();
127653
- }
127654
127823
  async compact(options = {}) {
127655
127824
  this.ensureOpen();
127656
127825
  const instruction = normalizeOptionalString(options.instruction);
@@ -127857,7 +128026,8 @@ var ByfHarness = class {
127857
128026
  this.rpc = new SDKRpcClient({
127858
128027
  homeDir: options.homeDir,
127859
128028
  configPath: this.configPath,
127860
- skillDirs: options.skillDirs
128029
+ skillDirs: options.skillDirs,
128030
+ runtime: options.runtime
127861
128031
  });
127862
128032
  }
127863
128033
  configureLogging() {
@@ -127872,7 +128042,7 @@ var ByfHarness = class {
127872
128042
  set interactiveAgentId(agentId) {
127873
128043
  this.rpc.interactiveAgentId = agentId;
127874
128044
  }
127875
- track(event, properties) {}
128045
+ track(_event, _properties) {}
127876
128046
  async createSession(options) {
127877
128047
  const summary = await this.rpc.createSession(options);
127878
128048
  const session = new Session({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byfriends/sdk",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Public TypeScript SDK for BYF agents and sessions",
5
5
  "license": "Proprietary",
6
6
  "author": "ByronFinn",
@@ -49,10 +49,10 @@
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/yazl": "^2.4.6",
52
- "@byfriends/agent-core": "^0.3.0",
53
- "@byfriends/kosong": "^0.2.3",
54
- "@byfriends/kaos": "^0.2.2",
55
- "@byfriends/oauth": "^0.1.1"
52
+ "@byfriends/agent-core": "^0.3.2",
53
+ "@byfriends/kosong": "^0.3.2",
54
+ "@byfriends/kaos": "^0.3.2",
55
+ "@byfriends/oauth": "^0.3.2"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsdown && pnpm run build:dts",