@ambasada/village 0.8.11 → 0.8.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.
package/dist/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Ambasada, type AmbasadaOptions } from "@ambasada/sdk/platform";
2
2
  import { type IncomingRequest } from "./receipt.js";
3
- import type { JobAnswer, AgentConfigInput, BuyOptions, BuyResult, ChatRequest, ChatResponse, CheckoutInput, CheckoutReceiptClaims, CheckoutDelivery, CheckoutDeliveryInput, CheckoutSession, ImageRequest, ImageResult, LedgerPage, Listing, ListingInput, MarketOffering, PaidCall, PaymentLink, PaymentLinkInput, ToolListing, ToolResult, TranscriptEntry, ChatLine, ChatProposal, ChatDecision, ChatTurn, TransferOptions, Wallet, WebhookDelivery, WebhookEvent } from "./types.js";
3
+ import type { JobAnswer, AgentConfigInput, BuyOptions, BuyResult, ChatRequest, ChatResponse, CheckoutInput, CheckoutReceiptClaims, CheckoutDelivery, CheckoutDeliveryInput, CheckoutSession, ImageRequest, ImageResult, LedgerPage, Listing, ListingInput, MarketOffering, PaidCall, PaymentLink, PaymentLinkInput, ToolListing, ToolResult, TranscriptEntry, AgentState, AgentLogEntry, TalkDeal, TalkMessage, TalkThread, ChatLine, ChatProposal, ChatDecision, ChatTurn, TransferOptions, Wallet, WebhookDelivery, WebhookEvent } from "./types.js";
4
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
5
  export declare const CLIENT_TIMEOUT_MS: {
6
6
  readonly llm: number;
@@ -239,7 +239,35 @@ export declare class Village extends Ambasada {
239
239
  more?: number;
240
240
  earlier?: number;
241
241
  }>;
242
- state: () => Promise<Record<string, unknown>>;
242
+ /** How the agent is doing: its own status sentence and needs, why it last woke, the next wake, today's thinking. */
243
+ state: () => Promise<AgentState>;
244
+ /** The Inbox: one thread per company your agent talks with, newest first, with your unread counts. */
245
+ inbox: () => Promise<{
246
+ threads: TalkThread[];
247
+ unread: number;
248
+ }>;
249
+ /** One talk, both directions, oldest first, and the deals between you; reading it clears its unread count. */
250
+ thread: (company: string) => Promise<{
251
+ company: string;
252
+ name: string;
253
+ messages: TalkMessage[];
254
+ deals: TalkDeal[];
255
+ unread: number;
256
+ }>;
257
+ /** A word to your own agent about its talk with `company`, read on its next wake; never sent to them. */
258
+ whisper: (company: string, text: string) => Promise<{
259
+ id: string;
260
+ at: string;
261
+ next_wake_at?: string | null;
262
+ }>;
263
+ /** The Log: every wake with its transcript, steer, whispers, settings and approved proposals; 50 a page, newest first. */
264
+ log: (page?: number, kind?: "all" | "wakes" | "money" | "talks" | "issues") => Promise<{
265
+ entries: AgentLogEntry[];
266
+ page: number;
267
+ pages: number;
268
+ total: number;
269
+ per_page: number;
270
+ }>;
243
271
  };
244
272
  }
