comisai 1.0.19 → 1.0.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.
Files changed (154) hide show
  1. package/dist/cli-entry.js +0 -0
  2. package/node_modules/@comis/agent/dist/context-engine/context-engine.js +43 -2
  3. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +51 -0
  4. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +110 -0
  5. package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.d.ts +54 -0
  6. package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.js +145 -0
  7. package/node_modules/@comis/agent/dist/context-engine/types-core.d.ts +17 -0
  8. package/node_modules/@comis/agent/dist/executor/error-classifier.d.ts +11 -1
  9. package/node_modules/@comis/agent/dist/executor/error-classifier.js +13 -0
  10. package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.d.ts +1 -0
  11. package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.js +55 -0
  12. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +106 -5
  13. package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +1 -0
  14. package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +1 -4
  15. package/node_modules/@comis/agent/dist/executor/pi-executor.js +30 -3
  16. package/node_modules/@comis/agent/dist/executor/replay-drift-detector.d.ts +85 -0
  17. package/node_modules/@comis/agent/dist/executor/replay-drift-detector.js +92 -0
  18. package/node_modules/@comis/agent/dist/executor/signature-block-scrubber.d.ts +34 -0
  19. package/node_modules/@comis/agent/dist/executor/signature-block-scrubber.js +69 -0
  20. package/node_modules/@comis/agent/dist/executor/signed-replay-detector.d.ts +39 -0
  21. package/node_modules/@comis/agent/dist/executor/signed-replay-detector.js +72 -0
  22. package/node_modules/@comis/agent/package.json +1 -1
  23. package/node_modules/@comis/channels/package.json +1 -1
  24. package/node_modules/@comis/cli/dist/cli.js +0 -0
  25. package/node_modules/@comis/cli/package.json +1 -1
  26. package/node_modules/@comis/core/dist/config/git-manager.js +10 -4
  27. package/node_modules/@comis/core/dist/config/index.d.ts +1 -0
  28. package/node_modules/@comis/core/dist/config/index.js +2 -0
  29. package/node_modules/@comis/core/dist/config/managed-sections.d.ts +67 -0
  30. package/node_modules/@comis/core/dist/config/managed-sections.js +124 -0
  31. package/node_modules/@comis/core/dist/config/schema-agent.d.ts +28 -10
  32. package/node_modules/@comis/core/dist/config/schema-agent.js +6 -0
  33. package/node_modules/@comis/core/dist/config/schema-gateway.d.ts +2 -2
  34. package/node_modules/@comis/core/dist/config/schema.d.ts +65 -64
  35. package/node_modules/@comis/core/dist/event-bus/events-messaging.d.ts +16 -0
  36. package/node_modules/@comis/core/dist/exports/config.d.ts +1 -1
  37. package/node_modules/@comis/core/dist/exports/config.js +1 -1
  38. package/node_modules/@comis/core/package.json +1 -1
  39. package/node_modules/@comis/daemon/bundled-skills/skill-creator/scripts/init-skill.py +0 -0
  40. package/node_modules/@comis/daemon/bundled-skills/skill-creator/scripts/validate-skill.py +0 -0
  41. package/node_modules/@comis/daemon/dist/daemon.js +11 -4
  42. package/node_modules/@comis/daemon/dist/rpc/config-handlers.js +20 -7
  43. package/node_modules/@comis/daemon/dist/rpc/session-handlers.js +27 -1
  44. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.d.ts +22 -0
  45. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.js +34 -8
  46. package/node_modules/@comis/daemon/dist/wiring/setup-tools.js +14 -1
  47. package/node_modules/@comis/daemon/package.json +1 -1
  48. package/node_modules/@comis/gateway/package.json +1 -1
  49. package/node_modules/@comis/infra/dist/logging/log-fields.d.ts +2 -2
  50. package/node_modules/@comis/infra/package.json +1 -1
  51. package/node_modules/@comis/memory/package.json +1 -1
  52. package/node_modules/@comis/scheduler/package.json +1 -1
  53. package/node_modules/@comis/shared/package.json +1 -1
  54. package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +23 -8
  55. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +1 -1
  56. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +18 -14
  57. package/node_modules/@comis/skills/dist/builtin/platform/unified-session-tool.js +1 -1
  58. package/node_modules/@comis/skills/dist/builtin/sandbox/detect-provider.d.ts +1 -0
  59. package/node_modules/@comis/skills/dist/builtin/sandbox/detect-provider.js +78 -5
  60. package/node_modules/@comis/skills/package.json +1 -1
  61. package/node_modules/@comis/web/package.json +1 -1
  62. package/package.json +24 -26
  63. package/node_modules/@comis/agent/dist/provider/response/strip-minimax-xml.d.ts +0 -9
  64. package/node_modules/@comis/agent/dist/provider/response/strip-minimax-xml.js +0 -17
  65. package/node_modules/@comis/agent/dist/provider/response/strip-model-tokens.d.ts +0 -13
  66. package/node_modules/@comis/agent/dist/provider/response/strip-model-tokens.js +0 -19
  67. package/node_modules/@comis/agent/dist/provider/response/strip-tool-text.d.ts +0 -11
  68. package/node_modules/@comis/agent/dist/provider/response/strip-tool-text.js +0 -32
  69. package/node_modules/@comis/agent/dist/safety/follow-through-detector.d.ts +0 -46
  70. package/node_modules/@comis/agent/dist/safety/follow-through-detector.js +0 -76
  71. package/node_modules/@comis/agent/dist/safety/post-compaction-safety.d.ts +0 -30
  72. package/node_modules/@comis/agent/dist/safety/post-compaction-safety.js +0 -51
  73. package/node_modules/@comis/agent/dist/safety/schema-normalizer.d.ts +0 -37
  74. package/node_modules/@comis/agent/dist/safety/schema-normalizer.js +0 -137
  75. package/node_modules/@comis/agent/dist/safety/schema-pruning.d.ts +0 -50
  76. package/node_modules/@comis/agent/dist/safety/schema-pruning.js +0 -112
  77. package/node_modules/@comis/agent/dist/safety/tool-image-sanitizer.d.ts +0 -43
  78. package/node_modules/@comis/agent/dist/safety/tool-image-sanitizer.js +0 -96
  79. package/node_modules/@comis/agent/dist/safety/tool-sanitizer.d.ts +0 -44
  80. package/node_modules/@comis/agent/dist/safety/tool-sanitizer.js +0 -94
  81. package/node_modules/@comis/channels/dist/shared/thinking-tag-filter.d.ts +0 -28
  82. package/node_modules/@comis/channels/dist/shared/thinking-tag-filter.js +0 -206
  83. package/node_modules/@comis/cli/dist/wizard/config-writer.d.ts +0 -25
  84. package/node_modules/@comis/cli/dist/wizard/config-writer.js +0 -144
  85. package/node_modules/@comis/cli/dist/wizard/flow-types.d.ts +0 -48
  86. package/node_modules/@comis/cli/dist/wizard/flow-types.js +0 -70
  87. package/node_modules/@comis/cli/dist/wizard/manual-flow.d.ts +0 -21
  88. package/node_modules/@comis/cli/dist/wizard/manual-flow.js +0 -345
  89. package/node_modules/@comis/cli/dist/wizard/quickstart-flow.d.ts +0 -21
  90. package/node_modules/@comis/cli/dist/wizard/quickstart-flow.js +0 -116
  91. package/node_modules/@comis/core/dist/config/schema-agent-model.d.ts +0 -135
  92. package/node_modules/@comis/core/dist/config/schema-agent-model.js +0 -114
  93. package/node_modules/@comis/core/dist/config/schema-agent-session.d.ts +0 -177
  94. package/node_modules/@comis/core/dist/config/schema-agent-session.js +0 -116
  95. package/node_modules/@comis/core/dist/config/schema-context-engine.d.ts +0 -92
  96. package/node_modules/@comis/core/dist/config/schema-context-engine.js +0 -92
  97. package/node_modules/@comis/core/dist/config/schema-context-guard.d.ts +0 -34
  98. package/node_modules/@comis/core/dist/config/schema-context-guard.js +0 -32
  99. package/node_modules/@comis/core/dist/config/schema-delivery-mirror.d.ts +0 -27
  100. package/node_modules/@comis/core/dist/config/schema-delivery-mirror.js +0 -26
  101. package/node_modules/@comis/core/dist/config/schema-delivery-queue.d.ts +0 -31
  102. package/node_modules/@comis/core/dist/config/schema-delivery-queue.js +0 -30
  103. package/node_modules/@comis/core/dist/config/schema-delivery-timing.d.ts +0 -41
  104. package/node_modules/@comis/core/dist/config/schema-delivery-timing.js +0 -31
  105. package/node_modules/@comis/core/dist/config/schema-monitoring.d.ts +0 -105
  106. package/node_modules/@comis/core/dist/config/schema-monitoring.js +0 -67
  107. package/node_modules/@comis/core/dist/ports/media-ports.d.ts +0 -278
  108. package/node_modules/@comis/core/dist/ports/media-ports.js +0 -1
  109. package/node_modules/@comis/core/dist/security/input-guard.d.ts +0 -46
  110. package/node_modules/@comis/core/dist/security/input-guard.js +0 -166
  111. package/node_modules/@comis/core/dist/security/scoped-secret-manager.d.ts +0 -38
  112. package/node_modules/@comis/core/dist/security/scoped-secret-manager.js +0 -94
  113. package/node_modules/@comis/daemon/dist/observability/delivery-context.d.ts +0 -37
  114. package/node_modules/@comis/daemon/dist/observability/delivery-context.js +0 -1
  115. package/node_modules/@comis/daemon/dist/observability/log-level-manager.d.ts +0 -23
  116. package/node_modules/@comis/daemon/dist/observability/log-level-manager.js +0 -34
  117. package/node_modules/@comis/daemon/dist/observability/log-transport.d.ts +0 -44
  118. package/node_modules/@comis/daemon/dist/observability/log-transport.js +0 -74
  119. package/node_modules/@comis/daemon/dist/observability/obs-write-buffer.d.ts +0 -53
  120. package/node_modules/@comis/daemon/dist/observability/obs-write-buffer.js +0 -68
  121. package/node_modules/@comis/daemon/dist/observability/types.d.ts +0 -6
  122. package/node_modules/@comis/daemon/dist/observability/types.js +0 -1
  123. package/node_modules/@comis/daemon/dist/wiring/seed-bundled-skills.d.ts +0 -41
  124. package/node_modules/@comis/daemon/dist/wiring/seed-bundled-skills.js +0 -84
  125. package/node_modules/@comis/daemon/dist/wiring/setup-delivery-mirror.d.ts +0 -24
  126. package/node_modules/@comis/daemon/dist/wiring/setup-delivery-mirror.js +0 -88
  127. package/node_modules/@comis/daemon/dist/wiring/setup-delivery-queue.d.ts +0 -31
  128. package/node_modules/@comis/daemon/dist/wiring/setup-delivery-queue.js +0 -132
  129. package/node_modules/@comis/daemon/dist/wiring/setup-monitoring.d.ts +0 -38
  130. package/node_modules/@comis/daemon/dist/wiring/setup-monitoring.js +0 -100
  131. package/node_modules/@comis/daemon/dist/wiring/setup-rpc-bridge.d.ts +0 -34
  132. package/node_modules/@comis/daemon/dist/wiring/setup-rpc-bridge.js +0 -52
  133. package/node_modules/@comis/daemon/dist/wiring/setup-task-extraction.d.ts +0 -41
  134. package/node_modules/@comis/daemon/dist/wiring/setup-task-extraction.js +0 -86
  135. package/node_modules/@comis/memory/dist/embedding-cache.d.ts +0 -36
  136. package/node_modules/@comis/memory/dist/embedding-cache.js +0 -94
  137. package/node_modules/@comis/skills/dist/bridge/tool-output-schemas.d.ts +0 -17
  138. package/node_modules/@comis/skills/dist/bridge/tool-output-schemas.js +0 -125
  139. package/node_modules/@comis/skills/dist/bridge/tool-parallelism-metadata.d.ts +0 -14
  140. package/node_modules/@comis/skills/dist/bridge/tool-parallelism-metadata.js +0 -92
  141. package/node_modules/@comis/skills/dist/bridge/tool-result-caps.d.ts +0 -14
  142. package/node_modules/@comis/skills/dist/bridge/tool-result-caps.js +0 -36
  143. package/node_modules/@comis/skills/dist/bridge/tool-search-hints.d.ts +0 -15
  144. package/node_modules/@comis/skills/dist/bridge/tool-search-hints.js +0 -68
  145. package/node_modules/@comis/skills/dist/bridge/tool-validators.d.ts +0 -11
  146. package/node_modules/@comis/skills/dist/bridge/tool-validators.js +0 -105
  147. package/node_modules/@comis/skills/dist/builtin/file/find-sort-wrapper.d.ts +0 -22
  148. package/node_modules/@comis/skills/dist/builtin/file/find-sort-wrapper.js +0 -95
  149. package/node_modules/@comis/skills/dist/builtin/file/grep-output-mode-wrapper.d.ts +0 -24
  150. package/node_modules/@comis/skills/dist/builtin/file/grep-output-mode-wrapper.js +0 -167
  151. package/node_modules/@comis/skills/dist/builtin/task-plan-tool.d.ts +0 -25
  152. package/node_modules/@comis/skills/dist/builtin/task-plan-tool.js +0 -67
  153. package/node_modules/@comis/skills/dist/integrations/mcp-tool-bridge.d.ts +0 -75
  154. package/node_modules/@comis/skills/dist/integrations/mcp-tool-bridge.js +0 -235
