crewly 1.8.8 → 1.8.9
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/backend/backend/src/constants.d.ts +12 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +12 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.controller.js +17 -0
- package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +8 -1
- package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +15 -7
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-bridge.service.js +15 -29
- package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts +97 -1
- package/dist/backend/backend/src/services/browser/browser-proxy.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-proxy.service.js +174 -15
- package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.d.ts +12 -4
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.js +17 -5
- package/dist/backend/backend/src/services/browser/browser-relay-adapter.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts +75 -0
- package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-client.service.js +164 -12
- package/dist/backend/backend/src/services/cloud/cloud-client.service.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +12 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +12 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/cli/src/index.js +0 -0
- package/package.json +1 -1
- package/config/constants.d.ts.map +0 -1
- package/config/index.d.ts.map +0 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +0 -169
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +0 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +0 -1779
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts +0 -513
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +0 -1568
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.d.ts +0 -86
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.js +0 -147
- package/dist/backend/backend/src/services/agent/crewly-agent/agent-worker.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts +0 -68
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js +0 -131
- package/dist/backend/backend/src/services/agent/crewly-agent/api-client.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.d.ts +0 -130
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.js +0 -263
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts +0 -74
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js +0 -140
- package/dist/backend/backend/src/services/agent/crewly-agent/audit-trail.service.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts +0 -29
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js +0 -279
- package/dist/backend/backend/src/services/agent/crewly-agent/auditor-tools.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts +0 -340
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js +0 -1176
- package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.d.ts +0 -79
- package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.js +0 -145
- package/dist/backend/backend/src/services/agent/crewly-agent/deepseek-sse-transform.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.d.ts +0 -79
- package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.js +0 -218
- package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts +0 -16
- package/dist/backend/backend/src/services/agent/crewly-agent/index.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/index.js +0 -16
- package/dist/backend/backend/src/services/agent/crewly-agent/index.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts +0 -135
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js +0 -185
- package/dist/backend/backend/src/services/agent/crewly-agent/mcp-tool-bridge.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts +0 -141
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js +0 -310
- package/dist/backend/backend/src/services/agent/crewly-agent/model-manager.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.d.ts +0 -91
- package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.js +0 -143
- package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.d.ts +0 -103
- package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.js +0 -256
- package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts +0 -143
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js +0 -264
- package/dist/backend/backend/src/services/agent/crewly-agent/rate-limiter.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts +0 -13
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js +0 -91
- package/dist/backend/backend/src/services/agent/crewly-agent/smoke-test.js.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts +0 -135
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts.map +0 -1
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js +0 -1937
- package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js.map +0 -1
- package/dist/backend/backend/src/services/autonomous/auto-assign.service.d.ts +0 -429
- package/dist/backend/backend/src/services/autonomous/auto-assign.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/autonomous/auto-assign.service.js +0 -852
- package/dist/backend/backend/src/services/autonomous/auto-assign.service.js.map +0 -1
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts +0 -171
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/project/task-tracking.service.js +0 -725
- package/dist/backend/backend/src/services/project/task-tracking.service.js.map +0 -1
- package/dist/backend/backend/src/services/v3/project-task-watcher.service.d.ts +0 -118
- package/dist/backend/backend/src/services/v3/project-task-watcher.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/v3/project-task-watcher.service.js +0 -326
- package/dist/backend/backend/src/services/v3/project-task-watcher.service.js.map +0 -1
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.d.ts +0 -74
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.d.ts.map +0 -1
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.js +0 -154
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.js.map +0 -1
- package/dist/backend/backend/src/types/auto-assign.types.d.ts +0 -271
- package/dist/backend/backend/src/types/auto-assign.types.d.ts.map +0 -1
- package/dist/backend/backend/src/types/auto-assign.types.js +0 -136
- package/dist/backend/backend/src/types/auto-assign.types.js.map +0 -1
- package/dist/backend/backend/src/utils/esm-require.utils.d.ts +0 -111
- package/dist/backend/backend/src/utils/esm-require.utils.d.ts.map +0 -1
- package/dist/backend/backend/src/utils/esm-require.utils.js +0 -124
- package/dist/backend/backend/src/utils/esm-require.utils.js.map +0 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts +0 -220
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts.map +0 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.js +0 -37
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.js.map +0 -1
- package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.d.ts +0 -56
- package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.d.ts.map +0 -1
- package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.js +0 -91
- package/dist/cli/backend/src/services/knowledge/fts5-search-strategy.js.map +0 -1
- package/dist/cli/backend/src/services/knowledge/learnings-index.service.d.ts +0 -159
- package/dist/cli/backend/src/services/knowledge/learnings-index.service.d.ts.map +0 -1
- package/dist/cli/backend/src/services/knowledge/learnings-index.service.js +0 -304
- package/dist/cli/backend/src/services/knowledge/learnings-index.service.js.map +0 -1
- package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.d.ts +0 -115
- package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.d.ts.map +0 -1
- package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.js +0 -215
- package/dist/cli/backend/src/services/knowledge/wiki-compiler.service.js.map +0 -1
- package/dist/cli/backend/src/services/memory/embedding-provider.d.ts +0 -78
- package/dist/cli/backend/src/services/memory/embedding-provider.d.ts.map +0 -1
- package/dist/cli/backend/src/services/memory/embedding-provider.js +0 -179
- package/dist/cli/backend/src/services/memory/embedding-provider.js.map +0 -1
- package/dist/cli/backend/src/services/memory/vector-store.service.d.ts +0 -331
- package/dist/cli/backend/src/services/memory/vector-store.service.d.ts.map +0 -1
- package/dist/cli/backend/src/services/memory/vector-store.service.js +0 -814
- package/dist/cli/backend/src/services/memory/vector-store.service.js.map +0 -1
- package/dist/cli/backend/src/services/project/task-tracking.service.d.ts +0 -171
- package/dist/cli/backend/src/services/project/task-tracking.service.d.ts.map +0 -1
- package/dist/cli/backend/src/services/project/task-tracking.service.js +0 -725
- package/dist/cli/backend/src/services/project/task-tracking.service.js.map +0 -1
- package/dist/cli/backend/src/types/auto-assign.types.d.ts +0 -271
- package/dist/cli/backend/src/types/auto-assign.types.d.ts.map +0 -1
- package/dist/cli/backend/src/types/auto-assign.types.js +0 -136
- package/dist/cli/backend/src/types/auto-assign.types.js.map +0 -1
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Crewly Agent Model Manager
|
|
3
|
-
*
|
|
4
|
-
* Multi-provider model factory that creates AI SDK model instances
|
|
5
|
-
* from configuration. Supports Anthropic, OpenAI, Google, DeepSeek, and
|
|
6
|
-
* Ollama providers.
|
|
7
|
-
*
|
|
8
|
-
* API keys for cloud providers are resolved through the settings service
|
|
9
|
-
* (skill → runtime → global → env var) and injected into process.env so the
|
|
10
|
-
* provider SDKs can pick them up:
|
|
11
|
-
* - ANTHROPIC_API_KEY
|
|
12
|
-
* - OPENAI_API_KEY
|
|
13
|
-
* - GOOGLE_GENERATIVE_AI_API_KEY
|
|
14
|
-
* - DEEPSEEK_API_KEY (DeepSeek; served via OpenAI-compatible API)
|
|
15
|
-
*
|
|
16
|
-
* Ollama runs locally and does not require an API key.
|
|
17
|
-
* Configure the Ollama base URL via OLLAMA_BASE_URL (default: http://localhost:11434).
|
|
18
|
-
*
|
|
19
|
-
* @module services/agent/crewly-agent/model-manager
|
|
20
|
-
*/
|
|
21
|
-
import { CREWLY_AGENT_DEFAULTS } from './types.js';
|
|
22
|
-
import { getSettingsService } from '../../settings/settings.service.js';
|
|
23
|
-
import { teeAndParse } from './deepseek-sse-transform.js';
|
|
24
|
-
/**
|
|
25
|
-
* Base URL for DeepSeek's OpenAI-compatible chat completions endpoint.
|
|
26
|
-
* DeepSeek implements /chat/completions only — not /responses — so we
|
|
27
|
-
* must route via the `.chat(modelId)` factory of @ai-sdk/openai's
|
|
28
|
-
* createOpenAI() return value. Extracted per CLAUDE.md no-hardcoded-values rule.
|
|
29
|
-
*/
|
|
30
|
-
const DEEPSEEK_BASE_URL = 'https://api.deepseek.com/v1';
|
|
31
|
-
/**
|
|
32
|
-
* Factory for creating AI SDK language model instances from configuration.
|
|
33
|
-
*
|
|
34
|
-
* Uses dynamic imports to avoid loading provider SDKs that aren't needed,
|
|
35
|
-
* keeping the startup cost minimal when only one provider is used.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```typescript
|
|
39
|
-
* const manager = new ModelManager();
|
|
40
|
-
* const model = await manager.getModel({ provider: 'anthropic', modelId: 'claude-sonnet-4-20250514' });
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
export class ModelManager {
|
|
44
|
-
/** Cached provider module references to avoid re-importing */
|
|
45
|
-
providerCache = new Map();
|
|
46
|
-
/**
|
|
47
|
-
* Per-instance buffer of parsed DeepSeek-R1 reasoning_content from in-flight
|
|
48
|
-
* and recently-completed HTTP calls. Each `streamText` call to a DeepSeek
|
|
49
|
-
* model triggers one or more fetch calls (one per agentic step); each fetch
|
|
50
|
-
* appends its parsed reasoning to this buffer. Consumer (agent-runner) reads
|
|
51
|
-
* via `consumeDeepseekReasoning()` after `await streamResult` and the buffer
|
|
52
|
-
* resets to `''` on read.
|
|
53
|
-
*
|
|
54
|
-
* **Concurrency:** AgentRunner uses one ModelManager per session and calls
|
|
55
|
-
* streamText serially per session (the rate limiter enforces this).
|
|
56
|
-
* Cross-session concurrency is not a concern because each AgentRunner gets
|
|
57
|
-
* its own ModelManager via `new ModelManager()` in the constructor.
|
|
58
|
-
*/
|
|
59
|
-
deepseekReasoningBuffer = '';
|
|
60
|
-
/** Tracks in-flight parsed-SSE handles so we can wait for drain on consume. */
|
|
61
|
-
deepseekParsedHandles = [];
|
|
62
|
-
/**
|
|
63
|
-
* Get an AI SDK language model instance for the given configuration.
|
|
64
|
-
*
|
|
65
|
-
* Resolves API keys from settings (with override chain) and injects them
|
|
66
|
-
* into the environment before creating the model, so provider SDKs can find them.
|
|
67
|
-
*
|
|
68
|
-
* @param config - Model configuration specifying provider and model ID
|
|
69
|
-
* @returns AI SDK LanguageModel instance ready for use with generateText
|
|
70
|
-
* @throws Error if the provider is unknown or the SDK is not installed
|
|
71
|
-
*/
|
|
72
|
-
async getModel(config = CREWLY_AGENT_DEFAULTS.DEFAULT_MODEL) {
|
|
73
|
-
// Ensure the provider's API key is in the environment from settings
|
|
74
|
-
await this.ensureApiKeyInEnv(config.provider);
|
|
75
|
-
const providerFn = await this.getProviderFunction(config.provider);
|
|
76
|
-
return providerFn(config.modelId);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Get provider function, using cache for repeated calls.
|
|
80
|
-
*
|
|
81
|
-
* @param provider - Provider name
|
|
82
|
-
* @returns Function that creates a model from a model ID string
|
|
83
|
-
*/
|
|
84
|
-
async getProviderFunction(provider) {
|
|
85
|
-
const cached = this.providerCache.get(provider);
|
|
86
|
-
if (cached)
|
|
87
|
-
return cached;
|
|
88
|
-
let providerFn;
|
|
89
|
-
try {
|
|
90
|
-
switch (provider) {
|
|
91
|
-
case 'anthropic': {
|
|
92
|
-
const { anthropic } = await import('@ai-sdk/anthropic');
|
|
93
|
-
providerFn = (modelId) => anthropic(modelId);
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
case 'openai': {
|
|
97
|
-
const { openai } = await import('@ai-sdk/openai');
|
|
98
|
-
providerFn = (modelId) => openai(modelId);
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
101
|
-
case 'google': {
|
|
102
|
-
const { google } = await import('@ai-sdk/google');
|
|
103
|
-
providerFn = (modelId) => google(modelId);
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
case 'ollama': {
|
|
107
|
-
const { createOllama } = await import('ollama-ai-provider');
|
|
108
|
-
const baseURL = process.env.OLLAMA_BASE_URL || CREWLY_AGENT_DEFAULTS.OLLAMA_BASE_URL;
|
|
109
|
-
const ollamaProvider = createOllama({ baseURL });
|
|
110
|
-
// ollama-ai-provider exports LanguageModelV1 which is compatible but
|
|
111
|
-
// doesn't extend the newer LanguageModel union — safe to cast.
|
|
112
|
-
providerFn = (modelId) => ollamaProvider(modelId);
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
case 'deepseek': {
|
|
116
|
-
// DeepSeek API is OpenAI-compatible — reuse the OpenAI SDK with a custom baseURL.
|
|
117
|
-
// IMPORTANT: must call deepseekProvider.chat(modelId), NOT deepseekProvider(modelId).
|
|
118
|
-
// The bare function-call form on @ai-sdk/openai >=3.x routes to /responses, which
|
|
119
|
-
// DeepSeek does not implement — it only exposes /chat/completions. The .chat factory
|
|
120
|
-
// forces the chat-completions path. See PR #400 review for full trace.
|
|
121
|
-
//
|
|
122
|
-
// **I2 — reasoning_content extraction:**
|
|
123
|
-
// Pass a custom `fetch` that tees the SSE response body. One branch flows
|
|
124
|
-
// through to AI SDK unmodified (zero impact on existing behavior); the other
|
|
125
|
-
// branch is parsed for `delta.reasoning_content` text and accumulated into
|
|
126
|
-
// `this.deepseekReasoningBuffer`, which agent-runner consumes after
|
|
127
|
-
// streamResult drains. See deepseek-sse-transform.ts for the parser.
|
|
128
|
-
const { createOpenAI } = await import('@ai-sdk/openai');
|
|
129
|
-
const customFetch = this.makeDeepseekFetch();
|
|
130
|
-
const deepseekProvider = createOpenAI({
|
|
131
|
-
baseURL: DEEPSEEK_BASE_URL,
|
|
132
|
-
apiKey: process.env.DEEPSEEK_API_KEY,
|
|
133
|
-
fetch: customFetch,
|
|
134
|
-
});
|
|
135
|
-
providerFn = (modelId) => deepseekProvider.chat(modelId);
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
default:
|
|
139
|
-
throw new Error(`Unknown model provider: ${provider}`);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
if (error instanceof Error && error.message.startsWith('Unknown model provider:')) {
|
|
144
|
-
throw error;
|
|
145
|
-
}
|
|
146
|
-
throw new Error(`Failed to load provider SDK for '${provider}'. Is the package installed? ` +
|
|
147
|
-
`Original error: ${error instanceof Error ? error.message : String(error)}`);
|
|
148
|
-
}
|
|
149
|
-
this.providerCache.set(provider, providerFn);
|
|
150
|
-
return providerFn;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Check which providers have API keys configured (settings + env vars).
|
|
154
|
-
*
|
|
155
|
-
* @returns Object indicating which providers are available
|
|
156
|
-
*/
|
|
157
|
-
async getAvailableProviders() {
|
|
158
|
-
const settingsService = getSettingsService();
|
|
159
|
-
const context = { runtime: 'crewly-agent' };
|
|
160
|
-
const [geminiKey, anthropicKey, openaiKey, deepseekKey] = await Promise.all([
|
|
161
|
-
settingsService.getApiKey('gemini', context),
|
|
162
|
-
settingsService.getApiKey('anthropic', context),
|
|
163
|
-
settingsService.getApiKey('openai', context),
|
|
164
|
-
settingsService.getApiKey('deepseek', context),
|
|
165
|
-
]);
|
|
166
|
-
return {
|
|
167
|
-
anthropic: !!anthropicKey,
|
|
168
|
-
openai: !!openaiKey,
|
|
169
|
-
google: !!geminiKey,
|
|
170
|
-
ollama: true, // Ollama runs locally, always "available" if installed
|
|
171
|
-
deepseek: !!deepseekKey,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Map model provider name to API key provider name.
|
|
176
|
-
* Only applicable for cloud providers wired through the settings service
|
|
177
|
-
* (anthropic, openai, google, deepseek). Ollama runs locally and is
|
|
178
|
-
* excluded.
|
|
179
|
-
*
|
|
180
|
-
* @param provider - Cloud model provider
|
|
181
|
-
* @returns Corresponding ApiKeyProvider name
|
|
182
|
-
*/
|
|
183
|
-
static providerToApiKeyProvider(provider) {
|
|
184
|
-
return provider === 'google' ? 'gemini' : provider;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Ensure the API key for a provider is available in process.env
|
|
188
|
-
* by resolving it from settings if not already present.
|
|
189
|
-
*
|
|
190
|
-
* No-op for 'ollama' (runs locally, no key required). All other providers —
|
|
191
|
-
* including 'deepseek' — flow through the settings service so users can
|
|
192
|
-
* configure them from the UI without touching env vars.
|
|
193
|
-
*
|
|
194
|
-
* @param provider - The model provider
|
|
195
|
-
*/
|
|
196
|
-
async ensureApiKeyInEnv(provider) {
|
|
197
|
-
if (provider === 'ollama')
|
|
198
|
-
return; // Ollama is local, no API key needed
|
|
199
|
-
const apiKeyProvider = ModelManager.providerToApiKeyProvider(provider);
|
|
200
|
-
const settingsService = getSettingsService();
|
|
201
|
-
const key = await settingsService.getApiKey(apiKeyProvider, { runtime: 'crewly-agent' });
|
|
202
|
-
if (!key)
|
|
203
|
-
return;
|
|
204
|
-
// Set env vars so the provider SDKs can find them.
|
|
205
|
-
// Always override — settings keys take priority over stale env vars.
|
|
206
|
-
switch (provider) {
|
|
207
|
-
case 'anthropic':
|
|
208
|
-
process.env.ANTHROPIC_API_KEY = key;
|
|
209
|
-
break;
|
|
210
|
-
case 'openai':
|
|
211
|
-
process.env.OPENAI_API_KEY = key;
|
|
212
|
-
break;
|
|
213
|
-
case 'google':
|
|
214
|
-
process.env.GOOGLE_GENERATIVE_AI_API_KEY = key;
|
|
215
|
-
break;
|
|
216
|
-
case 'deepseek':
|
|
217
|
-
process.env.DEEPSEEK_API_KEY = key;
|
|
218
|
-
break;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Clear the provider cache (useful for testing or reconfiguration).
|
|
223
|
-
* Also clears any buffered DeepSeek reasoning so a fresh test/run starts clean.
|
|
224
|
-
*/
|
|
225
|
-
clearCache() {
|
|
226
|
-
this.providerCache.clear();
|
|
227
|
-
this.deepseekReasoningBuffer = '';
|
|
228
|
-
this.deepseekParsedHandles = [];
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Build the custom fetch wrapper for the DeepSeek provider.
|
|
232
|
-
*
|
|
233
|
-
* Returns a function with the same signature as `globalThis.fetch` that:
|
|
234
|
-
* 1. Calls native fetch with the supplied input/init.
|
|
235
|
-
* 2. If the response is a streaming SSE body, tees it and parses one branch
|
|
236
|
-
* for `delta.reasoning_content`, accumulating into `this.deepseekReasoningBuffer`.
|
|
237
|
-
* 3. Returns a new Response wrapping the un-tampered passthrough branch as
|
|
238
|
-
* its body, so AI SDK consumes exactly the bytes DeepSeek sent.
|
|
239
|
-
*
|
|
240
|
-
* If the response is not an SSE stream (e.g. error JSON, no body), it is
|
|
241
|
-
* returned unchanged.
|
|
242
|
-
*
|
|
243
|
-
* **Why a method, not a free function:** the wrapper closes over `this` to
|
|
244
|
-
* append to the per-instance reasoning buffer. Each ModelManager instance
|
|
245
|
-
* has its own buffer (one per AgentRunner per session).
|
|
246
|
-
*/
|
|
247
|
-
makeDeepseekFetch() {
|
|
248
|
-
return async (input, init) => {
|
|
249
|
-
// Cast through `any` because @ai-sdk/openai's fetch type is the standard
|
|
250
|
-
// global fetch shape; we re-export native fetch behavior identically.
|
|
251
|
-
const response = await globalThis.fetch(input, init);
|
|
252
|
-
// Only intercept successful streaming responses. Non-stream errors
|
|
253
|
-
// (4xx/5xx with JSON body) and empty bodies pass through untouched.
|
|
254
|
-
if (!response.ok || !response.body)
|
|
255
|
-
return response;
|
|
256
|
-
const contentType = response.headers.get('content-type') ?? '';
|
|
257
|
-
if (!contentType.includes('text/event-stream'))
|
|
258
|
-
return response;
|
|
259
|
-
const parsed = teeAndParse(response.body);
|
|
260
|
-
this.deepseekParsedHandles.push(parsed);
|
|
261
|
-
// Wrap into a new Response with the passthrough branch as body.
|
|
262
|
-
// Headers, status, and statusText are copied so AI SDK sees an identical
|
|
263
|
-
// response shape.
|
|
264
|
-
return new Response(parsed.passthroughBody, {
|
|
265
|
-
status: response.status,
|
|
266
|
-
statusText: response.statusText,
|
|
267
|
-
headers: response.headers,
|
|
268
|
-
});
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Drain any in-flight DeepSeek SSE parser branches and return the accumulated
|
|
273
|
-
* `reasoning_content` string. Resets the buffer to `''` on each call (consume
|
|
274
|
-
* semantics).
|
|
275
|
-
*
|
|
276
|
-
* **Caller contract:** call AFTER `await streamResult` resolves in agent-runner.
|
|
277
|
-
* The AI SDK consumer branch must have been fully drained for the parser branch
|
|
278
|
-
* (which lags slightly due to tee buffering) to have caught up.
|
|
279
|
-
*
|
|
280
|
-
* **Multi-step accumulation:** if a single `streamText` call made multiple HTTP
|
|
281
|
-
* calls (one per agentic step), reasoning from all steps is concatenated in
|
|
282
|
-
* call order — not separated by step boundary. This matches the user-facing
|
|
283
|
-
* mental model of "what was the model's full chain of thought for this turn."
|
|
284
|
-
*
|
|
285
|
-
* **Returns `null` if no reasoning was captured.** Empty string means a fetch
|
|
286
|
-
* happened but produced no reasoning content (e.g. non-R1 DeepSeek model).
|
|
287
|
-
*/
|
|
288
|
-
async consumeDeepseekReasoning() {
|
|
289
|
-
const handles = this.deepseekParsedHandles;
|
|
290
|
-
this.deepseekParsedHandles = [];
|
|
291
|
-
if (handles.length === 0) {
|
|
292
|
-
const buffered = this.deepseekReasoningBuffer;
|
|
293
|
-
this.deepseekReasoningBuffer = '';
|
|
294
|
-
return buffered || null;
|
|
295
|
-
}
|
|
296
|
-
// Wait for all parser branches to finish draining (they should already be
|
|
297
|
-
// done if AI SDK consumer drained, but allow up to one event-loop tick).
|
|
298
|
-
for (const h of handles) {
|
|
299
|
-
if (!h.isDrained()) {
|
|
300
|
-
// Yield once so the parser background reader can flush.
|
|
301
|
-
await new Promise((r) => setImmediate(r));
|
|
302
|
-
}
|
|
303
|
-
this.deepseekReasoningBuffer += h.getReasoning();
|
|
304
|
-
}
|
|
305
|
-
const out = this.deepseekReasoningBuffer;
|
|
306
|
-
this.deepseekReasoningBuffer = '';
|
|
307
|
-
return out || null;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
//# sourceMappingURL=model-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model-manager.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/agent/crewly-agent/model-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Output Filter Service — API Key Redaction
|
|
3
|
-
*
|
|
4
|
-
* Scans all agent text output for API key patterns and replaces them
|
|
5
|
-
* with [REDACTED] before the output reaches users or logs.
|
|
6
|
-
*
|
|
7
|
-
* Detects patterns from major providers (OpenAI, Anthropic, Google, AWS)
|
|
8
|
-
* as well as generic key/token/secret assignments.
|
|
9
|
-
*
|
|
10
|
-
* @module services/agent/crewly-agent/output-filter.service
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* const filter = new OutputFilterService();
|
|
15
|
-
* const safe = filter.redact('My key is sk-abc123xyz');
|
|
16
|
-
* // => 'My key is [REDACTED]'
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
/**
|
|
20
|
-
* A single API key detection pattern with a label for audit logging.
|
|
21
|
-
*/
|
|
22
|
-
export interface KeyPattern {
|
|
23
|
-
/** Regex to match the key in text */
|
|
24
|
-
pattern: RegExp;
|
|
25
|
-
/** Human-readable label for audit/logging */
|
|
26
|
-
label: string;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Result of scanning text for API keys.
|
|
30
|
-
*/
|
|
31
|
-
export interface ScanResult {
|
|
32
|
-
/** Whether any keys were detected */
|
|
33
|
-
detected: boolean;
|
|
34
|
-
/** Number of keys found */
|
|
35
|
-
count: number;
|
|
36
|
-
/** Labels of the matched patterns */
|
|
37
|
-
matchedPatterns: string[];
|
|
38
|
-
/** Redacted text with keys replaced */
|
|
39
|
-
redactedText: string;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* API key patterns for major providers and generic secrets.
|
|
43
|
-
*
|
|
44
|
-
* Each pattern uses word boundaries or lookbehind/lookahead to minimize
|
|
45
|
-
* false positives while catching real key formats.
|
|
46
|
-
*/
|
|
47
|
-
export declare const API_KEY_PATTERNS: readonly KeyPattern[];
|
|
48
|
-
/** Replacement text for redacted keys */
|
|
49
|
-
export declare const REDACTION_PLACEHOLDER = "[REDACTED]";
|
|
50
|
-
/**
|
|
51
|
-
* Service that scans and redacts API keys from agent output text.
|
|
52
|
-
*/
|
|
53
|
-
export declare class OutputFilterService {
|
|
54
|
-
private readonly patterns;
|
|
55
|
-
/**
|
|
56
|
-
* Creates a new OutputFilterService.
|
|
57
|
-
* @param customPatterns - Optional additional patterns to detect (appended to defaults)
|
|
58
|
-
*/
|
|
59
|
-
constructor(customPatterns?: KeyPattern[]);
|
|
60
|
-
/**
|
|
61
|
-
* Scans text for API keys and returns detailed results.
|
|
62
|
-
*
|
|
63
|
-
* @param text - Text to scan for API keys
|
|
64
|
-
* @returns Scan result with detection info and redacted text
|
|
65
|
-
*/
|
|
66
|
-
scan(text: string): ScanResult;
|
|
67
|
-
/**
|
|
68
|
-
* Redacts all API keys in the given text.
|
|
69
|
-
* Convenience method that returns only the redacted string.
|
|
70
|
-
*
|
|
71
|
-
* @param text - Text to redact
|
|
72
|
-
* @returns Text with all detected API keys replaced with [REDACTED]
|
|
73
|
-
*/
|
|
74
|
-
redact(text: string): string;
|
|
75
|
-
/**
|
|
76
|
-
* Checks if text contains any API keys without modifying it.
|
|
77
|
-
*
|
|
78
|
-
* @param text - Text to check
|
|
79
|
-
* @returns True if any API key patterns are detected
|
|
80
|
-
*/
|
|
81
|
-
containsKeys(text: string): boolean;
|
|
82
|
-
/**
|
|
83
|
-
* Redacts API keys from a structured object (recursively scans string values).
|
|
84
|
-
* Useful for sanitizing tool call arguments and results before logging.
|
|
85
|
-
*
|
|
86
|
-
* @param obj - Object to scan and redact
|
|
87
|
-
* @returns Deep copy with all string values redacted
|
|
88
|
-
*/
|
|
89
|
-
redactObject(obj: unknown): unknown;
|
|
90
|
-
}
|
|
91
|
-
//# sourceMappingURL=output-filter.service.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"output-filter.service.d.ts","sourceRoot":"","sources":["../../../../../../../backend/src/services/agent/crewly-agent/output-filter.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,UAAU,EAqBxC,CAAC;AAEX,yCAAyC;AACzC,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAElD;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IAEjD;;;OAGG;gBACS,cAAc,CAAC,EAAE,UAAU,EAAE;IAMzC;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IA4B9B;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI5B;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IASnC;;;;;;OAMG;IACH,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;CAgBpC"}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Output Filter Service — API Key Redaction
|
|
3
|
-
*
|
|
4
|
-
* Scans all agent text output for API key patterns and replaces them
|
|
5
|
-
* with [REDACTED] before the output reaches users or logs.
|
|
6
|
-
*
|
|
7
|
-
* Detects patterns from major providers (OpenAI, Anthropic, Google, AWS)
|
|
8
|
-
* as well as generic key/token/secret assignments.
|
|
9
|
-
*
|
|
10
|
-
* @module services/agent/crewly-agent/output-filter.service
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* const filter = new OutputFilterService();
|
|
15
|
-
* const safe = filter.redact('My key is sk-abc123xyz');
|
|
16
|
-
* // => 'My key is [REDACTED]'
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
/**
|
|
20
|
-
* API key patterns for major providers and generic secrets.
|
|
21
|
-
*
|
|
22
|
-
* Each pattern uses word boundaries or lookbehind/lookahead to minimize
|
|
23
|
-
* false positives while catching real key formats.
|
|
24
|
-
*/
|
|
25
|
-
export const API_KEY_PATTERNS = [
|
|
26
|
-
// OpenAI: sk-<org>-<rest> or sk-<48+ chars>
|
|
27
|
-
{ pattern: /\bsk-[A-Za-z0-9_-]{20,}/g, label: 'OpenAI API Key' },
|
|
28
|
-
// Anthropic: sk-ant-api03-<rest>
|
|
29
|
-
{ pattern: /\bsk-ant-[A-Za-z0-9_-]{20,}/g, label: 'Anthropic API Key' },
|
|
30
|
-
// Google AI: AIza<rest>
|
|
31
|
-
{ pattern: /\bAIza[A-Za-z0-9_-]{30,}/g, label: 'Google API Key' },
|
|
32
|
-
// AWS Access Key: AKIA<16 alphanumeric>
|
|
33
|
-
{ pattern: /\bAKIA[A-Z0-9]{16}\b/g, label: 'AWS Access Key' },
|
|
34
|
-
// AWS Secret Key (often follows access key)
|
|
35
|
-
{ pattern: /(?<=aws_secret_access_key\s*[=:]\s*)[A-Za-z0-9/+=]{30,}/g, label: 'AWS Secret Key' },
|
|
36
|
-
// GitHub tokens: ghp_, gho_, ghu_, ghs_, ghr_
|
|
37
|
-
{ pattern: /\bgh[pousr]_[A-Za-z0-9_]{30,}/g, label: 'GitHub Token' },
|
|
38
|
-
// Stripe: sk_live_ or sk_test_
|
|
39
|
-
{ pattern: /\bsk_(live|test)_[A-Za-z0-9]{20,}/g, label: 'Stripe API Key' },
|
|
40
|
-
// Supabase anon/service keys (JWT-like, start with eyJ)
|
|
41
|
-
{ pattern: /\beyJ[A-Za-z0-9_-]{50,}\.[A-Za-z0-9_-]{50,}\.[A-Za-z0-9_-]{20,}/g, label: 'JWT Token' },
|
|
42
|
-
// Generic key=value patterns (key, token, secret, password, api_key, apikey)
|
|
43
|
-
{ pattern: /(?<=(?:api[_-]?key|api[_-]?secret|api[_-]?token|secret[_-]?key|access[_-]?token|auth[_-]?token|password|secret)\s*[=:]\s*["']?)[A-Za-z0-9_/+=.-]{16,}/gi, label: 'Generic Secret' },
|
|
44
|
-
// Environment variable assignments with sensitive names
|
|
45
|
-
{ pattern: /(?<=(?:ANTHROPIC_API_KEY|OPENAI_API_KEY|GOOGLE_API_KEY|AWS_SECRET_ACCESS_KEY|STRIPE_SECRET_KEY|SUPABASE_SERVICE_ROLE_KEY|DATABASE_URL|REDIS_URL)\s*=\s*["']?)[^\s"']{8,}/g, label: 'Environment Variable Secret' },
|
|
46
|
-
];
|
|
47
|
-
/** Replacement text for redacted keys */
|
|
48
|
-
export const REDACTION_PLACEHOLDER = '[REDACTED]';
|
|
49
|
-
/**
|
|
50
|
-
* Service that scans and redacts API keys from agent output text.
|
|
51
|
-
*/
|
|
52
|
-
export class OutputFilterService {
|
|
53
|
-
patterns;
|
|
54
|
-
/**
|
|
55
|
-
* Creates a new OutputFilterService.
|
|
56
|
-
* @param customPatterns - Optional additional patterns to detect (appended to defaults)
|
|
57
|
-
*/
|
|
58
|
-
constructor(customPatterns) {
|
|
59
|
-
this.patterns = customPatterns
|
|
60
|
-
? [...API_KEY_PATTERNS, ...customPatterns]
|
|
61
|
-
: API_KEY_PATTERNS;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Scans text for API keys and returns detailed results.
|
|
65
|
-
*
|
|
66
|
-
* @param text - Text to scan for API keys
|
|
67
|
-
* @returns Scan result with detection info and redacted text
|
|
68
|
-
*/
|
|
69
|
-
scan(text) {
|
|
70
|
-
if (!text) {
|
|
71
|
-
return { detected: false, count: 0, matchedPatterns: [], redactedText: text };
|
|
72
|
-
}
|
|
73
|
-
let redacted = text;
|
|
74
|
-
let totalCount = 0;
|
|
75
|
-
const matchedLabels = new Set();
|
|
76
|
-
for (const { pattern, label } of this.patterns) {
|
|
77
|
-
// Reset regex lastIndex for global patterns
|
|
78
|
-
const regex = new RegExp(pattern.source, pattern.flags);
|
|
79
|
-
const matches = redacted.match(regex);
|
|
80
|
-
if (matches) {
|
|
81
|
-
totalCount += matches.length;
|
|
82
|
-
matchedLabels.add(label);
|
|
83
|
-
redacted = redacted.replace(regex, REDACTION_PLACEHOLDER);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
detected: totalCount > 0,
|
|
88
|
-
count: totalCount,
|
|
89
|
-
matchedPatterns: Array.from(matchedLabels),
|
|
90
|
-
redactedText: redacted,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Redacts all API keys in the given text.
|
|
95
|
-
* Convenience method that returns only the redacted string.
|
|
96
|
-
*
|
|
97
|
-
* @param text - Text to redact
|
|
98
|
-
* @returns Text with all detected API keys replaced with [REDACTED]
|
|
99
|
-
*/
|
|
100
|
-
redact(text) {
|
|
101
|
-
return this.scan(text).redactedText;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Checks if text contains any API keys without modifying it.
|
|
105
|
-
*
|
|
106
|
-
* @param text - Text to check
|
|
107
|
-
* @returns True if any API key patterns are detected
|
|
108
|
-
*/
|
|
109
|
-
containsKeys(text) {
|
|
110
|
-
if (!text)
|
|
111
|
-
return false;
|
|
112
|
-
for (const { pattern } of this.patterns) {
|
|
113
|
-
const regex = new RegExp(pattern.source, pattern.flags);
|
|
114
|
-
if (regex.test(text))
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Redacts API keys from a structured object (recursively scans string values).
|
|
121
|
-
* Useful for sanitizing tool call arguments and results before logging.
|
|
122
|
-
*
|
|
123
|
-
* @param obj - Object to scan and redact
|
|
124
|
-
* @returns Deep copy with all string values redacted
|
|
125
|
-
*/
|
|
126
|
-
redactObject(obj) {
|
|
127
|
-
if (typeof obj === 'string') {
|
|
128
|
-
return this.redact(obj);
|
|
129
|
-
}
|
|
130
|
-
if (Array.isArray(obj)) {
|
|
131
|
-
return obj.map((item) => this.redactObject(item));
|
|
132
|
-
}
|
|
133
|
-
if (typeof obj === 'object' && obj !== null) {
|
|
134
|
-
const result = {};
|
|
135
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
136
|
-
result[key] = this.redactObject(value);
|
|
137
|
-
}
|
|
138
|
-
return result;
|
|
139
|
-
}
|
|
140
|
-
return obj;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
//# sourceMappingURL=output-filter.service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"output-filter.service.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/agent/crewly-agent/output-filter.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prompt Guard Service — Prompt Injection Protection
|
|
3
|
-
*
|
|
4
|
-
* Detects and blocks prompt injection attempts that try to extract API keys,
|
|
5
|
-
* secrets, or sensitive environment variables through agent commands.
|
|
6
|
-
*
|
|
7
|
-
* Integrates with the tool registry to block dangerous bash commands and
|
|
8
|
-
* logs blocked attempts to the audit trail.
|
|
9
|
-
*
|
|
10
|
-
* @module services/agent/crewly-agent/prompt-guard.service
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* const guard = new PromptGuardService();
|
|
15
|
-
* const result = guard.checkCommand('echo $ANTHROPIC_API_KEY');
|
|
16
|
-
* // { blocked: true, reason: 'Key extraction attempt: echo env var', pattern: '...' }
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
import type { AuditEntry } from './types.js';
|
|
20
|
-
/**
|
|
21
|
-
* A pattern that detects key extraction attempts.
|
|
22
|
-
*/
|
|
23
|
-
export interface GuardPattern {
|
|
24
|
-
/** Regex to match the dangerous command or prompt */
|
|
25
|
-
pattern: RegExp;
|
|
26
|
-
/** Human-readable reason for blocking */
|
|
27
|
-
reason: string;
|
|
28
|
-
/** Category for audit logging */
|
|
29
|
-
category: 'env_extraction' | 'key_dump' | 'prompt_injection' | 'file_exfiltration';
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Result of a prompt guard check.
|
|
33
|
-
*/
|
|
34
|
-
export interface GuardCheckResult {
|
|
35
|
-
/** Whether the command/prompt was blocked */
|
|
36
|
-
blocked: boolean;
|
|
37
|
-
/** Reason for blocking (empty if not blocked) */
|
|
38
|
-
reason: string;
|
|
39
|
-
/** Category of the threat (undefined if not blocked) */
|
|
40
|
-
category?: GuardPattern['category'];
|
|
41
|
-
/** The matched pattern source (for audit logging) */
|
|
42
|
-
matchedPattern?: string;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Patterns that detect attempts to extract API keys or secrets via bash commands.
|
|
46
|
-
*/
|
|
47
|
-
export declare const KEY_EXTRACTION_PATTERNS: readonly GuardPattern[];
|
|
48
|
-
/**
|
|
49
|
-
* Prompt-level injection patterns (detected in natural language prompts, not just commands).
|
|
50
|
-
*/
|
|
51
|
-
export declare const PROMPT_INJECTION_PATTERNS: readonly GuardPattern[];
|
|
52
|
-
/**
|
|
53
|
-
* Additional blocked command patterns for tool-registry.ts integration.
|
|
54
|
-
* These extend the existing BLOCKED_COMMAND_PATTERNS with key extraction blocks.
|
|
55
|
-
*/
|
|
56
|
-
export declare const KEY_EXTRACTION_BLOCKED_COMMANDS: RegExp[];
|
|
57
|
-
/**
|
|
58
|
-
* Service that detects and blocks prompt injection and key extraction attempts.
|
|
59
|
-
*/
|
|
60
|
-
export declare class PromptGuardService {
|
|
61
|
-
private readonly commandPatterns;
|
|
62
|
-
private readonly promptPatterns;
|
|
63
|
-
/**
|
|
64
|
-
* Creates a new PromptGuardService.
|
|
65
|
-
*
|
|
66
|
-
* @param additionalCommandPatterns - Extra command-level patterns
|
|
67
|
-
* @param additionalPromptPatterns - Extra prompt-level patterns
|
|
68
|
-
*/
|
|
69
|
-
constructor(additionalCommandPatterns?: GuardPattern[], additionalPromptPatterns?: GuardPattern[]);
|
|
70
|
-
/**
|
|
71
|
-
* Checks a bash command for key extraction attempts.
|
|
72
|
-
*
|
|
73
|
-
* @param command - Raw bash command string
|
|
74
|
-
* @returns Guard check result
|
|
75
|
-
*/
|
|
76
|
-
checkCommand(command: string): GuardCheckResult;
|
|
77
|
-
/**
|
|
78
|
-
* Checks a user/agent prompt for injection attempts targeting secrets.
|
|
79
|
-
*
|
|
80
|
-
* @param prompt - The text prompt or message
|
|
81
|
-
* @returns Guard check result
|
|
82
|
-
*/
|
|
83
|
-
checkPrompt(prompt: string): GuardCheckResult;
|
|
84
|
-
/**
|
|
85
|
-
* Checks both command and prompt patterns.
|
|
86
|
-
* Use this for comprehensive scanning of any agent input.
|
|
87
|
-
*
|
|
88
|
-
* @param text - Text to check (command or prompt)
|
|
89
|
-
* @returns Guard check result
|
|
90
|
-
*/
|
|
91
|
-
check(text: string): GuardCheckResult;
|
|
92
|
-
/**
|
|
93
|
-
* Creates an audit entry for a blocked attempt.
|
|
94
|
-
*
|
|
95
|
-
* @param sessionName - Agent session that triggered the block
|
|
96
|
-
* @param toolName - Tool that was used (e.g. 'bash_exec')
|
|
97
|
-
* @param command - The blocked command
|
|
98
|
-
* @param guardResult - The guard check result
|
|
99
|
-
* @returns AuditEntry suitable for the audit log
|
|
100
|
-
*/
|
|
101
|
-
createAuditEntry(sessionName: string, toolName: string, command: string, guardResult: GuardCheckResult): AuditEntry;
|
|
102
|
-
}
|
|
103
|
-
//# sourceMappingURL=prompt-guard.service.d.ts.map
|