@actionway/cli-dev 0.0.0-dev.32821683196.320940b928ff → 0.0.0-dev.32848766753.0e740c8908f1
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/assets/skill/actionway/SKILL.md +1 -1
- package/assets/skill/actionway/references/capabilities/income-statement.md +1 -1
- package/assets/skill/actionway/references/capabilities/market-quote.md +1 -1
- package/assets/skill/actionway/references/capabilities/search-securities.md +1 -1
- package/assets/skill/actionway/references/capabilities/stock-download.md +1 -1
- package/dist/index.js +45 -129
- package/package.json +6 -6
|
@@ -71,7 +71,7 @@ Right after a successful `actionway init`, run `actionway account wallet` once a
|
|
|
71
71
|
- [Image Search](references/capabilities/image-search.md) (`web.image.search`) — Find visually similar or relevant existing images on the public web.
|
|
72
72
|
- [Fetch URL](references/capabilities/fetch.md) (`web.fetch`) — Fetch a supported URL as text, Markdown, or bounded raw content.
|
|
73
73
|
- [Search Stock Media](references/capabilities/stock-search.md) (`stock-media.search`) — Search one or more supported stock-media providers.
|
|
74
|
-
- [Download Stock Media](references/capabilities/stock-download.md) (`stock-media.download`) —
|
|
74
|
+
- [Download Stock Media](references/capabilities/stock-download.md) (`stock-media.download`) — Authorize a selected stock-media result for local download.
|
|
75
75
|
- [Knowledge Search](references/capabilities/knowledge-search.md) (`knowledge.search`) — Search curated domain libraries for audio, visual, voice, writing, or meme references.
|
|
76
76
|
|
|
77
77
|
**Live data**
|
|
@@ -7,6 +7,6 @@ Get standardized annual or quarterly company income statements.
|
|
|
7
7
|
|
|
8
8
|
## Indicative price
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
$0.01
|
|
11
11
|
|
|
12
12
|
Prices are indicative catalog values refreshed with each skill release. Before calling, Inspect the chosen variant: Inspect's input Schema and USD quote are authoritative.
|
|
@@ -7,6 +7,6 @@ Get the latest available market quote for one or more comma-separated symbols.
|
|
|
7
7
|
|
|
8
8
|
## Indicative price
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
$0.01
|
|
11
11
|
|
|
12
12
|
Prices are indicative catalog values refreshed with each skill release. Before calling, Inspect the chosen variant: Inspect's input Schema and USD quote are authoritative.
|
|
@@ -7,6 +7,6 @@ Search stocks and other market securities by name or symbol.
|
|
|
7
7
|
|
|
8
8
|
## Indicative price
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
$0.01
|
|
11
11
|
|
|
12
12
|
Prices are indicative catalog values refreshed with each skill release. Before calling, Inspect the chosen variant: Inspect's input Schema and USD quote are authoritative.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Download Stock Media (`stock-media.download`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Authorize a selected stock-media result for local download.
|
|
4
4
|
|
|
5
5
|
- Users ask for it as: download a selected stock-media item; download stock image; download stock video.
|
|
6
6
|
- Takes url, structured-data → returns image, video. Runs synchronously.
|
package/dist/index.js
CHANGED
|
@@ -11460,15 +11460,12 @@ function registerKnowledgeCommands(program2, getTransport2) {
|
|
|
11460
11460
|
|
|
11461
11461
|
// ../cli-core/src/commands/stock-download.ts
|
|
11462
11462
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
11463
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
11463
|
+
import { mkdir, rename, rm, writeFile } from "node:fs/promises";
|
|
11464
11464
|
import { dirname, extname, isAbsolute as isAbsolute2 } from "node:path";
|
|
11465
11465
|
var DEFAULT_DOWNLOAD_DIR = "/workspace/.stock-media";
|
|
11466
11466
|
var FETCH_TIMEOUT_MS = 6e4;
|
|
11467
11467
|
var MAX_DOWNLOAD_BYTES = 200 * 1024 * 1024;
|
|
11468
11468
|
var ASSET_ID_RE = /^([a-z0-9_-]+):([a-zA-Z0-9_.-]+)$/;
|
|
11469
|
-
function stockDownloadAvailable() {
|
|
11470
|
-
return false;
|
|
11471
|
-
}
|
|
11472
11469
|
var MIME_TO_EXT = /* @__PURE__ */ new Map([
|
|
11473
11470
|
["image/jpeg", "jpg"],
|
|
11474
11471
|
["image/jpg", "jpg"],
|
|
@@ -11579,7 +11576,7 @@ async function fetchBytes(url) {
|
|
|
11579
11576
|
clearTimeout(timer);
|
|
11580
11577
|
}
|
|
11581
11578
|
}
|
|
11582
|
-
function registerStockDownload(parent) {
|
|
11579
|
+
function registerStockDownload(parent, deps) {
|
|
11583
11580
|
parent.command("download").description("Fetch a stock-media asset (CDN URL from search result) into /workspace and echo full metadata.").addHelpText(
|
|
11584
11581
|
"after",
|
|
11585
11582
|
[
|
|
@@ -11589,19 +11586,12 @@ function registerStockDownload(parent) {
|
|
|
11589
11586
|
"so the local result retains its source and license metadata."
|
|
11590
11587
|
].join("\n")
|
|
11591
11588
|
).requiredOption("--asset-id <id>", "<provider>:<native_id> from a search result").requiredOption("--url <url>", "direct CDN URL from search result's download_url").option("--to <path>", `absolute path under /workspace (default: ${DEFAULT_DOWNLOAD_DIR}/<provider>-<id>.<ext>)`).option("--metadata-json <json>", "JSON-encoded metadata object from the search result; echoed back in output").action(async (opts) => {
|
|
11592
|
-
if (!stockDownloadAvailable()) {
|
|
11593
|
-
fail({
|
|
11594
|
-
code: "E_CAPABILITY_NOT_AVAILABLE",
|
|
11595
|
-
message: "stock download is deferred until Gateway command-level billing is available",
|
|
11596
|
-
hint: "do not fetch the asset directly as a workaround; wait for the stage-two stock billing integration"
|
|
11597
|
-
});
|
|
11598
|
-
}
|
|
11599
11589
|
const { provider, nativeId } = parseAssetId(String(opts.assetId));
|
|
11600
11590
|
const url = String(opts.url);
|
|
11601
11591
|
try {
|
|
11602
11592
|
const parsedUrl = new URL(url);
|
|
11603
|
-
if (parsedUrl.protocol !== "https:"
|
|
11604
|
-
fail({ code: "E_SCHEMA", message: `--url must
|
|
11593
|
+
if (parsedUrl.protocol !== "https:") {
|
|
11594
|
+
fail({ code: "E_SCHEMA", message: `--url must use https; got protocol ${parsedUrl.protocol}` });
|
|
11605
11595
|
}
|
|
11606
11596
|
} catch (err) {
|
|
11607
11597
|
if (err.name === "TypeError") {
|
|
@@ -11618,7 +11608,22 @@ function registerStockDownload(parent) {
|
|
|
11618
11608
|
const defaultPath = `${DEFAULT_DOWNLOAD_DIR}/${provider}-${nativeId}.${ext}`;
|
|
11619
11609
|
const destination = explicitDestination ?? validateDestination(void 0, defaultPath);
|
|
11620
11610
|
await mkdir(dirname(destination), { recursive: true });
|
|
11621
|
-
|
|
11611
|
+
const temporary = `${destination}.actionway-${jobRef}.tmp`;
|
|
11612
|
+
await writeFile(temporary, buf, { flag: "wx" });
|
|
11613
|
+
try {
|
|
11614
|
+
const transport = deps.getTransport();
|
|
11615
|
+
const body = { provider, native_id: nativeId, url, destination, kind: contentType?.startsWith("video/") ? "video" : "image" };
|
|
11616
|
+
if (deps.projectToolCall) {
|
|
11617
|
+
const response = await transport.callTool({ toolRef: "stock-media.download", arguments: body, idempotencyKey: jobRef, confirmation: { kind: "typed-command" } }, { jobRef, retries: 1 });
|
|
11618
|
+
if (response.status !== "completed") throw new StockDownloadError("stock download authorization did not complete");
|
|
11619
|
+
} else {
|
|
11620
|
+
await transport.post("internal/stock/download", body, { jobRef, retries: 1 });
|
|
11621
|
+
}
|
|
11622
|
+
await rename(temporary, destination);
|
|
11623
|
+
} catch (error) {
|
|
11624
|
+
await rm(temporary, { force: true });
|
|
11625
|
+
throw error;
|
|
11626
|
+
}
|
|
11622
11627
|
ok({
|
|
11623
11628
|
job_ref: jobRef,
|
|
11624
11629
|
asset_id: `${provider}:${nativeId}`,
|
|
@@ -11900,9 +11905,6 @@ var STOCK_DEFAULT_PROVIDER_ORDER = ["pexels", "pixabay", "openverse"];
|
|
|
11900
11905
|
var STOCK_ORIENTATIONS = ["landscape", "portrait", "square"];
|
|
11901
11906
|
var STOCK_TYPES = ["image", "video"];
|
|
11902
11907
|
var STOCK_MODES = ["fallback", "fanout"];
|
|
11903
|
-
function isStockSearchAvailable() {
|
|
11904
|
-
return false;
|
|
11905
|
-
}
|
|
11906
11908
|
function parsePositiveInt(raw, flag, max) {
|
|
11907
11909
|
const n = Number(raw);
|
|
11908
11910
|
if (!Number.isFinite(n) || !Number.isInteger(n) || n < 1 || n > max) {
|
|
@@ -11938,88 +11940,15 @@ function parseProviders(csv, type) {
|
|
|
11938
11940
|
}
|
|
11939
11941
|
return enabled;
|
|
11940
11942
|
}
|
|
11941
|
-
function
|
|
11942
|
-
if (err instanceof TransportError) {
|
|
11943
|
-
return {
|
|
11944
|
-
provider,
|
|
11945
|
-
...err.status !== void 0 ? { status: err.status } : {},
|
|
11946
|
-
reason: `${err.status ?? "transport"}: ${err.message}`
|
|
11947
|
-
};
|
|
11948
|
-
}
|
|
11949
|
-
if (err instanceof Error) return { provider, reason: err.message };
|
|
11950
|
-
return { provider, reason: String(err) };
|
|
11951
|
-
}
|
|
11952
|
-
function mergeResults(perProvider, limit) {
|
|
11953
|
-
const merged = [];
|
|
11954
|
-
const seen = /* @__PURE__ */ new Set();
|
|
11955
|
-
const cursors = perProvider.map(() => 0);
|
|
11956
|
-
let active = perProvider.filter((arr) => arr.length > 0).length;
|
|
11957
|
-
while (merged.length < limit && active > 0) {
|
|
11958
|
-
active = 0;
|
|
11959
|
-
for (let i = 0; i < perProvider.length; i++) {
|
|
11960
|
-
const arr = perProvider[i];
|
|
11961
|
-
const cursor = cursors[i];
|
|
11962
|
-
if (arr === void 0 || cursor === void 0 || cursor >= arr.length) continue;
|
|
11963
|
-
const r = arr[cursor];
|
|
11964
|
-
cursors[i] = cursor + 1;
|
|
11965
|
-
if (r !== void 0 && !seen.has(r.asset_id)) {
|
|
11966
|
-
seen.add(r.asset_id);
|
|
11967
|
-
merged.push(r);
|
|
11968
|
-
if (merged.length >= limit) break;
|
|
11969
|
-
}
|
|
11970
|
-
if (cursor + 1 < arr.length) active += 1;
|
|
11971
|
-
}
|
|
11972
|
-
}
|
|
11973
|
-
return merged;
|
|
11974
|
-
}
|
|
11975
|
-
async function searchSequential(enabled, opts, limit, searchFn) {
|
|
11976
|
-
const collected = [];
|
|
11977
|
-
const seen = /* @__PURE__ */ new Set();
|
|
11978
|
-
const queried = [];
|
|
11979
|
-
const failed = [];
|
|
11980
|
-
for (const name of enabled) {
|
|
11981
|
-
queried.push(name);
|
|
11982
|
-
try {
|
|
11983
|
-
const results = await searchFn(name, opts);
|
|
11984
|
-
for (const r of results) {
|
|
11985
|
-
if (!seen.has(r.asset_id)) {
|
|
11986
|
-
seen.add(r.asset_id);
|
|
11987
|
-
collected.push(r);
|
|
11988
|
-
if (collected.length >= limit) break;
|
|
11989
|
-
}
|
|
11990
|
-
}
|
|
11991
|
-
} catch (err) {
|
|
11992
|
-
failed.push(describeProviderFailure(name, err));
|
|
11993
|
-
}
|
|
11994
|
-
if (collected.length >= limit) break;
|
|
11995
|
-
}
|
|
11996
|
-
return { results: collected.slice(0, limit), queried, failed };
|
|
11997
|
-
}
|
|
11998
|
-
async function searchFanout(enabled, opts, limit, searchFn) {
|
|
11999
|
-
const settled = await Promise.allSettled(enabled.map((n) => searchFn(n, opts)));
|
|
12000
|
-
const perProviderResults = [];
|
|
12001
|
-
const failed = [];
|
|
12002
|
-
for (let i = 0; i < enabled.length; i++) {
|
|
12003
|
-
const r = settled[i];
|
|
12004
|
-
const name = enabled[i];
|
|
12005
|
-
if (r !== void 0 && r.status === "fulfilled") {
|
|
12006
|
-
perProviderResults.push(r.value);
|
|
12007
|
-
} else {
|
|
12008
|
-
perProviderResults.push([]);
|
|
12009
|
-
if (r !== void 0 && name !== void 0) failed.push(describeProviderFailure(name, r.reason));
|
|
12010
|
-
}
|
|
12011
|
-
}
|
|
12012
|
-
return { results: mergeResults(perProviderResults, limit), queried: [...enabled], failed };
|
|
12013
|
-
}
|
|
12014
|
-
function registerStockSearch(parent, getTransport2) {
|
|
11943
|
+
function registerStockSearch(parent, deps) {
|
|
12015
11944
|
parent.command("search").description(
|
|
12016
11945
|
"Sequential-fallback search across providers (Pexels -> Pixabay -> Openverse). Use --mode=fanout for parallel."
|
|
12017
11946
|
).addHelpText(
|
|
12018
11947
|
"after",
|
|
12019
11948
|
[
|
|
12020
11949
|
"",
|
|
12021
|
-
"
|
|
12022
|
-
"
|
|
11950
|
+
"Execution:",
|
|
11951
|
+
" Gateway orchestrates all selected providers and bills the search once.",
|
|
12023
11952
|
"",
|
|
12024
11953
|
"Modes:",
|
|
12025
11954
|
" fallback (default) - calls Pexels -> Pixabay -> Openverse in order and stops once limit results are collected.",
|
|
@@ -12048,13 +11977,6 @@ function registerStockSearch(parent, getTransport2) {
|
|
|
12048
11977
|
`search strategy: ${STOCK_MODES.join(" | ")} (default fallback saves API budget)`,
|
|
12049
11978
|
"fallback"
|
|
12050
11979
|
).action(async (opts) => {
|
|
12051
|
-
if (!isStockSearchAvailable()) {
|
|
12052
|
-
fail({
|
|
12053
|
-
code: "E_CAPABILITY_NOT_AVAILABLE",
|
|
12054
|
-
message: "stock search is not available in migration stage one",
|
|
12055
|
-
hint: "Gateway command-level stock billing/orchestration is required before this command can be enabled."
|
|
12056
|
-
});
|
|
12057
|
-
}
|
|
12058
11980
|
const type = String(opts.type);
|
|
12059
11981
|
if (!STOCK_TYPES.includes(type)) {
|
|
12060
11982
|
fail({ code: "E_SCHEMA", message: `--type must be image|video; got ${String(opts.type)}` });
|
|
@@ -12071,42 +11993,35 @@ function registerStockSearch(parent, getTransport2) {
|
|
|
12071
11993
|
}
|
|
12072
11994
|
const limit = typeof opts.limit === "number" ? opts.limit : 10;
|
|
12073
11995
|
const enabled = parseProviders(opts.providers !== void 0 ? String(opts.providers) : void 0, type);
|
|
12074
|
-
const perProviderLimit = mode === "fanout" ? Math.max(1, Math.ceil(limit * 1.5 / enabled.length)) : limit;
|
|
12075
11996
|
const searchOpts = {
|
|
12076
11997
|
query: String(opts.query),
|
|
12077
11998
|
type,
|
|
12078
11999
|
...opts.orientation !== void 0 ? { orientation: String(opts.orientation) } : {},
|
|
12079
12000
|
...typeof opts.minWidth === "number" ? { minWidth: opts.minWidth } : {},
|
|
12080
12001
|
...typeof opts.durationMin === "number" ? { durationMin: opts.durationMin } : {},
|
|
12081
|
-
...typeof opts.durationMax === "number" ? { durationMax: opts.durationMax } : {}
|
|
12082
|
-
perProviderLimit
|
|
12002
|
+
...typeof opts.durationMax === "number" ? { durationMax: opts.durationMax } : {}
|
|
12083
12003
|
};
|
|
12084
12004
|
const jobRef = randomUUID4();
|
|
12085
12005
|
try {
|
|
12086
|
-
const transport =
|
|
12087
|
-
const
|
|
12088
|
-
const provider = ALL_PROVIDERS[name];
|
|
12089
|
-
if (!provider) throw new Error(`unknown stock provider: ${name}`);
|
|
12090
|
-
return provider.search(o, transport);
|
|
12091
|
-
};
|
|
12092
|
-
const { results, queried, failed } = mode === "fanout" ? await searchFanout(enabled, searchOpts, limit, searchFn) : await searchSequential(enabled, searchOpts, limit, searchFn);
|
|
12093
|
-
if (results.length === 0 && failed.length > 0 && failed.length === queried.length) {
|
|
12094
|
-
fail({
|
|
12095
|
-
code: "E_BACKEND",
|
|
12096
|
-
message: `all stock-media providers failed for "${String(opts.query)}"`,
|
|
12097
|
-
hint: "check gateway provider routes / quota; see providers_failed for per-provider reason.",
|
|
12098
|
-
extra: { job_ref: jobRef, mode, providers_queried: queried, providers_failed: failed }
|
|
12099
|
-
});
|
|
12100
|
-
}
|
|
12101
|
-
ok({
|
|
12102
|
-
job_ref: jobRef,
|
|
12006
|
+
const transport = deps.getTransport();
|
|
12007
|
+
const body = {
|
|
12103
12008
|
query: searchOpts.query,
|
|
12104
12009
|
type,
|
|
12105
12010
|
mode,
|
|
12106
|
-
|
|
12107
|
-
|
|
12108
|
-
|
|
12109
|
-
|
|
12011
|
+
limit,
|
|
12012
|
+
providers: enabled,
|
|
12013
|
+
...searchOpts.orientation ? { orientation: searchOpts.orientation } : {},
|
|
12014
|
+
...searchOpts.minWidth !== void 0 ? { min_width: searchOpts.minWidth } : {},
|
|
12015
|
+
...searchOpts.durationMin !== void 0 ? { duration_min: searchOpts.durationMin } : {},
|
|
12016
|
+
...searchOpts.durationMax !== void 0 ? { duration_max: searchOpts.durationMax } : {}
|
|
12017
|
+
};
|
|
12018
|
+
if (deps.projectToolCall) {
|
|
12019
|
+
const response2 = await transport.callTool({ toolRef: "stock-media.search", arguments: body, idempotencyKey: jobRef, confirmation: { kind: "typed-command" } }, { jobRef, retries: 1 });
|
|
12020
|
+
if (response2.status !== "completed") return ok({ ...response2, job_ref: jobRef });
|
|
12021
|
+
return ok({ job_ref: jobRef, ...response2.result });
|
|
12022
|
+
}
|
|
12023
|
+
const response = await transport.post("internal/stock/search", body, { jobRef, retries: 1 });
|
|
12024
|
+
ok({ job_ref: jobRef, ...response });
|
|
12110
12025
|
} catch (err) {
|
|
12111
12026
|
if (err instanceof TransportError) {
|
|
12112
12027
|
fail({ code: err.code, message: err.message, extra: { ...err.extra ?? {}, job_ref: jobRef } });
|
|
@@ -12121,10 +12036,11 @@ function registerStockSearch(parent, getTransport2) {
|
|
|
12121
12036
|
}
|
|
12122
12037
|
|
|
12123
12038
|
// ../cli-core/src/commands/stock.ts
|
|
12124
|
-
function registerStockCommands(program2,
|
|
12039
|
+
function registerStockCommands(program2, depsOrTransport) {
|
|
12040
|
+
const deps = typeof depsOrTransport === "function" ? { getTransport: depsOrTransport } : depsOrTransport;
|
|
12125
12041
|
const stock = program2.command("stock").description("Search and download public stock media (Pexels / Pixabay / Openverse) for b-roll.");
|
|
12126
|
-
registerStockSearch(stock,
|
|
12127
|
-
registerStockDownload(stock);
|
|
12042
|
+
registerStockSearch(stock, deps);
|
|
12043
|
+
registerStockDownload(stock, deps);
|
|
12128
12044
|
}
|
|
12129
12045
|
|
|
12130
12046
|
// ../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/esm.mjs
|
|
@@ -13993,7 +13909,7 @@ function buildProgram() {
|
|
|
13993
13909
|
registerPollCommand(program2, getTransport2);
|
|
13994
13910
|
registerKnowledgeCommands(program2, getTransport2);
|
|
13995
13911
|
registerAssetCommands(program2, getTransport2);
|
|
13996
|
-
registerStockCommands(program2,
|
|
13912
|
+
registerStockCommands(program2, actionDeps);
|
|
13997
13913
|
return program2;
|
|
13998
13914
|
}
|
|
13999
13915
|
var invokedAsBin = isDirectExecution(import.meta.url);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actionway/cli-dev",
|
|
3
|
-
"version": "0.0.0-dev.
|
|
3
|
+
"version": "0.0.0-dev.32848766753.0e740c8908f1",
|
|
4
4
|
"description": "Actionway development CLI for dev.actionway.ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"tsx": "^4.20.0",
|
|
20
20
|
"typescript": "7.0.2",
|
|
21
21
|
"vitest": "^3.2.7",
|
|
22
|
-
"@actionway/
|
|
23
|
-
"@actionway/
|
|
22
|
+
"@actionway/cli-core": "0.1.0",
|
|
23
|
+
"@actionway/contracts": "0.1.0"
|
|
24
24
|
},
|
|
25
25
|
"engines": {
|
|
26
26
|
"node": ">=20"
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
},
|
|
37
37
|
"actionway": {
|
|
38
38
|
"channel": "development",
|
|
39
|
-
"source_sha": "
|
|
40
|
-
"run_id":
|
|
41
|
-
"run_url": "https://github.com/PawLogic/actionway/actions/runs/
|
|
39
|
+
"source_sha": "0e740c8908f1097143ccd81e75990c6ab3bb9428",
|
|
40
|
+
"run_id": 32848766753,
|
|
41
|
+
"run_url": "https://github.com/PawLogic/actionway/actions/runs/32848766753",
|
|
42
42
|
"gateway_url": "https://dev.actionway.ai"
|
|
43
43
|
}
|
|
44
44
|
}
|