@askalf/dario 6.9.2 → 6.9.3

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.
@@ -16,11 +16,22 @@ export declare const CC_TEMPLATE: TemplateData;
16
16
  export declare function filterToolsForPlatform<T extends {
17
17
  name: string;
18
18
  }>(tools: T[], platform: string): T[];
19
+ /**
20
+ * A tool definition the API will accept: an `input_schema` object with a
21
+ * string `type`. A capture can carry less — the 2026-09-18T01:26Z rebake on
22
+ * CC v2.1.275 recorded `advisor` as `{"name":"advisor","description":"",
23
+ * "input_schema":{}}`, a remote-config tool caught half-loaded — and Fable
24
+ * refuses any request advertising it (`tools.0.custom.input_schema.type: Field
25
+ * required`, dario#1376) while other families let it through. The name stays
26
+ * KNOWN (CC_NATIVE_NAMES_UNION, identity mapping, the config-scoped
27
+ * preservation); the definition is never put on the wire.
28
+ */
29
+ export declare function isAdvertisableToolDefinition(def: unknown): boolean;
30
+ /** Names in the bundle whose definition is not advertisable (see above). Empty on a clean bake. */
31
+ export declare const CC_TOOL_DEFINITIONS_UNADVERTISABLE: Set<string>;
19
32
  /** CC's exact tool definitions for the current platform — filtered from the bundled union. */
20
33
  export declare const CC_TOOL_DEFINITIONS: {
21
34
  name: string;
22
- description: string;
23
- input_schema: Record<string, unknown>;
24
35
  }[];
25
36
  /** The UNFILTERED bundled union — every tool the bake knows across platforms
26
37
  * (PLATFORM_ONLY_TOOLS keeps the bundle a superset). The identity-mapping,
@@ -36,9 +47,8 @@ export declare const CC_TOOL_DEFINITIONS: {
36
47
  * merge-mode base array, and Fable's no-tools shape. */
37
48
  export declare const CC_TOOL_DEFINITIONS_UNION: {
38
49
  name: string;
39
- description: string;
40
- input_schema: Record<string, unknown>;
41
50
  }[];
51
+ /** Every name the bundle knows — including one whose definition is not advertisable (dario#1376). */
42
52
  export declare const CC_NATIVE_NAMES_UNION: Set<string>;
43
53
  /** CC's own tool names, EXACT case ("Read", "Bash", "Agent", …). A CC client's
44
54
  * tools identity-map to themselves and OVERRIDE TOOL_MAP — whose lowercase
@@ -29,8 +29,26 @@ export function filterToolsForPlatform(tools, platform) {
29
29
  return true;
30
30
  });
31
31
  }
32
+ /**
33
+ * A tool definition the API will accept: an `input_schema` object with a
34
+ * string `type`. A capture can carry less — the 2026-09-18T01:26Z rebake on
35
+ * CC v2.1.275 recorded `advisor` as `{"name":"advisor","description":"",
36
+ * "input_schema":{}}`, a remote-config tool caught half-loaded — and Fable
37
+ * refuses any request advertising it (`tools.0.custom.input_schema.type: Field
38
+ * required`, dario#1376) while other families let it through. The name stays
39
+ * KNOWN (CC_NATIVE_NAMES_UNION, identity mapping, the config-scoped
40
+ * preservation); the definition is never put on the wire.
41
+ */
42
+ export function isAdvertisableToolDefinition(def) {
43
+ if (!def || typeof def !== 'object')
44
+ return false;
45
+ const schema = def.input_schema;
46
+ return !!schema && typeof schema === 'object' && typeof schema.type === 'string';
47
+ }
48
+ /** Names in the bundle whose definition is not advertisable (see above). Empty on a clean bake. */
49
+ export const CC_TOOL_DEFINITIONS_UNADVERTISABLE = new Set(TEMPLATE.tools.filter((t) => !isAdvertisableToolDefinition(t)).map((t) => String(t.name)));
32
50
  /** CC's exact tool definitions for the current platform — filtered from the bundled union. */
33
- export const CC_TOOL_DEFINITIONS = filterToolsForPlatform(TEMPLATE.tools, process.platform);
51
+ export const CC_TOOL_DEFINITIONS = filterToolsForPlatform(TEMPLATE.tools.filter(isAdvertisableToolDefinition), process.platform);
34
52
  /** The UNFILTERED bundled union — every tool the bake knows across platforms
35
53
  * (PLATFORM_ONLY_TOOLS keeps the bundle a superset). The identity-mapping,
36
54
  * detection, and advertise paths intersect with what the CLIENT declared,
@@ -43,7 +61,8 @@ export const CC_TOOL_DEFINITIONS = filterToolsForPlatform(TEMPLATE.tools, proces
43
61
  * upstream). Host-filtered CC_TOOL_DEFINITIONS stays correct for the paths
44
62
  * with no client declaration to mirror: the full-template fallback, the
45
63
  * merge-mode base array, and Fable's no-tools shape. */