@@ -1,137 +0,0 @@
1
- /**
2
- * Provider-specific JSON Schema normalization: strips unsupported keywords
3
- * from tool definitions based on the target LLM provider.
4
- *
5
- * Different providers reject different JSON Schema keywords in tool
6
- * input_schema definitions. This normalizer deep-walks the schema tree
7
- * and strips keywords that the target provider does not support.
8
- *
9
- * Designed for use as a StreamFnWrapper in stream-wrappers.ts. Wiring
10
- * is NOT done here -- this is a pure function module.
11
- *
12
- * @module
13
- */
14
- // ---------------------------------------------------------------------------
15
- // Provider keyword maps
16
- // ---------------------------------------------------------------------------
17
- /**
18
- * Map of provider -> set of unsupported JSON Schema keywords to strip.
19
- * OpenAI is not listed because it supports the standard keywords.
20
- * OpenRouter passes through to the underlying provider.
21
- */
22
- export const PROVIDER_UNSUPPORTED_KEYWORDS = {
23
- anthropic: new Set([
24
- "format",
25
- "pattern",
26
- "minLength",
27
- "maxLength",
28
- "minimum",
29
- "maximum",
30
- "exclusiveMinimum",
31
- "exclusiveMaximum",
32
- "multipleOf",
33
- "minItems",
34
- "maxItems",
35
- "uniqueItems",
36
- "minProperties",
37
- "maxProperties",
38
- "patternProperties",
39
- "additionalItems",
40
- ]),
41
- google: new Set([
42
- "additionalProperties",
43
- "format",
44
- "pattern",
45
- "minLength",
46
- "maxLength",
47
- "minimum",
48
- "maximum",
49
- "exclusiveMinimum",
50
- "exclusiveMaximum",
51
- "multipleOf",
52
- "minItems",
53
- "maxItems",
54
- "uniqueItems",
55
- ]),
56
- };
57
- // ---------------------------------------------------------------------------
58
- // Schema walking
59
- // ---------------------------------------------------------------------------
60
- /** Keys that contain nested schema objects to recurse into. */
61
- const NESTED_SCHEMA_KEYS = new Set([
62
- "properties",
63
- "items",
64
- "allOf",
65
- "anyOf",
66
- "oneOf",
67
- "not",
68
- "if",
69
- "then",
70
- "else",
71
- "additionalProperties",
72
- ]);
73
- /**
74
- * Deep-walk a schema node and strip unsupported keywords.
75
- * Mutates the clone in-place and collects stripped keyword names.
76
- */
77
- function walkAndStrip(node, unsupported, stripped) {
78
- // Strip unsupported keywords at this level
79
- for (const key of Object.keys(node)) {
80
- if (unsupported.has(key)) {
81
- stripped.add(key);
82
- delete node[key];
83
- }
84
- }
85
- // Recurse into nested schema structures
86
- for (const key of NESTED_SCHEMA_KEYS) {
87
- const value = node[key];
88
- if (value === undefined || value === null)
89
- continue;
90
- // Skip $ref -- don't walk into references
91
- if (key === "$ref")
92
- continue;
93
- if (key === "properties" && typeof value === "object" && !Array.isArray(value)) {
94
- // properties: { propName: schemaObject, ... }
95
- for (const propSchema of Object.values(value)) {
96
- if (propSchema && typeof propSchema === "object" && !Array.isArray(propSchema)) {
97
- walkAndStrip(propSchema, unsupported, stripped);
98
- }
99
- }
100
- }
101
- else if (Array.isArray(value)) {
102
- // allOf, anyOf, oneOf: array of schema objects
103
- for (const item of value) {
104
- if (item && typeof item === "object" && !Array.isArray(item)) {
105
- walkAndStrip(item, unsupported, stripped);
106
- }
107
- }
108
- }
109
- else if (typeof value === "object") {
110
- // items, not, if, then, else, additionalProperties: single schema object
111
- walkAndStrip(value, unsupported, stripped);
112
- }
113
- }
114
- }
115
- // ---------------------------------------------------------------------------
116
- // Public API
117
- // ---------------------------------------------------------------------------
118
- /**
119
- * Deep-clone a JSON Schema and strip unsupported keywords for the given provider.
120
- *
121
- * If the provider has no entry in PROVIDER_UNSUPPORTED_KEYWORDS, returns the
122
- * schema unchanged (still cloned to prevent mutation).
123
- *
124
- * @param schema - The JSON Schema to normalize
125
- * @param provider - Target LLM provider name
126
- * @returns Normalized schema with list of stripped keywords
127
- */
128
- export function normalizeToolSchema(schema, provider) {
129
- const cloned = structuredClone(schema);
130
- const unsupported = PROVIDER_UNSUPPORTED_KEYWORDS[provider];
131
- if (!unsupported || unsupported.size === 0) {
132
- return { schema: cloned, strippedKeywords: [] };
133
- }
134
- const stripped = new Set();
135
- walkAndStrip(cloned, unsupported, stripped);
136
- return { schema: cloned, strippedKeywords: [...stripped].sort() };
137
- }
@@ -1,50 +0,0 @@
1
- /**
2
- * Schema description pruning: strips optional parameter descriptions from
3
- * tool JSON schemas to save tokens for small models.
4
- *
5
- * Small models (context window <= 32K) waste tokens on optional parameter
6
- * descriptions they rarely use. This module strips those descriptions while
7
- * preserving required parameter descriptions and excluding designated tools
8
- * (e.g., browser) from pruning.
9
- *
10
- * Designed as a pure function module -- wiring is done in pi-executor.ts.
11
- *
12
- * @module
13
- */
14
- import type { ToolDefinition } from "@mariozechner/pi-coding-agent";
15
- /** Result of pruning descriptions from a single schema. */
16
- export interface PruneResult {
17
- schema: Record<string, unknown>;
18
- removedCount: number;
19
- }
20
- /** Result of pruning descriptions from an array of tool definitions. */
21
- export interface PruneToolsResult {
22
- tools: ToolDefinition[];
23
- totalRemoved: number;
24
- estimatedTokensSaved: number;
25
- }
26
- /**
27
- * Deep-clone a JSON Schema and strip descriptions from optional parameters.
28
- *
29
- * Required parameters (listed in the schema's `required` array) retain
30
- * their descriptions unconditionally. Parameters not in `required` have
31
- * their `description` field removed.
32
- *
33
- * CRITICAL: Uses structuredClone to avoid mutating shared TypeBox TSchema
34
- * objects that may be referenced across sessions.
35
- *
36
- * @param schema - The JSON Schema to prune
37
- * @returns Pruned schema with removal count
38
- */
39
- export declare function pruneSchemaDescriptions(schema: Record<string, unknown>): PruneResult;
40
- /**
41
- * Prune optional parameter descriptions from an array of tool definitions.
42
- *
43
- * Tools whose name is in `excludeNames` are passed through unmodified
44
- * (default: browser tool excluded since it needs full descriptions).
45
- *
46
- * @param tools - Array of tool definitions to prune
47
- * @param excludeNames - Tool names to skip (default: `new Set(["browser"])`)
48
- * @returns Pruned tools with total removal count and estimated token savings
49
- */
50
- export declare function pruneToolSchemas(tools: ToolDefinition[], excludeNames?: Set<string>): PruneToolsResult;
@@ -1,112 +0,0 @@
1
- /**
2
- * Schema description pruning: strips optional parameter descriptions from
3
- * tool JSON schemas to save tokens for small models.
4
- *
5
- * Small models (context window <= 32K) waste tokens on optional parameter
6
- * descriptions they rarely use. This module strips those descriptions while
7
- * preserving required parameter descriptions and excluding designated tools
8
- * (e.g., browser) from pruning.
9
- *
10
- * Designed as a pure function module -- wiring is done in pi-executor.ts.
11
- *
12
- * @module
13
- */
14
- import { CHARS_PER_TOKEN_RATIO } from "../context-engine/constants.js";
15
- // ---------------------------------------------------------------------------
16
- // Schema walking
17
- // ---------------------------------------------------------------------------
18
- /**
19
- * Walk a schema node and strip descriptions from optional parameters.
20
- * Mutates the clone in-place. Returns the count of removed descriptions
21
- * and the total character length of removed description strings.
22
- */
23
- function walkAndPrune(node, requiredSet) {
24
- let removed = 0;
25
- let charsRemoved = 0;
26
- const properties = node.properties;
27
- if (!properties || typeof properties !== "object") {
28
- return { removed, charsRemoved };
29
- }
30
- for (const [propName, propSchema] of Object.entries(properties)) {
31
- if (!propSchema || typeof propSchema !== "object")
32
- continue;
33
- if (!requiredSet.has(propName) && "description" in propSchema) {
34
- const desc = propSchema.description;
35
- if (typeof desc === "string") {
36
- charsRemoved += desc.length;
37
- }
38
- delete propSchema.description;
39
- removed++;
40
- }
41
- // Recurse into nested object properties
42
- if (propSchema.type === "object" &&
43
- propSchema.properties &&
44
- typeof propSchema.properties === "object") {
45
- const innerRequired = Array.isArray(propSchema.required)
46
- ? new Set(propSchema.required)
47
- : new Set();
48
- const inner = walkAndPrune(propSchema, innerRequired);
49
- removed += inner.removed;
50
- charsRemoved += inner.charsRemoved;
51
- }
52
- }
53
- return { removed, charsRemoved };
54
- }
55
- // ---------------------------------------------------------------------------
56
- // Public API
57
- // ---------------------------------------------------------------------------
58
- /**
59
- * Deep-clone a JSON Schema and strip descriptions from optional parameters.
60
- *
61
- * Required parameters (listed in the schema's `required` array) retain
62
- * their descriptions unconditionally. Parameters not in `required` have
63
- * their `description` field removed.
64
- *
65
- * CRITICAL: Uses structuredClone to avoid mutating shared TypeBox TSchema
66
- * objects that may be referenced across sessions.
67
- *
68
- * @param schema - The JSON Schema to prune
69
- * @returns Pruned schema with removal count
70
- */
71
- export function pruneSchemaDescriptions(schema) {
72
- const cloned = structuredClone(schema);
73
- const requiredSet = Array.isArray(cloned.required)
74
- ? new Set(cloned.required)
75
- : new Set();
76
- const { removed } = walkAndPrune(cloned, requiredSet);
77
- return { schema: cloned, removedCount: removed };
78
- }
79
- /**
80
- * Prune optional parameter descriptions from an array of tool definitions.
81
- *
82
- * Tools whose name is in `excludeNames` are passed through unmodified
83
- * (default: browser tool excluded since it needs full descriptions).
84
- *
85
- * @param tools - Array of tool definitions to prune
86
- * @param excludeNames - Tool names to skip (default: `new Set(["browser"])`)
87
- * @returns Pruned tools with total removal count and estimated token savings
88
- */
89
- export function pruneToolSchemas(tools, excludeNames = new Set(["browser"])) {
90
- let totalRemoved = 0;
91
- let totalCharsRemoved = 0;
92
- const prunedTools = tools.map((tool) => {
93
- if (excludeNames.has(tool.name)) {
94
- return tool;
95
- }
96
- const schema = tool.parameters;
97
- const cloned = structuredClone(schema);
98
- const requiredSet = Array.isArray(cloned.required)
99
- ? new Set(cloned.required)
100
- : new Set();
101
- const { removed, charsRemoved } = walkAndPrune(cloned, requiredSet);
102
- totalRemoved += removed;
103
- totalCharsRemoved += charsRemoved;
104
- return { ...tool, parameters: cloned };
105
- });
106
- const estimatedTokensSaved = Math.ceil(totalCharsRemoved / CHARS_PER_TOKEN_RATIO);
107
- return {
108
- tools: prunedTools,
109
- totalRemoved,
110
- estimatedTokensSaved,
111
- };
112
- }
@@ -1,43 +0,0 @@
1
- /**
2
- * Tool image sanitizer -- validates, resizes, and re-encodes images
3
- * from tool results before they enter LLM context.
4
- *
5
- * Prevents memory spikes from oversized images and rejects corrupt
6
- * or unsupported image data. Uses sharp for processing with
7
- * decompression bomb protection via limitInputPixels.
8
- */
9
- import type { Result } from "@comis/shared";
10
- /** Configuration options for image sanitization. */
11
- export interface ImageSanitizeOptions {
12
- /** Max width in pixels (default: 1024) */
13
- maxWidth?: number;
14
- /** Max height in pixels (default: 1024) */
15
- maxHeight?: number;
16
- /** Max input size in bytes (default: 10_485_760 = 10MB) */
17
- maxInputBytes?: number;
18
- /** Output format (default: "png") */
19
- outputFormat?: "png" | "jpeg" | "webp";
20
- /** JPEG/WebP quality 1-100 (default: 85) */
21
- quality?: number;
22
- }
23
- /** Result of a successful image sanitization. */
24
- export interface SanitizeResult {
25
- buffer: Buffer;
26
- format: string;
27
- width: number;
28
- height: number;
29
- originalBytes: number;
30
- sanitizedBytes: number;
31
- }
32
- /** Tool image sanitizer interface. */
33
- export interface ToolImageSanitizer {
34
- /** Sanitize a base64-encoded image. Returns Result with sanitized buffer or error. */
35
- sanitize(base64Data: string, mimeType?: string): Promise<Result<SanitizeResult, string>>;
36
- }
37
- /**
38
- * Create a tool image sanitizer instance.
39
- *
40
- * @param opts - Optional configuration overriding defaults.
41
- * @returns A ToolImageSanitizer instance.
42
- */
43
- export declare function createToolImageSanitizer(opts?: ImageSanitizeOptions): ToolImageSanitizer;
@@ -1,96 +0,0 @@
1
- /**
2
- * Tool image sanitizer -- validates, resizes, and re-encodes images
3
- * from tool results before they enter LLM context.
4
- *
5
- * Prevents memory spikes from oversized images and rejects corrupt
6
- * or unsupported image data. Uses sharp for processing with
7
- * decompression bomb protection via limitInputPixels.
8
- */
9
- import sharp from "sharp";
10
- import { ok, err } from "@comis/shared";
11
- // Disable sharp cache to prevent memory accumulation across calls
12
- sharp.cache(false);
13
- /** Default limit for decompression bomb protection (268 million pixels). */
14
- const DEFAULT_LIMIT_INPUT_PIXELS = 268_402_689;
15
- /**
16
- * Create a tool image sanitizer instance.
17
- *
18
- * @param opts - Optional configuration overriding defaults.
19
- * @returns A ToolImageSanitizer instance.
20
- */
21
- export function createToolImageSanitizer(opts) {
22
- const maxWidth = opts?.maxWidth ?? 1024;
23
- const maxHeight = opts?.maxHeight ?? 1024;
24
- const maxInputBytes = opts?.maxInputBytes ?? 10_485_760;
25
- const outputFormat = opts?.outputFormat ?? "png";
26
- const quality = opts?.quality ?? 85;
27
- return {
28
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
29
- async sanitize(base64Data, _mimeType) {
30
- // Reject empty input
31
- if (!base64Data || base64Data.length === 0) {
32
- return err("Empty image data provided");
33
- }
34
- // Decode base64 to buffer
35
- let inputBuffer;
36
- try {
37
- inputBuffer = Buffer.from(base64Data, "base64");
38
- }
39
- catch {
40
- return err("Failed to decode base64 image data");
41
- }
42
- // Reject if decoded buffer is empty (empty base64 decodes to empty buffer)
43
- if (inputBuffer.length === 0) {
44
- return err("Empty image data after base64 decode");
45
- }
46
- // Check size against maxInputBytes
47
- if (inputBuffer.length > maxInputBytes) {
48
- return err(`Image size ${inputBuffer.length} bytes exceeds maximum allowed ${maxInputBytes} bytes`);
49
- }
50
- try {
51
- // Create sharp instance with decompression bomb protection
52
- const image = sharp(inputBuffer, {
53
- limitInputPixels: DEFAULT_LIMIT_INPUT_PIXELS,
54
- });
55
- // Read metadata to determine if resize is needed
56
- const metadata = await image.metadata();
57
- if (!metadata.width || !metadata.height) {
58
- return err("Unable to read image dimensions -- possibly corrupt or unsupported format");
59
- }
60
- // Resize if exceeds limits (fit: inside preserves aspect ratio)
61
- const needsResize = metadata.width > maxWidth || metadata.height > maxHeight;
62
- if (needsResize) {
63
- image.resize(maxWidth, maxHeight, { fit: "inside" });
64
- }
65
- // Convert to output format
66
- let outputBuffer;
67
- switch (outputFormat) {
68
- case "jpeg":
69
- outputBuffer = await image.jpeg({ quality }).toBuffer();
70
- break;
71
- case "webp":
72
- outputBuffer = await image.webp({ quality }).toBuffer();
73
- break;
74
- case "png":
75
- default:
76
- outputBuffer = await image.png().toBuffer();
77
- break;
78
- }
79
- // Read final metadata from the output
80
- const outputMeta = await sharp(outputBuffer).metadata();
81
- return ok({
82
- buffer: outputBuffer,
83
- format: outputFormat,
84
- width: outputMeta.width ?? (needsResize ? maxWidth : metadata.width),
85
- height: outputMeta.height ?? (needsResize ? maxHeight : metadata.height),
86
- originalBytes: inputBuffer.length,
87
- sanitizedBytes: outputBuffer.length,
88
- });
89
- }
90
- catch (e) {
91
- const message = e instanceof Error ? e.message : String(e);
92
- return err(`Image processing failed: ${message}`);
93
- }
94
- },
95
- };
96
- }
@@ -1,44 +0,0 @@
1
- /**
2
- * Tool output sanitizer -- strips indirect prompt injection patterns.
3
- *
4
- * Detects instruction-like text in tool outputs that could be used
5
- * to hijack the agent's behavior via indirect prompt injection.
6
- * Replaces detected patterns with "[REDACTED]" and truncates
7
- * oversized output at newline boundaries.
8
- */
9
- /**
10
- * Normalize text for secure pattern matching.
11
- * 1. Apply Unicode NFKC normalization (compatibility decomposition + canonical composition)
12
- * 2. Strip zero-width and invisible formatting characters (including tag block bypass)
13
- *
14
- * IMPORTANT: Always normalize FIRST, then do pattern matching on the normalized string.
15
- * NFKC can change string length (e.g., fullwidth A -> A, ligatures decompose).
16
- */
17
- export declare function normalizeForMatching(text: string): string;
18
- /**
19
- * Regex patterns that indicate potential prompt injection attempts.
20
- *
21
- * Imported from @comis/core injection-patterns.ts (single source of truth).
22
- * Each pattern uses the `gi` flag for case-insensitive global matching.
23
- *
24
- * Note: The `system\s*:\s+` pattern requires whitespace after colon
25
- * to avoid matching URLs like `https://system.example.com:8080`
26
- * or code like `process.env.system`.
27
- */
28
- export declare const INSTRUCTION_PATTERNS: readonly RegExp[];
29
- /**
30
- * Sanitize tool output against indirect prompt injection.
31
- *
32
- * 1. Checks for Unicode tag block bypass characters (for caller-side INFO logging)
33
- * 2. Replaces instruction-like injection patterns with "[REDACTED]"
34
- * 3. Truncates output exceeding `maxChars` at the last newline before
35
- * the 95% mark, appending a truncation notice
36
- *
37
- * @param text - Raw tool output text
38
- * @param maxChars - Maximum allowed characters (default: 50,000)
39
- * @param options - Optional callbacks for tag block detection logging
40
- * @returns Sanitized text with injections redacted and size enforced
41
- */
42
- export declare function sanitizeToolOutput(text: string, maxChars?: number, options?: {
43
- onTagBlockDetected?: () => void;
44
- }): string;
@@ -1,94 +0,0 @@
1
- /**
2
- * Tool output sanitizer -- strips indirect prompt injection patterns.
3
- *
4
- * Detects instruction-like text in tool outputs that could be used
5
- * to hijack the agent's behavior via indirect prompt injection.
6
- * Replaces detected patterns with "[REDACTED]" and truncates
7
- * oversized output at newline boundaries.
8
- */
9
- import { stripInvisible, containsTagBlockChars, IGNORE_PREV_INSTRUCTIONS, YOU_ARE_NOW, FORGET_EVERYTHING, NEW_INSTRUCTIONS, SYSTEM_COLON, SYSTEM_BRACKET, INST_BRACKET, SYSTEM_TAG, IMPORTANT_OVERRIDE, DISREGARD_INSTRUCTIONS, ACT_AS_ROLE, ASSISTANT_ROLE_MARKER, SPECIAL_TOKEN_DELIMITERS, CONTEXT_RESET, RULE_REPLACEMENT, OVERRIDE_SAFETY, } from "@comis/core";
10
- /**
11
- * Normalize text for secure pattern matching.
12
- * 1. Apply Unicode NFKC normalization (compatibility decomposition + canonical composition)
13
- * 2. Strip zero-width and invisible formatting characters (including tag block bypass)
14
- *
15
- * IMPORTANT: Always normalize FIRST, then do pattern matching on the normalized string.
16
- * NFKC can change string length (e.g., fullwidth A -> A, ligatures decompose).
17
- */
18
- export function normalizeForMatching(text) {
19
- return stripInvisible(text.normalize("NFKC")).text;
20
- }
21
- /** Default maximum characters for tool output */
22
- const DEFAULT_MAX_CHARS = 50_000;
23
- /** Truncation message appended when output is cut */
24
- const TRUNCATION_MSG = "\n[Content truncated -- exceeded size limit]";
25
- /**
26
- * Regex patterns that indicate potential prompt injection attempts.
27
- *
28
- * Imported from @comis/core injection-patterns.ts (single source of truth).
29
- * Each pattern uses the `gi` flag for case-insensitive global matching.
30
- *
31
- * Note: The `system\s*:\s+` pattern requires whitespace after colon
32
- * to avoid matching URLs like `https://system.example.com:8080`
33
- * or code like `process.env.system`.
34
- */
35
- export const INSTRUCTION_PATTERNS = [
36
- IGNORE_PREV_INSTRUCTIONS, // /ignore\s+(all\s+)?previous\s+instructions/gi
37
- YOU_ARE_NOW, // /you\s+are\s+now\s+/gi
38
- FORGET_EVERYTHING, // /forget\s+(everything|all|your)\s/gi
39
- NEW_INSTRUCTIONS, // /new\s+instructions?\s*:/gi
40
- SYSTEM_COLON, // /system\s*:\s+/gi
41
- SYSTEM_BRACKET, // /\[SYSTEM\]/gi
42
- INST_BRACKET, // /\[INST\]/gi
43
- SYSTEM_TAG, // /<\/?system>/gi
44
- IMPORTANT_OVERRIDE, // /IMPORTANT\s*:\s*override/gi
45
- DISREGARD_INSTRUCTIONS, // /disregard ... instructions/
46
- ACT_AS_ROLE, // /act as root|admin|.../
47
- ASSISTANT_ROLE_MARKER, // /assistant:|user:/
48
- SPECIAL_TOKEN_DELIMITERS, // /<|...|>/
49
- CONTEXT_RESET, // /context reset|cleared|.../
50
- RULE_REPLACEMENT, // /new rules:|updated guidelines:/
51
- OVERRIDE_SAFETY, // /override safety|bypass security/
52
- ];
53
- /**
54
- * Sanitize tool output against indirect prompt injection.
55
- *
56
- * 1. Checks for Unicode tag block bypass characters (for caller-side INFO logging)
57
- * 2. Replaces instruction-like injection patterns with "[REDACTED]"
58
- * 3. Truncates output exceeding `maxChars` at the last newline before
59
- * the 95% mark, appending a truncation notice
60
- *
61
- * @param text - Raw tool output text
62
- * @param maxChars - Maximum allowed characters (default: 50,000)
63
- * @param options - Optional callbacks for tag block detection logging
64
- * @returns Sanitized text with injections redacted and size enforced
65
- */
66
- export function sanitizeToolOutput(text, maxChars = DEFAULT_MAX_CHARS, options) {
67
- if (text.length === 0)
68
- return text;
69
- // Check for tag block bypass BEFORE normalization strips them
70
- if (containsTagBlockChars(text)) {
71
- options?.onTagBlockDetected?.();
72
- }
73
- // Phase 1: Normalize for pattern matching (NFKC + strip zero-width + tag block)
74
- let sanitized = normalizeForMatching(text);
75
- // Phase 2: Redact injection patterns (on normalized text)
76
- for (const pattern of INSTRUCTION_PATTERNS) {
77
- // Reset lastIndex for sticky/global regexes across multiple calls
78
- pattern.lastIndex = 0;
79
- sanitized = sanitized.replace(pattern, "[REDACTED]");
80
- }
81
- // Phase 3: Truncate oversized output
82
- if (sanitized.length > maxChars) {
83
- const cutPoint = Math.floor(maxChars * 0.95);
84
- const lastNewline = sanitized.lastIndexOf("\n", cutPoint);
85
- if (lastNewline > 0) {
86
- sanitized = sanitized.slice(0, lastNewline + 1) + TRUNCATION_MSG;
87
- }
88
- else {
89
- // No newline found -- hard cut at 95%
90
- sanitized = sanitized.slice(0, cutPoint) + TRUNCATION_MSG;
91
- }
92
- }
93
- return sanitized;
94
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * Thinking tag filter -- strips <think>, <thinking>, and <final> blocks
3
- * from streaming deltas using a character-level state machine.
4
- *
5
- * Handles tags split across chunk boundaries by buffering partial
6
- * tag sequences and resolving them when more data arrives.
7
- *
8
- * @module
9
- */
10
- /** Streaming thinking tag filter interface. */
11
- export interface ThinkingTagFilter {
12
- /** Process a streaming delta, returning only visible text. */
13
- feed(delta: string): string;
14
- /** Flush any buffered partial tag text (call at stream end). */
15
- flush(): string;
16
- /** Reset state for a new message. */
17
- reset(): void;
18
- }
19
- /**
20
- * Create a thinking tag filter that strips thinking blocks from streaming deltas.
21
- *
22
- * The filter processes characters one at a time through a state machine:
23
- * - `passthrough`: Normal text flows through. On `<`, transition to `buffering`.
24
- * - `buffering`: Accumulating chars after `<` to identify an opening or closing tag.
25
- * - `inside_block`: All text is suppressed. On `<`, transition to `close_buffering`.
26
- * - `close_buffering`: Inside a block, checking for the matching closing tag.
27
- */
28
- export declare function createThinkingTagFilter(): ThinkingTagFilter;