@tangle-network/agent-app 0.47.21 → 0.47.23

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createChatTurnRoutes,
3
3
  streamChatRouteAsSandboxEvents
4
- } from "../chunk-3GVFJYLO.js";
4
+ } from "../chunk-42NBWR4U.js";
5
5
  import "../chunk-ZSSCVT6H.js";
6
6
  import "../chunk-3YUI7WNW.js";
7
7
  import "../chunk-4PZE7XAM.js";
@@ -12,7 +12,7 @@ import "../chunk-JEZJ6HTF.js";
12
12
  import "../chunk-ZMMIQOFI.js";
13
13
  import "../chunk-M3K2HVQD.js";
14
14
  import "../chunk-YJMCRXQQ.js";
15
- import "../chunk-ES3I3UGP.js";
15
+ import "../chunk-N4RR4WAI.js";
16
16
 
17
17
  // src/public-consultation/index.ts
18
18
  import { searchKnowledge } from "@tangle-network/agent-knowledge";
@@ -99,7 +99,7 @@ import {
99
99
  workspaceSandboxRecoveryMessage,
100
100
  workspaceSandboxRecoveryRecommendedActions,
101
101
  writeProfileFilesToBox
102
- } from "../chunk-XR5ZXMYL.js";
102
+ } from "../chunk-PMAQSFJS.js";
103
103
  import "../chunk-MCYJON3F.js";
104
104
  import "../chunk-LWSJK546.js";
105
105
  import "../chunk-P5PIAQVS.js";
