@capybara-hq/kernel 0.1.0-rc.6 → 0.1.0-rc.7
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/bootstrap.json +27 -3
- package/dist/admin/admin.controller.d.ts +8 -72
- package/dist/admin/admin.controller.js +21 -46
- package/dist/admin/admin.schemas.d.ts +57 -0
- package/dist/admin/admin.schemas.js +50 -0
- package/dist/admin/extensions.controller.d.ts +10 -0
- package/dist/admin/extensions.controller.js +18 -0
- package/dist/admin/extensions.schemas.d.ts +7 -0
- package/dist/admin/extensions.schemas.js +10 -0
- package/dist/admin/limit-defaults.d.ts +20 -0
- package/dist/admin/limit-defaults.js +10 -0
- package/dist/agents/agent-profile.service.d.ts +7 -5
- package/dist/agents/agent-profile.service.js +14 -9
- package/dist/agents/agents.controller.d.ts +7 -287
- package/dist/agents/agents.controller.js +7 -67
- package/dist/agents/agents.schemas.d.ts +389 -0
- package/dist/agents/agents.schemas.js +126 -0
- package/dist/agents/agents.service.d.ts +13 -5
- package/dist/agents/agents.service.js +67 -13
- package/dist/agents/definition.d.ts +47 -19
- package/dist/agents/definition.js +119 -38
- package/dist/agents/from-template.d.ts +2 -2
- package/dist/agents/from-template.js +76 -45
- package/dist/agents/from-template.service.d.ts +12 -0
- package/dist/agents/from-template.service.js +20 -3
- package/dist/agents/models.controller.d.ts +1 -2
- package/dist/agents/models.controller.js +1 -1
- package/dist/agents/org-templates.d.ts +13 -3
- package/dist/agents/org-templates.js +69 -28
- package/dist/agents/pending-connector-requests.d.ts +2 -0
- package/dist/agents/pending-connector-requests.js +1 -1
- package/dist/agents/pending-connectors.controller.d.ts +1 -1
- package/dist/agents/pending-connectors.controller.js +2 -2
- package/dist/agents/pending-connectors.service.d.ts +2 -2
- package/dist/agents/pending-connectors.service.js +19 -19
- package/dist/agents/profile.d.ts +18 -0
- package/dist/agents/profile.js +5 -1
- package/dist/agents/templates.controller.d.ts +8 -17
- package/dist/agents/templates.controller.js +13 -31
- package/dist/agents/templates.schemas.d.ts +20 -0
- package/dist/agents/templates.schemas.js +45 -0
- package/dist/background/background.controller.js +3 -2
- package/dist/background/background.schemas.d.ts +10 -0
- package/dist/background/background.schemas.js +16 -0
- package/dist/background/tasks.service.d.ts +1 -1
- package/dist/background/tasks.service.js +7 -2
- package/dist/catalog/admin-catalog.controller.d.ts +4 -57
- package/dist/catalog/admin-catalog.controller.js +8 -45
- package/dist/catalog/admin-catalog.schemas.d.ts +72 -0
- package/dist/catalog/admin-catalog.schemas.js +92 -0
- package/dist/catalog/catalog-content.d.ts +12 -2
- package/dist/catalog/catalog-scope.service.js +8 -2
- package/dist/catalog/catalog.service.d.ts +2 -0
- package/dist/catalog/catalog.service.js +3 -0
- package/dist/catalog/component-scope.controller.d.ts +3 -65
- package/dist/catalog/component-scope.controller.js +3 -56
- package/dist/catalog/component-scope.schemas.d.ts +114 -0
- package/dist/catalog/component-scope.schemas.js +97 -0
- package/dist/catalog/component-scope.service.d.ts +28 -4
- package/dist/catalog/component-scope.service.js +55 -3
- package/dist/catalog/component-state.d.ts +9 -2
- package/dist/catalog/component-state.js +22 -13
- package/dist/catalog/marketplaces.controller.d.ts +5 -35
- package/dist/catalog/marketplaces.controller.js +6 -34
- package/dist/catalog/marketplaces.schemas.d.ts +48 -0
- package/dist/catalog/marketplaces.schemas.js +53 -0
- package/dist/catalog/marketplaces.service.d.ts +15 -1
- package/dist/catalog/marketplaces.service.js +22 -1
- package/dist/catalog/org-catalog.controller.d.ts +6 -62
- package/dist/catalog/org-catalog.controller.js +12 -66
- package/dist/catalog/org-catalog.schemas.d.ts +79 -0
- package/dist/catalog/org-catalog.schemas.js +82 -0
- package/dist/catalog/org-catalog.service.d.ts +9 -2
- package/dist/catalog/org-catalog.service.js +38 -5
- package/dist/catalog/org-extension.controller.d.ts +1 -12
- package/dist/catalog/org-extension.controller.js +1 -10
- package/dist/catalog/org-extension.schemas.d.ts +15 -0
- package/dist/catalog/org-extension.schemas.js +22 -0
- package/dist/catalog/org-plugin-uploads.controller.d.ts +2 -19
- package/dist/catalog/org-plugin-uploads.controller.js +15 -28
- package/dist/catalog/org-plugin-uploads.schemas.d.ts +20 -0
- package/dist/catalog/org-plugin-uploads.schemas.js +32 -0
- package/dist/catalog/owned-items.d.ts +6 -2
- package/dist/catalog/owned-items.js +16 -4
- package/dist/catalog/platform-components.d.ts +2 -0
- package/dist/catalog/platform-components.js +2 -0
- package/dist/catalog/plugin-import.js +1 -0
- package/dist/catalog/plugin-install.js +1 -1
- package/dist/catalog/requests.service.d.ts +2 -1
- package/dist/catalog/requests.service.js +6 -2
- package/dist/channels/channels.schemas.d.ts +33 -0
- package/dist/channels/channels.schemas.js +34 -0
- package/dist/channels/connections.controller.d.ts +2 -29
- package/dist/channels/connections.controller.js +1 -23
- package/dist/channels/connections.service.d.ts +8 -2
- package/dist/channels/connections.service.js +23 -5
- package/dist/channels/inbound.js +4 -0
- package/dist/conversations/conversations.controller.d.ts +16 -37
- package/dist/conversations/conversations.controller.js +16 -56
- package/dist/conversations/conversations.schemas.d.ts +52 -0
- package/dist/conversations/conversations.schemas.js +79 -0
- package/dist/conversations/conversations.service.d.ts +9 -1
- package/dist/conversations/conversations.service.js +23 -18
- package/dist/conversations/events.d.ts +80 -6
- package/dist/conversations/events.js +60 -5
- package/dist/conversations/message-context.d.ts +28 -0
- package/dist/conversations/message-context.js +56 -0
- package/dist/conversations/queue.d.ts +2 -1
- package/dist/conversations/queue.js +11 -2
- package/dist/db/kernel-schema.d.ts +20 -0
- package/dist/environments/environments.schemas.d.ts +3 -0
- package/dist/environments/environments.schemas.js +14 -0
- package/dist/environments/environments.service.d.ts +16 -4
- package/dist/environments/environments.service.js +58 -13
- package/dist/errors.d.ts +3 -0
- package/dist/errors.js +3 -0
- package/dist/evals/evals.schemas.d.ts +110 -0
- package/dist/evals/evals.schemas.js +107 -0
- package/dist/evals/reconstruct.js +18 -11
- package/dist/evals/recorded-tools.d.ts +2 -1
- package/dist/evals/recorded-tools.js +11 -3
- package/dist/evals/run-replay.d.ts +8 -1
- package/dist/evals/run-replay.js +13 -0
- package/dist/evals/runs.controller.d.ts +2 -57
- package/dist/evals/runs.controller.js +1 -42
- package/dist/evals/runs.service.d.ts +6 -6
- package/dist/evals/runs.service.js +32 -18
- package/dist/evals/sets.controller.d.ts +2 -28
- package/dist/evals/sets.controller.js +1 -31
- package/dist/evals/sets.service.d.ts +7 -7
- package/dist/evals/sets.service.js +23 -17
- package/dist/evals/snapshot.d.ts +3 -2
- package/dist/evals/snapshot.js +17 -4
- package/dist/extensions/admin-ops.d.ts +5 -3
- package/dist/extensions/admin-ops.js +17 -12
- package/dist/extensions/deployment-config.d.ts +16 -1
- package/dist/extensions/deployment-config.js +83 -0
- package/dist/extensions/extensions.module.js +3 -0
- package/dist/extensions/host.d.ts +33 -2
- package/dist/extensions/host.js +107 -1
- package/dist/extensions/installs.d.ts +5 -0
- package/dist/extensions/installs.js +12 -0
- package/dist/extensions/org-config.d.ts +17 -2
- package/dist/extensions/org-config.js +23 -4
- package/dist/extensions/point-defaults.controller.d.ts +2 -8
- package/dist/extensions/point-defaults.controller.js +1 -3
- package/dist/extensions/point-defaults.d.ts +3 -1
- package/dist/extensions/point-defaults.js +4 -2
- package/dist/extensions/point-defaults.schemas.d.ts +9 -0
- package/dist/extensions/point-defaults.schemas.js +14 -0
- package/dist/extensions/unavailable.d.ts +49 -0
- package/dist/extensions/unavailable.js +113 -0
- package/dist/files/previewers.controller.js +2 -3
- package/dist/files/previewers.d.ts +1 -1
- package/dist/files/previewers.js +4 -4
- package/dist/files/previewers.schemas.d.ts +10 -0
- package/dist/files/previewers.schemas.js +9 -0
- package/dist/http/api.module.js +2 -0
- package/dist/identity/accounts.d.ts +43 -4
- package/dist/identity/accounts.js +74 -6
- package/dist/identity/auth.guard.js +10 -1
- package/dist/identity/cookies.d.ts +6 -0
- package/dist/identity/cookies.js +14 -0
- package/dist/identity/identity.module.js +3 -0
- package/dist/identity/initial-passwords.controller.d.ts +22 -0
- package/dist/identity/initial-passwords.controller.js +49 -0
- package/dist/identity/initial-passwords.d.ts +61 -0
- package/dist/identity/initial-passwords.job.d.ts +16 -0
- package/dist/identity/initial-passwords.job.js +46 -0
- package/dist/identity/initial-passwords.js +159 -0
- package/dist/identity/me.controller.d.ts +14 -0
- package/dist/identity/me.controller.js +39 -1
- package/dist/identity/principal.d.ts +8 -0
- package/dist/identity/principal.js +8 -0
- package/dist/identity/settings.d.ts +3 -1
- package/dist/identity/settings.js +6 -4
- package/dist/inbox/inbox.schemas.d.ts +8 -0
- package/dist/inbox/inbox.schemas.js +11 -0
- package/dist/inbox/platform-inbox.controller.d.ts +1 -1
- package/dist/inbox/platform-inbox.controller.js +2 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -0
- package/dist/lifecycle/kernel-lifecycle.js +4 -0
- package/dist/models/enablement.d.ts +2 -0
- package/dist/models/enablement.js +1 -0
- package/dist/models/org-models.schemas.d.ts +8 -0
- package/dist/models/org-models.schemas.js +22 -0
- package/dist/models/prices.d.ts +3 -1
- package/dist/models/prices.js +7 -5
- package/dist/models/purposes.d.ts +12 -2
- package/dist/models/purposes.js +22 -8
- package/dist/orgs/orgs.controller.d.ts +2 -5
- package/dist/orgs/orgs.controller.js +3 -6
- package/dist/orgs/orgs.schemas.d.ts +8 -0
- package/dist/orgs/orgs.schemas.js +16 -0
- package/dist/orgs/orgs.service.d.ts +3 -1
- package/dist/orgs/orgs.service.js +6 -4
- package/dist/orgs/settings.service.d.ts +9 -1
- package/dist/orgs/settings.service.js +20 -5
- package/dist/overrides.d.ts +4 -0
- package/dist/overrides.js +2 -0
- package/dist/platform/errors.d.ts +21 -4
- package/dist/platform/errors.js +45 -6
- package/dist/platform/exclusions.d.ts +2 -3
- package/dist/platform/exclusions.js +68 -849
- package/dist/platform/method.js +1 -1
- package/dist/platform/operation.d.ts +82 -5
- package/dist/platform/operation.js +62 -7
- package/dist/platform/ops/accounts.ops.d.ts +32 -0
- package/dist/platform/ops/accounts.ops.js +291 -0
- package/dist/platform/ops/admin.ops.d.ts +36 -0
- package/dist/platform/ops/admin.ops.js +389 -0
- package/dist/platform/ops/agent-skills.ops.d.ts +24 -0
- package/dist/platform/ops/agent-skills.ops.js +226 -0
- package/dist/platform/ops/agent-templates.ops.d.ts +4 -1
- package/dist/platform/ops/agent-templates.ops.js +194 -14
- package/dist/platform/ops/agents.ops.d.ts +19 -1
- package/dist/platform/ops/agents.ops.js +481 -58
- package/dist/platform/ops/approvals.ops.d.ts +30 -0
- package/dist/platform/ops/approvals.ops.js +116 -0
- package/dist/platform/ops/background.ops.d.ts +14 -0
- package/dist/platform/ops/background.ops.js +134 -0
- package/dist/platform/ops/catalog-admin.ops.d.ts +74 -0
- package/dist/platform/ops/catalog-admin.ops.js +587 -0
- package/dist/platform/ops/channels.ops.d.ts +16 -0
- package/dist/platform/ops/channels.ops.js +195 -0
- package/dist/platform/ops/components.ops.d.ts +46 -0
- package/dist/platform/ops/components.ops.js +853 -0
- package/dist/platform/ops/connectors.ops.d.ts +4 -2
- package/dist/platform/ops/connectors.ops.js +68 -6
- package/dist/platform/ops/conversations.ops.d.ts +30 -0
- package/dist/platform/ops/conversations.ops.js +470 -0
- package/dist/platform/ops/environments.ops.d.ts +26 -0
- package/dist/platform/ops/environments.ops.js +289 -0
- package/dist/platform/ops/errors.d.ts +10 -5
- package/dist/platform/ops/errors.js +19 -11
- package/dist/platform/ops/evals.ops.d.ts +28 -0
- package/dist/platform/ops/evals.ops.js +783 -0
- package/dist/platform/ops/extensions-admin.ops.d.ts +25 -0
- package/dist/platform/ops/extensions-admin.ops.js +344 -0
- package/dist/platform/ops/extensions.ops.d.ts +7 -1
- package/dist/platform/ops/extensions.ops.js +248 -17
- package/dist/platform/ops/inbox.ops.d.ts +25 -0
- package/dist/platform/ops/inbox.ops.js +378 -0
- package/dist/platform/ops/marketplaces.ops.d.ts +7 -1
- package/dist/platform/ops/marketplaces.ops.js +326 -17
- package/dist/platform/ops/models.ops.d.ts +25 -0
- package/dist/platform/ops/models.ops.js +232 -0
- package/dist/platform/ops/org-plugins.ops.d.ts +29 -0
- package/dist/platform/ops/org-plugins.ops.js +329 -0
- package/dist/platform/ops/org-settings.ops.d.ts +16 -0
- package/dist/platform/ops/org-settings.ops.js +102 -0
- package/dist/platform/ops/orgs.ops.d.ts +28 -0
- package/dist/platform/ops/orgs.ops.js +295 -0
- package/dist/platform/ops/other-orgs.d.ts +20 -0
- package/dist/platform/ops/other-orgs.js +72 -0
- package/dist/platform/ops/platform.ops.d.ts +4 -4
- package/dist/platform/ops/platform.ops.js +23 -24
- package/dist/platform/ops/plugins.ops.d.ts +10 -8
- package/dist/platform/ops/plugins.ops.js +176 -77
- package/dist/platform/ops/previewers.ops.d.ts +14 -0
- package/dist/platform/ops/previewers.ops.js +109 -0
- package/dist/platform/ops/requests.ops.js +57 -19
- package/dist/platform/ops/skills.ops.d.ts +5 -1
- package/dist/platform/ops/skills.ops.js +129 -11
- package/dist/platform/ops/unavailable.d.ts +23 -0
- package/dist/platform/ops/unavailable.js +111 -0
- package/dist/platform/parity.d.ts +33 -0
- package/dist/platform/parity.js +272 -0
- package/dist/platform/platform-ops.module.d.ts +32 -0
- package/dist/platform/platform-ops.module.js +78 -11
- package/dist/platform/route-schemas.d.ts +18 -0
- package/dist/platform/route-schemas.js +60 -0
- package/dist/roles/worker.module.js +2 -0
- package/dist/runtime/context/build.d.ts +2 -0
- package/dist/runtime/context/build.js +28 -2
- package/dist/runtime/context/compaction.js +10 -1
- package/dist/runtime/context/run-context.d.ts +65 -0
- package/dist/runtime/context/run-context.js +215 -0
- package/dist/runtime/model-call.js +2 -1
- package/dist/runtime/providers.js +8 -1
- package/dist/runtime/run-context.service.d.ts +65 -0
- package/dist/runtime/run-context.service.js +220 -0
- package/dist/runtime/run-worker.d.ts +5 -0
- package/dist/runtime/run-worker.js +31 -6
- package/dist/runtime/runtime.module.js +2 -0
- package/dist/runtime/subagents/definition.d.ts +15 -15
- package/dist/runtime/subagents/definition.js +46 -115
- package/dist/skills/changes.controller.js +2 -1
- package/dist/skills/changes.service.d.ts +1 -1
- package/dist/skills/changes.service.js +4 -4
- package/dist/skills/invocable.controller.d.ts +1 -1
- package/dist/skills/invocable.controller.js +2 -2
- package/dist/skills/invoke.d.ts +2 -2
- package/dist/skills/invoke.js +8 -1
- package/dist/skills/skills.controller.d.ts +4 -13
- package/dist/skills/skills.controller.js +8 -24
- package/dist/skills/skills.schemas.d.ts +48 -0
- package/dist/skills/skills.schemas.js +61 -0
- package/dist/skills/skills.service.d.ts +11 -1
- package/dist/skills/skills.service.js +37 -14
- package/dist/time-zone.d.ts +5 -0
- package/dist/time-zone.js +19 -0
- package/dist/tools/approvals.controller.js +2 -3
- package/dist/tools/approvals.schemas.d.ts +21 -0
- package/dist/tools/approvals.schemas.js +15 -0
- package/dist/tools/builtin-names.d.ts +10 -8
- package/dist/tools/builtin-names.js +16 -11
- package/dist/tools/builtins/builtin-tools.d.ts +3 -1
- package/dist/tools/builtins/builtin-tools.js +15 -3
- package/dist/tools/builtins/current-time.d.ts +26 -0
- package/dist/tools/builtins/current-time.js +99 -0
- package/dist/tools/builtins/platform.d.ts +19 -2
- package/dist/tools/builtins/platform.js +105 -16
- package/dist/tools/connectors.controller.d.ts +1 -2
- package/dist/tools/connectors.controller.js +1 -4
- package/dist/tools/connectors.schemas.d.ts +12 -0
- package/dist/tools/connectors.schemas.js +19 -0
- package/dist/tools/connectors.service.d.ts +5 -2
- package/dist/tools/connectors.service.js +7 -5
- package/dist/tools/org-tool-switches.d.ts +16 -2
- package/dist/tools/org-tool-switches.js +26 -9
- package/dist/tools/pipeline.js +3 -1
- package/dist/tools/registry.d.ts +48 -51
- package/dist/tools/registry.js +222 -233
- package/package.json +3 -3
- package/src/migrations/0090_initial_passwords.sql +27 -0
- package/src/migrations/0091_account_time_zone.sql +4 -0
- package/src/migrations/0092_tools_default_on.sql +27 -0
- package/dist/platform/redact-orgs.d.ts +0 -7
- package/dist/platform/redact-orgs.js +0 -52
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { RouteSchemas } from "../platform/route-schemas.js";
|
|
3
|
+
/**
|
|
4
|
+
* The fields of `POST /skills` before the either-or refinement: zod 4 cannot `pick` / `omit` a
|
|
5
|
+
* refined object, so operations build from these and the route validates {@link SkillCreateBody}.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SkillCreateFields: z.ZodObject<{
|
|
8
|
+
uploadId: z.ZodOptional<z.ZodString>;
|
|
9
|
+
name: z.ZodOptional<z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>>;
|
|
10
|
+
description: z.ZodOptional<z.ZodString>;
|
|
11
|
+
body: z.ZodOptional<z.ZodString>;
|
|
12
|
+
shareable: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
}, z.core.$strict>;
|
|
14
|
+
export declare const SkillCreateBody: z.ZodObject<{
|
|
15
|
+
uploadId: z.ZodOptional<z.ZodString>;
|
|
16
|
+
name: z.ZodOptional<z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>>;
|
|
17
|
+
description: z.ZodOptional<z.ZodString>;
|
|
18
|
+
body: z.ZodOptional<z.ZodString>;
|
|
19
|
+
shareable: z.ZodOptional<z.ZodBoolean>;
|
|
20
|
+
}, z.core.$strict>;
|
|
21
|
+
/** `:id` where the route validates it (`@ZParam`). */
|
|
22
|
+
export declare const SkillIdParams: z.ZodObject<{
|
|
23
|
+
id: z.ZodString;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
/** `:id` where the route takes it as is (`@Param`). */
|
|
26
|
+
export declare const SkillPathParams: z.ZodObject<{
|
|
27
|
+
id: z.ZodString;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
export declare const SkillShareableSchema: z.ZodObject<{
|
|
30
|
+
shareable: z.ZodBoolean;
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
/** `:id` of `GET /skill-changes/:id` (taken as is). */
|
|
33
|
+
export declare const SkillChangePathParams: z.ZodObject<{
|
|
34
|
+
id: z.ZodString;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
/** `:agentId` of the agent's skills and invocable skills routes (taken as is). */
|
|
37
|
+
export declare const AgentSkillsListParams: z.ZodObject<{
|
|
38
|
+
agentId: z.ZodString;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
export declare const AgentSkillPathParams: z.ZodObject<{
|
|
41
|
+
agentId: z.ZodString;
|
|
42
|
+
skillId: z.ZodString;
|
|
43
|
+
}, z.core.$strip>;
|
|
44
|
+
/** `?conversationId=` of `GET /agents/:agentId/invocable-skills`. */
|
|
45
|
+
export declare const InvocableSkillsQuerySchema: z.ZodObject<{
|
|
46
|
+
conversationId: z.ZodOptional<z.ZodString>;
|
|
47
|
+
}, z.core.$strict>;
|
|
48
|
+
export declare const SKILL_ROUTES: readonly RouteSchemas[];
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { isSkillName, SKILL_LIMITS } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { SKILL_WRITE_MAX_BYTES } from "../tools/builtins/skill-write.js";
|
|
4
|
+
/**
|
|
5
|
+
* The fields of `POST /skills` before the either-or refinement: zod 4 cannot `pick` / `omit` a
|
|
6
|
+
* refined object, so operations build from these and the route validates {@link SkillCreateBody}.
|
|
7
|
+
*/
|
|
8
|
+
export const SkillCreateFields = z
|
|
9
|
+
.object({
|
|
10
|
+
uploadId: z.string().min(1).max(100).optional(),
|
|
11
|
+
name: z
|
|
12
|
+
.string()
|
|
13
|
+
.refine(isSkillName, "name must be 1-64 lowercase letters, digits and single hyphens")
|
|
14
|
+
.optional(),
|
|
15
|
+
description: z.string().min(1).max(SKILL_LIMITS.descriptionMaxChars).optional(),
|
|
16
|
+
body: z.string().max(SKILL_WRITE_MAX_BYTES).optional(),
|
|
17
|
+
shareable: z.boolean().optional(),
|
|
18
|
+
})
|
|
19
|
+
.strict();
|
|
20
|
+
export const SkillCreateBody = SkillCreateFields.refine((v) => v.uploadId !== undefined
|
|
21
|
+
? v.name === undefined && v.description === undefined && v.body === undefined
|
|
22
|
+
: v.name !== undefined && v.description !== undefined && v.body !== undefined, "send either { uploadId } or { name, description, body }");
|
|
23
|
+
/** `:id` where the route validates it (`@ZParam`). */
|
|
24
|
+
export const SkillIdParams = z.object({ id: z.string().min(1).max(100) });
|
|
25
|
+
/** `:id` where the route takes it as is (`@Param`). */
|
|
26
|
+
export const SkillPathParams = z.object({ id: z.string().min(1) });
|
|
27
|
+
export const SkillShareableSchema = z.object({ shareable: z.boolean() }).strict();
|
|
28
|
+
/** `:id` of `GET /skill-changes/:id` (taken as is). */
|
|
29
|
+
export const SkillChangePathParams = z.object({ id: z.string().min(1).max(100) });
|
|
30
|
+
/** `:agentId` of the agent's skills and invocable skills routes (taken as is). */
|
|
31
|
+
export const AgentSkillsListParams = z.object({ agentId: z.string().min(1).max(100) });
|
|
32
|
+
export const AgentSkillPathParams = AgentSkillsListParams.extend({
|
|
33
|
+
skillId: z.string().min(1).max(100),
|
|
34
|
+
});
|
|
35
|
+
/** `?conversationId=` of `GET /agents/:agentId/invocable-skills`. */
|
|
36
|
+
export const InvocableSkillsQuerySchema = z
|
|
37
|
+
.object({ conversationId: z.string().min(1).max(100).optional() })
|
|
38
|
+
.strict();
|
|
39
|
+
export const SKILL_ROUTES = [
|
|
40
|
+
{ route: "GET /api/v1/orgs/:orgId/skill-changes/:id", params: SkillChangePathParams },
|
|
41
|
+
{ route: "GET /api/v1/orgs/:orgId/agents/:agentId/skills", params: AgentSkillsListParams },
|
|
42
|
+
{
|
|
43
|
+
route: "DELETE /api/v1/orgs/:orgId/agents/:agentId/skills/:skillId",
|
|
44
|
+
params: AgentSkillPathParams,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
route: "GET /api/v1/orgs/:orgId/agents/:agentId/invocable-skills",
|
|
48
|
+
params: AgentSkillsListParams,
|
|
49
|
+
query: InvocableSkillsQuerySchema,
|
|
50
|
+
},
|
|
51
|
+
{ route: "GET /api/v1/orgs/:orgId/skills" },
|
|
52
|
+
{ route: "GET /api/v1/orgs/:orgId/skills/:id", params: SkillPathParams },
|
|
53
|
+
{ route: "POST /api/v1/orgs/:orgId/skills", body: SkillCreateBody },
|
|
54
|
+
{
|
|
55
|
+
route: "PUT /api/v1/orgs/:orgId/skills/:id/shareable",
|
|
56
|
+
params: SkillIdParams,
|
|
57
|
+
body: SkillShareableSchema,
|
|
58
|
+
},
|
|
59
|
+
{ route: "GET /api/v1/orgs/:orgId/skills/:id/delete-preview", params: SkillIdParams },
|
|
60
|
+
{ route: "DELETE /api/v1/orgs/:orgId/skills/:id", params: SkillPathParams },
|
|
61
|
+
];
|
|
@@ -188,6 +188,16 @@ export declare class SkillsService {
|
|
|
188
188
|
* ({@link createVersionIn} joins it).
|
|
189
189
|
*/
|
|
190
190
|
private createUploadedVersionIn;
|
|
191
|
+
/**
|
|
192
|
+
* The read-only checks of {@link createFromText}, for the `Platform` tool's precheck (before the
|
|
193
|
+
* card): custom skills allowed, a valid `SKILL.md`, and no live org skill of the name. Throws the
|
|
194
|
+
* same `ApiError` the create would; the create checks the name again under its lock.
|
|
195
|
+
*/
|
|
196
|
+
checkCreateFromText(orgId: string, input: {
|
|
197
|
+
name: string;
|
|
198
|
+
description: string;
|
|
199
|
+
body: string;
|
|
200
|
+
}): Promise<void>;
|
|
191
201
|
/**
|
|
192
202
|
* Creates an org skill from text (spec §14, P3-24): `SKILL.md` is built from the name,
|
|
193
203
|
* description and body ({@link buildSkillWrite}, the description a YAML string) and checked like
|
|
@@ -285,5 +295,5 @@ export declare class SkillsService {
|
|
|
285
295
|
* (audit `skill.deleted`); missing or deleted -> `skill.not_found`. The owner delete of a
|
|
286
296
|
* promoted skill (`OwnedItems.deleteSkill`) calls it after its platform row was dealt with.
|
|
287
297
|
*/
|
|
288
|
-
deleteOrgSkillIn(orgId: string, skillId: string, actorAccountId: string, actorTokenId: string | undefined): Promise<void>;
|
|
298
|
+
deleteOrgSkillIn(orgId: string, skillId: string, actorAccountId: string, actorTokenId: string | undefined, auditDetail?: Record<string, unknown>): Promise<void>;
|
|
289
299
|
}
|
|
@@ -126,6 +126,19 @@ const PUT_CONCURRENCY = 4;
|
|
|
126
126
|
/** 详情里读取 SKILL.md 正文的上限。 */
|
|
127
127
|
export const SKILL_BODY_MAX_BYTES = 1024 * 1024;
|
|
128
128
|
const notFound = () => new ApiError("skill.not_found", "Skill not found");
|
|
129
|
+
const nameExists = (name) => new ApiError("skill.name_exists", `A skill named "${name}" already exists in this organization. Choose another name.`);
|
|
130
|
+
/** The checked files of a skill written as text (a built `SKILL.md`); `validation_failed` if not. */
|
|
131
|
+
function textSkillFiles(input) {
|
|
132
|
+
const built = buildSkillWrite({
|
|
133
|
+
name: input.name,
|
|
134
|
+
description: input.description,
|
|
135
|
+
files: [{ path: SKILL_ENTRY_FILE, content: input.body }],
|
|
136
|
+
});
|
|
137
|
+
if ("errors" in built) {
|
|
138
|
+
throw new ApiError("validation_failed", `Invalid skill: ${built.errors[0] ?? "unknown problem"}`, built.errors.map((message) => ({ path: "body", message })));
|
|
139
|
+
}
|
|
140
|
+
return checkBuiltSkillFiles(built.files);
|
|
141
|
+
}
|
|
129
142
|
/**
|
|
130
143
|
* 在调用方事务里核对 agent 定义引用的组织技能:每个 id 都必须是该组织未删除的 `scope=org` 技能
|
|
131
144
|
* (or, phase 2, a platform skill on in the org: skills/usable.ts),
|
|
@@ -449,6 +462,25 @@ let SkillsService = class SkillsService {
|
|
|
449
462
|
...(owner !== undefined && { owner }),
|
|
450
463
|
});
|
|
451
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* The read-only checks of {@link createFromText}, for the `Platform` tool's precheck (before the
|
|
467
|
+
* card): custom skills allowed, a valid `SKILL.md`, and no live org skill of the name. Throws the
|
|
468
|
+
* same `ApiError` the create would; the create checks the name again under its lock.
|
|
469
|
+
*/
|
|
470
|
+
async checkCreateFromText(orgId, input) {
|
|
471
|
+
await assertCustomAllowed(this.db.db, "customSkills");
|
|
472
|
+
const pkg = textSkillFiles(input);
|
|
473
|
+
const existing = await this.db
|
|
474
|
+
.selectFrom("skills")
|
|
475
|
+
.select("id")
|
|
476
|
+
.where("org_id", "=", orgId)
|
|
477
|
+
.where("scope", "=", "org")
|
|
478
|
+
.where("name", "=", pkg.name)
|
|
479
|
+
.where("deleted_at", "is", null)
|
|
480
|
+
.executeTakeFirst();
|
|
481
|
+
if (existing)
|
|
482
|
+
throw nameExists(pkg.name);
|
|
483
|
+
}
|
|
452
484
|
/**
|
|
453
485
|
* Creates an org skill from text (spec §14, P3-24): `SKILL.md` is built from the name,
|
|
454
486
|
* description and body ({@link buildSkillWrite}, the description a YAML string) and checked like
|
|
@@ -458,15 +490,7 @@ let SkillsService = class SkillsService {
|
|
|
458
490
|
async createFromText(orgId, actorAccountId, input) {
|
|
459
491
|
this.storage.assertAvailable();
|
|
460
492
|
await assertCustomAllowed(this.db.db, "customSkills");
|
|
461
|
-
const
|
|
462
|
-
name: input.name,
|
|
463
|
-
description: input.description,
|
|
464
|
-
files: [{ path: SKILL_ENTRY_FILE, content: input.body }],
|
|
465
|
-
});
|
|
466
|
-
if ("errors" in built) {
|
|
467
|
-
throw new ApiError("validation_failed", `Invalid skill: ${built.errors[0] ?? "unknown problem"}`, built.errors.map((message) => ({ path: "body", message })));
|
|
468
|
-
}
|
|
469
|
-
const pkg = checkBuiltSkillFiles(built.files);
|
|
493
|
+
const pkg = textSkillFiles(input);
|
|
470
494
|
const prefix = skillFilesPrefix(randomUUID());
|
|
471
495
|
await this.putFiles(orgId, prefix, pkg.files);
|
|
472
496
|
return this.createVersionIn(orgId, actorAccountId, pkg, skillManifest(pkg), prefix, {
|
|
@@ -533,9 +557,8 @@ let SkillsService = class SkillsService {
|
|
|
533
557
|
.where("deleted_at", "is", null)
|
|
534
558
|
.forUpdate()
|
|
535
559
|
.executeTakeFirst();
|
|
536
|
-
if (existing && opts.failIfExists)
|
|
537
|
-
throw
|
|
538
|
-
}
|
|
560
|
+
if (existing && opts.failIfExists)
|
|
561
|
+
throw nameExists(pkg.name);
|
|
539
562
|
// The org's own skill it promoted (ruling P3-3): its new version goes to the platform row and
|
|
540
563
|
// reaches every org using it (ruling P3-4); the files were written there before this
|
|
541
564
|
// transaction, for the platform version current then
|
|
@@ -904,7 +927,7 @@ let SkillsService = class SkillsService {
|
|
|
904
927
|
* (audit `skill.deleted`); missing or deleted -> `skill.not_found`. The owner delete of a
|
|
905
928
|
* promoted skill (`OwnedItems.deleteSkill`) calls it after its platform row was dealt with.
|
|
906
929
|
*/
|
|
907
|
-
async deleteOrgSkillIn(orgId, skillId, actorAccountId, actorTokenId) {
|
|
930
|
+
async deleteOrgSkillIn(orgId, skillId, actorAccountId, actorTokenId, auditDetail) {
|
|
908
931
|
const r = await this.db
|
|
909
932
|
.updateTable("skills")
|
|
910
933
|
.set({ deleted_at: sql `now()`, updated_at: sql `now()` })
|
|
@@ -922,7 +945,7 @@ let SkillsService = class SkillsService {
|
|
|
922
945
|
orgId,
|
|
923
946
|
action: "skill.deleted",
|
|
924
947
|
target: skillId,
|
|
925
|
-
detail: { name: r.name },
|
|
948
|
+
detail: { name: r.name, ...auditDetail },
|
|
926
949
|
});
|
|
927
950
|
}
|
|
928
951
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Whether `tz` is an IANA time zone this runtime knows (run context spec §3.3, §3.4). */
|
|
3
|
+
export declare function isTimeZone(tz: string): boolean;
|
|
4
|
+
/** An IANA time zone name, checked with `Intl.DateTimeFormat`. */
|
|
5
|
+
export declare const IanaTimeZone: z.ZodString;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Whether `tz` is an IANA time zone this runtime knows (run context spec §3.3, §3.4). */
|
|
3
|
+
export function isTimeZone(tz) {
|
|
4
|
+
if (tz === "" || tz.length > 64)
|
|
5
|
+
return false;
|
|
6
|
+
try {
|
|
7
|
+
new Intl.DateTimeFormat("en", { timeZone: tz });
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** An IANA time zone name, checked with `Intl.DateTimeFormat`. */
|
|
15
|
+
export const IanaTimeZone = z
|
|
16
|
+
.string()
|
|
17
|
+
.min(1)
|
|
18
|
+
.max(64)
|
|
19
|
+
.refine(isTimeZone, "must be an IANA time zone name, such as Asia/Shanghai");
|
|
@@ -14,10 +14,9 @@ import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
|
14
14
|
import { ZBody, ZQuery } from "../infra/validation/zod-params.js";
|
|
15
15
|
import { CurrentOrg, OrgAction } from "../orgs/org.guard.js";
|
|
16
16
|
import { CONTROL_OR_HIDDEN_RE } from "../text.js";
|
|
17
|
+
import { ApprovalsListQuerySchema } from "./approvals.schemas.js";
|
|
17
18
|
import { APPROVAL_DENY_REASON_MAX_CHARS, ApprovalsService, } from "./approvals.service.js";
|
|
18
|
-
const ListQuery =
|
|
19
|
-
.object({ status: z.enum(["pending", "approved", "denied", "expired", "cancelled"]).optional() })
|
|
20
|
-
.strict();
|
|
19
|
+
const ListQuery = ApprovalsListQuerySchema;
|
|
21
20
|
const DecisionBody = z
|
|
22
21
|
.object({
|
|
23
22
|
decision: z.enum(["approve", "deny"]),
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { RouteSchemas } from "../platform/route-schemas.js";
|
|
3
|
+
/** `GET /approvals?status=`: absent lists every status. */
|
|
4
|
+
export declare const ApprovalsListQuerySchema: z.ZodObject<{
|
|
5
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
6
|
+
approved: "approved";
|
|
7
|
+
cancelled: "cancelled";
|
|
8
|
+
denied: "denied";
|
|
9
|
+
expired: "expired";
|
|
10
|
+
pending: "pending";
|
|
11
|
+
}>>;
|
|
12
|
+
}, z.core.$strict>;
|
|
13
|
+
/** `:id` of `GET /approvals/:id`, as the route takes it (`@Param`). */
|
|
14
|
+
export declare const ApprovalPathParams: z.ZodObject<{
|
|
15
|
+
id: z.ZodString;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
/**
|
|
18
|
+
* The approval reads a Platform operation mirrors. Deciding (`POST /approvals/:id/decision`) is a
|
|
19
|
+
* person's act and stays excluded (spec §6.4, §14.1 item 2), so it has no entry here.
|
|
20
|
+
*/
|
|
21
|
+
export declare const APPROVAL_ROUTES: readonly RouteSchemas[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** `GET /approvals?status=`: absent lists every status. */
|
|
3
|
+
export const ApprovalsListQuerySchema = z
|
|
4
|
+
.object({ status: z.enum(["pending", "approved", "denied", "expired", "cancelled"]).optional() })
|
|
5
|
+
.strict();
|
|
6
|
+
/** `:id` of `GET /approvals/:id`, as the route takes it (`@Param`). */
|
|
7
|
+
export const ApprovalPathParams = z.object({ id: z.string() });
|
|
8
|
+
/**
|
|
9
|
+
* The approval reads a Platform operation mirrors. Deciding (`POST /approvals/:id/decision`) is a
|
|
10
|
+
* person's act and stays excluded (spec §6.4, §14.1 item 2), so it has no entry here.
|
|
11
|
+
*/
|
|
12
|
+
export const APPROVAL_ROUTES = [
|
|
13
|
+
{ route: "GET /api/v1/orgs/:orgId/approvals", query: ApprovalsListQuerySchema },
|
|
14
|
+
{ route: "GET /api/v1/orgs/:orgId/approvals/:id", params: ApprovalPathParams },
|
|
15
|
+
];
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { AgentToolRef } from "../agents/definition.js";
|
|
2
1
|
import type { ToolKind } from "./info.js";
|
|
3
2
|
/**
|
|
4
3
|
* The names (model-visible keys) of the kernel's builtin tools, following Claude Code (tool naming
|
|
@@ -28,6 +27,7 @@ export declare const BUILTIN: {
|
|
|
28
27
|
readonly WebSearch: "WebSearch";
|
|
29
28
|
readonly WebFetch: "WebFetch";
|
|
30
29
|
readonly Platform: "Platform";
|
|
30
|
+
readonly CurrentTime: "CurrentTime";
|
|
31
31
|
};
|
|
32
32
|
export type BuiltinName = (typeof BUILTIN)[keyof typeof BUILTIN];
|
|
33
33
|
/**
|
|
@@ -49,12 +49,13 @@ export declare const BASH_COMPANION_TOOLS: readonly BuiltinName[];
|
|
|
49
49
|
*/
|
|
50
50
|
export declare const SANDBOX_ASK_TOOL_NAMES: ReadonlySet<string>;
|
|
51
51
|
/**
|
|
52
|
-
* Every builtin name. Saving an agent checks
|
|
53
|
-
* registered now, so the order the implementations land in never affects a saved
|
|
54
|
-
*
|
|
52
|
+
* Every builtin name. Saving an agent checks turned-off builtins against this list, not against
|
|
53
|
+
* what is registered now, so the order the implementations land in never affects a saved
|
|
54
|
+
* definition. `ToolSearch` and `Skill` are added
|
|
55
55
|
* by the registry; `Agent` dispatches sub-agents and its description is built per agent;
|
|
56
56
|
* `SendMessage` and `SubagentHandback` are added by the registry ({@link SUBAGENT_MESSAGE_TOOLS}).
|
|
57
57
|
* `Platform` calls the platform's own operations as the run's person (Platform tool spec).
|
|
58
|
+
* `CurrentTime` reads the clock (the run context carries only the date).
|
|
58
59
|
*/
|
|
59
60
|
export declare const BUILTIN_TOOL_NAMES: readonly BuiltinName[];
|
|
60
61
|
/** The builtin that loads a skill (added by the registry when the log has a skills catalog). */
|
|
@@ -91,11 +92,12 @@ export declare const R3_SHARED_AGENT_ONLY_TOOL_KEYS: ReadonlySet<string>;
|
|
|
91
92
|
*/
|
|
92
93
|
export declare const CHILD_REMOVED_TOOLS: readonly ["AskUserQuestion", "Deliver", "SkillWrite"];
|
|
93
94
|
/**
|
|
94
|
-
* The
|
|
95
|
-
*
|
|
96
|
-
* `
|
|
95
|
+
* The builtins every agent has unless it turns them off (tools default-on spec §4), in this
|
|
96
|
+
* order: {@link BUILTIN_TOOL_NAMES} without the ones the registry manages by rule (`ToolSearch`,
|
|
97
|
+
* `Skill`, `SendMessage`, `SubagentHandback`) and without `TaskOutput` / `TaskStop`, which come
|
|
98
|
+
* with `Bash` ({@link BASH_COMPANION_TOOLS}). These are also the builtins an agent can turn off.
|
|
97
99
|
*/
|
|
98
|
-
export declare const
|
|
100
|
+
export declare const AGENT_BUILTIN_NAMES: readonly BuiltinName[];
|
|
99
101
|
/** Kinds of the builtin tools (display only); a builtin missing here is a plain `tool`. */
|
|
100
102
|
export declare const BUILTIN_TOOL_KINDS: Readonly<Record<string, ToolKind>>;
|
|
101
103
|
/**
|
|
@@ -26,6 +26,7 @@ export const BUILTIN = {
|
|
|
26
26
|
WebSearch: "WebSearch",
|
|
27
27
|
WebFetch: "WebFetch",
|
|
28
28
|
Platform: "Platform",
|
|
29
|
+
CurrentTime: "CurrentTime",
|
|
29
30
|
};
|
|
30
31
|
/**
|
|
31
32
|
* The builtin tools that run in the conversation's sandbox. `TaskOutput` and `TaskStop` read and
|
|
@@ -61,12 +62,13 @@ export const SANDBOX_ASK_TOOL_NAMES = new Set([
|
|
|
61
62
|
BUILTIN.Deliver,
|
|
62
63
|
]);
|
|
63
64
|
/**
|
|
64
|
-
* Every builtin name. Saving an agent checks
|
|
65
|
-
* registered now, so the order the implementations land in never affects a saved
|
|
66
|
-
*
|
|
65
|
+
* Every builtin name. Saving an agent checks turned-off builtins against this list, not against
|
|
66
|
+
* what is registered now, so the order the implementations land in never affects a saved
|
|
67
|
+
* definition. `ToolSearch` and `Skill` are added
|
|
67
68
|
* by the registry; `Agent` dispatches sub-agents and its description is built per agent;
|
|
68
69
|
* `SendMessage` and `SubagentHandback` are added by the registry ({@link SUBAGENT_MESSAGE_TOOLS}).
|
|
69
70
|
* `Platform` calls the platform's own operations as the run's person (Platform tool spec).
|
|
71
|
+
* `CurrentTime` reads the clock (the run context carries only the date).
|
|
70
72
|
*/
|
|
71
73
|
export const BUILTIN_TOOL_NAMES = [
|
|
72
74
|
BUILTIN.AskUserQuestion,
|
|
@@ -80,6 +82,7 @@ export const BUILTIN_TOOL_NAMES = [
|
|
|
80
82
|
BUILTIN.SubagentHandback,
|
|
81
83
|
...WEB_TOOL_NAMES,
|
|
82
84
|
BUILTIN.Platform,
|
|
85
|
+
BUILTIN.CurrentTime,
|
|
83
86
|
];
|
|
84
87
|
/** The builtin that loads a skill (added by the registry when the log has a skills catalog). */
|
|
85
88
|
export const SKILL_LOAD = BUILTIN.Skill;
|
|
@@ -124,15 +127,16 @@ export const CHILD_REMOVED_TOOLS = [
|
|
|
124
127
|
BUILTIN.SkillWrite,
|
|
125
128
|
];
|
|
126
129
|
/**
|
|
127
|
-
* The
|
|
128
|
-
*
|
|
129
|
-
* `
|
|
130
|
+
* The builtins every agent has unless it turns them off (tools default-on spec §4), in this
|
|
131
|
+
* order: {@link BUILTIN_TOOL_NAMES} without the ones the registry manages by rule (`ToolSearch`,
|
|
132
|
+
* `Skill`, `SendMessage`, `SubagentHandback`) and without `TaskOutput` / `TaskStop`, which come
|
|
133
|
+
* with `Bash` ({@link BASH_COMPANION_TOOLS}). These are also the builtins an agent can turn off.
|
|
130
134
|
*/
|
|
131
|
-
export const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
export const AGENT_BUILTIN_NAMES = BUILTIN_TOOL_NAMES.filter((n) => n !== BUILTIN.ToolSearch &&
|
|
136
|
+
n !== BUILTIN.Skill &&
|
|
137
|
+
n !== BUILTIN.SendMessage &&
|
|
138
|
+
n !== BUILTIN.SubagentHandback &&
|
|
139
|
+
!BASH_COMPANION_TOOLS.includes(n));
|
|
136
140
|
/** Kinds of the builtin tools (display only); a builtin missing here is a plain `tool`. */
|
|
137
141
|
export const BUILTIN_TOOL_KINDS = {
|
|
138
142
|
[BUILTIN.Bash]: "command",
|
|
@@ -154,6 +158,7 @@ export const BUILTIN_TOOL_KINDS = {
|
|
|
154
158
|
[BUILTIN.WebSearch]: "search",
|
|
155
159
|
[BUILTIN.WebFetch]: "read",
|
|
156
160
|
[BUILTIN.Platform]: "tool",
|
|
161
|
+
[BUILTIN.CurrentTime]: "tool",
|
|
157
162
|
};
|
|
158
163
|
/**
|
|
159
164
|
* Input fields left out when matching a replayed call with a recorded one (full-run replay), per
|
|
@@ -33,7 +33,9 @@ export declare class BuiltinTools {
|
|
|
33
33
|
/** The WebFetch extraction call: the `web_fetch` purpose, its hooks, usage and denials. */
|
|
34
34
|
purposes: ModelPurposesService, host: {
|
|
35
35
|
readonly hooks?: HookRunner;
|
|
36
|
-
} | undefined, usageReport: UsageReporter, stepLog: StepLog, log: Logger, background: BackgroundTaskStore, finisher: BackgroundTaskFinisher, stopper: BackgroundTaskStopper, platformOps: PlatformOperations, platformActor: PlatformActor, agentDocs: AgentDocs
|
|
36
|
+
} | undefined, usageReport: UsageReporter, stepLog: StepLog, log: Logger, background: BackgroundTaskStore, finisher: BackgroundTaskFinisher, stopper: BackgroundTaskStopper, platformOps: PlatformOperations, platformActor: PlatformActor, agentDocs: AgentDocs,
|
|
37
|
+
/** The clock `CurrentTime` reads (the run context's clock seam; `Date.now` by default). */
|
|
38
|
+
now?: () => number);
|
|
37
39
|
/** The builtin tools, in a fixed order. */
|
|
38
40
|
list(): readonly BuiltinTool[];
|
|
39
41
|
}
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Inject, Injectable } from "@nestjs/common";
|
|
10
|
+
import { Inject, Injectable, Optional } from "@nestjs/common";
|
|
11
11
|
import { BackgroundTaskFinisher } from "../../background/finish.js";
|
|
12
12
|
import { BackgroundTaskStopper } from "../../background/stop.js";
|
|
13
13
|
import { BackgroundTaskStore } from "../../background/store.js";
|
|
@@ -24,6 +24,7 @@ import { readOrgSettings } from "../../orgs/settings.service.js";
|
|
|
24
24
|
import { PlatformActor } from "../../platform/actor.js";
|
|
25
25
|
import { AgentDocs } from "../../platform/agent-docs.js";
|
|
26
26
|
import { PlatformOperations } from "../../platform/registry.js";
|
|
27
|
+
import { conversationTimeZone, RUN_CONTEXT_CLOCK } from "../../runtime/run-context.service.js";
|
|
27
28
|
import { StepLog } from "../../runtime/step-log.js";
|
|
28
29
|
import { UsageReporter } from "../../runtime/usage-report.js";
|
|
29
30
|
import { SandboxService } from "../../sandbox/sandbox.service.js";
|
|
@@ -32,6 +33,7 @@ import { StorageService } from "../../storage/storage.service.js";
|
|
|
32
33
|
import { ToolOutputs } from "../outputs.js";
|
|
33
34
|
import { agentTool } from "./agent.js";
|
|
34
35
|
import { askUserTool } from "./ask-user.js";
|
|
36
|
+
import { currentTimeTool } from "./current-time.js";
|
|
35
37
|
import { handbackTool } from "./handback.js";
|
|
36
38
|
import { platformTool } from "./platform.js";
|
|
37
39
|
import { readToolOutputTool } from "./read-tool-output.js";
|
|
@@ -51,7 +53,9 @@ let BuiltinTools = class BuiltinTools {
|
|
|
51
53
|
tools;
|
|
52
54
|
constructor(db, config, outputs, storage, skillChanges, attachments, eventLog, sandbox, environments, points, webPages,
|
|
53
55
|
/** The WebFetch extraction call: the `web_fetch` purpose, its hooks, usage and denials. */
|
|
54
|
-
purposes, host, usageReport, stepLog, log, background, finisher, stopper, platformOps, platformActor, agentDocs
|
|
56
|
+
purposes, host, usageReport, stepLog, log, background, finisher, stopper, platformOps, platformActor, agentDocs,
|
|
57
|
+
/** The clock `CurrentTime` reads (the run context's clock seam; `Date.now` by default). */
|
|
58
|
+
now) {
|
|
55
59
|
const sandboxDeps = {
|
|
56
60
|
sandbox,
|
|
57
61
|
environments,
|
|
@@ -101,6 +105,12 @@ let BuiltinTools = class BuiltinTools {
|
|
|
101
105
|
actor: platformActor,
|
|
102
106
|
docs: agentDocs,
|
|
103
107
|
setting: async (orgId) => (await readOrgSettings(db.db, orgId)).platformTool,
|
|
108
|
+
log,
|
|
109
|
+
}),
|
|
110
|
+
// the clock in the run context's time zone (the run context carries only the date)
|
|
111
|
+
currentTimeTool({
|
|
112
|
+
now: now ?? Date.now,
|
|
113
|
+
timeZoneOf: ({ orgId, conversationId }) => conversationTimeZone(db.db, orgId, conversationId),
|
|
104
114
|
}),
|
|
105
115
|
];
|
|
106
116
|
}
|
|
@@ -132,6 +142,8 @@ BuiltinTools = __decorate([
|
|
|
132
142
|
__param(18, Inject(BackgroundTaskStopper)),
|
|
133
143
|
__param(19, Inject(PlatformOperations)),
|
|
134
144
|
__param(20, Inject(PlatformActor)),
|
|
135
|
-
__param(21, Inject(AgentDocs))
|
|
145
|
+
__param(21, Inject(AgentDocs)),
|
|
146
|
+
__param(22, Optional()),
|
|
147
|
+
__param(22, Inject(RUN_CONTEXT_CLOCK))
|
|
136
148
|
], BuiltinTools);
|
|
137
149
|
export { BuiltinTools };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { BuiltinTool } from "../registry.js";
|
|
2
|
+
/** An unknown zone: what was wrong and how to call again. */
|
|
3
|
+
export declare const unknownTimeZoneText: (zone: string) => string;
|
|
4
|
+
/** The local wall clock of `now` in `timeZone`, with its offset from UTC. */
|
|
5
|
+
export interface LocalTime {
|
|
6
|
+
/** `YYYY-MM-DDTHH:mm:ss±HH:MM`. */
|
|
7
|
+
local: string;
|
|
8
|
+
weekday: string;
|
|
9
|
+
/** `+08:00`, `-05:00`, `+00:00`. */
|
|
10
|
+
offset: string;
|
|
11
|
+
/** `YYYY-MM-DDTHH:mm:ssZ`. */
|
|
12
|
+
utc: string;
|
|
13
|
+
}
|
|
14
|
+
/** Formats `now` in `timeZone` (a zone {@link isTimeZone} accepts). Seconds precision. */
|
|
15
|
+
export declare function localTime(now: Date, timeZone: string): LocalTime;
|
|
16
|
+
export interface CurrentTimeDeps {
|
|
17
|
+
/** The clock (epoch ms): the kernel's `RUN_CONTEXT_CLOCK` seam, `Date.now` by default. */
|
|
18
|
+
now: () => number;
|
|
19
|
+
/** The conversation's time zone (its run context's, else the org default, else UTC). */
|
|
20
|
+
timeZoneOf: (ctx: {
|
|
21
|
+
orgId: string;
|
|
22
|
+
conversationId: string;
|
|
23
|
+
}) => Promise<string>;
|
|
24
|
+
}
|
|
25
|
+
/** The `CurrentTime` builtin. */
|
|
26
|
+
export declare function currentTimeTool(deps: CurrentTimeDeps): BuiltinTool;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ToolError } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { isTimeZone } from "../../time-zone.js";
|
|
4
|
+
import { BUILTIN } from "../builtin-names.js";
|
|
5
|
+
/**
|
|
6
|
+
* The `CurrentTime` builtin: the current local date-time in a time zone. The run context gives the
|
|
7
|
+
* model the date only (day granularity, run context spec §3), so the time of day, durations and
|
|
8
|
+
* other zones come from this tool. Read-only, no side effects: `defaultPolicy` is allow. The
|
|
9
|
+
* result goes into the log like any tool result, so replays read the recorded answer.
|
|
10
|
+
*/
|
|
11
|
+
const SPEC = {
|
|
12
|
+
name: BUILTIN.CurrentTime,
|
|
13
|
+
description: "Get the current time: the local date and time with its UTC offset, the weekday, the time " +
|
|
14
|
+
"zone and the UTC instant. Today's date is already in your context; call this when you need " +
|
|
15
|
+
"the time of day, to work out a duration or how long ago something happened, or to know the " +
|
|
16
|
+
"time in another time zone. Without timeZone it uses the time zone of the person you work " +
|
|
17
|
+
"for. Read-only, no side effects.",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
timeZone: {
|
|
22
|
+
type: "string",
|
|
23
|
+
minLength: 1,
|
|
24
|
+
maxLength: 64,
|
|
25
|
+
description: "An IANA time zone name, e.g. Asia/Shanghai, America/New_York or UTC. Omit it to use " +
|
|
26
|
+
"the time zone of the person you work for.",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
const Input = z.object({ timeZone: z.string().min(1).max(64).optional() }).strict();
|
|
33
|
+
/** An unknown zone: what was wrong and how to call again. */
|
|
34
|
+
export const unknownTimeZoneText = (zone) => `Unknown time zone '${zone}'; use an IANA name such as Asia/Shanghai or America/New_York, ` +
|
|
35
|
+
"or omit timeZone to use the time zone of the person you work for.";
|
|
36
|
+
/** The input did not parse (the schema check runs first, so this is a guard). */
|
|
37
|
+
const INVALID_INPUT_TEXT = "Invalid input; pass an object with an optional timeZone string (an IANA name such as Asia/Shanghai).";
|
|
38
|
+
const pad = (n, w = 2) => String(n).padStart(w, "0");
|
|
39
|
+
/** Formats `now` in `timeZone` (a zone {@link isTimeZone} accepts). Seconds precision. */
|
|
40
|
+
export function localTime(now, timeZone) {
|
|
41
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
42
|
+
timeZone,
|
|
43
|
+
year: "numeric",
|
|
44
|
+
month: "2-digit",
|
|
45
|
+
day: "2-digit",
|
|
46
|
+
hour: "2-digit",
|
|
47
|
+
minute: "2-digit",
|
|
48
|
+
second: "2-digit",
|
|
49
|
+
weekday: "long",
|
|
50
|
+
hourCycle: "h23",
|
|
51
|
+
}).formatToParts(now);
|
|
52
|
+
const part = (type) => parts.find((p) => p.type === type)?.value ?? "";
|
|
53
|
+
const [y, mo, d, h, mi, s] = ["year", "month", "day", "hour", "minute", "second"].map((t) => Number(part(t)));
|
|
54
|
+
const seconds = Math.floor(now.getTime() / 1000) * 1000;
|
|
55
|
+
// the zone's offset: the wall clock read as if it were UTC, minus the instant
|
|
56
|
+
const offsetMin = Math.round((Date.UTC(y, mo - 1, d, h, mi, s) - seconds) / 60_000);
|
|
57
|
+
const abs = Math.abs(offsetMin);
|
|
58
|
+
const offset = `${offsetMin < 0 ? "-" : "+"}${pad(Math.floor(abs / 60))}:${pad(abs % 60)}`;
|
|
59
|
+
return {
|
|
60
|
+
local: `${pad(y, 4)}-${pad(mo)}-${pad(d)}T${pad(h)}:${pad(mi)}:${pad(s)}${offset}`,
|
|
61
|
+
weekday: part("weekday"),
|
|
62
|
+
offset,
|
|
63
|
+
utc: `${new Date(seconds).toISOString().slice(0, 19)}Z`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/** The `CurrentTime` builtin. */
|
|
67
|
+
export function currentTimeTool(deps) {
|
|
68
|
+
return {
|
|
69
|
+
spec: SPEC,
|
|
70
|
+
defaultPolicy: "allow",
|
|
71
|
+
async run(input, ctx) {
|
|
72
|
+
const parsed = Input.safeParse(input ?? {});
|
|
73
|
+
if (!parsed.success)
|
|
74
|
+
throw new ToolError(INVALID_INPUT_TEXT);
|
|
75
|
+
const asked = parsed.data.timeZone?.trim();
|
|
76
|
+
if (asked !== undefined && !isTimeZone(asked)) {
|
|
77
|
+
throw new ToolError(unknownTimeZoneText(asked));
|
|
78
|
+
}
|
|
79
|
+
const zone = asked ?? (await deps.timeZoneOf({ orgId: ctx.orgId, conversationId: ctx.conversationId }));
|
|
80
|
+
const t = localTime(new Date(deps.now()), zone);
|
|
81
|
+
const text = `Current time: ${t.local} (${t.weekday})\n` +
|
|
82
|
+
`Time zone: ${zone} (UTC${t.offset})\n` +
|
|
83
|
+
`UTC: ${t.utc}`;
|
|
84
|
+
// the row's key argument already shows a zone the model passed; the summary then gives the
|
|
85
|
+
// time alone, and names the zone only when it came from the run context
|
|
86
|
+
const hm = t.local.slice(11, 16);
|
|
87
|
+
const where = asked === undefined ? { zh: `(${zone})`, en: ` (${zone})` } : { zh: "", en: "" };
|
|
88
|
+
return {
|
|
89
|
+
content: [{ type: "text", text }],
|
|
90
|
+
display: {
|
|
91
|
+
summary: {
|
|
92
|
+
zh: `已获取当前时间 · ${hm}${where.zh}`,
|
|
93
|
+
en: `Got the current time · ${hm}${where.en}`,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|