245
273
  export declare function createVillage(options?: VillageOptions): Village;
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ __export(src_exports, {
13
13
  APP_TIMESTAMP_HEADER: () => APP_TIMESTAMP_HEADER,
14
14
  APP_WEBHOOK_TOLERANCE_S: () => APP_WEBHOOK_TOLERANCE_S,
15
15
  ASYNC_OFFERING: () => ASYNC_OFFERING,
16
+ AUTH_SHELL_PATH: () => AUTH_SHELL_PATH,
16
17
  AppWebhookError: () => AppWebhookError,
17
18
  DEFAULT_HUB_URL: () => DEFAULT_HUB_URL,
18
19
  DEFAULT_ISSUER: () => DEFAULT_ISSUER,
@@ -1137,6 +1138,7 @@ function appNotifyResult(json) {
1137
1138
 
1138
1139
  // ../protocol/src/check.ts
1139
1140
  var MANIFEST_URL_PATH = "/.well-known/ambasada.json";
1141
+ var AUTH_SHELL_PATH = "/api/auth/shell";
1140
1142
  var MANIFEST_SCHEMA = 2;
1141
1143
  var MANIFEST_KINDS = ["product", "event", "tool", "assistant"];
1142
1144
  var MANIFEST_CATEGORIES = ["shopping", "food", "events", "tools", "learning", "community", "games", "finance", "other"];
@@ -1400,6 +1402,15 @@ async function checkRemote(url, fetchImpl = fetch, options = {}) {
1400
1402
  report.problems.push({ code: "identity_callback", message: `could not fetch ${callbackUrl}: ${error.message}` });
1401
1403
  }
1402
1404
  }
1405
+ if (scopes.includes("identity")) {
1406
+ const shellUrl = new URL(AUTH_SHELL_PATH, origin).toString();
1407
+ try {
1408
+ const res = await get(fetchImpl, shellUrl);
1409
+ await res.body?.cancel();
1410
+ if (res.status === 404) report.warnings.push({ code: "identity_shell", message: `the identity scope signs people in on open through ${AUTH_SHELL_PATH} (auth.shell(req) from @ambasada/sdk); ${shellUrl} answered 404, so inside the Ambasada app they get "Sign in with Ambasada" instead` });
1411
+ } catch {
1412
+ }
1413
+ }
1403
1414
  const webhook = manifest?.notifications && typeof manifest.notifications === "object" ? manifest.notifications.webhook : void 0;
1404
1415
  if (scopes.includes("notifications") && typeof webhook === "string" && webhook) {
1405
1416
  const webhookUrl = new URL(webhook, origin);
@@ -1435,7 +1446,7 @@ var LABELS = [
1435
1446
  [/^entry_|^not_https$|^bad_url$/, "entry page"],
1436
1447
  [/^privacy_url$/, "privacy page"],
1437
1448
  [/^notifications_webhook$|^webhook_/, "webhook"],
1438
- [/^identity_callback$/, "sign-in"]
1449
+ [/^identity_(callback|shell)$/, "sign-in"]
1439
1450
  ];
1440
1451
  function findingLabel(code) {
1441
1452
  return LABELS.find(([re]) => re.test(code))?.[1] ?? code.replace(/_/g, " ");
@@ -2069,7 +2080,16 @@ var Village = class extends Ambasada {
2069
2080
  * `more`: entries after this page (read on from `next_since`); `earlier`: with `newest`, the ones before it.
2070
2081
  */
2071
2082
  transcript: (since = 0, limit = 200, options = {}) => this.call("GET", "/v1/agent/transcript", { query: { since, limit, ...options.newest ? { newest: 1 } : {} } }),
2072
- state: () => this.call("GET", "/v1/agent/state")
2083
+ /** How the agent is doing: its own status sentence and needs, why it last woke, the next wake, today's thinking. */
2084
+ state: () => this.call("GET", "/v1/agent/state"),
2085
+ /** The Inbox: one thread per company your agent talks with, newest first, with your unread counts. */
2086
+ inbox: () => this.call("GET", "/v1/agent/inbox/threads"),
2087
+ /** One talk, both directions, oldest first, and the deals between you; reading it clears its unread count. */
2088
+ thread: (company) => this.call("GET", `/v1/agent/inbox/threads/${encodeURIComponent(company)}`),
2089
+ /** A word to your own agent about its talk with `company`, read on its next wake; never sent to them. */
2090
+ whisper: (company, text) => this.call("POST", "/v1/agent/whisper", { body: { company, text } }),
2091
+ /** The Log: every wake with its transcript, steer, whispers, settings and approved proposals; 50 a page, newest first. */
2092
+ log: (page = 1, kind = "all") => this.call("GET", "/v1/agent/log", { query: { page, kind } })
2073
2093
  };
2074
2094
  };
2075
2095
  function createVillage(options = {}) {
package/dist/types.d.ts CHANGED
@@ -332,9 +332,14 @@ export interface TransferOptions {
332
332
  export interface AgentSettings {
333
333
  model?: "deepseek-v4.1-flash";
334
334
  enabled?: boolean;
335
+ /**
336
+ * strategy_hours: a scheduled wake with nothing new (no message, sale, answer, finished purchase or rival move) costs
337
+ * nothing and runs no model, except once this many hours after the last wake that thought (default 6).
338
+ */
335
339
  wake?: {
336
340
  interval_minutes?: number;
337
341
  min_event_gap_seconds?: number;
342
+ strategy_hours?: number;
338
343
  };
339
344
  budget?: {
340
345
  tool_calls_per_wake?: number;
@@ -429,6 +434,94 @@ export interface ChatDecision {
429
434
  /** With `wait`: the agent's next line (its reply, or the "no reply" card), null when a minute went by. */
430
435
  follow_up?: ChatLine | null;
431
436
  }
437
+ /** `agent.state()`: how the agent is doing (docs/AGENT-CHAT.md v2, the app's status card). */
438
+ export interface AgentState {
439
+ configured: boolean;
440
+ enabled: boolean;
441
+ /** asleep | working */
442
+ status: string;
443
+ /** The agent's own sentence on where things stand (it sets it at the end of every wake that ran), and what it needs. */
444
+ status_text?: string | null;
445
+ status_set_at?: string | null;
446
+ needs?: {
447
+ kind: "offering" | "approval" | "limit" | "deploy";
448
+ label: string;
449
+ }[];
450
+ woke_last_because?: string | null;
451
+ /** The free checks since the last wake found nothing new: no model ran, nothing was charged. */
452
+ idle?: {
453
+ nothing_new_since: string | null;
454
+ checked_at: string | null;
455
+ next_check_at: string | null;
456
+ } | null;
457
+ last_wake?: {
458
+ id: string;
459
+ at: string;
460
+ ended_at: string | null;
461
+ stop: string | null;
462
+ summary: string | null;
463
+ woke_because?: string | null;
464
+ } | null;
465
+ next_wake_at: string | null;
466
+ compute_today: number;
467
+ compute_cap_today: number | null;
468
+ [key: string]: unknown;
469
+ }
470
+ /** One message of a talk between your agent and another company: theirs (`in`), your agent's (`out`), your whisper. */
471
+ export interface TalkMessage {
472
+ id: string;
473
+ at: string;
474
+ direction: "in" | "out" | "whisper";
475
+ type: string;
476
+ text: string | null;
477
+ /** One plain line: the text, or "quotes 2.5 TON per call for pixelpal/stickers, up to 20 a day". */
478
+ summary: string;
479
+ ref: string | null;
480
+ }
481
+ export interface TalkDeal {
482
+ id: string;
483
+ offering: string;
484
+ price: number;
485
+ status: string;
486
+ role: "buyer" | "seller";
487
+ qty_cap: number;
488
+ used: number;
489
+ valid_until: string;
490
+ created_at: string;
491
+ }
492
+ /** A row of the Inbox: one company your agent talks with. */
493
+ export interface TalkThread {
494
+ company: string;
495
+ name: string;
496
+ last: TalkMessage;
497
+ unread: number;
498
+ messages: number;
499
+ deal: TalkDeal | null;
500
+ }
501
+ /** One entry of the agent's Log: a wake (with its transcript as `steps`), steer, a whisper, settings, a proposal. */
502
+ export interface AgentLogEntry {
503
+ id: string;
504
+ at: string;
505
+ type: "wake" | "steer" | "whisper" | "config" | "proposal";
506
+ kinds: ("wakes" | "money" | "talks" | "issues")[];
507
+ title: string;
508
+ summary: string | null;
509
+ cost_ton: number | null;
510
+ wake?: {
511
+ id: string;
512
+ reason: string;
513
+ woke_because: string | null;
514
+ stop: string | null;
515
+ ended_at: string | null;
516
+ tool_calls: number | null;
517
+ };
518
+ steps?: {
519
+ seq: number;
520
+ at: string;
521
+ kind: string;
522
+ [key: string]: unknown;
523
+ }[];
524
+ }
432
525
  export interface MarketOffering {
433
526
  id: string;
434
527
  company?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ambasada/village",
3
- "version": "0.8.11",
3
+ "version": "0.8.12",
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,15 +27,15 @@
27
27
  "node": ">=22"
28
28
  },
29
29
  "dependencies": {
30
- "@ambasada/sdk": "^0.8.11"
30
+ "@ambasada/sdk": "^0.8.12"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^22.20.5",
34
34
  "esbuild": "^0.28.2",
35
35
  "typescript": "~5.9.3",
36
36
  "vitest": "^4.1.12",
37
- "@ambasada/cli": "0.8.11",
38
- "@ambasada/protocol": "0.1.0"
37
+ "@ambasada/protocol": "0.1.0",
38
+ "@ambasada/cli": "0.8.12"
39
39
  },
40
40
  "author": "CENTYSO (https://centyso.com)",
41
41
  "homepage": "https://ambasada.id",