@@ -42,7 +42,7 @@ import {
42
42
  pumpBufferedTurn,
43
43
  replayTurnEvents,
44
44
  stampReplaySeq
45
- } from "../chunk-ES3I3UGP.js";
45
+ } from "../chunk-N4RR4WAI.js";
46
46
  export {
47
47
  DEFAULT_RUNNING_TURN_LEASE_MS,
48
48
  DEFAULT_RUNNING_TURN_RENEW_INTERVAL_MS,
@@ -200,7 +200,6 @@ export declare const TURN_STATUS_SCOPE_MIGRATION_SQL = "ALTER TABLE turn_status
200
200
  /** For deployments that already have the turn tables, add the index used by
201
201
  * terminal-turn retention without rerunning the table migration. */
202
202
  export declare const TURN_STATUS_RETENTION_MIGRATION_SQL = "CREATE INDEX IF NOT EXISTS idx_turn_status_retention ON turn_status (status, updatedAt);";
203
- /** Resolve a TurnEventStore that appends and reads turn events using a D1-like database interface */
204
203
  export declare function createD1TurnEventStore(db: D1LikeForTurns, options?: TurnEventStoreOptions): TurnEventStore;
205
204
  /** In-memory store for tests and keyless local dev. */
206
205
  export declare function createMemoryTurnEventStore(options?: TurnEventStoreOptions): TurnEventStore;
@@ -16,10 +16,10 @@
16
16
  * (their Tangle session authorizes the app for a connection + scopes).
17
17
  * 2. On the callback, the consumer's client `exchangeAuthCode`s the `agc_`
18
18
  * code into the first broker token + a durable grant.
19
- * 3. {@link createBrokerTokenProvider} — the runtime path: a cached provider
20
- * that re-mints a fresh single-use broker token per `/v1/hub/exec` from the
21
- * durable grant using only the app credentials (no user session). Caches
22
- * until just before expiry so a burst of hub calls shares one mint.
19
+ * 3. {@link createBrokerTokenProvider} — the runtime path: each request mints
20
+ * a fresh single-use broker token from the durable grant using only app
21
+ * credentials (no user session). Neither tokens nor in-flight mint
22
+ * promises may be shared between execution attempts.
23
23
  */
24
24
  /** A single-use hub bearer minted from a durable grant — mirrors
25
25
  * `@tangle-network/agent-integrations`'s `BrokerToken`. */
@@ -71,24 +71,24 @@ export interface BrokerTokenProviderOptions {
71
71
  grantId: string;
72
72
  /** Requested token TTL (seconds). */
73
73
  ttlSeconds?: number;
74
- /** Re-mint this many ms BEFORE expiry so an in-flight call never uses a
75
- * just-expired token. Default 30s. */
74
+ /** @deprecated Retained for source compatibility. Single-use tokens are
75
+ * never cached, so refresh skew is ignored. */
76
76
  refreshSkewMs?: number;
77
- /** Injectable clock (ms). Default `Date.now`. */
77
+ /** @deprecated Retained for source compatibility; no local expiry cache. */
78
78
  now?: () => number;
79
79
  }
80
- /** Provide and refresh broker bearer tokens, allowing forced token invalidation */
80
+ /** Mint a separate single-use bearer for each execution attempt. */
81
81
  export interface BrokerTokenProvider {
82
- /** A valid `sk-tan-broker-` bearer, minting/refreshing as needed. */
82
+ /** Mint a fresh bearer for exactly one Hub execution; never cache or share it. */
83
83
  getToken(): Promise<string>;
84
- /** Force the next `getToken` to re-mint (e.g. after a 401 from the hub). */
84
+ /** Compatibility no-op: no bearer is cached. Does not revoke Hub grants or
85
+ * already-issued tokens; revocation belongs to the authoritative Hub. */
85
86
  invalidate(): void;
86
87
  }
87
88
  /**
88
- * Cache + auto-refresh a broker token for one grant. A burst of hub calls
89
- * shares a single mint; the token is re-minted once it's within `refreshSkewMs`
90
- * of expiry, or on demand via {@link BrokerTokenProvider.invalidate}.
91
- * Concurrent `getToken` calls during a mint share the same in-flight promise
92
- * (no thundering herd).
89
+ * Mint a fresh broker token for every call, including concurrent calls.
90
+ * A broker bearer is consumed by one Hub execution even when its TTL has not
91
+ * expired. Cache the durable grant, never the bearer or an in-flight mint.
92
+ * Mint failures propagate; this helper never retries an external action.
93
93
  */
94
94
  export declare function createBrokerTokenProvider(opts: BrokerTokenProviderOptions): BrokerTokenProvider;
@@ -12,31 +12,17 @@ function buildConsentUrl(input) {
12
12
  return `${base}/cross-site/app-consent?${params.toString()}`;
13
13
  }
14
14
  function createBrokerTokenProvider(opts) {
15
- const now = opts.now ?? (() => Date.now());
16
- const skew = opts.refreshSkewMs ?? 3e4;
17
- let cached = null;
18
- let inflight = null;
19
- async function mint() {
20
- const t = await opts.client.mintBrokerToken({
21
- clientId: opts.clientId,
22
- clientSecret: opts.clientSecret,
23
- grantId: opts.grantId,
24
- ttlSeconds: opts.ttlSeconds
25
- });
26
- cached = { token: t.accessToken, expiresAt: now() + t.expiresIn * 1e3 };
27
- return t.accessToken;
28
- }
29
15
  return {
30
16
  async getToken() {
31
- if (cached && now() < cached.expiresAt - skew) return cached.token;
32
- if (inflight) return inflight;
33
- inflight = mint().finally(() => {
34
- inflight = null;
17
+ const token = await opts.client.mintBrokerToken({
18
+ clientId: opts.clientId,
19
+ clientSecret: opts.clientSecret,
20
+ grantId: opts.grantId,
21
+ ttlSeconds: opts.ttlSeconds
35
22
  });
36
- return inflight;
23
+ return token.accessToken;
37
24
  },
38
25
  invalidate() {
39
- cached = null;
40
26
  }
41
27
  };
42
28
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tangle/index.ts"],"sourcesContent":["/**\n * Tangle login + the developer self-service app-registration → broker-token\n * flow, for apps built on agent-app.\n *\n * The platform (agent-dev-container integration hub) lets a developer register\n * their client app and obtain a `sk-tan-broker-` bearer to call `/v1/hub/exec`\n * on a user's connected integrations — WITHOUT being a hard-coded \"trusted app\".\n * The wire client (`TangleAppsClient` — registerApp / exchangeAuthCode /\n * mintBrokerToken) lives in `@tangle-network/agent-integrations`; this module is\n * the app-shell layer on top, and is intentionally **structural**: it depends on\n * the minter CONTRACT, not the concrete client, so it installs without the\n * agent-integrations publish and is trivially testable. A consumer constructs\n * the real client and passes it in.\n *\n * 1. {@link buildConsentUrl} — send the user through the ONE-TIME consent\n * (their Tangle session authorizes the app for a connection + scopes).\n * 2. On the callback, the consumer's client `exchangeAuthCode`s the `agc_`\n * code into the first broker token + a durable grant.\n * 3. {@link createBrokerTokenProvider} — the runtime path: a cached provider\n * that re-mints a fresh single-use broker token per `/v1/hub/exec` from the\n * durable grant using only the app credentials (no user session). Caches\n * until just before expiry so a burst of hub calls shares one mint.\n */\n\n/** A single-use hub bearer minted from a durable grant — mirrors\n * `@tangle-network/agent-integrations`'s `BrokerToken`. */\nexport interface BrokerToken {\n /** The `sk-tan-broker-…` bearer for a single `/v1/hub/exec` call. */\n accessToken: string\n /** Seconds until expiry. */\n expiresIn: number\n scope: string\n connectionId?: string\n}\n\n/** The one method the provider needs — `TangleAppsClient` satisfies it\n * structurally, so `createBrokerTokenProvider({ client: tangleAppsClient, … })`\n * type-checks without importing the concrete class. */\nexport interface BrokerTokenMinter {\n mintBrokerToken(input: { clientId: string; clientSecret: string; grantId: string; ttlSeconds?: number }): Promise<BrokerToken>\n}\n\n/** Define input parameters required to generate a consent URL for OAuth authorization */\nexport interface ConsentUrlInput {\n /** Platform base URL (e.g. https://id.tangle.tools). */\n endpoint: string\n clientId: string\n /** Must match one of the app's registered redirect URIs. */\n redirectUri: string\n /** Scopes the app is requesting for this connection (e.g. ['gmail.read']). */\n scopes: string[]\n /** Opaque CSRF/state value the callback echoes back — verify it on return. */\n state: string\n /** Optionally pre-select a specific connection to authorize. */\n connectionId?: string\n}\n\n/**\n * Build the URL to send the user to for the one-time app-consent. The user's\n * Tangle session (not the app's credentials) authorizes it; on approval the\n * platform redirects to `redirectUri?code=agc_…&state=…`.\n */\nexport function buildConsentUrl(input: ConsentUrlInput): string {\n const base = input.endpoint.replace(/\\/+$/, '')\n const params = new URLSearchParams({\n client_id: input.clientId,\n redirect_uri: input.redirectUri,\n scope: input.scopes.join(' '),\n state: input.state,\n response_type: 'code',\n })\n if (input.connectionId) params.set('connection_id', input.connectionId)\n return `${base}/cross-site/app-consent?${params.toString()}`\n}\n\n/** Define options for configuring a broker token provider including client credentials and token management settings */\nexport interface BrokerTokenProviderOptions {\n client: BrokerTokenMinter\n clientId: string\n clientSecret: string\n /** The durable grant id from the consent exchange. */\n grantId: string\n /** Requested token TTL (seconds). */\n ttlSeconds?: number\n /** Re-mint this many ms BEFORE expiry so an in-flight call never uses a\n * just-expired token. Default 30s. */\n refreshSkewMs?: number\n /** Injectable clock (ms). Default `Date.now`. */\n now?: () => number\n}\n\n/** Provide and refresh broker bearer tokens, allowing forced token invalidation */\nexport interface BrokerTokenProvider {\n /** A valid `sk-tan-broker-` bearer, minting/refreshing as needed. */\n getToken(): Promise<string>\n /** Force the next `getToken` to re-mint (e.g. after a 401 from the hub). */\n invalidate(): void\n}\n\n/**\n * Cache + auto-refresh a broker token for one grant. A burst of hub calls\n * shares a single mint; the token is re-minted once it's within `refreshSkewMs`\n * of expiry, or on demand via {@link BrokerTokenProvider.invalidate}.\n * Concurrent `getToken` calls during a mint share the same in-flight promise\n * (no thundering herd).\n */\nexport function createBrokerTokenProvider(opts: BrokerTokenProviderOptions): BrokerTokenProvider {\n const now = opts.now ?? (() => Date.now())\n const skew = opts.refreshSkewMs ?? 30_000\n let cached: { token: string; expiresAt: number } | null = null\n let inflight: Promise<string> | null = null\n\n async function mint(): Promise<string> {\n const t = await opts.client.mintBrokerToken({\n clientId: opts.clientId,\n clientSecret: opts.clientSecret,\n grantId: opts.grantId,\n ttlSeconds: opts.ttlSeconds,\n })\n cached = { token: t.accessToken, expiresAt: now() + t.expiresIn * 1000 }\n return t.accessToken\n }\n\n return {\n async getToken() {\n if (cached && now() < cached.expiresAt - skew) return cached.token\n if (inflight) return inflight\n inflight = mint().finally(() => {\n inflight = null\n })\n return inflight\n },\n invalidate() {\n cached = null\n },\n }\n}\n"],"mappings":";AA8DO,SAAS,gBAAgB,OAAgC;AAC9D,QAAM,OAAO,MAAM,SAAS,QAAQ,QAAQ,EAAE;AAC9C,QAAM,SAAS,IAAI,gBAAgB;AAAA,IACjC,WAAW,MAAM;AAAA,IACjB,cAAc,MAAM;AAAA,IACpB,OAAO,MAAM,OAAO,KAAK,GAAG;AAAA,IAC5B,OAAO,MAAM;AAAA,IACb,eAAe;AAAA,EACjB,CAAC;AACD,MAAI,MAAM,aAAc,QAAO,IAAI,iBAAiB,MAAM,YAAY;AACtE,SAAO,GAAG,IAAI,2BAA2B,OAAO,SAAS,CAAC;AAC5D;AAiCO,SAAS,0BAA0B,MAAuD;AAC/F,QAAM,MAAM,KAAK,QAAQ,MAAM,KAAK,IAAI;AACxC,QAAM,OAAO,KAAK,iBAAiB;AACnC,MAAI,SAAsD;AAC1D,MAAI,WAAmC;AAEvC,iBAAe,OAAwB;AACrC,UAAM,IAAI,MAAM,KAAK,OAAO,gBAAgB;AAAA,MAC1C,UAAU,KAAK;AAAA,MACf,cAAc,KAAK;AAAA,MACnB,SAAS,KAAK;AAAA,MACd,YAAY,KAAK;AAAA,IACnB,CAAC;AACD,aAAS,EAAE,OAAO,EAAE,aAAa,WAAW,IAAI,IAAI,EAAE,YAAY,IAAK;AACvE,WAAO,EAAE;AAAA,EACX;AAEA,SAAO;AAAA,IACL,MAAM,WAAW;AACf,UAAI,UAAU,IAAI,IAAI,OAAO,YAAY,KAAM,QAAO,OAAO;AAC7D,UAAI,SAAU,QAAO;AACrB,iBAAW,KAAK,EAAE,QAAQ,MAAM;AAC9B,mBAAW;AAAA,MACb,CAAC;AACD,aAAO;AAAA,IACT;AAAA,IACA,aAAa;AACX,eAAS;AAAA,IACX;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/tangle/index.ts"],"sourcesContent":["/**\n * Tangle login + the developer self-service app-registration → broker-token\n * flow, for apps built on agent-app.\n *\n * The platform (agent-dev-container integration hub) lets a developer register\n * their client app and obtain a `sk-tan-broker-` bearer to call `/v1/hub/exec`\n * on a user's connected integrations — WITHOUT being a hard-coded \"trusted app\".\n * The wire client (`TangleAppsClient` — registerApp / exchangeAuthCode /\n * mintBrokerToken) lives in `@tangle-network/agent-integrations`; this module is\n * the app-shell layer on top, and is intentionally **structural**: it depends on\n * the minter CONTRACT, not the concrete client, so it installs without the\n * agent-integrations publish and is trivially testable. A consumer constructs\n * the real client and passes it in.\n *\n * 1. {@link buildConsentUrl} — send the user through the ONE-TIME consent\n * (their Tangle session authorizes the app for a connection + scopes).\n * 2. On the callback, the consumer's client `exchangeAuthCode`s the `agc_`\n * code into the first broker token + a durable grant.\n * 3. {@link createBrokerTokenProvider} — the runtime path: each request mints\n * a fresh single-use broker token from the durable grant using only app\n * credentials (no user session). Neither tokens nor in-flight mint\n * promises may be shared between execution attempts.\n */\n\n/** A single-use hub bearer minted from a durable grant — mirrors\n * `@tangle-network/agent-integrations`'s `BrokerToken`. */\nexport interface BrokerToken {\n /** The `sk-tan-broker-…` bearer for a single `/v1/hub/exec` call. */\n accessToken: string\n /** Seconds until expiry. */\n expiresIn: number\n scope: string\n connectionId?: string\n}\n\n/** The one method the provider needs — `TangleAppsClient` satisfies it\n * structurally, so `createBrokerTokenProvider({ client: tangleAppsClient, … })`\n * type-checks without importing the concrete class. */\nexport interface BrokerTokenMinter {\n mintBrokerToken(input: { clientId: string; clientSecret: string; grantId: string; ttlSeconds?: number }): Promise<BrokerToken>\n}\n\n/** Define input parameters required to generate a consent URL for OAuth authorization */\nexport interface ConsentUrlInput {\n /** Platform base URL (e.g. https://id.tangle.tools). */\n endpoint: string\n clientId: string\n /** Must match one of the app's registered redirect URIs. */\n redirectUri: string\n /** Scopes the app is requesting for this connection (e.g. ['gmail.read']). */\n scopes: string[]\n /** Opaque CSRF/state value the callback echoes back — verify it on return. */\n state: string\n /** Optionally pre-select a specific connection to authorize. */\n connectionId?: string\n}\n\n/**\n * Build the URL to send the user to for the one-time app-consent. The user's\n * Tangle session (not the app's credentials) authorizes it; on approval the\n * platform redirects to `redirectUri?code=agc_…&state=…`.\n */\nexport function buildConsentUrl(input: ConsentUrlInput): string {\n const base = input.endpoint.replace(/\\/+$/, '')\n const params = new URLSearchParams({\n client_id: input.clientId,\n redirect_uri: input.redirectUri,\n scope: input.scopes.join(' '),\n state: input.state,\n response_type: 'code',\n })\n if (input.connectionId) params.set('connection_id', input.connectionId)\n return `${base}/cross-site/app-consent?${params.toString()}`\n}\n\n/** Define options for configuring a broker token provider including client credentials and token management settings */\nexport interface BrokerTokenProviderOptions {\n client: BrokerTokenMinter\n clientId: string\n clientSecret: string\n /** The durable grant id from the consent exchange. */\n grantId: string\n /** Requested token TTL (seconds). */\n ttlSeconds?: number\n /** @deprecated Retained for source compatibility. Single-use tokens are\n * never cached, so refresh skew is ignored. */\n refreshSkewMs?: number\n /** @deprecated Retained for source compatibility; no local expiry cache. */\n now?: () => number\n}\n\n/** Mint a separate single-use bearer for each execution attempt. */\nexport interface BrokerTokenProvider {\n /** Mint a fresh bearer for exactly one Hub execution; never cache or share it. */\n getToken(): Promise<string>\n /** Compatibility no-op: no bearer is cached. Does not revoke Hub grants or\n * already-issued tokens; revocation belongs to the authoritative Hub. */\n invalidate(): void\n}\n\n/**\n * Mint a fresh broker token for every call, including concurrent calls.\n * A broker bearer is consumed by one Hub execution even when its TTL has not\n * expired. Cache the durable grant, never the bearer or an in-flight mint.\n * Mint failures propagate; this helper never retries an external action.\n */\nexport function createBrokerTokenProvider(opts: BrokerTokenProviderOptions): BrokerTokenProvider {\n return {\n async getToken() {\n const token = await opts.client.mintBrokerToken({\n clientId: opts.clientId,\n clientSecret: opts.clientSecret,\n grantId: opts.grantId,\n ttlSeconds: opts.ttlSeconds,\n })\n return token.accessToken\n },\n invalidate() {\n // No cached bearer to clear. Keep this method for existing callers.\n },\n }\n}\n"],"mappings":";AA8DO,SAAS,gBAAgB,OAAgC;AAC9D,QAAM,OAAO,MAAM,SAAS,QAAQ,QAAQ,EAAE;AAC9C,QAAM,SAAS,IAAI,gBAAgB;AAAA,IACjC,WAAW,MAAM;AAAA,IACjB,cAAc,MAAM;AAAA,IACpB,OAAO,MAAM,OAAO,KAAK,GAAG;AAAA,IAC5B,OAAO,MAAM;AAAA,IACb,eAAe;AAAA,EACjB,CAAC;AACD,MAAI,MAAM,aAAc,QAAO,IAAI,iBAAiB,MAAM,YAAY;AACtE,SAAO,GAAG,IAAI,2BAA2B,OAAO,SAAS,CAAC;AAC5D;AAiCO,SAAS,0BAA0B,MAAuD;AAC/F,SAAO;AAAA,IACL,MAAM,WAAW;AACf,YAAM,QAAQ,MAAM,KAAK,OAAO,gBAAgB;AAAA,QAC9C,UAAU,KAAK;AAAA,QACf,cAAc,KAAK;AAAA,QACnB,SAAS,KAAK;AAAA,QACd,YAAY,KAAK;AAAA,MACnB,CAAC;AACD,aAAO,MAAM;AAAA,IACf;AAAA,IACA,aAAa;AAAA,IAEb;AAAA,EACF;AACF;","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-CCVWR33L.js";
4
4
  import {
5
5
  DEFAULT_RUNNING_TURN_LEASE_MS
6
- } from "../chunk-ES3I3UGP.js";
6
+ } from "../chunk-N4RR4WAI.js";
7
7
 
8
8
  // src/turn-stream/core.ts
9
9
  function isTerminalRunEvent(type) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-app",
3
- "version": "0.47.21",
3
+ "version": "0.47.23",
4
4
  "packageManager": "pnpm@11.24.0",
5
5
  "description": "Build agent applications with typed chat, tools, sandboxes, integrations, billing, and evaluation.",
6
6
  "keywords": [
@@ -541,7 +541,7 @@
541
541
  "@tangle-network/agent-interface": "2.6.0",
542
542
  "@tangle-network/agent-knowledge": "15.0.3",
543
543
  "@tangle-network/agent-profile-materialize": "0.19.0",
544
- "@tangle-network/agent-runtime": "0.219.0",
544
+ "@tangle-network/agent-runtime": "0.222.1",
545
545
  "@tangle-network/brand": "1.5.0",
546
546
  "@tangle-network/sandbox": "0.39.2",
547
547
  "@tangle-network/sandbox-ui": "0.113.3",
@@ -601,7 +601,7 @@
601
601
  "@tangle-network/agent-interface": "^2.6.0",
602
602
  "@tangle-network/agent-knowledge": "^15.0.3",
603
603
  "@tangle-network/agent-profile-materialize": ">=0.19.0 <0.20.0",
604
- "@tangle-network/agent-runtime": ">=0.219.0 <0.220.0",
604
+ "@tangle-network/agent-runtime": ">=0.222.1 <0.223.0",
605
605
  "@tangle-network/brand": ">=1.5.0",
606
606
  "@tangle-network/sandbox": ">=0.38.2 <0.40.0",
607
607
  "@tangle-network/sandbox-ui": ">=0.113.3 <0.114.0",