@ambasada/village 0.8.6 → 0.8.7
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/dist/cli.mjs +577 -59
- package/dist/client.d.ts +11 -2
- package/dist/index.js +37 -22
- package/dist/types.d.ts +14 -1
- package/package.json +3 -3
package/dist/client.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { Ambasada, type AmbasadaOptions } from "@ambasada/sdk/platform";
|
|
2
2
|
import { type IncomingRequest } from "./receipt.js";
|
|
3
3
|
import type { AgentConfigInput, BuyOptions, BuyResult, ChatRequest, ChatResponse, CheckoutInput, CheckoutReceiptClaims, CheckoutDelivery, CheckoutDeliveryInput, CheckoutSession, ImageRequest, ImageResult, LedgerPage, Listing, ListingInput, MarketOffering, PaidCall, PaymentLink, PaymentLinkInput, ToolListing, ToolResult, TranscriptEntry, ChatLine, ChatProposal, ChatTurn, TransferOptions, Wallet, WebhookDelivery, WebhookEvent } from "./types.js";
|
|
4
|
+
/** How long a utility call may take here: the API's own limit plus a margin, so the SDK never gives up on a call the API finishes and charges. */
|
|
5
|
+
export declare const CLIENT_TIMEOUT_MS: {
|
|
6
|
+
readonly llm: number;
|
|
7
|
+
readonly image: number;
|
|
8
|
+
readonly tool: number;
|
|
9
|
+
};
|
|
4
10
|
/** The Hack A Ton API. The platform API (`@ambasada/sdk`) is https://api.ambasada.dev. */
|
|
5
11
|
export declare const DEFAULT_VILLAGE_API_URL = "https://hackaton.ambasada.id";
|
|
6
12
|
export declare const DEFAULT_MODEL = "deepseek-v4.1-flash";
|
|
7
13
|
export interface VillageOptions extends AmbasadaOptions {
|
|
8
|
-
/** Team key (`sk_live_…`, from the village app →
|
|
14
|
+
/** Team key (`sk_live_…`, from the village app → Team → Settings). Default: `AMBASADA_API_KEY`. */
|
|
9
15
|
apiKey?: string;
|
|
10
16
|
/**
|
|
11
17
|
* Default: `AMBASADA_VILLAGE_API_URL`, else `AMBASADA_API_URL` when it is not the platform host (0.7
|
|
@@ -74,7 +80,9 @@ export declare class Village extends Ambasada {
|
|
|
74
80
|
}>;
|
|
75
81
|
/**
|
|
76
82
|
* Tells the village what a paid checkout delivered (`text` ≤ 4000 chars, an https `url`, or both): the person sees it
|
|
77
|
-
* with the purchase in their app and can rate it.
|
|
83
|
+
* with the purchase in their app (one push, the first time) and can rate it. The same delivery again changes nothing;
|
|
84
|
+
* a new text replaces it. `{ status: "working" }` / `{ status: "failed", error }` while the work runs or when it gave
|
|
85
|
+
* up (never over a delivery). CONFLICT before it is paid.
|
|
78
86
|
*/
|
|
79
87
|
deliverCheckout(id: string, delivery: CheckoutDeliveryInput): Promise<CheckoutDelivery>;
|
|
80
88
|
/** A reusable payment link for static pages (`<button data-village-pay="pl_…">` with pay.js). */
|
|
@@ -101,6 +109,7 @@ export declare class Village extends Ambasada {
|
|
|
101
109
|
}>;
|
|
102
110
|
/** Sends a `webhook.test` event now and returns the delivery. */
|
|
103
111
|
testWebhook(): Promise<WebhookDelivery>;
|
|
112
|
+
/** Sends a failed or pending delivery again now (same `webhook-id`). CONFLICT for one already delivered: it never goes out twice. */
|
|
104
113
|
retryWebhookDelivery(id: string): Promise<WebhookDelivery>;
|
|
105
114
|
/** Buys one call of `company/offering` through the Gateway. Money moves only if the seller answers 2xx with valid output. */
|
|
106
115
|
buy<Output = any>(offering: string, input: unknown, options?: BuyOptions): Promise<BuyResult<Output>>;
|
package/dist/index.js
CHANGED
|
@@ -4,22 +4,6 @@ var __export = (target, all) => {
|
|
|
4
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
-
// src/client.ts
|
|
8
|
-
import { Ambasada, AmbasadaError as AmbasadaError3 } from "@ambasada/sdk/platform";
|
|
9
|
-
|
|
10
|
-
// src/errors.ts
|
|
11
|
-
import { AmbasadaError, isAmbasadaError } from "@ambasada/sdk/platform";
|
|
12
|
-
var VillageError = AmbasadaError;
|
|
13
|
-
var isVillageError = isAmbasadaError;
|
|
14
|
-
var ReceiptInvalidError = class extends AmbasadaError {
|
|
15
|
-
reason;
|
|
16
|
-
constructor(reason, message) {
|
|
17
|
-
super("RECEIPT_INVALID", `payment required: ${message}`, 402, { reason });
|
|
18
|
-
this.name = "ReceiptInvalidError";
|
|
19
|
-
this.reason = reason;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
|
|
23
7
|
// ../protocol/src/index.ts
|
|
24
8
|
var src_exports = {};
|
|
25
9
|
__export(src_exports, {
|
|
@@ -57,7 +41,9 @@ __export(src_exports, {
|
|
|
57
41
|
SHELL_TOKEN_TTL_S: () => SHELL_TOKEN_TTL_S,
|
|
58
42
|
SLOW_ENTRY_MS: () => SLOW_ENTRY_MS,
|
|
59
43
|
SYSTEM_ACCOUNT: () => SYSTEM_ACCOUNT,
|
|
60
|
-
|
|
44
|
+
UTILITY_CLIENT_MARGIN_MS: () => UTILITY_CLIENT_MARGIN_MS,
|
|
45
|
+
UTILITY_TIMEOUT_MS: () => UTILITY_TIMEOUT_MS,
|
|
46
|
+
VillageError: () => VillageError,
|
|
61
47
|
WEBHOOK_HEADERS: () => WEBHOOK_HEADERS,
|
|
62
48
|
WebhookError: () => WebhookError,
|
|
63
49
|
appNotifyBody: () => appNotifyBody,
|
|
@@ -189,7 +175,7 @@ var ERROR_STATUS = {
|
|
|
189
175
|
// Deploy-freeze and unattended windows: agents keep running, but config and steer are closed (DESIGN.md §5)
|
|
190
176
|
FROZEN: 403
|
|
191
177
|
};
|
|
192
|
-
var
|
|
178
|
+
var VillageError = class extends Error {
|
|
193
179
|
code;
|
|
194
180
|
status;
|
|
195
181
|
details;
|
|
@@ -1505,12 +1491,30 @@ var HEADERS = {
|
|
|
1505
1491
|
};
|
|
1506
1492
|
var MAX_DEPTH = 4;
|
|
1507
1493
|
var OFFERING_TIMEOUT_MS = { min: 100, max: 3e4 };
|
|
1494
|
+
var UTILITY_TIMEOUT_MS = { llm: 12e4, image: 18e4, tool: 6e4 };
|
|
1495
|
+
var UTILITY_CLIENT_MARGIN_MS = 1e4;
|
|
1508
1496
|
function offeringTimeoutProblem(value) {
|
|
1509
1497
|
if (value === void 0) return null;
|
|
1510
1498
|
const n = Number(value);
|
|
1511
1499
|
return Number.isInteger(n) && n >= OFFERING_TIMEOUT_MS.min && n <= OFFERING_TIMEOUT_MS.max ? null : `timeout_ms must be between ${OFFERING_TIMEOUT_MS.min} and ${OFFERING_TIMEOUT_MS.max} (got ${JSON.stringify(value)})`;
|
|
1512
1500
|
}
|
|
1513
1501
|
|
|
1502
|
+
// src/client.ts
|
|
1503
|
+
import { Ambasada, AmbasadaError as AmbasadaError3 } from "@ambasada/sdk/platform";
|
|
1504
|
+
|
|
1505
|
+
// src/errors.ts
|
|
1506
|
+
import { AmbasadaError, isAmbasadaError } from "@ambasada/sdk/platform";
|
|
1507
|
+
var VillageError2 = AmbasadaError;
|
|
1508
|
+
var isVillageError = isAmbasadaError;
|
|
1509
|
+
var ReceiptInvalidError = class extends AmbasadaError {
|
|
1510
|
+
reason;
|
|
1511
|
+
constructor(reason, message) {
|
|
1512
|
+
super("RECEIPT_INVALID", `payment required: ${message}`, 402, { reason });
|
|
1513
|
+
this.name = "ReceiptInvalidError";
|
|
1514
|
+
this.reason = reason;
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
|
|
1514
1518
|
// src/receipt.ts
|
|
1515
1519
|
import { AmbasadaError as AmbasadaError2, getHeader } from "@ambasada/sdk/platform";
|
|
1516
1520
|
var RECEIPT_HEADER2 = "x-village-receipt";
|
|
@@ -1627,6 +1631,11 @@ async function verifyWebhookPayload(secret, headers, body, options = {}) {
|
|
|
1627
1631
|
}
|
|
1628
1632
|
|
|
1629
1633
|
// src/client.ts
|
|
1634
|
+
var CLIENT_TIMEOUT_MS = {
|
|
1635
|
+
llm: UTILITY_TIMEOUT_MS.llm + UTILITY_CLIENT_MARGIN_MS,
|
|
1636
|
+
image: UTILITY_TIMEOUT_MS.image + UTILITY_CLIENT_MARGIN_MS,
|
|
1637
|
+
tool: UTILITY_TIMEOUT_MS.tool + UTILITY_CLIENT_MARGIN_MS
|
|
1638
|
+
};
|
|
1630
1639
|
var DEFAULT_VILLAGE_API_URL = "https://hackaton.ambasada.id";
|
|
1631
1640
|
var DEFAULT_MODEL = "deepseek-v4.1-flash";
|
|
1632
1641
|
function randomKey() {
|
|
@@ -1755,7 +1764,9 @@ var Village = class extends Ambasada {
|
|
|
1755
1764
|
}
|
|
1756
1765
|
/**
|
|
1757
1766
|
* Tells the village what a paid checkout delivered (`text` ≤ 4000 chars, an https `url`, or both): the person sees it
|
|
1758
|
-
* with the purchase in their app and can rate it.
|
|
1767
|
+
* with the purchase in their app (one push, the first time) and can rate it. The same delivery again changes nothing;
|
|
1768
|
+
* a new text replaces it. `{ status: "working" }` / `{ status: "failed", error }` while the work runs or when it gave
|
|
1769
|
+
* up (never over a delivery). CONFLICT before it is paid.
|
|
1759
1770
|
*/
|
|
1760
1771
|
deliverCheckout(id, delivery) {
|
|
1761
1772
|
return this.call("POST", `/v1/checkout/sessions/${encodeURIComponent(id)}/delivery`, { body: delivery });
|
|
@@ -1789,6 +1800,7 @@ var Village = class extends Ambasada {
|
|
|
1789
1800
|
testWebhook() {
|
|
1790
1801
|
return this.call("POST", "/v1/webhook/test");
|
|
1791
1802
|
}
|
|
1803
|
+
/** Sends a failed or pending delivery again now (same `webhook-id`). CONFLICT for one already delivered: it never goes out twice. */
|
|
1792
1804
|
retryWebhookDelivery(id) {
|
|
1793
1805
|
return this.call("POST", `/v1/webhook/deliveries/${encodeURIComponent(id)}/retry`);
|
|
1794
1806
|
}
|
|
@@ -1845,12 +1857,13 @@ var Village = class extends Ambasada {
|
|
|
1845
1857
|
return res.choices[0]?.message.content ?? "";
|
|
1846
1858
|
},
|
|
1847
1859
|
{
|
|
1848
|
-
|
|
1860
|
+
// The API waits up to 120 s for the model (one that reasons first can take a minute): not the client's 45 s.
|
|
1861
|
+
chat: (req) => this.call("POST", "/v1/llm/chat", { body: { ...req, model: req.model ?? DEFAULT_MODEL }, timeoutMs: CLIENT_TIMEOUT_MS.llm })
|
|
1849
1862
|
}
|
|
1850
1863
|
);
|
|
1851
1864
|
images = {
|
|
1852
1865
|
/** Generates an image; the URL is re-hosted in the village files store. Default model: nano_banana. */
|
|
1853
|
-
generate: (req) => this.call("POST", "/v1/images", { body: { ...req, model: req.model ?? "nano_banana" } })
|
|
1866
|
+
generate: (req) => this.call("POST", "/v1/images", { body: { ...req, model: req.model ?? "nano_banana" }, timeoutMs: CLIENT_TIMEOUT_MS.image })
|
|
1854
1867
|
};
|
|
1855
1868
|
tools = {
|
|
1856
1869
|
/** The curated LLMOK tool catalog with TON prices. */
|
|
@@ -1863,6 +1876,8 @@ var Village = class extends Ambasada {
|
|
|
1863
1876
|
const res = await this.send("POST", `/v1/tools/${encodeURIComponent(id)}`, {
|
|
1864
1877
|
body: input ?? {},
|
|
1865
1878
|
retry: true,
|
|
1879
|
+
// Image tools take as long as images; a routed search may try several providers within the API's 60 s.
|
|
1880
|
+
timeoutMs: id.startsWith("image.") ? CLIENT_TIMEOUT_MS.image : CLIENT_TIMEOUT_MS.tool,
|
|
1866
1881
|
headers: { "idempotency-key": options.idempotencyKey ?? randomKey() }
|
|
1867
1882
|
});
|
|
1868
1883
|
const json = res.json;
|
|
@@ -1951,7 +1966,7 @@ export {
|
|
|
1951
1966
|
RECEIPT_HEADER2 as RECEIPT_HEADER,
|
|
1952
1967
|
ReceiptInvalidError,
|
|
1953
1968
|
Village,
|
|
1954
|
-
VillageError,
|
|
1969
|
+
VillageError2 as VillageError,
|
|
1955
1970
|
WEBHOOK_HEADERS2 as WEBHOOK_HEADERS,
|
|
1956
1971
|
WebhookInvalidError2 as WebhookInvalidError,
|
|
1957
1972
|
createVillage,
|
package/dist/types.d.ts
CHANGED
|
@@ -55,15 +55,26 @@ export interface CheckoutInput {
|
|
|
55
55
|
/** Seconds, 300–86400 (default 3600). */
|
|
56
56
|
expires_in?: number;
|
|
57
57
|
}
|
|
58
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* What a paid checkout delivered (`POST /v1/checkout/sessions/:id/delivery`): text, an https URL, or both. While the
|
|
60
|
+
* work runs (the templates' Jobs Durable Object), `status: "working"` (with `error`: why the last attempt failed, while
|
|
61
|
+
* it retries); `status: "failed"` with `error` when it gives up. `ambasada village deliveries` shows all three.
|
|
62
|
+
*/
|
|
59
63
|
export interface CheckoutDeliveryInput {
|
|
60
64
|
text?: string;
|
|
61
65
|
url?: string;
|
|
66
|
+
/** Default `delivered` (with text and/or url). */
|
|
67
|
+
status?: "working" | "delivered" | "failed";
|
|
68
|
+
/** Why an attempt failed (working: retrying) or why it gave up (failed); at most 300 characters are kept. */
|
|
69
|
+
error?: string;
|
|
62
70
|
}
|
|
63
71
|
export interface CheckoutDelivery {
|
|
64
72
|
session: string;
|
|
73
|
+
/** `delivered` when the API predates delivery statuses. */
|
|
74
|
+
status?: "working" | "delivered" | "failed";
|
|
65
75
|
text: string | null;
|
|
66
76
|
url: string | null;
|
|
77
|
+
error?: string | null;
|
|
67
78
|
at: string;
|
|
68
79
|
}
|
|
69
80
|
export interface CheckoutSession {
|
|
@@ -166,6 +177,8 @@ export interface ChatRequest {
|
|
|
166
177
|
messages: ChatMessage[];
|
|
167
178
|
temperature?: number;
|
|
168
179
|
max_tokens?: number;
|
|
180
|
+
/** How much the model thinks before it answers; the village sends "low" when you leave it out. More thinking takes longer and more of `max_tokens`. */
|
|
181
|
+
reasoning_effort?: "low" | "medium" | "high" | (string & {});
|
|
169
182
|
/** `json_schema`: JSON in the schema's shape (live, and the mock's sample of it under `ambasada dev`); `json_object`: any JSON. */
|
|
170
183
|
response_format?: {
|
|
171
184
|
type: "text" | "json_object";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ambasada/village",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "The Hack A Ton add-on for Ambasada apps: TON checkout, receipts, offerings, LLM, the agent, the market; CLI commands and the local bank.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"node": ">=22"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@ambasada/sdk": "^0.8.
|
|
30
|
+
"@ambasada/sdk": "^0.8.7"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^22.20.5",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"typescript": "~5.9.3",
|
|
36
36
|
"vitest": "^4.1.12",
|
|
37
37
|
"@ambasada/protocol": "0.1.0",
|
|
38
|
-
"@ambasada/cli": "0.8.
|
|
38
|
+
"@ambasada/cli": "0.8.7"
|
|
39
39
|
},
|
|
40
40
|
"author": "CENTYSO (https://centyso.com)",
|
|
41
41
|
"homepage": "https://ambasada.id",
|