@capybara-hq/kernel 0.1.0-rc.2 → 0.1.0-rc.4
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/admin/admin.controller.d.ts +9 -4
- package/dist/admin/admin.controller.js +13 -4
- package/dist/admin/extensions.controller.d.ts +8 -1
- package/dist/admin/extensions.controller.js +22 -2
- package/dist/agents/agent-lookup.d.ts +3 -0
- package/dist/agents/agent-lookup.js +20 -2
- package/dist/agents/agent-profile.service.d.ts +29 -0
- package/dist/agents/agent-profile.service.js +117 -0
- package/dist/agents/agents.controller.d.ts +93 -3
- package/dist/agents/agents.controller.js +114 -4
- package/dist/agents/agents.module.js +6 -2
- package/dist/agents/agents.service.d.ts +13 -5
- package/dist/agents/agents.service.js +49 -13
- package/dist/agents/definition.d.ts +35 -8
- package/dist/agents/definition.js +203 -17
- package/dist/agents/instruction-files.d.ts +60 -0
- package/dist/agents/instruction-files.js +111 -0
- package/dist/agents/models.controller.d.ts +9 -3
- package/dist/agents/models.controller.js +19 -4
- package/dist/agents/profile.d.ts +96 -0
- package/dist/agents/profile.js +51 -0
- package/dist/agents/readiness.controller.d.ts +26 -0
- package/dist/agents/readiness.controller.js +56 -0
- package/dist/agents/templates.js +20 -5
- package/dist/background/background.controller.d.ts +38 -0
- package/dist/background/background.controller.js +87 -0
- package/dist/background/background.module.d.ts +10 -0
- package/dist/background/background.module.js +32 -0
- package/dist/background/finish.d.ts +43 -0
- package/dist/background/finish.js +94 -0
- package/dist/background/launch-lock.d.ts +14 -0
- package/dist/background/launch-lock.js +39 -0
- package/dist/background/launch.d.ts +36 -0
- package/dist/background/launch.js +70 -0
- package/dist/background/poll.job.d.ts +53 -0
- package/dist/background/poll.job.js +182 -0
- package/dist/background/render.d.ts +23 -0
- package/dist/background/render.js +48 -0
- package/dist/background/session.d.ts +37 -0
- package/dist/background/session.js +66 -0
- package/dist/background/status.d.ts +35 -0
- package/dist/background/status.js +57 -0
- package/dist/background/stop.d.ts +62 -0
- package/dist/background/stop.js +225 -0
- package/dist/background/store.d.ts +150 -0
- package/dist/background/store.js +351 -0
- package/dist/background/store.module.d.ts +6 -0
- package/dist/background/store.module.js +22 -0
- package/dist/background/tasks.service.d.ts +67 -0
- package/dist/background/tasks.service.js +186 -0
- package/dist/background/wake-rules.d.ts +57 -0
- package/dist/background/wake-rules.js +83 -0
- package/dist/background/wake.d.ts +28 -0
- package/dist/background/wake.js +57 -0
- package/dist/catalog/catalog-content.js +4 -1
- package/dist/catalog/claude/agents.js +15 -10
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/plugin-import.js +1 -1
- package/dist/catalog/plugin-upgrade.js +1 -1
- package/dist/channels/cards.d.ts +8 -2
- package/dist/channels/cards.js +17 -9
- package/dist/channels/connections.service.d.ts +16 -1
- package/dist/channels/connections.service.js +38 -4
- package/dist/channels/threads.d.ts +5 -0
- package/dist/channels/threads.js +8 -0
- package/dist/config/schema.d.ts +18 -0
- package/dist/config/schema.js +104 -2
- package/dist/conversations/access.js +2 -0
- package/dist/conversations/artifacts.d.ts +1 -1
- package/dist/conversations/artifacts.js +1 -1
- package/dist/conversations/attachments.service.d.ts +30 -0
- package/dist/conversations/attachments.service.js +130 -5
- package/dist/conversations/conversations.controller.d.ts +36 -5
- package/dist/conversations/conversations.controller.js +62 -12
- package/dist/conversations/conversations.module.js +3 -0
- package/dist/conversations/conversations.service.d.ts +44 -2
- package/dist/conversations/conversations.service.js +140 -12
- package/dist/conversations/event-log.d.ts +12 -1
- package/dist/conversations/event-log.js +29 -1
- package/dist/conversations/events.d.ts +81 -3
- package/dist/conversations/events.js +83 -16
- package/dist/conversations/queue.d.ts +3 -1
- package/dist/conversations/queue.js +13 -2
- package/dist/conversations/queue.service.js +3 -1
- package/dist/conversations/titles.d.ts +7 -0
- package/dist/conversations/titles.js +15 -0
- package/dist/db/kernel-schema.d.ts +60 -4
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.js +3 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.js +8 -0
- package/dist/evals/recorded-tools.d.ts +27 -1
- package/dist/evals/recorded-tools.js +85 -10
- package/dist/evals/run-replay.d.ts +10 -2
- package/dist/evals/run-replay.js +49 -12
- package/dist/evals/step-replay.js +12 -6
- package/dist/evals/trajectory.d.ts +2 -2
- package/dist/evals/trajectory.js +1 -1
- package/dist/extensions/admin-ops.js +2 -0
- package/dist/extensions/admin-view.d.ts +3 -1
- package/dist/extensions/admin-view.js +10 -2
- package/dist/extensions/blobs.js +1 -0
- package/dist/extensions/config-issues.d.ts +13 -1
- package/dist/extensions/config-issues.js +22 -5
- package/dist/extensions/config-json-schema.d.ts +43 -7
- package/dist/extensions/config-json-schema.js +124 -58
- package/dist/extensions/deployment-config-store.d.ts +6 -0
- package/dist/extensions/deployment-config.d.ts +50 -3
- package/dist/extensions/deployment-config.js +125 -28
- package/dist/extensions/display-name.d.ts +22 -0
- package/dist/extensions/display-name.js +77 -0
- package/dist/extensions/extensions.module.js +6 -0
- package/dist/extensions/host.d.ts +26 -1
- package/dist/extensions/host.js +82 -9
- package/dist/extensions/org-config.controller.d.ts +11 -3
- package/dist/extensions/org-config.controller.js +14 -6
- package/dist/extensions/org-config.d.ts +6 -0
- package/dist/extensions/org-config.js +12 -13
- package/dist/extensions/package.d.ts +14 -1
- package/dist/extensions/package.js +51 -2
- package/dist/extensions/permission-view.d.ts +3 -0
- package/dist/extensions/point-defaults.controller.d.ts +34 -0
- package/dist/extensions/point-defaults.controller.js +71 -0
- package/dist/extensions/point-defaults.d.ts +64 -0
- package/dist/extensions/point-defaults.js +206 -0
- package/dist/extensions/registry.d.ts +1 -1
- package/dist/extensions/registry.js +2 -0
- package/dist/http/api.module.js +8 -0
- package/dist/http/nest-logger.d.ts +6 -5
- package/dist/http/nest-logger.js +24 -10
- package/dist/identity/auth.controller.js +9 -5
- package/dist/identity/cookies.d.ts +20 -5
- package/dist/identity/cookies.js +44 -6
- package/dist/identity/me.controller.d.ts +5 -1
- package/dist/identity/me.controller.js +12 -3
- package/dist/identity/sessions.d.ts +12 -0
- package/dist/identity/sessions.js +45 -0
- package/dist/identity/settings.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/infra/config/kernel-config.service.js +6 -0
- package/dist/infra/database/database.module.js +1 -0
- package/dist/infra/events/kernel-events.d.ts +8 -0
- package/dist/infra/lifecycle/process-guards.js +4 -0
- package/dist/infra/logging/logging.module.d.ts +4 -2
- package/dist/infra/logging/logging.module.js +24 -6
- package/dist/infra/queue/redis-connection.d.ts +6 -0
- package/dist/infra/queue/redis-connection.js +7 -0
- package/dist/infra/redis/redis.module.js +6 -2
- package/dist/infra/tokens.d.ts +6 -1
- package/dist/infra/tokens.js +6 -1
- package/dist/lifecycle/kernel-lifecycle.js +5 -0
- package/dist/log.d.ts +13 -1
- package/dist/log.js +93 -17
- package/dist/models/purposes.d.ts +23 -0
- package/dist/models/purposes.js +31 -10
- package/dist/orgs/offboarding.d.ts +3 -1
- package/dist/orgs/offboarding.js +26 -16
- package/dist/orgs/settings.service.d.ts +7 -2
- package/dist/orgs/settings.service.js +15 -4
- package/dist/roles/worker.module.js +6 -0
- package/dist/runtime/context/build.d.ts +15 -13
- package/dist/runtime/context/build.js +45 -27
- package/dist/runtime/context/claude-tools.d.ts +3 -1
- package/dist/runtime/context/claude-tools.js +12 -12
- package/dist/runtime/context/compaction.js +4 -0
- package/dist/runtime/context/legacy-text.d.ts +22 -0
- package/dist/runtime/context/legacy-text.js +37 -0
- package/dist/runtime/context/skills.d.ts +29 -11
- package/dist/runtime/context/skills.js +37 -30
- package/dist/runtime/langgraph-loop.js +3 -2
- package/dist/runtime/loop.d.ts +5 -4
- package/dist/runtime/maintenance.d.ts +4 -2
- package/dist/runtime/maintenance.js +17 -5
- package/dist/runtime/model-call.d.ts +17 -1
- package/dist/runtime/model-call.js +4 -3
- package/dist/runtime/providers.d.ts +6 -0
- package/dist/runtime/providers.js +8 -0
- package/dist/runtime/run-finish.d.ts +1 -1
- package/dist/runtime/run-queue.d.ts +28 -5
- package/dist/runtime/run-queue.js +131 -35
- package/dist/runtime/run-worker.d.ts +2 -2
- package/dist/runtime/run-worker.js +20 -7
- package/dist/runtime/runtime.module.js +8 -3
- package/dist/runtime/step-log.d.ts +6 -0
- package/dist/runtime/step-log.js +16 -2
- package/dist/runtime/subagents/definition.d.ts +1 -6
- package/dist/runtime/subagents/definition.js +14 -13
- package/dist/runtime/subagents/dispatch.d.ts +2 -2
- package/dist/runtime/subagents/dispatch.js +2 -2
- package/dist/runtime/subagents/org-agents.js +2 -1
- package/dist/runtime/subagents/roster.d.ts +1 -1
- package/dist/runtime/subagents/roster.js +1 -1
- package/dist/runtime/subagents/skill-fork.d.ts +2 -2
- package/dist/runtime/subagents/skill-fork.js +2 -2
- package/dist/runtime/subagents/subagents.service.d.ts +3 -3
- package/dist/runtime/subagents/subagents.service.js +3 -3
- package/dist/runtime/usage-report.d.ts +2 -1
- package/dist/runtime/usage-report.js +2 -1
- package/dist/runtime/waits.d.ts +13 -7
- package/dist/runtime/waits.js +42 -16
- package/dist/sandbox/sandbox.module.js +6 -1
- package/dist/sandbox/sandbox.service.d.ts +61 -3
- package/dist/sandbox/sandbox.service.js +141 -7
- package/dist/skills/catalog.d.ts +4 -4
- package/dist/skills/catalog.js +4 -4
- package/dist/skills/changes.service.d.ts +2 -2
- package/dist/skills/changes.service.js +5 -4
- package/dist/skills/invocation-keys.d.ts +1 -1
- package/dist/skills/invocation-keys.js +1 -1
- package/dist/skills/invoke.d.ts +1 -1
- package/dist/skills/invoke.js +5 -4
- package/dist/tools/approvals.service.d.ts +6 -0
- package/dist/tools/approvals.service.js +21 -1
- package/dist/tools/builtin-names.d.ts +91 -0
- package/dist/tools/builtin-names.js +143 -0
- package/dist/tools/builtins/agent.d.ts +7 -7
- package/dist/tools/builtins/agent.js +7 -11
- package/dist/tools/builtins/ask-user.d.ts +1 -1
- package/dist/tools/builtins/ask-user.js +2 -2
- package/dist/tools/builtins/builtin-tools.d.ts +17 -3
- package/dist/tools/builtins/builtin-tools.js +36 -4
- package/dist/tools/builtins/read-tool-output.d.ts +1 -1
- package/dist/tools/builtins/read-tool-output.js +2 -2
- package/dist/tools/builtins/sandbox/bash.d.ts +4 -4
- package/dist/tools/builtins/sandbox/bash.js +259 -29
- package/dist/tools/builtins/sandbox/common.d.ts +30 -7
- package/dist/tools/builtins/sandbox/common.js +9 -5
- package/dist/tools/builtins/sandbox/deliver.d.ts +1 -1
- package/dist/tools/builtins/sandbox/deliver.js +12 -12
- package/dist/tools/builtins/sandbox/edit.d.ts +1 -1
- package/dist/tools/builtins/sandbox/edit.js +41 -30
- package/dist/tools/builtins/sandbox/file-state.d.ts +34 -0
- package/dist/tools/builtins/sandbox/file-state.js +34 -0
- package/dist/tools/builtins/sandbox/glob-match.d.ts +1 -1
- package/dist/tools/builtins/sandbox/glob-match.js +1 -1
- package/dist/tools/builtins/sandbox/glob.d.ts +1 -1
- package/dist/tools/builtins/sandbox/glob.js +4 -4
- package/dist/tools/builtins/sandbox/grep.d.ts +7 -4
- package/dist/tools/builtins/sandbox/grep.js +147 -30
- package/dist/tools/builtins/sandbox/index.d.ts +3 -1
- package/dist/tools/builtins/sandbox/index.js +7 -1
- package/dist/tools/builtins/sandbox/read.d.ts +2 -2
- package/dist/tools/builtins/sandbox/read.js +21 -14
- package/dist/tools/builtins/sandbox/task-output.d.ts +63 -0
- package/dist/tools/builtins/sandbox/task-output.js +304 -0
- package/dist/tools/builtins/sandbox/task-stop.d.ts +10 -0
- package/dist/tools/builtins/sandbox/task-stop.js +112 -0
- package/dist/tools/builtins/sandbox/write.d.ts +1 -1
- package/dist/tools/builtins/sandbox/write.js +37 -33
- package/dist/tools/builtins/skill-load.d.ts +3 -3
- package/dist/tools/builtins/skill-load.js +32 -16
- package/dist/tools/builtins/skill-write.d.ts +4 -4
- package/dist/tools/builtins/skill-write.js +10 -10
- package/dist/tools/builtins/tool-search.d.ts +13 -9
- package/dist/tools/builtins/tool-search.js +25 -14
- package/dist/tools/builtins/web/errors.d.ts +8 -0
- package/dist/tools/builtins/web/errors.js +53 -0
- package/dist/tools/builtins/web/extract.d.ts +62 -0
- package/dist/tools/builtins/web/extract.js +267 -0
- package/dist/tools/builtins/web/fetch.d.ts +55 -0
- package/dist/tools/builtins/web/fetch.js +174 -0
- package/dist/tools/builtins/web/index.d.ts +13 -0
- package/dist/tools/builtins/web/index.js +12 -0
- package/dist/tools/builtins/web/page-cache.d.ts +25 -0
- package/dist/tools/builtins/web/page-cache.js +77 -0
- package/dist/tools/builtins/web/search.d.ts +25 -0
- package/dist/tools/builtins/web/search.js +209 -0
- package/dist/tools/builtins/web/url.d.ts +17 -0
- package/dist/tools/builtins/web/url.js +43 -0
- package/dist/tools/connectors.service.js +4 -4
- package/dist/tools/display-names.d.ts +9 -0
- package/dist/tools/display-names.js +24 -0
- package/dist/tools/drift.js +5 -5
- package/dist/tools/elicitation.js +1 -1
- package/dist/tools/info.d.ts +20 -4
- package/dist/tools/info.js +55 -32
- package/dist/tools/legacy-data.d.ts +34 -0
- package/dist/tools/legacy-data.js +76 -0
- package/dist/tools/legacy-keys.d.ts +51 -0
- package/dist/tools/legacy-keys.js +115 -0
- package/dist/tools/naming.d.ts +1 -5
- package/dist/tools/naming.js +1 -7
- package/dist/tools/oauth/flow-paths.d.ts +1 -1
- package/dist/tools/oauth/flow-paths.js +1 -1
- package/dist/tools/outputs.js +1 -1
- package/dist/tools/pipeline.d.ts +13 -7
- package/dist/tools/pipeline.js +112 -39
- package/dist/tools/policy.d.ts +1 -14
- package/dist/tools/policy.js +13 -19
- package/dist/tools/questions.controller.d.ts +1 -1
- package/dist/tools/questions.controller.js +1 -1
- package/dist/tools/questions.service.d.ts +1 -1
- package/dist/tools/registry.d.ts +38 -24
- package/dist/tools/registry.js +54 -47
- package/dist/tools/resources.d.ts +1 -1
- package/dist/tools/resources.js +1 -1
- package/dist/tools/tools.module.js +13 -1
- package/dist/tools/validate.js +1 -1
- package/package.json +3 -3
- package/src/migrations/0063_tool_keys_claude_code.sql +220 -0
- package/src/migrations/0064_account_last_org.sql +7 -0
- package/src/migrations/0065_conversation_archive.sql +8 -0
- package/src/migrations/0066_extension_display_name.sql +4 -0
- package/src/migrations/0067_agent_profiles.sql +20 -0
- package/src/migrations/0068_agent_avatar_uploads.sql +7 -0
- package/src/migrations/0069_attachments_agent_idx.sql +3 -0
- package/src/migrations/0070_background_tasks.sql +37 -0
- package/src/migrations/0071_background_tasks_reserve.sql +6 -0
- package/src/migrations/0072_background_tasks_stopping.sql +5 -0
- package/src/migrations/0073_org_extension_point_defaults.sql +11 -0
- package/dist/tools/builtins/sandbox/names.d.ts +0 -7
- package/dist/tools/builtins/sandbox/names.js +0 -20
|
@@ -68,7 +68,7 @@ export const DEPLOYMENT_SETTINGS = z.object({
|
|
|
68
68
|
/** 组织能否自建连接器(不经企业目录)。 */
|
|
69
69
|
customConnectors: CustomPolicy.default("allow"),
|
|
70
70
|
/**
|
|
71
|
-
* 组织能否自建技能(不经企业目录):deny 时组织管理员不能上传技能包。agent 自写技能(`
|
|
71
|
+
* 组织能否自建技能(不经企业目录):deny 时组织管理员不能上传技能包。agent 自写技能(`SkillWrite`,私有 agent 的
|
|
72
72
|
* agent 级技能与共享 agent 经负责人审批的变更)不受此开关约束——那是 agent 定义的一部分,由 R3 / R4 把关。
|
|
73
73
|
*/
|
|
74
74
|
customSkills: CustomPolicy.default("allow"),
|
package/dist/index.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export { type ApprovalDecision, ExtensionApprovals, type PendingExtension, type
|
|
|
31
31
|
export { blobKey, ExtensionBlobIntegrityError, type ExtensionBlobSource, ExtensionBlobs, } from "./extensions/blobs.js";
|
|
32
32
|
export { BOOTSTRAP_MANIFEST_FILE, type BootstrapEntryResult, BootstrapFailedError, type BootstrapFailure, type BootstrapResolveOptions, type BootstrapResult, BootstrapService, bootstrapManifestSha256, readBootstrapManifest, resolveBootstrapPackages, } from "./extensions/bootstrap.js";
|
|
33
33
|
export { type ExtensionCli, openExtensionCli } from "./extensions/cli.js";
|
|
34
|
-
export { DEPLOYMENT_SECRETS_ORG, type DeploymentConfigField, type DeploymentConfigView, ExtensionDeploymentConfigService, mergeDeploymentConfig, PLUGIN_DEPLOYMENT_CONFIG_TOPIC, readStoredDeploymentConfig, } from "./extensions/deployment-config.js";
|
|
34
|
+
export { DEPLOYMENT_SECRETS_ORG, type DeploymentConfigField, type DeploymentConfigView, ExtensionDeploymentConfigService, mergeDeploymentConfig, PLUGIN_DEPLOYMENT_CONFIG_TOPIC, readStoredDeploymentConfig, type SecretEntry, } from "./extensions/deployment-config.js";
|
|
35
35
|
export { assertSecretsReachable, ExtensionHost, type ExtensionLoadPlan, type InspectedExtension, type InstalledExtensionLoader, type InstallFailureReason, } from "./extensions/host.js";
|
|
36
36
|
export { ExtensionUnloadedError, type InflightEntry, InflightTracker, PLUGIN_UNLOADED_TOOL_ERROR, type TrackOptions, trackCalls, } from "./extensions/inflight.js";
|
|
37
37
|
export { type DesiredExtension, type ExtensionInstallRow, ExtensionInstalls, type IngestSource, type PackageReview, } from "./extensions/installs.js";
|
|
@@ -34,6 +34,12 @@ const HOT_APPLIERS = {
|
|
|
34
34
|
"subagents.maxConcurrentPerRun": () => { },
|
|
35
35
|
"subagents.maxDispatchesPerRun": () => { },
|
|
36
36
|
"subagents.maxTokensPerRun": () => { },
|
|
37
|
+
// The web tools read these limits through the config service on every call.
|
|
38
|
+
"web.search.maxResults": () => { },
|
|
39
|
+
"web.fetch.maxPageChars": () => { },
|
|
40
|
+
"web.fetch.maxAnswerTokens": () => { },
|
|
41
|
+
"web.fetch.cacheSeconds": () => { },
|
|
42
|
+
"web.fetch.timeoutMs": () => { },
|
|
37
43
|
};
|
|
38
44
|
const HOT_PATHS = configFields(KernelConfigSchema)
|
|
39
45
|
.filter((f) => f.meta?.hot)
|
|
@@ -66,6 +66,7 @@ let DatabaseModule = class DatabaseModule {
|
|
|
66
66
|
const { db } = config.get();
|
|
67
67
|
return createDb(db.url, db.poolMax, (err) => log.error("pg idle client error", { err }), {
|
|
68
68
|
connectTimeoutMs: db.connectTimeoutMs,
|
|
69
|
+
idleTimeoutMs: db.idleTimeoutMs,
|
|
69
70
|
onClientError: (err) => log.warn("pg client error", { err }),
|
|
70
71
|
});
|
|
71
72
|
},
|
|
@@ -78,6 +78,14 @@ export interface KernelEventMap {
|
|
|
78
78
|
"run.orphaned": {
|
|
79
79
|
runId: string;
|
|
80
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* A background task of the conversation finished (after the commit of its
|
|
83
|
+
* `background_task_finished` event). `BackgroundWake` asks the run queue for a wake run; a lost
|
|
84
|
+
* event is re-derived by the next `ensureRun` (a message, the end of a run, a page opening).
|
|
85
|
+
*/
|
|
86
|
+
"background_task.finished": {
|
|
87
|
+
conversationId: string;
|
|
88
|
+
};
|
|
81
89
|
}
|
|
82
90
|
type Handler<K extends keyof KernelEventMap> = (payload: KernelEventMap[K]) => Promise<void> | void;
|
|
83
91
|
/** Typed in-process event emitter; handlers run in order, a failing one is logged and skipped. */
|
|
@@ -39,6 +39,10 @@ export function createFatalRecorder(deps) {
|
|
|
39
39
|
let recent = [];
|
|
40
40
|
let open = false;
|
|
41
41
|
return (kind, err) => {
|
|
42
|
+
// Exiting already: log nothing more. A failing log write (EPIPE on a dead stdout) raises the
|
|
43
|
+
// next event itself; logging it again would keep the process busy forever and starve the exit.
|
|
44
|
+
if (open)
|
|
45
|
+
return;
|
|
42
46
|
try {
|
|
43
47
|
const t = now();
|
|
44
48
|
recent = recent.filter((x) => t - x < GUARD_CIRCUIT_WINDOW_MS);
|
|
@@ -6,8 +6,10 @@ export interface LoggingModuleOptions {
|
|
|
6
6
|
logger?: KernelLogger;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* Provides the process logger as `
|
|
10
|
-
*
|
|
9
|
+
* Provides the process logger as `KERNEL_ROOT_LOGGER` and, as `KERNEL_LOGGER`, one child per injecting
|
|
10
|
+
* class with `context` = the class name (the `[context=…]` of the pretty output; octok's
|
|
11
|
+
* per-class Nest logger context). The logger is created before the Nest context (it must exist for
|
|
12
|
+
* startup errors), so it is passed in or derived from the startup config here.
|
|
11
13
|
*/
|
|
12
14
|
export declare class LoggingModule {
|
|
13
15
|
static forRoot(config: KernelConfig, opts?: LoggingModuleOptions): DynamicModule;
|
|
@@ -5,12 +5,15 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
var LoggingModule_1;
|
|
8
|
-
import { Global, Module } from "@nestjs/common";
|
|
8
|
+
import { Global, Module, Scope } from "@nestjs/common";
|
|
9
|
+
import { INQUIRER } from "@nestjs/core";
|
|
9
10
|
import { createConfiguredLogger } from "../../log-config.js";
|
|
10
|
-
import { KERNEL_LOGGER } from "../tokens.js";
|
|
11
|
+
import { KERNEL_LOGGER, KERNEL_ROOT_LOGGER } from "../tokens.js";
|
|
11
12
|
/**
|
|
12
|
-
* Provides the process logger as `
|
|
13
|
-
*
|
|
13
|
+
* Provides the process logger as `KERNEL_ROOT_LOGGER` and, as `KERNEL_LOGGER`, one child per injecting
|
|
14
|
+
* class with `context` = the class name (the `[context=…]` of the pretty output; octok's
|
|
15
|
+
* per-class Nest logger context). The logger is created before the Nest context (it must exist for
|
|
16
|
+
* startup errors), so it is passed in or derived from the startup config here.
|
|
14
17
|
*/
|
|
15
18
|
let LoggingModule = LoggingModule_1 = class LoggingModule {
|
|
16
19
|
static forRoot(config, opts = {}) {
|
|
@@ -21,8 +24,16 @@ let LoggingModule = LoggingModule_1 = class LoggingModule {
|
|
|
21
24
|
return {
|
|
22
25
|
module: LoggingModule_1,
|
|
23
26
|
global: true,
|
|
24
|
-
providers: [
|
|
25
|
-
|
|
27
|
+
providers: [
|
|
28
|
+
{ provide: KERNEL_ROOT_LOGGER, useValue: logger },
|
|
29
|
+
{
|
|
30
|
+
provide: KERNEL_LOGGER,
|
|
31
|
+
scope: Scope.TRANSIENT,
|
|
32
|
+
inject: [KERNEL_ROOT_LOGGER, INQUIRER],
|
|
33
|
+
useFactory: (root, inquirer) => contextLogger(root, inquirer),
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
exports: [KERNEL_ROOT_LOGGER, KERNEL_LOGGER],
|
|
26
37
|
};
|
|
27
38
|
}
|
|
28
39
|
};
|
|
@@ -32,3 +43,10 @@ LoggingModule = LoggingModule_1 = __decorate([
|
|
|
32
43
|
// biome-ignore lint/complexity/noStaticOnlyClass: a Nest dynamic module
|
|
33
44
|
], LoggingModule);
|
|
34
45
|
export { LoggingModule };
|
|
46
|
+
/** The child of `root` for the class instance `inquirer`; `root` itself for a factory provider. */
|
|
47
|
+
function contextLogger(root, inquirer) {
|
|
48
|
+
const name = inquirer?.constructor?.name;
|
|
49
|
+
return typeof name === "string" && name !== "" && name !== "Object"
|
|
50
|
+
? root.child({ context: name })
|
|
51
|
+
: root;
|
|
52
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { RedisOptions } from "bullmq";
|
|
2
|
+
/**
|
|
3
|
+
* TCP keepalive of every long-lived kernel Redis connection: probes start after 10 s idle (the OS
|
|
4
|
+
* default is 2 hours), so a connection a dropped network left half-open is found and reconnected
|
|
5
|
+
* before a command waits on it, not at the next write (EPIPE).
|
|
6
|
+
*/
|
|
7
|
+
export declare const REDIS_KEEPALIVE_MS = 10000;
|
|
2
8
|
/**
|
|
3
9
|
* BullMQ connection options from the kernel's Redis URL, the same connection the hand-made
|
|
4
10
|
* `new Redis(url, { maxRetriesPerRequest: null })` workers use: BullMQ requires
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TCP keepalive of every long-lived kernel Redis connection: probes start after 10 s idle (the OS
|
|
3
|
+
* default is 2 hours), so a connection a dropped network left half-open is found and reconnected
|
|
4
|
+
* before a command waits on it, not at the next write (EPIPE).
|
|
5
|
+
*/
|
|
6
|
+
export const REDIS_KEEPALIVE_MS = 10_000;
|
|
1
7
|
/**
|
|
2
8
|
* BullMQ connection options from the kernel's Redis URL, the same connection the hand-made
|
|
3
9
|
* `new Redis(url, { maxRetriesPerRequest: null })` workers use: BullMQ requires
|
|
@@ -14,5 +20,6 @@ export function bullConnectionOptions(url) {
|
|
|
14
20
|
...(db !== undefined && Number.isInteger(db) && { db }),
|
|
15
21
|
...(u.protocol === "rediss:" && { tls: {} }),
|
|
16
22
|
maxRetriesPerRequest: null,
|
|
23
|
+
keepAlive: REDIS_KEEPALIVE_MS,
|
|
17
24
|
};
|
|
18
25
|
}
|
|
@@ -14,6 +14,7 @@ import { closeWithin } from "../close-within.js";
|
|
|
14
14
|
import { KernelConfigService } from "../config/kernel-config.service.js";
|
|
15
15
|
import { GracefulShutdownModule } from "../lifecycle/graceful-shutdown.module.js";
|
|
16
16
|
import { GracefulShutdown } from "../lifecycle/graceful-shutdown.service.js";
|
|
17
|
+
import { REDIS_KEEPALIVE_MS } from "../queue/redis-connection.js";
|
|
17
18
|
import { KERNEL_BUS, KERNEL_LOGGER, REDIS, REDIS_SUBSCRIBER } from "../tokens.js";
|
|
18
19
|
/**
|
|
19
20
|
* Closes the bus subscriber, then the main connection, at the end of the shutdown
|
|
@@ -64,7 +65,10 @@ RedisModule = __decorate([
|
|
|
64
65
|
provide: REDIS,
|
|
65
66
|
inject: [KernelConfigService, KERNEL_LOGGER],
|
|
66
67
|
useFactory: (config, log) => {
|
|
67
|
-
const redis = new Redis(config.get().redis.url, {
|
|
68
|
+
const redis = new Redis(config.get().redis.url, {
|
|
69
|
+
lazyConnect: true,
|
|
70
|
+
keepAlive: REDIS_KEEPALIVE_MS,
|
|
71
|
+
});
|
|
68
72
|
redis.on("error", (err) => log.error("redis connection error", { err }));
|
|
69
73
|
return redis;
|
|
70
74
|
},
|
|
@@ -72,7 +76,7 @@ RedisModule = __decorate([
|
|
|
72
76
|
{
|
|
73
77
|
provide: REDIS_SUBSCRIBER,
|
|
74
78
|
inject: [KernelConfigService, KERNEL_LOGGER],
|
|
75
|
-
useFactory: (config, log) => createBusSubscriber(() => new Redis(config.get().redis.url), log),
|
|
79
|
+
useFactory: (config, log) => createBusSubscriber(() => new Redis(config.get().redis.url, { keepAlive: REDIS_KEEPALIVE_MS }), log),
|
|
76
80
|
},
|
|
77
81
|
{
|
|
78
82
|
provide: KERNEL_BUS,
|
package/dist/infra/tokens.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/** Injection tokens of the global infra modules. */
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* A class's logger (`KernelLogger`): the process logger with `context` set to the injecting class's
|
|
4
|
+
* name. Transient, so `app.get` cannot resolve it; use `KERNEL_ROOT_LOGGER` outside an injection.
|
|
5
|
+
*/
|
|
3
6
|
export declare const KERNEL_LOGGER: unique symbol;
|
|
7
|
+
/** The process logger itself (`KernelLogger`), without a context. */
|
|
8
|
+
export declare const KERNEL_ROOT_LOGGER: unique symbol;
|
|
4
9
|
/** The startup input of `KernelConfigService`: `{ config, env }`. */
|
|
5
10
|
export declare const KERNEL_CONFIG_INPUT: unique symbol;
|
|
6
11
|
/** The Kysely pool, untyped (`Kysely<any>`); infra only, services inject `KernelDb`. */
|
package/dist/infra/tokens.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/** Injection tokens of the global infra modules. */
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* A class's logger (`KernelLogger`): the process logger with `context` set to the injecting class's
|
|
4
|
+
* name. Transient, so `app.get` cannot resolve it; use `KERNEL_ROOT_LOGGER` outside an injection.
|
|
5
|
+
*/
|
|
3
6
|
export const KERNEL_LOGGER = Symbol("KERNEL_LOGGER");
|
|
7
|
+
/** The process logger itself (`KernelLogger`), without a context. */
|
|
8
|
+
export const KERNEL_ROOT_LOGGER = Symbol("KERNEL_ROOT_LOGGER");
|
|
4
9
|
/** The startup input of `KernelConfigService`: `{ config, env }`. */
|
|
5
10
|
export const KERNEL_CONFIG_INPUT = Symbol("KERNEL_CONFIG_INPUT");
|
|
6
11
|
/** The Kysely pool, untyped (`Kysely<any>`); infra only, services inject `KernelDb`. */
|
|
@@ -36,6 +36,7 @@ import { GatewayRole } from "../roles/gateway-role.js";
|
|
|
36
36
|
import { WorkerRole } from "../roles/worker-role.js";
|
|
37
37
|
import { UsageReporter } from "../runtime/usage-report.js";
|
|
38
38
|
import { sandboxConfigWarnings } from "../sandbox/sandbox.service.js";
|
|
39
|
+
import { warnLegacyToolKeys } from "../tools/legacy-data.js";
|
|
39
40
|
import { KERNEL_APP_OPTIONS } from "./tokens.js";
|
|
40
41
|
/**
|
|
41
42
|
* The stop phase budgets. Each phase waits `min(its budget, what is left of the total)`, where the
|
|
@@ -193,6 +194,10 @@ let KernelLifecycle = class KernelLifecycle {
|
|
|
193
194
|
// In flight for the stop: aborted when the shutdown begins, which then waits for its session to end
|
|
194
195
|
await this.shutdown.trackInFlight(migrate(config.db.url, { schema: KERNEL_SCHEMA, dir: KERNEL_MIGRATIONS_DIR }, { connectTimeoutMs: config.db.connectTimeoutMs, signal: this.shutdown.signal }));
|
|
195
196
|
this.checkpoint();
|
|
197
|
+
// Rows still holding a release-candidate tool key that migration 0063 could not map: one
|
|
198
|
+
// read-only count, a WARN when there are any (tool naming spec §8.2); never blocks the start
|
|
199
|
+
await warnLegacyToolKeys(this.kdb.db, this.log).catch((e) => this.log.warn("tools.legacy_key_count_failed", { error: errMsg(e) }));
|
|
200
|
+
this.checkpoint();
|
|
196
201
|
// official 清单来源按配置同步(幂等;每个副本启动时都做)
|
|
197
202
|
await this.marketplaces.syncOfficialFromConfig();
|
|
198
203
|
// The bootstrap plugins (spec §7), once per manifest across replicas (the Redis lock
|
package/dist/log.d.ts
CHANGED
|
@@ -30,6 +30,11 @@ export interface KernelLogger extends Logger {
|
|
|
30
30
|
redact(text: string): string;
|
|
31
31
|
/** Waits until buffered records reached every output (Loki); never rejects. Call before exit. */
|
|
32
32
|
flush(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* A logger that adds `fields` to every record (e.g. `{ context: "RunWorker" }`); call fields cannot
|
|
35
|
+
* overwrite them. It shares everything else with this logger: level, secrets, outputs.
|
|
36
|
+
*/
|
|
37
|
+
child(fields: Record<string, string>): KernelLogger;
|
|
33
38
|
}
|
|
34
39
|
/**
|
|
35
40
|
* 用与 logger 相同的匹配器打码任意文本(工具结果等不经过日志的内容用):展开规则同 `addOrgSecrets`
|
|
@@ -37,13 +42,15 @@ export interface KernelLogger extends Logger {
|
|
|
37
42
|
* 不得小于匹配器的分桶前缀长度 4)。没有可用的值时原样返回。
|
|
38
43
|
*/
|
|
39
44
|
export declare function createRedactor(values: readonly unknown[], minLength?: number): (s: string) => string;
|
|
40
|
-
/** Console format: `pretty` (pino-pretty
|
|
45
|
+
/** Console format: `pretty` (pino-pretty), `json`, or `auto` (pretty on a TTY). */
|
|
41
46
|
export declare const LOG_FORMATS: readonly ["auto", "pretty", "json"];
|
|
42
47
|
/** Console format. */
|
|
43
48
|
export type LogFormat = (typeof LOG_FORMATS)[number];
|
|
44
49
|
/** A minimal writable the console output goes to (`process.stdout` by default). */
|
|
45
50
|
export interface LogOutput {
|
|
46
51
|
write(chunk: string): unknown;
|
|
52
|
+
/** A stream's `error` event (EPIPE when its reader is gone). */
|
|
53
|
+
on?(event: "error", listener: (err: unknown) => void): unknown;
|
|
47
54
|
}
|
|
48
55
|
/** Options of {@link createLogger}. */
|
|
49
56
|
export interface LoggerOptions {
|
|
@@ -58,6 +65,11 @@ export interface LoggerOptions {
|
|
|
58
65
|
out?: LogOutput;
|
|
59
66
|
/** Whether the console is a terminal (picks `auto` and colors); default `process.stdout.isTTY`. */
|
|
60
67
|
isTTY?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Pretty output in colors; default: `FORCE_COLOR` (set and not `0`) turns them on, `NO_COLOR` off,
|
|
70
|
+
* else a TTY. `pnpm dev:kernel` forces them, since its output goes through `tee`.
|
|
71
|
+
*/
|
|
72
|
+
colors?: boolean;
|
|
61
73
|
/** Also push every record to Loki. */
|
|
62
74
|
loki?: LokiOptions;
|
|
63
75
|
/** Fields on every record (e.g. `role`); log calls cannot overwrite them. */
|
package/dist/log.js
CHANGED
|
@@ -105,15 +105,16 @@ function expandSecret(value) {
|
|
|
105
105
|
}
|
|
106
106
|
return out;
|
|
107
107
|
}
|
|
108
|
-
/** Console format: `pretty` (pino-pretty
|
|
108
|
+
/** Console format: `pretty` (pino-pretty), `json`, or `auto` (pretty on a TTY). */
|
|
109
109
|
export const LOG_FORMATS = ["auto", "pretty", "json"];
|
|
110
|
-
/** Fields shown in the pretty prefix instead of the
|
|
111
|
-
const PREFIX_FIELDS = ["reqId", "
|
|
112
|
-
/**
|
|
110
|
+
/** Fields shown in the pretty prefix instead of the lines below, in this order. */
|
|
111
|
+
const PREFIX_FIELDS = ["traceId", "reqId", "queue", "jobId", "runId", "context", "plugin"];
|
|
112
|
+
/**
|
|
113
|
+
* pino-pretty's message format, the octok layout:
|
|
114
|
+
* `[pid=…] - [traceId=…] [reqId=…] [context=…] msg`, each bracket only when present.
|
|
115
|
+
*/
|
|
113
116
|
function prettyMessage(log, messageKey) {
|
|
114
|
-
const parts = [];
|
|
115
|
-
if (typeof log.role === "string")
|
|
116
|
-
parts.push(`[${log.role}]`);
|
|
117
|
+
const parts = [`[pid=${process.pid}] -`];
|
|
117
118
|
for (const k of PREFIX_FIELDS) {
|
|
118
119
|
const v = log[k];
|
|
119
120
|
if (typeof v === "string" || typeof v === "number")
|
|
@@ -122,6 +123,24 @@ function prettyMessage(log, messageKey) {
|
|
|
122
123
|
parts.push(String(log[messageKey] ?? ""));
|
|
123
124
|
return parts.join(" ");
|
|
124
125
|
}
|
|
126
|
+
/** The HTTP access record (`http/app.ts`) as one sentence: method, path, status and duration. */
|
|
127
|
+
function foldAccessLine(log) {
|
|
128
|
+
if (log.msg !== "request" || typeof log.method !== "string" || typeof log.url !== "string") {
|
|
129
|
+
return log;
|
|
130
|
+
}
|
|
131
|
+
const { method, url, status, ms, ...rest } = log;
|
|
132
|
+
return { ...rest, msg: `${method} ${url} ${status} ${ms}ms` };
|
|
133
|
+
}
|
|
134
|
+
function colorsOn(opts, isTTY) {
|
|
135
|
+
if (opts.colors !== undefined)
|
|
136
|
+
return opts.colors;
|
|
137
|
+
const force = process.env.FORCE_COLOR;
|
|
138
|
+
if (force !== undefined && force !== "0")
|
|
139
|
+
return true;
|
|
140
|
+
if (process.env.NO_COLOR)
|
|
141
|
+
return false;
|
|
142
|
+
return isTTY;
|
|
143
|
+
}
|
|
125
144
|
function consoleStream(opts) {
|
|
126
145
|
if (opts.write) {
|
|
127
146
|
const write = opts.write;
|
|
@@ -132,23 +151,50 @@ function consoleStream(opts) {
|
|
|
132
151
|
if (!LOG_FORMATS.includes(format)) {
|
|
133
152
|
throw new Error(`invalid log.format "${format}" (expected ${LOG_FORMATS.join(", ")})`);
|
|
134
153
|
}
|
|
135
|
-
const
|
|
154
|
+
const target = opts.out ?? process.stdout;
|
|
155
|
+
// A console whose reader is gone (the `tee` of `pnpm dev:kernel` stopped by Ctrl-C, a closed
|
|
156
|
+
// pipe) fails every write with EPIPE. Unhandled, each failure is an uncaught exception the
|
|
157
|
+
// process guard logs, which writes again: an endless chain that starves the event loop. So the
|
|
158
|
+
// first stream error ends console output for good (Loki, when configured, still gets records).
|
|
159
|
+
let broken = false;
|
|
160
|
+
target.on?.("error", () => {
|
|
161
|
+
broken = true;
|
|
162
|
+
});
|
|
163
|
+
const out = {
|
|
164
|
+
write: (s) => {
|
|
165
|
+
if (!broken)
|
|
166
|
+
target.write(s);
|
|
167
|
+
},
|
|
168
|
+
};
|
|
136
169
|
const isTTY = opts.isTTY ?? process.stdout.isTTY === true;
|
|
137
170
|
const pretty = format === "pretty" || (format === "auto" && isTTY);
|
|
138
171
|
if (!pretty)
|
|
139
172
|
return { write: (s) => out.write(s) };
|
|
140
|
-
|
|
173
|
+
const colors = colorsOn(opts, isTTY);
|
|
174
|
+
// In process (no worker thread): pino-pretty formats each record synchronously. The layout follows
|
|
175
|
+
// octok's buildPinoPrettyOptions: full local time, colored level, the bracket prefix, and
|
|
176
|
+
// the remaining fields as indented `key: value` lines below the message (errors with their stack).
|
|
141
177
|
const format_ = prettyFactory({
|
|
142
|
-
colorize:
|
|
143
|
-
colorizeObjects:
|
|
144
|
-
singleLine:
|
|
145
|
-
|
|
146
|
-
errorLikeObjectKeys: [],
|
|
147
|
-
translateTime: "SYS:HH:MM:ss.l",
|
|
178
|
+
colorize: colors,
|
|
179
|
+
colorizeObjects: colors,
|
|
180
|
+
singleLine: false,
|
|
181
|
+
translateTime: "SYS:standard",
|
|
148
182
|
ignore: ["pid", "hostname", "role", "spanId", ...PREFIX_FIELDS].join(","),
|
|
149
183
|
messageFormat: (log, messageKey) => prettyMessage(log, messageKey),
|
|
150
184
|
});
|
|
151
|
-
return {
|
|
185
|
+
return {
|
|
186
|
+
write: (s) => {
|
|
187
|
+
let record;
|
|
188
|
+
try {
|
|
189
|
+
record = JSON.parse(s);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
out.write(s);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
out.write(format_(foldAccessLine(record)));
|
|
196
|
+
},
|
|
197
|
+
};
|
|
152
198
|
}
|
|
153
199
|
/**
|
|
154
200
|
* Creates the kernel logger on pino. Each record is `{ time, level, msg, ...base, ...fields }` with
|
|
@@ -254,7 +300,7 @@ export function createLogger(level = "info", opts = {}) {
|
|
|
254
300
|
}
|
|
255
301
|
sink[lvl](obj, redactMsg(msg));
|
|
256
302
|
};
|
|
257
|
-
|
|
303
|
+
const root = {
|
|
258
304
|
debug: (msg, fields) => emit("debug", msg, fields),
|
|
259
305
|
info: (msg, fields) => emit("info", msg, fields),
|
|
260
306
|
warn: (msg, fields) => emit("warn", msg, fields),
|
|
@@ -299,5 +345,35 @@ export function createLogger(level = "info", opts = {}) {
|
|
|
299
345
|
}
|
|
300
346
|
}
|
|
301
347
|
},
|
|
348
|
+
// a method, so a wrapper of this logger (a test proxy) is the parent its children forward to
|
|
349
|
+
child(fields) {
|
|
350
|
+
return childLogger(this, fields);
|
|
351
|
+
},
|
|
352
|
+
};
|
|
353
|
+
return root;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* A logger that adds `bound` to every record and forwards it to `parent`'s public methods (so a spy
|
|
357
|
+
* on the parent sees its children's records); call fields cannot overwrite the bound ones.
|
|
358
|
+
*/
|
|
359
|
+
function childLogger(parent, bound) {
|
|
360
|
+
const merged = (fields) => ({ ...fields, ...bound });
|
|
361
|
+
const child = {
|
|
362
|
+
debug: (msg, fields) => parent.debug(msg, merged(fields)),
|
|
363
|
+
info: (msg, fields) => parent.info(msg, merged(fields)),
|
|
364
|
+
warn: (msg, fields) => parent.warn(msg, merged(fields)),
|
|
365
|
+
error: (msg, fields) => parent.error(msg, merged(fields)),
|
|
366
|
+
get level() {
|
|
367
|
+
return parent.level;
|
|
368
|
+
},
|
|
369
|
+
setLevel: (level) => parent.setLevel(level),
|
|
370
|
+
addSecrets: (values) => parent.addSecrets(values),
|
|
371
|
+
addOrgSecrets: (values) => parent.addOrgSecrets(values),
|
|
372
|
+
redact: (text) => parent.redact(text),
|
|
373
|
+
flush: () => parent.flush(),
|
|
374
|
+
child(fields) {
|
|
375
|
+
return childLogger(this, fields);
|
|
376
|
+
},
|
|
302
377
|
};
|
|
378
|
+
return child;
|
|
303
379
|
}
|
|
@@ -35,6 +35,13 @@ export declare const KERNEL_PURPOSES: readonly [{
|
|
|
35
35
|
readonly zh: "会话标题";
|
|
36
36
|
readonly en: "Conversation titles";
|
|
37
37
|
};
|
|
38
|
+
}, {
|
|
39
|
+
readonly purpose: "web_fetch";
|
|
40
|
+
readonly kind: "chat";
|
|
41
|
+
readonly label: {
|
|
42
|
+
readonly zh: "网页提取";
|
|
43
|
+
readonly en: "Web page extraction";
|
|
44
|
+
};
|
|
38
45
|
}, {
|
|
39
46
|
readonly purpose: "subagent_fast";
|
|
40
47
|
readonly kind: "chat";
|
|
@@ -140,6 +147,19 @@ export declare class ModelPurposesService {
|
|
|
140
147
|
setOrg(orgId: string, purpose: string, target: PurposeTarget | null, actor: string, actorTokenId?: string): Promise<PurposeView>;
|
|
141
148
|
/** 生效的映射:组织覆盖,否则部署默认;都没有 → `model.unconfigured`;用途未声明 → `model.purpose_unknown`。 */
|
|
142
149
|
resolve(orgId: string, purpose: string): Promise<PurposeTarget>;
|
|
150
|
+
/** The target a {@link chat} call on `purpose` uses: the mapping, else `fallback` when unmapped. */
|
|
151
|
+
private chatTarget;
|
|
152
|
+
/**
|
|
153
|
+
* The limits of the model a {@link chat} call on `purpose` would use now (the same mapping and
|
|
154
|
+
* `fallback` rule): its context window and output cap, so a caller can size its request (e.g.
|
|
155
|
+
* the `WebFetch` page) before the call. Fails as `chat` does before sending.
|
|
156
|
+
*/
|
|
157
|
+
chatLimits(orgId: string, purpose: string, opts?: {
|
|
158
|
+
fallback?: PurposeTarget;
|
|
159
|
+
}): Promise<{
|
|
160
|
+
contextWindow: number;
|
|
161
|
+
maxOutputTokens: number;
|
|
162
|
+
}>;
|
|
143
163
|
/**
|
|
144
164
|
* 按用途发一次对话请求:解析映射、按目标模型的声明宽松处理参数(补默认值,与运行时一致),用 `consumeModelStream`
|
|
145
165
|
* 收完(只有流空闲看门狗)。输出上限取 `min(req.maxOutputTokens, 目标模型的 maxOutputTokens)`。
|
|
@@ -147,10 +167,13 @@ export declare class ModelPurposesService {
|
|
|
147
167
|
* `opts.fallback`: the target used when the purpose is not mapped (`model.unconfigured`).
|
|
148
168
|
* `opts.beforeSend`: called with the resolved target and the final request just before sending;
|
|
149
169
|
* what it throws is thrown as is (a pre-send failure, e.g. a denied `model.request` hook).
|
|
170
|
+
* `opts.paramDefaults`: values for parameters the target does not set, kept only where the
|
|
171
|
+
* target model declares the key and the value fits it (e.g. `thinking: "off"` for a short call).
|
|
150
172
|
*/
|
|
151
173
|
chat(orgId: string, purpose: string, req: Omit<ModelRequest, "model" | "params">, signal: AbortSignal, opts?: {
|
|
152
174
|
fallback?: PurposeTarget;
|
|
153
175
|
beforeSend?: (target: ModelRef, request: ModelRequest) => Promise<void>;
|
|
176
|
+
paramDefaults?: Record<string, ParamValue>;
|
|
154
177
|
}): Promise<{
|
|
155
178
|
content: ContentBlock[];
|
|
156
179
|
stopReason: StopReason;
|
package/dist/models/purposes.js
CHANGED
|
@@ -41,6 +41,11 @@ export const KERNEL_PURPOSES = [
|
|
|
41
41
|
{ purpose: "eval", kind: "chat", label: { zh: "评测评委", en: "Eval judge" } },
|
|
42
42
|
/** Conversation titles (UI refresh B); unmapped → the conversation's current chat model. */
|
|
43
43
|
{ purpose: "title", kind: "chat", label: { zh: "会话标题", en: "Conversation titles" } },
|
|
44
|
+
/**
|
|
45
|
+
* The `WebFetch` extraction call (web tools spec §5); unmapped → the calling conversation's
|
|
46
|
+
* current chat model (a sub-agent's call: the sub-agent's).
|
|
47
|
+
*/
|
|
48
|
+
{ purpose: "web_fetch", kind: "chat", label: { zh: "网页提取", en: "Web page extraction" } },
|
|
44
49
|
{
|
|
45
50
|
purpose: "subagent_fast",
|
|
46
51
|
kind: "chat",
|
|
@@ -254,6 +259,27 @@ let ModelPurposesService = class ModelPurposesService {
|
|
|
254
259
|
}
|
|
255
260
|
return view.effective;
|
|
256
261
|
}
|
|
262
|
+
/** The target a {@link chat} call on `purpose` uses: the mapping, else `fallback` when unmapped. */
|
|
263
|
+
async chatTarget(orgId, purpose, fallback) {
|
|
264
|
+
try {
|
|
265
|
+
return await this.resolve(orgId, purpose);
|
|
266
|
+
}
|
|
267
|
+
catch (e) {
|
|
268
|
+
if (!(e instanceof ApiError && e.code === "model.unconfigured") || !fallback)
|
|
269
|
+
throw e;
|
|
270
|
+
return fallback;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* The limits of the model a {@link chat} call on `purpose` would use now (the same mapping and
|
|
275
|
+
* `fallback` rule): its context window and output cap, so a caller can size its request (e.g.
|
|
276
|
+
* the `WebFetch` page) before the call. Fails as `chat` does before sending.
|
|
277
|
+
*/
|
|
278
|
+
async chatLimits(orgId, purpose, opts = {}) {
|
|
279
|
+
const target = await this.chatTarget(orgId, purpose, opts.fallback);
|
|
280
|
+
const { info } = await this.providers.resolve(target.model);
|
|
281
|
+
return { contextWindow: info.contextWindow, maxOutputTokens: info.maxOutputTokens };
|
|
282
|
+
}
|
|
257
283
|
/**
|
|
258
284
|
* 按用途发一次对话请求:解析映射、按目标模型的声明宽松处理参数(补默认值,与运行时一致),用 `consumeModelStream`
|
|
259
285
|
* 收完(只有流空闲看门狗)。输出上限取 `min(req.maxOutputTokens, 目标模型的 maxOutputTokens)`。
|
|
@@ -261,22 +287,17 @@ let ModelPurposesService = class ModelPurposesService {
|
|
|
261
287
|
* `opts.fallback`: the target used when the purpose is not mapped (`model.unconfigured`).
|
|
262
288
|
* `opts.beforeSend`: called with the resolved target and the final request just before sending;
|
|
263
289
|
* what it throws is thrown as is (a pre-send failure, e.g. a denied `model.request` hook).
|
|
290
|
+
* `opts.paramDefaults`: values for parameters the target does not set, kept only where the
|
|
291
|
+
* target model declares the key and the value fits it (e.g. `thinking: "off"` for a short call).
|
|
264
292
|
*/
|
|
265
293
|
async chat(orgId, purpose, req, signal, opts = {}) {
|
|
266
|
-
|
|
267
|
-
try {
|
|
268
|
-
target = await this.resolve(orgId, purpose);
|
|
269
|
-
}
|
|
270
|
-
catch (e) {
|
|
271
|
-
if (!(e instanceof ApiError && e.code === "model.unconfigured") || !opts.fallback)
|
|
272
|
-
throw e;
|
|
273
|
-
target = opts.fallback;
|
|
274
|
-
}
|
|
294
|
+
const target = await this.chatTarget(orgId, purpose, opts.fallback);
|
|
275
295
|
const { provider, info } = await this.providers.resolve(target.model);
|
|
276
296
|
const request = {
|
|
277
297
|
...req,
|
|
278
298
|
model: info.id,
|
|
279
|
-
|
|
299
|
+
// undeclared or unfitting defaults are dropped like any other parameter
|
|
300
|
+
params: sanitizeParams(info.parameters, { ...opts.paramDefaults, ...target.params }).value,
|
|
280
301
|
// 输出上限不超过目标模型自己的上限(与运行时 assembleModelRequest 一致)
|
|
281
302
|
maxOutputTokens: Math.min(req.maxOutputTokens, info.maxOutputTokens),
|
|
282
303
|
};
|
|
@@ -83,7 +83,9 @@ export declare class Offboarding {
|
|
|
83
83
|
* In the caller's transaction (`mandatory`: the caller holds the org row lock, order org row →
|
|
84
84
|
* membership, and did the "last owner" checks):
|
|
85
85
|
* 1. 删除成员关系(非成员 → `member.not_found`;删后组织没有 owner → `org.last_owner`),清空指向该组织的会话当前组织;
|
|
86
|
-
* 2.
|
|
86
|
+
* 2. Removal and directory offboarding revoke **every** session and personal token of the
|
|
87
|
+
* account (both are account-wide, so conservatively all); a person who leaves (`left`) keeps
|
|
88
|
+
* them, and the session's current org is cleared (the membership check ends the access);
|
|
87
89
|
* 3. 删除其在该组织所有连接器上的个人凭据;
|
|
88
90
|
* 4. 取消其作为处理人的 pending 审批与提问(写 cancelled 事件),记下此人在该组织进行中的运行(提交后中止);
|
|
89
91
|
* 5. 其负责的该组织 agent 转给组织所有者(最早加入的 owner)并置 `needs_reassignment = true`;
|
package/dist/orgs/offboarding.js
CHANGED
|
@@ -83,7 +83,9 @@ let Offboarding = class Offboarding {
|
|
|
83
83
|
* In the caller's transaction (`mandatory`: the caller holds the org row lock, order org row →
|
|
84
84
|
* membership, and did the "last owner" checks):
|
|
85
85
|
* 1. 删除成员关系(非成员 → `member.not_found`;删后组织没有 owner → `org.last_owner`),清空指向该组织的会话当前组织;
|
|
86
|
-
* 2.
|
|
86
|
+
* 2. Removal and directory offboarding revoke **every** session and personal token of the
|
|
87
|
+
* account (both are account-wide, so conservatively all); a person who leaves (`left`) keeps
|
|
88
|
+
* them, and the session's current org is cleared (the membership check ends the access);
|
|
87
89
|
* 3. 删除其在该组织所有连接器上的个人凭据;
|
|
88
90
|
* 4. 取消其作为处理人的 pending 审批与提问(写 cancelled 事件),记下此人在该组织进行中的运行(提交后中止);
|
|
89
91
|
* 5. 其负责的该组织 agent 转给组织所有者(最早加入的 owner)并置 `needs_reassignment = true`;
|
|
@@ -150,21 +152,29 @@ let Offboarding = class Offboarding {
|
|
|
150
152
|
.where("account_id", "=", accountId)
|
|
151
153
|
.where("current_org_id", "=", orgId)
|
|
152
154
|
.execute();
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
.
|
|
155
|
+
// A person who leaves keeps their sign-in and personal tokens: the org guard reads the
|
|
156
|
+
// membership on every request, so access to this org ends with the row above, and their other
|
|
157
|
+
// orgs keep working. Removal and directory offboarding revoke both (account-wide, conservative).
|
|
158
|
+
const revoke = reason !== "left";
|
|
159
|
+
const sessions = revoke
|
|
160
|
+
? await this.db
|
|
161
|
+
.updateTable("sessions")
|
|
162
|
+
.set({ revoked_at: sql `now()` })
|
|
163
|
+
.where("account_id", "=", accountId)
|
|
164
|
+
.where("revoked_at", "is", null)
|
|
165
|
+
.returning("id")
|
|
166
|
+
.execute()
|
|
167
|
+
: [];
|
|
168
|
+
const tokens = revoke
|
|
169
|
+
? await this.db
|
|
170
|
+
.updateTable("api_tokens")
|
|
171
|
+
.set({ revoked_at: sql `now()` })
|
|
172
|
+
.where("kind", "=", "personal")
|
|
173
|
+
.where("account_id", "=", accountId)
|
|
174
|
+
.where("revoked_at", "is", null)
|
|
175
|
+
.returning("id")
|
|
176
|
+
.execute()
|
|
177
|
+
: [];
|
|
168
178
|
// in this transaction (the approvals and questions services join it: `mandatory`)
|
|
169
179
|
const credentials = await this.credentials.clearAccount(orgId, accountId);
|
|
170
180
|
const approvals = await this.approvals.cancelPendingFor(orgId, accountId);
|