keystone-cli 2.0.0 → 2.0.1
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/README.md +13 -0
- package/package.json +1 -1
- package/src/parser/config-schema.ts +6 -0
- package/src/runner/llm-adapter.ts +11 -1
- package/src/runner/workflow-runner.ts +18 -14
package/README.md
CHANGED
|
@@ -237,6 +237,10 @@ storage:
|
|
|
237
237
|
|
|
238
238
|
expression:
|
|
239
239
|
strict: false
|
|
240
|
+
|
|
241
|
+
logging:
|
|
242
|
+
suppress_security_warning: false
|
|
243
|
+
suppress_ai_sdk_warnings: false
|
|
240
244
|
```
|
|
241
245
|
|
|
242
246
|
### Storage Configuration
|
|
@@ -246,6 +250,13 @@ The `storage` section controls data retention and security for workflow runs:
|
|
|
246
250
|
- **`retention_days`**: Sets the default window used by `keystone maintenance` / `keystone prune` commands to clean up old run data.
|
|
247
251
|
- **`redact_secrets_at_rest`**: Controls whether secret inputs and known secrets are redacted before storing run data (default `true`).
|
|
248
252
|
|
|
253
|
+
### Logging Configuration
|
|
254
|
+
|
|
255
|
+
The `logging` section allows you to suppress warnings:
|
|
256
|
+
|
|
257
|
+
- **`suppress_security_warning`**: Silences the "Security Warning" about running workflows from untrusted sources (default `false`).
|
|
258
|
+
- **`suppress_ai_sdk_warnings`**: Silences internal warnings from the Vercel AI SDK, such as compatibility mode messages (default `false`).
|
|
259
|
+
|
|
249
260
|
### Bring Your Own Provider (BYOP)
|
|
250
261
|
|
|
251
262
|
Keystone uses the **Vercel AI SDK**, allowing you to use any compatible provider. You must install the provider package (e.g., `@ai-sdk/openai`, `ai-sdk-provider-gemini-cli`) so Keystone can resolve it.
|
|
@@ -1246,6 +1257,8 @@ Request steps enforce SSRF protections and require HTTPS by default. Cross-origi
|
|
|
1246
1257
|
graph TD
|
|
1247
1258
|
CLI[CLI Entry Point] --> WR[WorkflowRunner]
|
|
1248
1259
|
CLI --> MCPServer[MCP Server]
|
|
1260
|
+
Config[ConfigLoader] --> WR
|
|
1261
|
+
Config --> Adapter
|
|
1249
1262
|
|
|
1250
1263
|
subgraph "Core Orchestration"
|
|
1251
1264
|
WR --> Scheduler[WorkflowScheduler]
|
package/package.json
CHANGED
|
@@ -116,6 +116,12 @@ export const ConfigSchema = z.object({
|
|
|
116
116
|
.optional(),
|
|
117
117
|
})
|
|
118
118
|
.optional(),
|
|
119
|
+
logging: z
|
|
120
|
+
.object({
|
|
121
|
+
suppress_security_warning: z.boolean().default(false),
|
|
122
|
+
suppress_ai_sdk_warnings: z.boolean().default(false),
|
|
123
|
+
})
|
|
124
|
+
.default({}),
|
|
119
125
|
});
|
|
120
126
|
|
|
121
127
|
export type Config = z.infer<typeof ConfigSchema>;
|
|
@@ -55,7 +55,7 @@ class LocalEmbeddingModel {
|
|
|
55
55
|
return Array.from(output.data) as number[];
|
|
56
56
|
})
|
|
57
57
|
);
|
|
58
|
-
return { embeddings };
|
|
58
|
+
return { embeddings, warnings: [] };
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
@@ -298,6 +298,11 @@ async function prepareProvider(
|
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
export async function getModel(model: string): Promise<LanguageModel> {
|
|
301
|
+
const configValues = ConfigLoader.load();
|
|
302
|
+
if (configValues.logging?.suppress_ai_sdk_warnings) {
|
|
303
|
+
process.env.AI_SDK_LOG_WARNINGS = 'false';
|
|
304
|
+
}
|
|
305
|
+
|
|
301
306
|
const { provider, resolvedModel } = await prepareProvider(model);
|
|
302
307
|
|
|
303
308
|
// AI SDK convention: provider(modelId)
|
|
@@ -321,6 +326,11 @@ export async function getModel(model: string): Promise<LanguageModel> {
|
|
|
321
326
|
}
|
|
322
327
|
|
|
323
328
|
export async function getEmbeddingModel(model: string): Promise<EmbeddingModel> {
|
|
329
|
+
const configValues = ConfigLoader.load();
|
|
330
|
+
if (configValues.logging?.suppress_ai_sdk_warnings) {
|
|
331
|
+
process.env.AI_SDK_LOG_WARNINGS = 'false';
|
|
332
|
+
}
|
|
333
|
+
|
|
324
334
|
// 1. Check for local fallback
|
|
325
335
|
if (model === 'local' || model === 'keystone-local') {
|
|
326
336
|
return new LocalEmbeddingModel();
|
|
@@ -46,7 +46,7 @@ class RedactingLogger implements Logger {
|
|
|
46
46
|
constructor(
|
|
47
47
|
private inner: Logger,
|
|
48
48
|
private redactor: Redactor
|
|
49
|
-
) {}
|
|
49
|
+
) { }
|
|
50
50
|
|
|
51
51
|
log(msg: string): void {
|
|
52
52
|
this.inner.log(this.redactor.redact(msg));
|
|
@@ -193,7 +193,7 @@ export class WorkflowRunner {
|
|
|
193
193
|
|
|
194
194
|
if (parentSignal.aborted) {
|
|
195
195
|
controller.abort();
|
|
196
|
-
return { controller, cleanup: () => {} };
|
|
196
|
+
return { controller, cleanup: () => { } };
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
parentSignal.addEventListener('abort', onAbort, { once: true });
|
|
@@ -816,11 +816,11 @@ export class WorkflowRunner {
|
|
|
816
816
|
const idempotencyContextForRetry =
|
|
817
817
|
idempotencyClaimed && scopedIdempotencyKey
|
|
818
818
|
? {
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
819
|
+
rawKey: idempotencyKey || scopedIdempotencyKey,
|
|
820
|
+
scopedKey: scopedIdempotencyKey,
|
|
821
|
+
ttlSeconds: idempotencyTtlSeconds,
|
|
822
|
+
claimed: true,
|
|
823
|
+
}
|
|
824
824
|
: undefined;
|
|
825
825
|
|
|
826
826
|
let stepToExecute = step;
|
|
@@ -932,9 +932,9 @@ export class WorkflowRunner {
|
|
|
932
932
|
try {
|
|
933
933
|
const outputForValidation =
|
|
934
934
|
stepToExecute.type === 'engine' &&
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
935
|
+
result.output &&
|
|
936
|
+
typeof result.output === 'object' &&
|
|
937
|
+
'summary' in result.output
|
|
938
938
|
? (result.output as { summary?: unknown }).summary
|
|
939
939
|
: result.output;
|
|
940
940
|
this.validator.validateSchema(
|
|
@@ -2076,12 +2076,16 @@ Revise the output to address the feedback. Return only the corrected output.`;
|
|
|
2076
2076
|
|
|
2077
2077
|
this.logger.log(`\n🏛️ ${isResume ? 'Resuming' : 'Running'} workflow: ${this.workflow.name}`);
|
|
2078
2078
|
this.logger.log(`Run ID: ${this.runId}`);
|
|
2079
|
-
|
|
2080
|
-
|
|
2079
|
+
|
|
2080
|
+
const config = ConfigLoader.load();
|
|
2081
|
+
if (!config.logging?.suppress_security_warning) {
|
|
2082
|
+
this.logger.log(
|
|
2083
|
+
'\n⚠️ Security Warning: Only run workflows from trusted sources.\n' +
|
|
2081
2084
|
' Workflows can execute arbitrary shell commands and access your environment.\n'
|
|
2082
|
-
|
|
2085
|
+
);
|
|
2086
|
+
}
|
|
2083
2087
|
|
|
2084
|
-
this.secretManager.redactAtRest =
|
|
2088
|
+
this.secretManager.redactAtRest = config.storage?.redact_secrets_at_rest ?? true;
|
|
2085
2089
|
|
|
2086
2090
|
// Apply defaults and validate inputs
|
|
2087
2091
|
const validated = this.validator.applyDefaultsAndValidate();
|