indusagi 0.13.10 → 0.13.12

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.
Files changed (35) hide show
  1. package/dist/agent.js +204 -29
  2. package/dist/ai.js +204 -29
  3. package/dist/cli.js +92 -9
  4. package/dist/index.js +186 -21
  5. package/dist/llmgateway.js +81 -4
  6. package/dist/mcp.js +94 -12
  7. package/dist/react-host/jsx-dev-runtime.js +93 -0
  8. package/dist/react-ink.js +11 -5
  9. package/dist/runtime.js +81 -4
  10. package/dist/shell-app.js +92 -9
  11. package/dist/smithy.js +81 -4
  12. package/dist/swarm.js +81 -4
  13. package/dist/types/facade/agent.d.ts +1 -1
  14. package/dist/types/facade/agent.test.d.ts +1 -0
  15. package/dist/types/facade/ai.d.ts +1 -1
  16. package/dist/types/facade/bot/types.d.ts +3 -3
  17. package/dist/types/facade/mcp.d.ts +1 -1
  18. package/dist/types/facade/ml/adapters/openai-codex-responses.d.ts +1 -1
  19. package/dist/types/facade/ml/adapters/openai-codex-responses.test.d.ts +1 -0
  20. package/dist/types/facade/ml/adapters/openai-responses.d.ts +1 -1
  21. package/dist/types/facade/ml/adapters/openai-responses.test.d.ts +1 -0
  22. package/dist/types/facade/ml/adapters/simple-options.d.ts +2 -2
  23. package/dist/types/facade/ml/auth-store.d.ts +7 -0
  24. package/dist/types/facade/ml/auth-store.test.d.ts +1 -0
  25. package/dist/types/facade/ml/models.generated.d.ts +162 -0
  26. package/dist/types/facade/ml/types.d.ts +14 -1
  27. package/dist/types/llmgateway/connectors/openai-responses.test.d.ts +1 -0
  28. package/dist/types/llmgateway/contract/index.d.ts +2 -2
  29. package/dist/types/llmgateway/contract/model-card.d.ts +14 -0
  30. package/dist/types/llmgateway/contract/options.d.ts +3 -1
  31. package/dist/types/react-host/jsx-dev-runtime.d.ts +3 -0
  32. package/dist/types/react-host/loader.d.ts +1 -0
  33. package/dist/types/security/private-state.d.ts +3 -0
  34. package/dist/zoho.js +94 -12
  35. package/package.json +7 -2
@@ -4637,6 +4637,87 @@ export declare const MODELS: {
4637
4637
  contextWindow: number;
4638
4638
  maxTokens: number;
4639
4639
  };
