comisai 1.0.12 → 1.0.13

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.
@@ -50,7 +50,10 @@ import type { AgentExecutor } from "./types.js";
50
50
  *
51
51
  * Extracted as a named function for independent unit testing.
52
52
  */
53
- export declare function createBeforeToolCallGuard(stepCounter: StepCounter, budgetGuard: BudgetGuard, circuitBreaker: CircuitBreaker, toolRetryBreaker?: ToolRetryBreaker, messageSendLimiter?: MessageSendLimiter): (context: unknown, _signal?: AbortSignal) => Promise<import("../safety/message-send-limiter.js").MessageSendVerdict | undefined>;
53
+ export declare function createBeforeToolCallGuard(stepCounter: StepCounter, budgetGuard: BudgetGuard, circuitBreaker: CircuitBreaker, toolRetryBreaker?: ToolRetryBreaker, messageSendLimiter?: MessageSendLimiter): (context: unknown, _signal?: AbortSignal) => Promise<{
54
+ block: boolean;
55
+ reason: string;
56
+ } | undefined>;
54
57
  /**
55
58
  * Merge SDK session stats into execution result for token totals (R-13).
56
59
  *
@@ -75,4 +75,5 @@ export const OPERATION_CACHE_DEFAULTS = {
75
75
  compaction: "none",
76
76
  taskExtraction: "none",
77
77
  condensation: "short",
78
+ cron: "short", // 5m TTL: covers within-execution multi-step reuse, avoids 1h write premium across hourly runs.
78
79
  };
@@ -55,15 +55,15 @@ export function createComisSessionManager(deps) {
55
55
  },
56
56
  async destroySession(sessionKey) {
57
57
  const sessionPath = sessionKeyToPath(sessionKey, deps.sessionBaseDir);
58
- try {
59
- await unlink(sessionPath);
60
- }
61
- catch {
62
- // File may not exist -- that's fine (already destroyed or never created)
63
- }
64
- // Clean up offloaded tool results
65
- const toolResultsDir = safePath(dirname(sessionPath), "tool-results");
66
- await suppressError(rm(toolResultsDir, { recursive: true, force: true }), "tool-results dir may not exist");
58
+ const sessionKeyStr = formatSessionKey(sessionKey);
59
+ await withSessionLock(deps.lockDir, sessionKeyStr, async () => {
60
+ try {
61
+ await unlink(sessionPath);
62
+ }
63
+ catch { /* ENOENT ok */ }
64
+ const toolResultsDir = safePath(dirname(sessionPath), "tool-results");
65
+ await suppressError(rm(toolResultsDir, { recursive: true, force: true }), "tool-results dir may not exist");
66
+ }, { retries: 10, retryMinTimeout: 500 });
67
67
  },
