@rivus/agent 0.5.1 → 0.5.2

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/acp.js CHANGED
@@ -312,7 +312,11 @@ function createAcpStdioAgentLoop(options) {
312
312
  resolveSession: async (input) => {
313
313
  const processConnection = await resolveConnection();
314
314
  const current = processConnection.sessions.get(input.sessionKey);
315
- if (current) return current;
315
+ if (current?.isReusable) return current;
316
+ if (current) {
317
+ current.dispose();
318
+ processConnection.sessions.delete(input.sessionKey);
319
+ }
316
320
  const session = new SdkAcpAgentSession(await processConnection.connection.agent.buildSession(options.workingDirectory).start(), processConnection.connection.agent);
317
321
  sessionKeys.set(session.sessionId, input.sessionKey);
318
322
  processConnection.sessions.set(input.sessionKey, session);
@@ -324,6 +328,7 @@ function createAcpStdioAgentLoop(options) {
324
328
  var SdkAcpAgentSession = class {
325
329
  session;
326
330
  agent;
331
+ reusable = true;
327
332
  constructor(session, agent) {
328
333
  this.session = session;
329
334
  this.agent = agent;
@@ -331,10 +336,15 @@ var SdkAcpAgentSession = class {
331
336
  get sessionId() {
332
337
  return this.session.sessionId;
333
338
  }
339
+ get isReusable() {
340
+ return this.reusable;
341
+ }
334
342
  cancel() {
343
+ this.reusable = false;
335
344
  return this.agent.notify(acp.methods.agent.session.cancel, { sessionId: this.session.sessionId });
336
345
  }
337
346
  dispose() {
347
+ this.reusable = false;
338
348
  this.session.dispose();
339
349
  }
340
350
  async prompt(text, onUpdate) {
package/dist/index.js CHANGED
@@ -2838,25 +2838,113 @@ function resolveRunPresentation(input) {
2838
2838
  }
2839
2839
  }
2840
2840
  //#endregion
2841
+ //#region src/infrastructure/feishu/feishu-tenant-token-provider.ts
2842
+ var FeishuTenantAccessTokenError = class {
2843
+ status;
2844
+ code;
2845
+ message;
2846
+ _tag = "FeishuTenantAccessTokenError";
2847
+ constructor(status, code, message) {
2848
+ this.status = status;
2849
+ this.code = code;
2850
+ this.message = message;
2851
+ }
2852
+ };
2853
+ const DEFAULT_REFRESH_WINDOW_MS = 1800 * 1e3;
2854
+ function createFeishuTenantAccessTokenProvider(options) {
2855
+ const baseUrl = (options.baseUrl ?? "https://open.feishu.cn").replace(/\/$/, "");
2856
+ const now = options.now ?? Date.now;
2857
+ const refreshWindowMs = options.refreshWindowMs ?? DEFAULT_REFRESH_WINDOW_MS;
2858
+ let cached;
2859
+ return { getTenantAccessToken: () => Effect.gen(function* () {
2860
+ if (cached && now() < cached.refreshAfterMs) return cached.token;
2861
+ const response = yield* options.request({
2862
+ body: {
2863
+ app_id: options.appId,
2864
+ app_secret: options.appSecret
2865
+ },
2866
+ headers: { "Content-Type": "application/json; charset=utf-8" },
2867
+ method: "POST",
2868
+ url: `${baseUrl}/open-apis/auth/v3/tenant_access_token/internal`
2869
+ });
2870
+ if (response.status < 200 || response.status >= 300 || response.body.code !== 0 || !response.body.tenant_access_token || typeof response.body.expire !== "number") return yield* Effect.fail(new FeishuTenantAccessTokenError(response.status, response.body.code, response.body.msg ?? "Failed to get tenant_access_token"));
2871
+ cached = {
2872
+ refreshAfterMs: now() + response.body.expire * 1e3 - refreshWindowMs,
2873
+ token: response.body.tenant_access_token
2874
+ };
2875
+ return cached.token;
2876
+ }) };
2877
+ }
2878
+ //#endregion
2879
+ //#region src/infrastructure/feishu/feishu-openapi-client.ts
2880
+ var FeishuOpenApiError = class extends Error {
2881
+ status;
2882
+ code;
2883
+ _tag = "FeishuOpenApiError";
2884
+ name = "FeishuOpenApiError";
2885
+ constructor(status, code, message) {
2886
+ super(message);
2887
+ this.status = status;
2888
+ this.code = code;
2889
+ }
2890
+ };
2891
+ function createFeishuOpenApiClient(options) {
2892
+ return { request: (request, errorMessage = "Feishu OpenAPI error") => Effect.gen(function* () {
2893
+ const token = yield* options.getTenantAccessToken();
2894
+ const response = yield* options.request({
2895
+ ...request,
2896
+ headers: {
2897
+ Authorization: `Bearer ${token}`,
2898
+ "Content-Type": "application/json; charset=utf-8"
2899
+ }
2900
+ });
2901
+ if (response.status < 200 || response.status >= 300 || response.body.code !== 0) return yield* Effect.fail(new FeishuOpenApiError(response.status, response.body.code, response.body.msg ?? errorMessage));
2902
+ return response;
2903
+ }) };
2904
+ }
2905
+ function createConfiguredFeishuOpenApiClient(options) {
2906
+ const tokenProvider = createFeishuTenantAccessTokenProvider({
2907
+ appId: options.config.feishu.appId,
2908
+ appSecret: options.config.feishu.appSecret,
2909
+ baseUrl: options.config.feishu.baseUrl,
2910
+ request: (request) => options.request(request).pipe(Effect.map((response) => response))
2911
+ });
2912
+ return createFeishuOpenApiClient({
2913
+ getTenantAccessToken: () => tokenProvider.getTenantAccessToken(),
2914
+ request: (request) => options.request(request).pipe(Effect.map((response) => response))
2915
+ });
2916
+ }
2917
+ //#endregion
2841
2918
  //#region src/infrastructure/feishu/feishu-cardkit-openapi-client.ts
2842
2919
  function createFeishuCardKitOpenApiClient(options) {
2843
2920
  const baseUrl = (options.baseUrl ?? "https://open.feishu.cn").replace(/\/$/, "");
2844
2921
  const agentName = options.agentName ?? "Rivus Agent";
2922
+ const streamingClosedCards = /* @__PURE__ */ new Set();
2845
2923
  const call = (request) => options.client.request(request).pipe(Effect.asVoid);
2924
+ const updateTerminal = (request, status) => updateTerminalCard(baseUrl, agentName, request, status, call).pipe(Effect.tap(() => Effect.sync(() => streamingClosedCards.delete(request.cardId))));
2846
2925
  return {
2847
- cancel: (request) => updateTerminalCard(baseUrl, agentName, request, "cancelled", call),
2848
- fail: (request) => updateTerminalCard(baseUrl, agentName, request, "failed", call),
2849
- finish: (request) => updateTerminalCard(baseUrl, agentName, request, "completed", call),
2850
- updateText: (request) => call({
2851
- body: {
2852
- content: request.content,
2853
- sequence: request.sequence
2854
- },
2855
- method: "PUT",
2856
- url: `${baseUrl}/open-apis/cardkit/v1/cards/${encodeURIComponent(request.cardId)}/elements/${encodeURIComponent(request.elementId)}/content`
2857
- })
2926
+ cancel: (request) => updateTerminal(request, "cancelled"),
2927
+ fail: (request) => updateTerminal(request, "failed"),
2928
+ finish: (request) => updateTerminal(request, "completed"),
2929
+ updateText: (request) => {
2930
+ if (streamingClosedCards.has(request.cardId)) return Effect.void;
2931
+ return call({
2932
+ body: {
2933
+ content: request.content,
2934
+ sequence: request.sequence
2935
+ },
2936
+ method: "PUT",
2937
+ url: `${baseUrl}/open-apis/cardkit/v1/cards/${encodeURIComponent(request.cardId)}/elements/${encodeURIComponent(request.elementId)}/content`
2938
+ }).pipe(Effect.catchAll((error) => {
2939
+ if (!isStreamingClosed(error)) return Effect.fail(error);
2940
+ return Effect.sync(() => streamingClosedCards.add(request.cardId));
2941
+ }));
2942
+ }
2858
2943
  };
2859
2944
  }
2945
+ function isStreamingClosed(error) {
2946
+ return error instanceof FeishuOpenApiError && (error.code === 200850 || error.code === 300309);
2947
+ }
2860
2948
  function updateTerminalCard(baseUrl, agentName, request, status, call) {
2861
2949
  const card = status === "completed" && "text" in request ? createFeishuAgentRunCard({
2862
2950
  agentName,
@@ -2988,83 +3076,6 @@ function createConfiguredFeishuCardKitPublisher(options) {
2988
3076
  }) });
2989
3077
  }
2990
3078
  //#endregion
2991
- //#region src/infrastructure/feishu/feishu-tenant-token-provider.ts
2992
- var FeishuTenantAccessTokenError = class {
2993
- status;
2994
- code;
2995
- message;
2996
- _tag = "FeishuTenantAccessTokenError";
2997
- constructor(status, code, message) {
2998
- this.status = status;
2999
- this.code = code;
3000
- this.message = message;
3001
- }
3002
- };
3003
- const DEFAULT_REFRESH_WINDOW_MS = 1800 * 1e3;
3004
- function createFeishuTenantAccessTokenProvider(options) {
3005
- const baseUrl = (options.baseUrl ?? "https://open.feishu.cn").replace(/\/$/, "");
3006
- const now = options.now ?? Date.now;
3007
- const refreshWindowMs = options.refreshWindowMs ?? DEFAULT_REFRESH_WINDOW_MS;
3008
- let cached;
3009
- return { getTenantAccessToken: () => Effect.gen(function* () {
3010
- if (cached && now() < cached.refreshAfterMs) return cached.token;
3011
- const response = yield* options.request({
3012
- body: {
3013
- app_id: options.appId,
3014
- app_secret: options.appSecret
3015
- },
3016
- headers: { "Content-Type": "application/json; charset=utf-8" },
3017
- method: "POST",
3018
- url: `${baseUrl}/open-apis/auth/v3/tenant_access_token/internal`
3019
- });
3020
- if (response.status < 200 || response.status >= 300 || response.body.code !== 0 || !response.body.tenant_access_token || typeof response.body.expire !== "number") return yield* Effect.fail(new FeishuTenantAccessTokenError(response.status, response.body.code, response.body.msg ?? "Failed to get tenant_access_token"));
3021
- cached = {
3022
- refreshAfterMs: now() + response.body.expire * 1e3 - refreshWindowMs,
3023
- token: response.body.tenant_access_token
3024
- };
3025
- return cached.token;
3026
- }) };
3027
- }
3028
- //#endregion
3029
- //#region src/infrastructure/feishu/feishu-openapi-client.ts
3030
- var FeishuOpenApiError = class extends Error {
3031
- status;
3032
- code;
3033
- _tag = "FeishuOpenApiError";
3034
- name = "FeishuOpenApiError";
3035
- constructor(status, code, message) {
3036
- super(message);
3037
- this.status = status;
3038
- this.code = code;
3039
- }
3040
- };
3041
- function createFeishuOpenApiClient(options) {
3042
- return { request: (request, errorMessage = "Feishu OpenAPI error") => Effect.gen(function* () {
3043
- const token = yield* options.getTenantAccessToken();
3044
- const response = yield* options.request({
3045
- ...request,
3046
- headers: {
3047
- Authorization: `Bearer ${token}`,
3048
- "Content-Type": "application/json; charset=utf-8"
3049
- }
3050
- });
3051
- if (response.status < 200 || response.status >= 300 || response.body.code !== 0) return yield* Effect.fail(new FeishuOpenApiError(response.status, response.body.code, response.body.msg ?? errorMessage));
3052
- return response;
3053
- }) };
3054
- }
3055
- function createConfiguredFeishuOpenApiClient(options) {
3056
- const tokenProvider = createFeishuTenantAccessTokenProvider({
3057
- appId: options.config.feishu.appId,
3058
- appSecret: options.config.feishu.appSecret,
3059
- baseUrl: options.config.feishu.baseUrl,
3060
- request: (request) => options.request(request).pipe(Effect.map((response) => response))
3061
- });
3062
- return createFeishuOpenApiClient({
3063
- getTenantAccessToken: () => tokenProvider.getTenantAccessToken(),
3064
- request: (request) => options.request(request).pipe(Effect.map((response) => response))
3065
- });
3066
- }
3067
- //#endregion
3068
3079
  //#region src/infrastructure/feishu/feishu-cardkit-target-preparation.ts
3069
3080
  const DEFAULT_ELEMENT_ID = "rivus_agent_answer";
3070
3081
  function createFeishuCardTargetPreparation(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rivus/agent",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "A local agent daemon core built around a usable agent harness and domain events.",
5
5
  "type": "module",
6
6
  "license": "MIT",