praxis-agent 0.63.0 → 0.64.0

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
@@ -28,8 +28,9 @@ sessions, configuration, or compatibility directories.
28
28
  - macOS or Linux
29
29
  - Node.js 24 or newer
30
30
  - [`ripgrep`](https://github.com/BurntSushi/ripgrep) (`rg`) for the Grep and Glob tools
31
- - an API key and model ID for an Anthropic, OpenAI-compatible, or OpenAI
32
- Responses provider (the stable setup), or the explicitly enabled experimental
31
+ - an API key for the uncustomized built-in Anthropic provider (which can select
32
+ its default model), or an API key and model ID for any other stable provider,
33
+ or the explicitly enabled experimental
33
34
  ChatGPT-backed Codex subscription integration
34
35
 
35
36
  Praxis does not use Claude subscription authentication. Claude-shaped message,
@@ -92,13 +93,18 @@ For Anthropic Messages:
92
93
  ```sh
93
94
  export PRAXIS_PROVIDER="anthropic"
94
95
  export PRAXIS_API_KEY="your-api-key"
96
+ # Optional: omit it, or use the exact value "default", for current Opus [1m]
95
97
  export PRAXIS_MODEL="claude-sonnet-4-6"
96
98
 
97
99
  cd /path/to/project
98
100
  praxis
99
101
  ```
100
102
 
101
- Anthropic models use a 200,000-token context window by default, including
103
+ For the uncustomized built-in `anthropic` provider, omitting `PRAXIS_MODEL` (or
104
+ setting it to the exact `default` alias) selects the current Opus model with a
105
+ 1,000,000-token context window (`claude-opus-5[1m]`). Other built-in providers
106
+ and custom providers still require an explicit model ID. Anthropic models use a
107
+ 200,000-token context window by default, including
102
108
  unknown model IDs. Add the exact terminal `[1m]` suffix (for example,
103
109
  `claude-sonnet-4-6[1m]`) to request a 1,000,000-token context window;
104
110
  Praxis keeps that selected model public, removes the suffix on the wire, and
@@ -306,7 +312,9 @@ troubleshooting. Run `praxis --help` for the authoritative command surface.
306
312
  route, whether primary or fallback, stays sticky only through that logical
307
313
  Turn's tool continuations; incompatible routes fail closed, and the next
308
314
  independent Turn starts from primary. Recovery may persist only an optional
309
- selected model, never provider route or wire state. Anthropic uses a
315
+ selected model, never provider route or wire state. Only the uncustomized
316
+ built-in Anthropic provider may omit a model, defaulting to
317
+ `claude-opus-5[1m]`; all other providers require an explicit model. Anthropic uses a
310
318
  200,000-token default or exact terminal `[1m]` model syntax for 1,000,000
311
319
  tokens; `PRAXIS_CONTEXT_WINDOW_TOKENS` overrides the advertised window.
312
320
  - **Transactional self-update** — `praxis update` verifies the package before
@@ -1,4 +1,6 @@
1
- export type AnthropicModelAliasOverrides = Readonly<Partial<Record<'sonnet' | 'opus' | 'haiku', string>>>;
1
+ export type AnthropicModelFamily = 'sonnet' | 'opus' | 'haiku';
2
+ export type AnthropicModelAliasOverrides = Readonly<Partial<Record<AnthropicModelFamily, string>>>;
3
+ export declare function resolveAnthropicModelAliasFamily(model: string): AnthropicModelFamily | undefined;
2
4
  export declare function anthropicModelAliasOverridesFromEnvironment(environment: Readonly<Record<string, string | undefined>>): AnthropicModelAliasOverrides;
3
5
  export declare function resolveAnthropicModelAlias(model: string, overrides?: AnthropicModelAliasOverrides): string;
4
6
  //# sourceMappingURL=anthropic-model-alias.d.ts.map
@@ -8,6 +8,13 @@ const ENVIRONMENT_KEYS = {
8
8
  opus: 'ANTHROPIC_DEFAULT_OPUS_MODEL',
9
9
  haiku: 'ANTHROPIC_DEFAULT_HAIKU_MODEL',
10
10
  };
11
+ export function resolveAnthropicModelAliasFamily(model) {
12
+ if (model === 'best' || model === 'default')
13
+ return 'opus';
14
+ if (model === 'sonnet' || model === 'opus' || model === 'haiku')
15
+ return model;
16
+ return undefined;
17
+ }
11
18
  export function anthropicModelAliasOverridesFromEnvironment(environment) {
12
19
  const overrides = {};
13
20
  for (const family of ['sonnet', 'opus', 'haiku']) {
@@ -23,14 +30,19 @@ export function anthropicModelAliasOverridesFromEnvironment(environment) {
23
30
  }
24
31
  export function resolveAnthropicModelAlias(model, overrides = {}) {
25
32
  const longContext = model.endsWith('[1m]');
26
- const family = longContext ? model.slice(0, -'[1m]'.length) : model;
27
- if (family !== 'sonnet' && family !== 'opus' && family !== 'haiku') {
28
- return model;
33
+ const forcedLongContext = model === 'default';
34
+ let family = resolveAnthropicModelAliasFamily(model);
35
+ if (family === undefined && longContext) {
36
+ const baseModel = model.slice(0, -'[1m]'.length);
37
+ if (baseModel !== 'best' && baseModel !== 'default')
38
+ family = resolveAnthropicModelAliasFamily(baseModel);
29
39
  }
40
+ if (family === undefined)
41
+ return model;
30
42
  if (longContext && family === 'haiku')
31
43
  return model;
32
44
  const resolved = overrides[family] ?? DEFAULTS[family];
33
- if (!longContext || resolved.endsWith('[1m]'))
45
+ if ((!longContext && !forcedLongContext) || resolved.endsWith('[1m]'))
34
46
  return resolved;
35
47
  return `${resolved}[1m]`;
36
48
  }
@@ -7,7 +7,7 @@ import { NonStreamingFallbackModelProvider } from './non-streaming-fallback-prov
7
7
  import { CodexOAuthCredentialManager, } from './codex-oauth.js';
8
8
  import { resolveProviderTarget, } from './provider-settings.js';
9
9
  import { resolveAnthropicModelSpec } from './anthropic-model-spec.js';
10
- import { anthropicModelAliasOverridesFromEnvironment, resolveAnthropicModelAlias, } from './anthropic-model-alias.js';
10
+ import { anthropicModelAliasOverridesFromEnvironment, resolveAnthropicModelAliasFamily, resolveAnthropicModelAlias, } from './anthropic-model-alias.js';
11
11
  import { ProviderAuthenticationError, resolveProviderCredential, } from './provider-auth.js';
12
12
  import { parseContextEnvironment, parseProviderEnvironment, } from './environment.js';
13
13
  import { createAnthropicPromptCachePolicyResolver, } from './anthropic-prompt-cache.js';
@@ -232,9 +232,10 @@ class NativeProviderRegistry {
232
232
  if (this.target.providerId !== 'anthropic' ||
233
233
  this.target.protocol !== 'anthropic-messages')
234
234
  return false;
235
- if (modelId !== 'sonnet' && modelId !== 'opus' && modelId !== 'haiku')
235
+ const family = resolveAnthropicModelAliasFamily(modelId);
236
+ if (family === undefined)
236
237
  return false;
237
- const override = this.options.anthropicModelAliasOverrides?.[modelId];
238
+ const override = this.options.anthropicModelAliasOverrides?.[family];
238
239
  return override !== undefined && override.trim().length > 0;
239
240
  }
240
241
  resolveTarget(target) {
@@ -29,6 +29,7 @@ const BUILT_INS = {
29
29
  },
30
30
  anthropic: {
31
31
  protocol: 'anthropic-messages',
32
+ defaultModel: 'default',
32
33
  profiles: {
33
34
  default: {
34
35
  baseUrl: 'https://api.anthropic.com/v1',
@@ -315,7 +316,7 @@ export async function resolveProviderTarget(options) {
315
316
  : undefined);
316
317
  if (!profile)
317
318
  throw new ProviderSettingsError('unknown_profile', `Invalid provider settings: unknown profile ${profileId} for provider ${providerId}`);
318
- const modelId = selected.model;
319
+ const modelId = selected.model ?? definition.defaultModel;
319
320
  if (!modelId)
320
321
  throw new ProviderSettingsError('model_required', 'Invalid provider settings: model is required');
321
322
  const override = environment.PRAXIS_BASE_URL;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "praxis-agent",
3
- "version": "0.63.0",
3
+ "version": "0.64.0",
4
4
  "description": "Local-first, single-user general agent for the command line.",
5
5
  "license": "MIT",
6
6
  "author": "wuqisen",