46
- export const CC_TOOL_DEFINITIONS_UNION = TEMPLATE.tools;
64
+ export const CC_TOOL_DEFINITIONS_UNION = TEMPLATE.tools.filter(isAdvertisableToolDefinition);
65
+ /** Every name the bundle knows — including one whose definition is not advertisable (dario#1376). */
47
66
  export const CC_NATIVE_NAMES_UNION = new Set(TEMPLATE.tools.map((t) => String(t.name)));
48
67
  /** CC's own tool names, EXACT case ("Read", "Bash", "Agent", …). A CC client's
49
68
  * tools identity-map to themselves and OVERRIDE TOOL_MAP — whose lowercase
@@ -2068,8 +2087,14 @@ export function buildCCRequest(clientBody, billingTag, cacheControl, identity, o
2068
2087
  // authoritative source, never the template.
2069
2088
  const availableCC = CC_TOOL_DEFINITIONS_UNION.filter((t) => !isMcpToolName(t.name) && clientToolNames.has(t.name.toLowerCase()));
2070
2089
  const mcpTools = clientTools.filter((t) => isMcpToolName(t.name));
2071
- ccRequest.tools = availableCC.length > 0 || mcpTools.length > 0
2072
- ? dedupeToolsByName([...availableCC, ...mcpTools])
2090
+ // A CC-native name the bundle knows but cannot advertise (dario#1376:
2091
+ // `advisor` captured with an empty schema) is still identity-mapped
2092
+ // above; the only usable definition is the client's own, so it goes out
2093
+ // verbatim, as MCP tools do. The client's schema is what its parser
2094
+ // expects back in any case.
2095
+ const clientOwnNative = clientTools.filter((t) => typeof t.name === 'string' && CC_TOOL_DEFINITIONS_UNADVERTISABLE.has(t.name) && isAdvertisableToolDefinition(t));
2096
+ ccRequest.tools = availableCC.length > 0 || mcpTools.length > 0 || clientOwnNative.length > 0
2097
+ ? dedupeToolsByName([...availableCC, ...clientOwnNative, ...mcpTools])
2073
2098
  : CC_TOOL_DEFINITIONS;
2074
2099
  }
2075
2100
  }
package/dist/proxy.js CHANGED
@@ -9,7 +9,7 @@ import { getAccessToken, getStatus, ignoreCcCredentials } from './oauth.js';
9
9
  import { buildHealthResponse, derivePoolStatus, probeRequested, shouldDiscloseHealthInternals, shouldRunServingProbe } from './health-response.js';
10
10
  import { getServingProbe } from './serving-probe.js';
11
11
  import { darioVersion } from './version.js';
12
- import { buildCCRequest, applyCcPromptCaching, isGenuineCCClient, parseEffortSuffix, reverseMapResponse, createStreamingReverseMapper, orderHeadersForOutbound, overlayTemplateHeaderValues, forwardClientCCIdentityHeaders, isMcpToolName, CC_TEMPLATE, effectiveCacheControl, withForced1hBeta } from './cc-template.js';
12
+ import { CC_TOOL_DEFINITIONS_UNADVERTISABLE, buildCCRequest, applyCcPromptCaching, isGenuineCCClient, parseEffortSuffix, reverseMapResponse, createStreamingReverseMapper, orderHeadersForOutbound, overlayTemplateHeaderValues, forwardClientCCIdentityHeaders, isMcpToolName, CC_TEMPLATE, effectiveCacheControl, withForced1hBeta } from './cc-template.js';
13
13
  import { stampCch, hasCchSeed } from './cch.js';
14
14
  import { foldTiming, timingHeaders, timingLogFields } from './timing.js';
15
15
  import { describeTemplate, detectDrift, checkCCCompat, probeInstalledCCVersion } from './live-fingerprint.js';
@@ -5650,6 +5650,11 @@ export async function startProxy(opts = {}) {
5650
5650
  // One-line template summary so users can tell at a glance whether they
5651
5651
  // booted on a fresh live capture or a stale bundled fallback.
5652
5652
  console.log(`[dario] template: ${describeTemplate(CC_TEMPLATE)}`);
5653
+ // A bundled definition the API refuses (dario#1376: advisor captured with an
5654
+ // empty schema) is kept as a known name and never advertised; say so once.
5655
+ if (CC_TOOL_DEFINITIONS_UNADVERTISABLE.size > 0) {
5656
+ console.log(`[dario] template: ${CC_TOOL_DEFINITIONS_UNADVERTISABLE.size} tool definition${CC_TOOL_DEFINITIONS_UNADVERTISABLE.size === 1 ? '' : 's'} without input_schema.type — known, never advertised: ${[...CC_TOOL_DEFINITIONS_UNADVERTISABLE].join(', ')}`);
5657
+ }
5653
5658
  // Drift check: compare captured CC version to the installed binary. If
5654
5659
  // they differ, force the background refresh to bypass TTL so the next
5655
5660
  // startup picks up the new capture. Drifted caches still serve the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "6.9.2",
3
+ "version": "6.9.3",
4
4
  "description": "Use your Claude and ChatGPT subscriptions in Cursor, Cline, Aider, Claude Code and the Agent SDK — at subscription pricing, not per-token API bills. One local Anthropic + OpenAI-compatible endpoint: either plan answers either wire shape, with automatic failover when one hits its limit.",
5
5
  "type": "module",
6
6
  "bin": {