@aisa-one/cli 0.1.2 → 0.1.4

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
@@ -187,6 +187,10 @@ Settings:
187
187
 
188
188
  Environment variable `AISA_API_KEY` takes precedence over stored key.
189
189
 
190
+ ## Known Issues
191
+
192
+ **GPT-4.1 streaming returns empty output.** The AISA gateway currently strips `choices[].delta.content` from GPT model SSE chunks, so streaming mode produces blank output for GPT models. Workaround: use `--no-stream` or switch to Claude/Qwen models which stream correctly. Non-streaming GPT works fine.
193
+
190
194
  ## Development
191
195
 
192
196
  ```bash
@@ -198,6 +202,24 @@ npm run dev # watch mode
198
202
  npm test # run tests
199
203
  ```
200
204
 
205
+ ## Appendix: Architecture Notes for Contributors
206
+
207
+ **Two base URLs.** The AISA platform uses separate base paths:
208
+ - LLM endpoints (chat, models): `https://api.aisa.one/v1/`
209
+ - Domain API endpoints (search, finance, twitter, video): `https://api.aisa.one/apis/v1/`
210
+
211
+ The `domain: true` option in `RequestOptions` (see `src/api.ts`) selects which base URL to use. The `run` command auto-detects based on the slug prefix.
212
+
213
+ **Parameter naming varies by endpoint.** Smart/full search uses `q`, scholar uses `query`, finance uses `ticker` (not `symbol`), Twitter uses `userName` (camelCase). Always check the [API Reference](https://docs.aisa.one/reference) for exact parameter names.
214
+
215
+ **Video generation is async.** POST to `/services/aigc/video-generation/video-synthesis` with header `X-DashScope-Async: enable`, then poll `GET /services/aigc/tasks?task_id=<id>` for status. Response shape uses `output.task_id`, `output.task_status`, `output.video_url`.
216
+
217
+ **Twitter write operations require login cookies.** `create_tweet_v2` and other action endpoints need `login_cookies` and `proxy` fields — they don't work with just the API key.
218
+
219
+ **Models API follows OpenAI format.** The `/v1/models` endpoint returns `owned_by` (not `provider`) and has no `name`, `pricing`, or `contextWindow` fields.
220
+
221
+ **Some financial endpoints return empty data.** `financial/prices` and `financial/financial-metrics/snapshot` may return `{}` for certain tickers. `financial/insider-trades`, `financial/news`, and `financial/filings` work reliably.
222
+
201
223
  ## License
202
224
 
203
225
  MIT
@@ -1,5 +1,5 @@
1
1
  export declare function balanceAction(): Promise<void>;
2
- export declare function usageAction(options: {
2
+ export declare function usageAction(_options: {
3
3
  limit?: string;
4
4
  days?: string;
5
5
  }): Promise<void>;
@@ -1,47 +1,13 @@
1
- import ora from "ora";
2
1
  import chalk from "chalk";
3
2
  import { requireApiKey } from "../config.js";
4
- import { apiRequest } from "../api.js";
5
- import { error, table } from "../utils/display.js";
3
+ import { hint } from "../utils/display.js";
6
4
  export async function balanceAction() {
7
- const key = requireApiKey();
8
- const spinner = ora("Fetching balance...").start();
9
- const res = await apiRequest(key, "credits/balance");
10
- if (!res.success || !res.data) {
11
- spinner.fail("Failed to fetch balance");
12
- error(res.error || "Unknown error");
13
- return;
14
- }
15
- spinner.stop();
16
- console.log(` Balance: ${chalk.green("$" + res.data.balance.toFixed(2))} ${res.data.currency}`);
17
- console.log(chalk.gray(" Add credits at https://aisa.one/dashboard/wallet"));
5
+ requireApiKey();
6
+ console.log(chalk.yellow(" Balance API is not yet available."));
7
+ hint("Check your balance at https://aisa.one/dashboard");
18
8
  }
19
- export async function usageAction(options) {
20
- const key = requireApiKey();
21
- const spinner = ora("Fetching usage...").start();
22
- const query = {};
23
- if (options.limit)
24
- query.limit = options.limit;
25
- if (options.days)
26
- query.days = options.days;
27
- const res = await apiRequest(key, "credits/usage", { query });
28
- if (!res.success || !res.data) {
29
- spinner.fail("Failed to fetch usage");
30
- error(res.error || "Unknown error");
31
- return;
32
- }
33
- spinner.stop();
34
- const { records } = res.data;
35
- if (records.length === 0) {
36
- console.log(" No usage records found.");
37
- return;
38
- }
39
- const rows = records.map((r) => [
40
- new Date(r.timestamp).toLocaleDateString(),
41
- r.api,
42
- r.endpoint,
43
- `$${r.cost.toFixed(4)}`,
44
- r.status,
45
- ]);
46
- console.log(table(["Date", "API", "Endpoint", "Cost", "Status"], rows));
9
+ export async function usageAction(_options) {
10
+ requireApiKey();
11
+ console.log(chalk.yellow(" Usage API is not yet available."));
12
+ hint("View usage history at https://aisa.one/dashboard");
47
13
  }
@@ -1,10 +1,10 @@
1
- export declare function apiListAction(options: {
1
+ export declare function apiListAction(_options: {
2
2
  category?: string;
3
3
  }): Promise<void>;
4
- export declare function apiSearchAction(query: string, options: {
4
+ export declare function apiSearchAction(_query: string, _options: {
5
5
  limit?: string;
6
6
  }): Promise<void>;
7
- export declare function apiShowAction(slug: string, path?: string): Promise<void>;
8
- export declare function apiCodeAction(slug: string, path: string, options: {
7
+ export declare function apiShowAction(_slug: string, _path?: string): Promise<void>;
8
+ export declare function apiCodeAction(_slug: string, _path: string, _options: {
9
9
  lang?: string;
10
10
  }): Promise<void>;
@@ -1,116 +1,26 @@
1
- import ora from "ora";
2
1
  import chalk from "chalk";
3
2
  import { requireApiKey } from "../config.js";
4
- import { apiRequest } from "../api.js";
5
- import { error, badge, table, hint, truncate } from "../utils/display.js";
6
- export async function apiListAction(options) {
7
- const key = requireApiKey();
8
- const spinner = ora("Listing APIs...").start();
9
- const query = {};
10
- if (options.category)
11
- query.category = options.category;
12
- const res = await apiRequest(key, "cli/apis", { query });
13
- if (!res.success || !res.data) {
14
- spinner.fail("Failed to list APIs");
15
- error(res.error || "Unknown error");
16
- return;
17
- }
18
- spinner.stop();
19
- const { apis } = res.data;
20
- if (apis.length === 0) {
21
- console.log(" No APIs found.");
22
- return;
23
- }
24
- for (const api of apis) {
25
- console.log(`\n ${chalk.cyan.bold(api.name)} ${chalk.gray(api.slug)} ${badge(api.category)}`);
26
- console.log(` ${chalk.gray(api.description)}`);
27
- const shown = api.endpoints.slice(0, 3);
28
- for (const ep of shown) {
29
- console.log(` ${chalk.yellow(ep.method.padEnd(6))} ${ep.path} ${chalk.gray("- " + truncate(ep.description, 50))}`);
30
- }
31
- if (api.endpoints.length > 3) {
32
- hint(`+${api.endpoints.length - 3} more endpoints`);
33
- }
34
- }
35
- console.log(chalk.gray("\n Run 'aisa api show <slug>' for endpoint details"));
3
+ import { hint } from "../utils/display.js";
4
+ const COMING_SOON = chalk.yellow(" API catalog is not yet available.");
5
+ const BROWSE_HINT = "Browse available APIs at https://docs.aisa.one/reference";
6
+ export async function apiListAction(_options) {
7
+ requireApiKey();
8
+ console.log(COMING_SOON);
9
+ hint(BROWSE_HINT);
10
+ hint("Use 'aisa run <slug> <path>' to call APIs directly");
36
11
  }
37
- export async function apiSearchAction(query, options) {
38
- const key = requireApiKey();
39
- const spinner = ora(`Searching "${query}"...`).start();
40
- const res = await apiRequest(key, "cli/apis/search", {
41
- method: "POST",
42
- body: { query, limit: parseInt(options.limit || "10") },
43
- });
44
- if (!res.success || !res.data) {
45
- spinner.fail("Search failed");
46
- error(res.error || "Unknown error");
47
- return;
48
- }
49
- spinner.stop();
50
- const { apis } = res.data;
51
- if (apis.length === 0) {
52
- console.log(` No APIs found for "${query}".`);
53
- return;
54
- }
55
- for (const api of apis) {
56
- console.log(`\n ${chalk.cyan.bold(api.name)} ${chalk.gray(api.slug)} ${badge(api.category)}`);
57
- console.log(` ${chalk.gray(api.description)}`);
58
- for (const ep of api.endpoints.slice(0, 2)) {
59
- console.log(` ${chalk.yellow(ep.method.padEnd(6))} ${ep.path}`);
60
- }
61
- }
62
- console.log(chalk.gray("\n Run 'aisa run <slug> <path>' to execute"));
12
+ export async function apiSearchAction(_query, _options) {
13
+ requireApiKey();
14
+ console.log(COMING_SOON);
15
+ hint(BROWSE_HINT);
63
16
  }
64
- export async function apiShowAction(slug, path) {
65
- const key = requireApiKey();
66
- const spinner = ora(`Loading ${slug}${path ? " " + path : ""}...`).start();
67
- const endpoint = path ? `cli/apis/${slug}${path}` : `cli/apis/${slug}`;
68
- const res = await apiRequest(key, endpoint);
69
- if (!res.success || !res.data) {
70
- spinner.fail("Failed to load API details");
71
- error(res.error || "Unknown error");
72
- return;
73
- }
74
- spinner.stop();
75
- const data = res.data;
76
- if ("endpoints" in data) {
77
- // ApiGroup
78
- console.log(`\n ${chalk.cyan.bold(data.name)} ${badge(data.category)}`);
79
- console.log(` ${data.description}\n`);
80
- for (const ep of data.endpoints) {
81
- console.log(` ${chalk.yellow(ep.method.padEnd(6))} ${ep.path}`);
82
- console.log(` ${chalk.gray(ep.description)}`);
83
- }
84
- }
85
- else {
86
- // ApiEndpoint with parameters
87
- console.log(`\n ${chalk.yellow(data.method)} ${data.path}`);
88
- console.log(` ${data.description}\n`);
89
- if (data.parameters && data.parameters.length > 0) {
90
- const rows = data.parameters.map((p) => [
91
- p.name,
92
- p.type,
93
- p.required ? chalk.red("required") : "optional",
94
- truncate(p.description, 40),
95
- ]);
96
- console.log(table(["Name", "Type", "Required", "Description"], rows));
97
- }
98
- console.log(chalk.gray(`\n Example: aisa run ${slug} ${data.path} -q "param=value"`));
99
- }
17
+ export async function apiShowAction(_slug, _path) {
18
+ requireApiKey();
19
+ console.log(COMING_SOON);
20
+ hint(BROWSE_HINT);
100
21
  }
101
- export async function apiCodeAction(slug, path, options) {
102
- const key = requireApiKey();
103
- const lang = options.lang || "typescript";
104
- const spinner = ora(`Generating ${lang} code...`).start();
105
- const res = await apiRequest(key, "cli/apis/code", {
106
- method: "POST",
107
- body: { slug, path, language: lang },
108
- });
109
- if (!res.success || !res.data) {
110
- spinner.fail("Failed to generate code");
111
- error(res.error || "Unknown error");
112
- return;
113
- }
114
- spinner.stop();
115
- console.log(`\n${res.data.code}`);
22
+ export async function apiCodeAction(_slug, _path, _options) {
23
+ requireApiKey();
24
+ console.log(COMING_SOON);
25
+ hint(BROWSE_HINT);
116
26
  }
@@ -1,4 +1,4 @@
1
- export declare const VERSION = "0.1.2";
1
+ export declare const VERSION = "0.1.4";
2
2
  export declare const BASE_URL = "https://api.aisa.one";
3
3
  export declare const CLI_BASE_URL = "https://api.aisa.one/v1";
4
4
  export declare const APIS_BASE_URL = "https://api.aisa.one/apis/v1";
package/dist/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- export const VERSION = "0.1.2";
1
+ export const VERSION = "0.1.4";
2
2
  export const BASE_URL = "https://api.aisa.one";
3
3
  export const CLI_BASE_URL = `${BASE_URL}/v1`;
4
4
  export const APIS_BASE_URL = `${BASE_URL}/apis/v1`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aisa-one/cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "CLI for the AISA unified AI infrastructure platform - access 70+ LLMs, web search, finance, Twitter, and video generation APIs",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",