4640
+ readonly "gpt-6-astra": {
4641
+ id: string;
4642
+ name: string;
4643
+ api: "openai-responses";
4644
+ provider: string;
4645
+ baseUrl: string;
4646
+ reasoning: true;
4647
+ reasoningEfforts: ("low" | "medium" | "high" | "xhigh" | "max")[];
4648
+ input: ("text" | "image")[];
4649
+ cost: {
4650
+ input: number;
4651
+ output: number;
4652
+ cacheRead: number;
4653
+ cacheWrite: number;
4654
+ };
4655
+ longContextPricing: {
4656
+ threshold: number;
4657
+ multipliers: {
4658
+ input: number;
4659
+ output: number;
4660
+ cacheRead: number;
4661
+ cacheWrite: number;
4662
+ };
4663
+ };
4664
+ contextWindow: number;
4665
+ maxTokens: number;
4666
+ };
4667
+ readonly "gpt-6-sol": {
4668
+ id: string;
4669
+ name: string;
4670
+ api: "openai-responses";
4671
+ provider: string;
4672
+ baseUrl: string;
4673
+ reasoning: true;
4674
+ reasoningEfforts: "high"[];
4675
+ input: ("text" | "image")[];
4676
+ cost: {
4677
+ input: number;
4678
+ output: number;
4679
+ cacheRead: number;
4680
+ cacheWrite: number;
4681
+ };
4682
+ longContextPricing: {
4683
+ threshold: number;
4684
+ multipliers: {
4685
+ input: number;
4686
+ output: number;
4687
+ cacheRead: number;
4688
+ cacheWrite: number;
4689
+ };
4690
+ };
4691
+ contextWindow: number;
4692
+ maxTokens: number;
4693
+ };
4694
+ readonly "gpt-6-luna": {
4695
+ id: string;
4696
+ name: string;
4697
+ api: "openai-responses";
4698
+ provider: string;
4699
+ baseUrl: string;
4700
+ reasoning: true;
4701
+ reasoningEfforts: ("low" | "medium" | "high" | "xhigh" | "max")[];
4702
+ input: ("text" | "image")[];
4703
+ cost: {
4704
+ input: number;
4705
+ output: number;
4706
+ cacheRead: number;
4707
+ cacheWrite: number;
4708
+ };
4709
+ longContextPricing: {
4710
+ threshold: number;
4711
+ multipliers: {
4712
+ input: number;
4713
+ output: number;
4714
+ cacheRead: number;
4715
+ cacheWrite: number;
4716
+ };
4717
+ };
4718
+ contextWindow: number;
4719
+ maxTokens: number;
4720
+ };
4640
4721
  readonly "gpt-5.6-sol": {
4641
4722
  id: string;
4642
4723
  name: string;
@@ -5098,6 +5179,87 @@ export declare const MODELS: {
5098
5179
  contextWindow: number;
5099
5180
  maxTokens: number;
5100
5181
  };
5182
+ readonly "gpt-6-astra": {
5183
+ id: string;
5184
+ name: string;
5185
+ api: "openai-codex-responses";
5186
+ provider: string;
5187
+ baseUrl: string;
5188
+ reasoning: true;
5189
+ reasoningEfforts: ("low" | "medium" | "high" | "xhigh" | "max")[];
5190
+ input: ("text" | "image")[];
5191
+ cost: {
5192
+ input: number;
5193
+ output: number;
5194
+ cacheRead: number;
5195
+ cacheWrite: number;
5196
+ };
5197
+ longContextPricing: {
5198
+ threshold: number;
5199
+ multipliers: {
5200
+ input: number;
5201
+ output: number;
5202
+ cacheRead: number;
5203
+ cacheWrite: number;
5204
+ };
5205
+ };
5206
+ contextWindow: number;
5207
+ maxTokens: number;
5208
+ };
5209
+ readonly "gpt-6-sol": {
5210
+ id: string;
5211
+ name: string;
5212
+ api: "openai-codex-responses";
5213
+ provider: string;
5214
+ baseUrl: string;
5215
+ reasoning: true;
5216
+ reasoningEfforts: "high"[];
5217
+ input: ("text" | "image")[];
5218
+ cost: {
5219
+ input: number;
5220
+ output: number;
5221
+ cacheRead: number;
5222
+ cacheWrite: number;
5223
+ };
5224
+ longContextPricing: {
5225
+ threshold: number;
5226
+ multipliers: {
5227
+ input: number;
5228
+ output: number;
5229
+ cacheRead: number;
5230
+ cacheWrite: number;
5231
+ };
5232
+ };
5233
+ contextWindow: number;
5234
+ maxTokens: number;
5235
+ };
5236
+ readonly "gpt-6-luna": {
5237
+ id: string;
5238
+ name: string;
5239
+ api: "openai-codex-responses";
5240
+ provider: string;
5241
+ baseUrl: string;
5242
+ reasoning: true;
5243
+ reasoningEfforts: ("low" | "medium" | "high" | "xhigh" | "max")[];
5244
+ input: ("text" | "image")[];
5245
+ cost: {
5246
+ input: number;
5247
+ output: number;
5248
+ cacheRead: number;
5249
+ cacheWrite: number;
5250
+ };
5251
+ longContextPricing: {
5252
+ threshold: number;
5253
+ multipliers: {
5254
+ input: number;
5255
+ output: number;
5256
+ cacheRead: number;
5257
+ cacheWrite: number;
5258
+ };
5259
+ };
5260
+ contextWindow: number;
5261
+ maxTokens: number;
5262
+ };
5101
5263
  };
