@askalf/dario 3.4.4 → 3.4.5

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/README.md CHANGED
@@ -37,7 +37,7 @@ export ANTHROPIC_API_KEY=dario # or OPENAI_API_KEY=dario
37
37
 
38
38
  Opus, Sonnet, Haiku — all models, streaming, tool use. **Zero dependencies.** ~2,000 lines of TypeScript. Works with Cursor, Continue, Aider, LiteLLM, Hermes, OpenClaw, or any tool that speaks the Anthropic or OpenAI API. Auto-launches under [Bun](https://bun.sh) when available for TLS fingerprint fidelity. **Auto-detects OAuth config from your installed CC binary** so dario stays in sync forever — Anthropic can rotate client IDs and dario picks them up on the next run.
39
39
 
40
- dario is built and maintained by [askalf](https://askalf.org) the open-source foundation of the askalf agent platform. If you need more than a proxy, [see below](#askalf).
40
+ dario is the **per-request layer** one account, one workload, every request indistinguishable from CC on the wire. Session-level and account-level concerns (multi-account pooling, behavioral-classifier shaping, 24/7 fleets) live a layer above dario, in [askalf](https://askalf.org) — [see below](#askalf). Both are built by the same team on the same OAuth and billing infrastructure.
41
41
 
42
42
  <table>
43
43
  <tr>
@@ -91,7 +91,7 @@ dario is the only proxy that solves this. Instead of transforming your requests
91
91
  | **Approach** | Template replay — sends CC's actual request | Signal matching or none |
92
92
  | **Tools** | CC's exact tool definitions sent upstream | Client tools (detected) |
93
93
  | **Max plan limits** | Used correctly | Bypassed — billed separately |
94
- | **Detection resistance** | Undetectable without flagging CC itself | Detected by tool names, field order, effort level, etc. |
94
+ | **Detection resistance** | Undetectable at the per-request level without flagging CC itself | Detected by tool names, field order, effort level, etc. |
95
95
  | **Dependencies** | 0 | Many |
96
96
 
97
97
  <details>
@@ -521,11 +521,11 @@ curl http://localhost:3456/health
521
521
 
522
522
  ## askalf
523
523
 
524
- dario solves the API access problem your $200/mo subscription, usable everywhere, billed correctly.
524
+ **dario and askalf solve different layers of the same problem.**
525
525
 
526
- But a proxy has a ceiling. Every request still runs on your single account, with your subscription's rate limits, on your machine. When you need to scale beyond that multiple accounts, persistent browser sessions, desktop control, scheduled workflows, a fleet of agents that can run while you sleep that's what [askalf](https://askalf.org) is built for.
526
+ dario is the per-request layer: one account, one workload, every request on the wire indistinguishable from Claude Code. It's what you reach for when you want your Max/Pro subscription usable from any tool that speaks the Anthropic or OpenAI API. It does not pool accounts, shape sessions, distribute load, or care about cumulative behavioral signals those are not per-request concerns, and solving them at the per-request layer is a category error.
527
527
 
528
- **askalf** is the agent platform built on top of the same OAuth and billing infrastructure that powers dario:
528
+ **askalf** is the layer above that: multi-account pooling behind one endpoint, session and workload shaping to stay under Anthropic's session-level classifiers, persistent browser and desktop sessions, scheduling, and a hosted fleet that runs 24/7. Built on the same OAuth and billing infrastructure as dario.
529
529
 
530
530
  | | dario | askalf |
531
531
  |---|---|---|
@@ -578,6 +578,9 @@ Dario auto-detects OAuth config from your installed Claude Code binary. When CC
578
578
  **I'm hitting rate limits. What do I do?**
579
579
  Claude subscriptions have rolling 5-hour and 7-day usage windows. Check your utilization with Claude Code's `/usage` command or the [statusline](https://code.claude.com/docs/en/statusline). Rate limit errors from dario include utilization percentages and reset times so you can see exactly when capacity returns.
580
580
 
581
+ **My multi-agent workload is getting reclassified to overage even though dario template-replays per request. Why?**
582
+ Because reclassification at high agent volume is not a per-request problem. Anthropic's classifier operates on cumulative per-OAuth-session behavioral aggregates — token throughput, conversation depth, streaming duration, inter-arrival timing, thinking-block volume. Dario can make each individual request indistinguishable from Claude Code and still hit this wall on a long-running agent session, because the wall isn't at the request level. Thorough diagnostic work on this was contributed by [@belangertrading](https://github.com/belangertrading) in [#23](https://github.com/askalf/dario/issues/23), including the per-request v3.4.3 hardening that landed as a result. For the session-layer shaping itself — multi-account pooling, session rotation, workload distribution that keeps any single account from concentrating the behavioral signal — that's what [askalf](https://askalf.org) is built for. Different layer, different tool.
583
+
581
584
  If you're running a multi-agent workload and consistently hitting limits, [askalf](https://askalf.org) distributes load across multiple accounts automatically.
582
585
 
583
586
  **What are the usage limits?**
@@ -675,7 +678,7 @@ npm run dev # runs with tsx (no build needed)
675
678
  | Who | Contributions |
676
679
  |-----|---------------|
677
680
  | [@GodsBoy](https://github.com/GodsBoy) | Proxy authentication, token redaction, error sanitization ([#2](https://github.com/askalf/dario/pull/2)) |
678
- | [@belangertrading](https://github.com/belangertrading) | Billing classification investigation ([#4](https://github.com/askalf/dario/issues/4)), billing reclassification root cause ([#7](https://github.com/askalf/dario/issues/7)) |
681
+ | [@belangertrading](https://github.com/belangertrading) | Billing classification investigation ([#4](https://github.com/askalf/dario/issues/4)), cache_control fingerprinting ([#6](https://github.com/askalf/dario/issues/6)), billing reclassification root cause ([#7](https://github.com/askalf/dario/issues/7)), OAuth client_id discovery ([#12](https://github.com/askalf/dario/issues/12)), multi-agent session-level billing analysis ([#23](https://github.com/askalf/dario/issues/23)) |
679
682
 
680
683
  ## License
681
684
 
@@ -15,6 +15,7 @@ export declare const CC_TOOL_DEFINITIONS: {
15
15
  export declare const CC_SYSTEM_PROMPT: string;
16
16
  /** CC's agent identity string. */
17
17
  export declare const CC_AGENT_IDENTITY: string;
18
+ export declare function scrubFrameworkIdentifiers(text: string): string;
18
19
  /** Client tool name → CC tool mapping with parameter translation. */
19
20
  interface ToolMapping {
20
21
  ccTool: string;
@@ -17,6 +17,28 @@ export const CC_TOOL_DEFINITIONS = TEMPLATE.tools;
17
17
  export const CC_SYSTEM_PROMPT = TEMPLATE.system_prompt;
18
18
  /** CC's agent identity string. */
19
19
  export const CC_AGENT_IDENTITY = TEMPLATE.agent_identity;
20
+ // Framework identifiers that would flag non-CC usage. Stripped from the system
21
+ // prompt and from message content text blocks before the request goes upstream.
22
+ const FRAMEWORK_PATTERNS = [
23
+ // Compound/hyphenated patterns run first so their halves can't be eaten
24
+ // by the simpler word-level patterns below.
25
+ /\b(roo[- ]?cline|big[- ]?agi|claude[- ]?bridge)\b/gi,
26
+ /\b(openclaw|hermes|aider|cursor|windsurf|cline|continue|copilot|cody)\b/gi,
27
+ /\b(librechat|typingmind)\b/gi,
28
+ /\b(openai|gpt-4|gpt-3\.5)\b/gi,
29
+ /powered by [a-z]+/gi,
30
+ /\bgateway\b/gi,
31
+ // OC's sessions_* tool-name prefix — flagged as a fingerprint in dario#23.
32
+ /\bsessions_[a-z_]+\b/gi,
33
+ ];
34
+ export function scrubFrameworkIdentifiers(text) {
35
+ let result = text;
36
+ for (const pattern of FRAMEWORK_PATTERNS) {
37
+ pattern.lastIndex = 0;
38
+ result = result.replace(pattern, '');
39
+ }
40
+ return result;
41
+ }
20
42
  const TOOL_MAP = {
21
43
  // Direct maps
22
44
  bash: { ccTool: 'Bash', translateArgs: (a) => ({ command: a.cmd || a.command || a.c || '' }) },
@@ -194,15 +216,31 @@ export function buildCCRequest(clientBody, billingTag, cache1h, identity, opts =
194
216
  .map(b => b.text)
195
217
  .join('\n\n');
196
218
  }
197
- // Strip framework identifiers from system prompt that would flag non-CC usage
198
- const FRAMEWORK_PATTERNS = [
199
- /\b(openclaw|hermes|aider|cursor|windsurf|cline|continue|copilot|cody)\b/gi,
200
- /\b(openai|gpt-4|gpt-3\.5)\b/gi,
201
- /powered by [a-z]+/gi,
202
- /\bgateway\b/gi,
203
- ];
204
- for (const pattern of FRAMEWORK_PATTERNS) {
205
- systemText = systemText.replace(pattern, '');
219
+ systemText = scrubFrameworkIdentifiers(systemText);
220
+ // Also scrub framework identifiers from message content text blocks.
221
+ // Clients often inject their product name into user/tool messages as well,
222
+ // and the system-prompt-only scrub used to miss those.
223
+ for (const msg of messages) {
224
+ if (typeof msg.content === 'string') {
225
+ msg.content = scrubFrameworkIdentifiers(msg.content);
226
+ }
227
+ else if (Array.isArray(msg.content)) {
228
+ for (const block of msg.content) {
229
+ if (block.type === 'text' && typeof block.text === 'string') {
230
+ block.text = scrubFrameworkIdentifiers(block.text);
231
+ }
232
+ if (block.type === 'tool_result' && typeof block.content === 'string') {
233
+ block.content = scrubFrameworkIdentifiers(block.content);
234
+ }
235
+ if (block.type === 'tool_result' && Array.isArray(block.content)) {
236
+ for (const sub of block.content) {
237
+ if (sub.type === 'text' && typeof sub.text === 'string') {
238
+ sub.text = scrubFrameworkIdentifiers(sub.text);
239
+ }
240
+ }
241
+ }
242
+ }
243
+ }
206
244
  }
207
245
  // ── Build the CC request from template ──
208
246
  // Key order matches CC v2.1.104 exactly:
package/dist/proxy.js CHANGED
@@ -147,6 +147,7 @@ const ORCHESTRATION_TAG_NAMES = [
147
147
  'system-reminder', 'env', 'system_information', 'current_working_directory',
148
148
  'operating_system', 'default_shell', 'home_directory', 'task_metadata',
149
149
  'directories', 'thinking',
150
+ 'agent_persona', 'agent_context', 'tool_context', 'persona', 'tool_call',
150
151
  ];
151
152
  const ORCHESTRATION_PATTERNS = ORCHESTRATION_TAG_NAMES.flatMap(tag => [
152
153
  new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`, 'gi'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "3.4.4",
3
+ "version": "3.4.5",
4
4
  "description": "Use your Claude subscription as an API. No API key needed. Local proxy for Claude Max/Pro subscriptions.",
5
5
  "type": "module",
6
6
  "bin": {