68
68
  writeSessionMetadata(sessionKey, metadata) {
69
69
  const sessionPath = sessionKeyToPath(sessionKey, deps.sessionBaseDir);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/agent",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "AI agent executor, budget control, and session management for Comis",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/channels",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Chat platform adapters — Discord, Telegram, Slack, WhatsApp, Signal, iMessage, IRC, LINE",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/cli",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Command-line interface for the Comis AI agent platform",
@@ -187,6 +187,8 @@ export interface InfraEvents {
187
187
  maxHistoryTurns?: number;
188
188
  /** Per-cron-job model override from CronPayload.agent_turn.model. */
189
189
  cronJobModel?: string;
190
+ /** Per-cron-job cache retention override from CronJob config. */
191
+ cacheRetention?: "none" | "short" | "long";
190
192
  /** Callback for agent_turn jobs to report execution result back to the scheduler.
191
193
  * Called by the event handler after agent execution completes. */
192
194
  onComplete?: (result: {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/core",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Core domain types, ports, event bus, security, and config for Comis",
@@ -159,7 +159,7 @@ export async function setupChannels(deps) {
159
159
  model: resolution.model,
160
160
  operationType: "cron",
161
161
  promptTimeout: { promptTimeoutMs: resolution.timeoutMs },
162
- cacheRetention: resolution.cacheRetention,
162
+ cacheRetention: payload.cacheRetention ?? resolution.cacheRetention,
163
163
  };
164
164
  logger.info({ jobName, model: resolution.model, source: resolution.source, agentId: payload.agentId }, "Cron model resolved");
165
165
  }
@@ -171,6 +171,15 @@ export async function setupChannels(deps) {
171
171
  // Fresh strategy — expire existing session before each execution
172
172
  if (sessionStrategy === "fresh") {
173
173
  sessionManager.expire(sessionKey);
174
+ const piAdapter = deps.piSessionAdapters?.get(payload.agentId)
175
+ ?? deps.piSessionAdapters?.get(defaultAgentId);
176
+ if (piAdapter) {
177
+ await piAdapter.destroySession(sessionKey);
178
+ }
179
+ else {
180
+ logger.warn({ agentId: payload.agentId, jobName, hint: "No piSessionAdapter found — JSONL may accumulate", errorKind: "config" }, "Cron fresh strategy could not destroy JSONL");
181
+ }
182
+ container.eventBus.emit("session:expired", { sessionKey, reason: "cron-fresh" });
174
183
  }
175
184
  const syntheticMsg = {
176
185
  id: `cron-${payload.jobId}-${Date.now()}`,
@@ -584,10 +593,12 @@ export async function setupChannels(deps) {
584
593
  if (adapter) {
585
594
  // eslint-disable-next-line no-restricted-syntax -- intentional fire-and-forget
586
595
  adapter.destroySession(key).catch(() => { });
596
+ container.eventBus.emit("session:expired", { sessionKey: key, reason: "chat-reset" });
587
597
  return;
588
598
  }
589
599
  // Fallback: expire via session manager
590
600
  deps.sessionManager.expire(key);
601
+ container.eventBus.emit("session:expired", { sessionKey: key, reason: "chat-reset" });
591
602
  },
592
603
  getAvailableModels: () => [],
593
604
  getUsageBreakdown: () => {
@@ -549,6 +549,7 @@ export async function setupGateway(deps) {
549
549
  const adapter = piSessionAdapters?.get(execAgentId);
550
550
  if (adapter) {
551
551
  suppressError(adapter.destroySession(key), "fire-and-forget session destroy");
552
+ container.eventBus.emit("session:expired", { sessionKey: key, reason: "gateway-reset" });
552
553
  return;
553
554
  }
554
555
  },
@@ -109,6 +109,7 @@ export async function setupSchedulers(deps) {
109
109
  sessionStrategy: job.sessionStrategy,
110
110
  maxHistoryTurns: job.maxHistoryTurns,
111
111
  cronJobModel: job.payload.kind === "agent_turn" ? job.payload.model : undefined,
112
+ cacheRetention: job.cacheRetention,
112
113
  onComplete: deferredResolve,
113
114
  });
114
115
  // Forward isolated results to main session if requested
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/daemon",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Background daemon and orchestrator for the Comis platform",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/gateway",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "HTTP, JSON-RPC, and WebSocket gateway for Comis",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/infra",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Structured logging infrastructure for Comis",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/memory",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "SQLite memory, embeddings, and RAG storage for Comis agents",
@@ -138,6 +138,12 @@ export declare const CronJobSchema: z.ZodObject<{
138
138
  }>>;
139
139
  /** Number of recent turns to keep for rolling strategy (default 3). */
140
140
  maxHistoryTurns: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
141
+ /** Per-job cache retention override. Default inherits OPERATION_CACHE_DEFAULTS["cron"] = "short". */
142
+ cacheRetention: z.ZodOptional<z.ZodEnum<{
143
+ none: "none";
144
+ short: "short";
145
+ long: "long";
146
+ }>>;
141
147
  /** Delivery target for routing results to originating channel */
142
148
  deliveryTarget: z.ZodOptional<z.ZodObject<{
143
149
  channelId: z.ZodString;
@@ -96,6 +96,8 @@ export const CronJobSchema = z.strictObject({
96
96
  sessionStrategy: CronSessionStrategySchema.default("fresh"),
97
97
  /** Number of recent turns to keep for rolling strategy (default 3). */
98
98
  maxHistoryTurns: z.number().int().positive().default(3).optional(),
99
+ /** Per-job cache retention override. Default inherits OPERATION_CACHE_DEFAULTS["cron"] = "short". */
100
+ cacheRetention: z.enum(["none", "short", "long"]).optional(),
99
101
  /** Delivery target for routing results to originating channel */
100
102
  deliveryTarget: CronDeliveryTargetSchema.optional(),
101
103
  /** Whether this job is currently enabled */
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/scheduler",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Task scheduling and cron management for Comis",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/shared",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Shared types and utilities for the Comis platform",
@@ -21,7 +21,7 @@ import type { RpcCall } from "./cron-tool.js";
21
21
  export declare const GATEWAY_ACTIONS: readonly ["read", "patch", "apply", "restart", "schema", "status", "history", "diff", "rollback", "env_set", "env_list"];
22
22
  export type GatewayAction = typeof GATEWAY_ACTIONS[number];
23
23
  declare const GatewayToolParams: import("@sinclair/typebox").TObject<{
24
- action: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"status" | "read" | "patch" | "diff" | "apply" | "restart" | "schema" | "history" | "rollback" | "env_set" | "env_list">[]>;
24
+ action: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"status" | "read" | "patch" | "apply" | "restart" | "schema" | "history" | "diff" | "rollback" | "env_set" | "env_list">[]>;
25
25
  section: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
26
26
  key: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
27
27
  value: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnknown>;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/skills",
3
3
  "private": true,
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Skill system, MCP integration, and tool sandbox for Comis agents",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "comisai",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "author": "Moshe Anconina",
5
5
  "license": "Apache-2.0",
6
6
  "description": "Security-first AI agent platform — connects AI agents to Discord, Telegram, Slack, WhatsApp, and more",
@@ -115,17 +115,17 @@
115
115
  "@comis/daemon"
116
116
  ],
117
117
  "dependencies": {
118
- "@comis/shared": "1.0.12",
119
- "@comis/core": "1.0.12",
120
- "@comis/infra": "1.0.12",
121
- "@comis/memory": "1.0.12",
122
- "@comis/gateway": "1.0.12",
123
- "@comis/skills": "1.0.12",
124
- "@comis/scheduler": "1.0.12",
125
- "@comis/agent": "1.0.12",
126
- "@comis/channels": "1.0.12",
127
- "@comis/cli": "1.0.12",
128
- "@comis/daemon": "1.0.12",
118
+ "@comis/shared": "1.0.13",
119
+ "@comis/core": "1.0.13",
120
+ "@comis/infra": "1.0.13",
121
+ "@comis/memory": "1.0.13",
122
+ "@comis/gateway": "1.0.13",
123
+ "@comis/skills": "1.0.13",
124
+ "@comis/scheduler": "1.0.13",
125
+ "@comis/agent": "1.0.13",
126
+ "@comis/channels": "1.0.13",
127
+ "@comis/cli": "1.0.13",
128
+ "@comis/daemon": "1.0.13",
129
129
  "@agentclientprotocol/sdk": "^0.15.0",
130
130
  "@clack/core": "^1.1.0",
131
131
  "@clack/prompts": "^1.1.0",