5102
5264
  readonly opencode: {
5103
5265
  readonly "big-pickle": {
@@ -4,13 +4,14 @@ export type KnownApi = "mock-ai" | "openai-completions" | "openai-responses" | "
4
4
  export type Api = KnownApi | (string & {});
5
5
  export type KnownProvider = "mock" | "amazon-bedrock" | "anthropic" | "google" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "opencode" | "kimi" | "kimi-coding" | "sarvam" | "krutrim" | "nvidia";
6
6
  export type Provider = KnownProvider | string;
7
- export type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh";
7
+ export type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
8
8
  /** Per-level token allowances for reasoning, used only by token-budget providers. */
9
9
  export interface ThinkingBudgets {
10
10
  minimal?: number;
11
11
  low?: number;
12
12
  medium?: number;
13
13
  high?: number;
14
+ max?: number;
14
15
  }
15
16
  export interface StreamOptions {
16
17
  temperature?: number;
@@ -228,6 +229,8 @@ export interface Model<TApi extends Api> {
228
229
  provider: Provider;
229
230
  baseUrl: string;
230
231
  reasoning: boolean;
232
+ /** Explicit reasoning efforts accepted by this model; omitted when provider defaults apply. */
233
+ reasoningEfforts?: readonly Exclude<ThinkingLevel, "minimal">[];
231
234
  input: ("text" | "image")[];
232
235
  cost: {
233
236
  input: number;
@@ -235,6 +238,16 @@ export interface Model<TApi extends Api> {
235
238
  cacheRead: number;
236
239
  cacheWrite: number;
237
240
  };
241
+ /** Optional pricing tier applied by providers after an input-token threshold. */
242
+ longContextPricing?: {
243
+ threshold: number;
244
+ multipliers: {
245
+ input: number;
246
+ output: number;
247
+ cacheRead: number;
248
+ cacheWrite: number;
249
+ };
250
+ };
238
251
  contextWindow: number;
239
252
  maxTokens: number;
240
253
  headers?: Record<string, string>;
@@ -3,11 +3,11 @@
3
3
  *
4
4
  * Every downstream gateway module imports its vocabulary from this barrel.
5
5
  */
6
- export type { ProviderId, ApiKind, Modality, CostSheet, ModelCard, } from "./model-card";
6
+ export type { ProviderId, ApiKind, Modality, CostSheet, LongContextPricing, ModelCard, } from "./model-card";
7
7
  export type { JsonSchema, TextBlock, ThinkingBlock, ToolCallBlock, ToolResultBlock, ImageBlock, CommandBlock, Block, UserTurn, AssistantTurn, ToolTurn, Turn, ToolDescriptor, Conversation, } from "./conversation";
8
8
  export type { Usage, StopReason, Reply } from "./reply";
9
9
  export type { TextEmission, ThinkingEmission, ToolCallStartEmission, ToolCallDeltaEmission, UsageEmission, StopEmission, DoneEmission, ErrorEmission, Emission, Channel, } from "./emission";
10
- export type { ThinkingLevel, ToolChoice, StreamOptions, } from "./options";
10
+ export type { ThinkingLevel, ReasoningEffort, ToolChoice, StreamOptions, } from "./options";
11
11
  export type { GatewayErrorKind, GatewayErrorExtra, } from "./errors";
12
12
  export { GatewayError, gatewayError } from "./errors";
13
13
  export type { Connector, CredentialResolver } from "./connector";
@@ -5,6 +5,7 @@
5
5
  * behavior; connectors read it to shape their wire requests, and the pricing
6
6
  * helpers read it to turn token counts into money.
7
7
  */
8
+ import type { ReasoningEffort } from "./options";
8
9
  /**
9
10
  * The upstream organization that owns a model. This is the *vendor* identity,
10
11
  * independent of which HTTP dialect we speak to reach it (see {@link ApiKind}).
@@ -25,6 +26,16 @@ export interface CostSheet {
25
26
  readonly cacheReadPerMTok?: number;
26
27
  readonly cacheWritePerMTok?: number;
27
28
  }
29
+ /** Optional higher-price tier triggered by a long input context. */
30
+ export interface LongContextPricing {
31
+ readonly threshold: number;
32
+ readonly multipliers: {
33
+ readonly input: number;
34
+ readonly output: number;
35
+ readonly cacheRead: number;
36
+ readonly cacheWrite: number;
37
+ };
38
+ }
28
39
  /**
29
40
  * Static descriptor for one model. Identified by `id` within a `provider`.
30
41
  */
@@ -38,5 +49,8 @@ export interface ModelCard {
38
49
  readonly maxOutputTokens: number;
39
50
  readonly modalities: readonly Modality[];
40
51
  readonly reasoning: boolean;
52
+ /** Explicit wire efforts for models whose accepted set differs from provider defaults. */
53
+ readonly reasoningEfforts?: readonly ReasoningEffort[];
54
+ readonly longContextPricing?: LongContextPricing;
41
55
  readonly cost: CostSheet;
42
56
  }
@@ -9,7 +9,9 @@
9
9
  * How much reasoning budget to grant a reasoning-capable model.
10
10
  * `off` disables thinking entirely; the remaining levels scale the budget up.
11
11
  */
12
- export type ThinkingLevel = "off" | "low" | "medium" | "high" | "max";
12
+ export type ThinkingLevel = "off" | "low" | "medium" | "high" | "xhigh" | "max";
13
+ /** Reasoning efforts that can be sent on the wire (excluding disabled reasoning). */
14
+ export type ReasoningEffort = Exclude<ThinkingLevel, "off">;
13
15
  /** Constrains how the model may use the declared tools on this turn. */
14
16
  export type ToolChoice = "auto" | "required" | "none";
15
17
  /** Options for a single streaming or one-shot invocation. */
@@ -0,0 +1,3 @@
1
+ import type * as ReactJsxDevRuntimeTypes from "react/jsx-dev-runtime";
2
+ export declare const Fragment: typeof ReactJsxDevRuntimeTypes.Fragment;
3
+ export declare const jsxDEV: typeof ReactJsxDevRuntimeTypes.jsxDEV;
@@ -1,3 +1,4 @@
1
1
  export declare function loadHostReact(): Promise<typeof import("react")>;
2
2
  export declare function loadHostJsxRuntime(): Promise<typeof import("react/jsx-runtime")>;
3
+ export declare function loadHostJsxDevRuntime(): Promise<typeof import("react/jsx-dev-runtime")>;
3
4
  export declare function loadHostInk(): Promise<typeof import("ink")>;
@@ -0,0 +1,3 @@
1
+ export declare function ensurePrivateDirectorySync(path: string): void;
2
+ export declare function readPrivateFileSync(path: string): string | null;
3
+ export declare function atomicWritePrivateFileSync(path: string, content: string): void;
package/dist/zoho.js CHANGED
@@ -840,8 +840,96 @@ function platformOpenCommand(url) {
840
840
  }
841
841
 
842
842
  // src/facade/mcp-core/oauth/token-store.ts
843
- import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
844
- import { dirname, join } from "node:path";
843
+ import { join } from "node:path";
844
+
845
+ // src/security/private-state.ts
846
+ import {
847
+ chmodSync,
848
+ closeSync,
849
+ constants,
850
+ fchmodSync,
851
+ fstatSync,
852
+ lstatSync,
853
+ mkdirSync,
854
+ openSync,
855
+ readFileSync,
856
+ renameSync,
857
+ rmSync,
858
+ writeFileSync
859
+ } from "node:fs";
860
+ import { randomUUID } from "node:crypto";
861
+ import { dirname } from "node:path";
862
+ var NO_FOLLOW = constants.O_NOFOLLOW ?? 0;
863
+ var isPosix = () => process.platform !== "win32";
864
+ function assertOwned(uid, path) {
865
+ if (!isPosix() || process.getuid === void 0) return;
866
+ if (uid !== process.getuid()) throw new Error(`Refusing sensitive path not owned by the current user: ${path}`);
867
+ }
868
+ function ensurePrivateDirectorySync(path) {
869
+ try {
870
+ const current = lstatSync(path);
871
+ if (current.isSymbolicLink() || !current.isDirectory()) throw new Error(`Refusing non-directory sensitive state path: ${path}`);
872
+ assertOwned(current.uid, path);
873
+ } catch (error) {
874
+ if (error.code !== "ENOENT") throw error;
875
+ mkdirSync(path, { recursive: true, mode: 448 });
876
+ }
877
+ if (isPosix()) chmodSync(path, 448);
878
+ }
879
+ function validateExistingFile(path) {
880
+ try {
881
+ const current = lstatSync(path);
882
+ if (current.isSymbolicLink() || !current.isFile()) throw new Error(`Refusing non-regular sensitive file: ${path}`);
883
+ assertOwned(current.uid, path);
884
+ } catch (error) {
885
+ if (error.code === "ENOENT") return;
886
+ throw error;
887
+ }
888
+ }
889
+ function readPrivateFileSync(path) {
890
+ ensurePrivateDirectorySync(dirname(path));
891
+ validateExistingFile(path);
892
+ let fd;
893
+ try {
894
+ fd = openSync(path, constants.O_RDONLY | NO_FOLLOW);
895
+ } catch (error) {
896
+ if (error.code === "ENOENT") return null;
897
+ throw error;
898
+ }
899
+ try {
900
+ const current = fstatSync(fd);
901
+ if (!current.isFile()) throw new Error(`Refusing non-regular sensitive file: ${path}`);
902
+ assertOwned(current.uid, path);
903
+ if (isPosix()) fchmodSync(fd, 384);
904
+ return readFileSync(fd, "utf8");
905
+ } finally {
906
+ closeSync(fd);
907
+ }
908
+ }
909
+ function atomicWritePrivateFileSync(path, content) {
910
+ ensurePrivateDirectorySync(dirname(path));
911
+ validateExistingFile(path);
912
+ const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
913
+ let fd;
914
+ try {
915
+ fd = openSync(temporary, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | NO_FOLLOW, 384);
916
+ writeFileSync(fd, content, "utf8");
917
+ if (isPosix()) fchmodSync(fd, 384);
918
+ closeSync(fd);
919
+ fd = void 0;
920
+ renameSync(temporary, path);
921
+ if (isPosix()) chmodSync(path, 384);
922
+ } catch (error) {
923
+ if (fd !== void 0) closeSync(fd);
924
+ try {
925
+ rmSync(temporary, { force: true });
926
+ } catch {
927
+ }
928
+ throw error;
929
+ }
930
+ }
931
+
932
+ // src/facade/mcp-core/oauth/token-store.ts
845
933
  function defaultCredentialsDir() {
846
934
  const xdg = process.env.XDG_CONFIG_HOME;
847
935
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
@@ -858,10 +946,11 @@ function credentialsPath(credentialsDir, id) {
858
946
  }
859
947
  function readMcpOAuthState(credentialsDir, id) {
860
948
  const path = credentialsPath(credentialsDir, id);
861
- if (!existsSync(path)) return void 0;
862
949
  let raw;
863
950
  try {
864
- raw = readFileSync(path, "utf8");
951
+ const stored = readPrivateFileSync(path);
952
+ if (stored === null) return void 0;
953
+ raw = stored;
865
954
  } catch (e) {
866
955
  return void 0;
867
956
  }
@@ -876,15 +965,8 @@ function readMcpOAuthState(credentialsDir, id) {
876
965
  }
877
966
  function writeMcpOAuthState(credentialsDir, state) {
878
967
  const path = credentialsPath(credentialsDir, state.id);
879
- mkdirSync(dirname(path), { recursive: true });
880
- const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
881
968
  const json = JSON.stringify({ ...state, updatedAt: Date.now() }, null, 2);
882
- writeFileSync(tmp, json, { mode: 384 });
883
- renameSync(tmp, path);
884
- try {
885
- chmodSync(path, 384);
886
- } catch {
887
- }
969
+ atomicWritePrivateFileSync(path, json);
888
970
  }
889
971
  function clearMcpOAuthState(credentialsDir, id) {
890
972
  const path = credentialsPath(credentialsDir, id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "indusagi",
3
- "version": "0.13.10",
3
+ "version": "0.13.12",
4
4
  "description": "Indusagi — a terminal-first AI coding agent framework. Clean-room implementation.",
5
5
  "author": "Varun Israni",
6
6
  "license": "AGPL-3.0",
@@ -138,7 +138,7 @@
138
138
  "@types/react": "^18.3.30",
139
139
  "esbuild": "^0.28.0",
140
140
  "typescript": "^5.7.2",
141
- "vitest": "^2.1.8"
141
+ "vitest": "^4.1.11"
142
142
  },
143
143
  "dependencies": {
144
144
  "@anthropic-ai/sdk": "^0.100.1",
@@ -162,5 +162,10 @@
162
162
  "strip-ansi": "^7.2.0",
163
163
  "ulid": "^3.0.2",
164
164
  "zod": "^4.4.3"
165
+ },
166
+ "overrides": {
167
+ "fast-uri": "3.1.6",
168
+ "hono": "4.13.5",
169
+ "qs": "6.16.0"
165
170
  }
166
171
  }