comisai 1.0.25 → 1.0.26
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/node_modules/@comis/agent/dist/bootstrap/sections/tool-descriptions.js +130 -10
- package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.d.ts +1 -1
- package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.js +9 -2
- package/node_modules/@comis/agent/dist/bridge/bridge-metrics.d.ts +8 -0
- package/node_modules/@comis/agent/dist/bridge/bridge-metrics.js +2 -0
- package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +29 -0
- package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +242 -2
- package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.d.ts +210 -0
- package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.js +566 -0
- package/node_modules/@comis/agent/dist/context-engine/context-engine.js +8 -6
- package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +51 -30
- package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +109 -36
- package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.js +5 -1
- package/node_modules/@comis/agent/dist/executor/executor-post-execution.js +22 -20
- package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.d.ts +2 -0
- package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +111 -15
- package/node_modules/@comis/agent/dist/executor/executor-response-filter.d.ts +20 -17
- package/node_modules/@comis/agent/dist/executor/executor-response-filter.js +132 -52
- package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +16 -3
- package/node_modules/@comis/agent/dist/executor/model-retry.d.ts +14 -0
- package/node_modules/@comis/agent/dist/executor/model-retry.js +72 -1
- package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +3 -0
- package/node_modules/@comis/agent/dist/executor/pi-executor.js +68 -9
- package/node_modules/@comis/agent/dist/executor/post-batch-continuation.d.ts +82 -0
- package/node_modules/@comis/agent/dist/executor/post-batch-continuation.js +200 -0
- package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.js +1 -9
- package/node_modules/@comis/agent/dist/executor/tool-deferral.d.ts +37 -2
- package/node_modules/@comis/agent/dist/executor/tool-deferral.js +45 -3
- package/node_modules/@comis/agent/dist/executor/tool-parallelism.js +0 -1
- package/node_modules/@comis/agent/dist/executor/types.d.ts +11 -2
- package/node_modules/@comis/agent/dist/index.d.ts +3 -1
- package/node_modules/@comis/agent/dist/index.js +2 -0
- package/node_modules/@comis/agent/dist/model/last-known-model.d.ts +36 -0
- package/node_modules/@comis/agent/dist/model/last-known-model.js +49 -0
- package/node_modules/@comis/agent/dist/model/model-registry-adapter.d.ts +16 -4
- package/node_modules/@comis/agent/dist/model/model-registry-adapter.js +65 -21
- package/node_modules/@comis/agent/dist/planner/types.d.ts +0 -2
- package/node_modules/@comis/agent/dist/session/comis-session-manager.d.ts +10 -0
- package/node_modules/@comis/agent/dist/session/comis-session-manager.js +5 -0
- package/node_modules/@comis/agent/dist/spawn/pi-mono-adapters.js +7 -0
- package/node_modules/@comis/agent/package.json +1 -1
- package/node_modules/@comis/channels/package.json +1 -1
- package/node_modules/@comis/cli/dist/client/rpc-client.js +6 -1
- package/node_modules/@comis/cli/dist/commands/doctor.js +5 -3
- package/node_modules/@comis/cli/dist/commands/health.js +5 -2
- package/node_modules/@comis/cli/dist/wizard/json-output.js +7 -3
- package/node_modules/@comis/cli/dist/wizard/steps/11-daemon-start.js +130 -0
- package/node_modules/@comis/cli/package.json +1 -1
- package/node_modules/@comis/core/dist/config/immutable-keys.d.ts +2 -2
- package/node_modules/@comis/core/dist/config/immutable-keys.js +8 -3
- package/node_modules/@comis/core/dist/config/managed-sections.d.ts +43 -4
- package/node_modules/@comis/core/dist/config/managed-sections.js +100 -6
- package/node_modules/@comis/core/dist/config/schema-agent.d.ts +39 -0
- package/node_modules/@comis/core/dist/config/schema-agent.js +14 -0
- package/node_modules/@comis/core/dist/config/schema.d.ts +4 -0
- package/node_modules/@comis/core/dist/config/schema.js +14 -0
- package/node_modules/@comis/core/dist/domain/execution-graph.d.ts +1 -1
- package/node_modules/@comis/core/dist/event-bus/events-agent.d.ts +17 -2
- package/node_modules/@comis/core/dist/exports/config.d.ts +2 -2
- package/node_modules/@comis/core/dist/exports/config.js +1 -1
- package/node_modules/@comis/core/package.json +1 -1
- package/node_modules/@comis/daemon/dist/daemon.d.ts +22 -0
- package/node_modules/@comis/daemon/dist/daemon.js +42 -0
- package/node_modules/@comis/daemon/dist/rpc/agent-handlers.d.ts +5 -2
- package/node_modules/@comis/daemon/dist/rpc/agent-handlers.js +80 -1
- package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.d.ts +67 -0
- package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.js +139 -0
- package/node_modules/@comis/daemon/dist/rpc/model-handlers.d.ts +3 -0
- package/node_modules/@comis/daemon/dist/rpc/model-handlers.js +29 -5
- package/node_modules/@comis/daemon/dist/rpc/probe-provider-auth.d.ts +30 -0
- package/node_modules/@comis/daemon/dist/rpc/probe-provider-auth.js +59 -0
- package/node_modules/@comis/daemon/dist/rpc/provider-handlers.d.ts +37 -0
- package/node_modules/@comis/daemon/dist/rpc/provider-handlers.js +330 -0
- package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.js +18 -1
- package/node_modules/@comis/daemon/dist/setup-docker-restart-warn.d.ts +4 -0
- package/node_modules/@comis/daemon/dist/setup-docker-restart-warn.js +30 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +3 -1
- package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +28 -2
- package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.js +1 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-tools.js +7 -4
- package/node_modules/@comis/daemon/package.json +1 -1
- package/node_modules/@comis/gateway/package.json +1 -1
- package/node_modules/@comis/infra/dist/index.d.ts +1 -0
- package/node_modules/@comis/infra/dist/index.js +2 -0
- package/node_modules/@comis/infra/dist/runtime/is-docker.d.ts +1 -0
- package/node_modules/@comis/infra/dist/runtime/is-docker.js +25 -0
- package/node_modules/@comis/infra/package.json +1 -1
- package/node_modules/@comis/memory/package.json +1 -1
- package/node_modules/@comis/scheduler/package.json +1 -1
- package/node_modules/@comis/shared/package.json +1 -1
- package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +1 -3
- package/node_modules/@comis/skills/dist/builtin/platform/admin-manage-factory.js +24 -1
- package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +53 -7
- package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +218 -24
- package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +4 -1
- package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +16 -1
- package/node_modules/@comis/skills/dist/builtin/platform/index.d.ts +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/index.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/providers-manage-tool.d.ts +56 -0
- package/node_modules/@comis/skills/dist/builtin/platform/providers-manage-tool.js +203 -0
- package/node_modules/@comis/skills/dist/index.d.ts +1 -1
- package/node_modules/@comis/skills/dist/index.js +2 -2
- package/node_modules/@comis/skills/dist/policy/tool-policy.js +0 -1
- package/node_modules/@comis/skills/package.json +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-detail-ru-AhppM.js → agent-detail-DqL6Artv.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-editor-hjwRuFVp.js → agent-editor-CNM_h94Y.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-list-6Uotjatr.js → agent-list-Dbh-xD_F.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{billing-view-CxysXH0p.js → billing-view-C1DmtyzK.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{channel-detail-BBCKtmne.js → channel-detail-CtCH22N1.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{channel-list-FkfeOLBQ.js → channel-list-C7xXn-60.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{chat-console-BumBaIgO.js → chat-console-C51pjFwk.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{config-editor-C9BSwHGy.js → config-editor-BLArYRB7.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{context-dag-browser-BHm00mJD.js → context-dag-browser-fuyMinNI.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{context-engine-BENY3pWE.js → context-engine-Bngf2bH0.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{delivery-view-BCnkPsAp.js → delivery-view-C80hucxX.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{diagnostics-view-C_jQFG2H.js → diagnostics-view-Cl4VbHZ6.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-chat-message-FdQcZsSQ.js → ic-chat-message-ByFUoMm6.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-connection-dot-BgYiK2N4.js → ic-connection-dot-C4nDHgY2.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-tool-call-DMPHsLyx.js → ic-tool-call-Bh5kq-yY.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{index-FLPhHz8p.js → index-BBkuC-EU.js} +2 -2
- package/node_modules/@comis/web/dist/assets/{mcp-management-5jyScQis.js → mcp-management-DB-phOo7.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{media-config-J9oT9PPs.js → media-config-CRqZ1ZUH.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{media-test-DGTCtM8-.js → media-test-C9vE20Oy.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{memory-inspector-D5Re9ptG.js → memory-inspector-CeqfnxMZ.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{message-center-cRLK6ZmG.js → message-center-Daup7Mof.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{models-D5vu07MR.js → models-DLYnEU8E.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{observe-view-CalNNEmd.js → observe-view-BTSt_PO5.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-builder-DUYDGwZf.js → pipeline-builder-DknfzyLt.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-history-BAO8brOe.js → pipeline-history-JnHZdeU_.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-DectIoQt.js → pipeline-history-detail-Dg4knsEb.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-list-BHlaBKww.js → pipeline-list-AEnibjsp.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-monitor-BhtpNEHf.js → pipeline-monitor-DG7RbIOO.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{scheduler-VafN_8xi.js → scheduler-uL1fYKAT.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{security-QQXMRTlo.js → security-C3DywRLH.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{session-detail-BpZ_8Yih.js → session-detail-BtqCNWXV.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{session-list-DfCm8Cec.js → session-list-CJXWa2XT.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{setup-wizard-C-z477CG.js → setup-wizard-ywn7oJvu.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{skills-BCOGPf6s.js → skills-DX0KYnWD.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{subagents-l-auUraL.js → subagents-B8p5YJEB.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{workspace-manager-DlvBixiq.js → workspace-manager-CgzNIrw1.js} +1 -1
- package/node_modules/@comis/web/dist/index.html +1 -1
- package/node_modules/@comis/web/package.json +1 -1
- package/package.json +13 -13
- package/node_modules/@comis/skills/dist/builtin/platform/agents-list-tool.d.ts +0 -19
- package/node_modules/@comis/skills/dist/builtin/platform/agents-list-tool.js +0 -39
|
@@ -49,7 +49,6 @@ export function registerAllToolMetadata() {
|
|
|
49
49
|
registerToolMetadata("sessions_list", { isReadOnly: true });
|
|
50
50
|
registerToolMetadata("session_status", { isReadOnly: true });
|
|
51
51
|
registerToolMetadata("sessions_history", { isReadOnly: true });
|
|
52
|
-
registerToolMetadata("agents_list", { isReadOnly: true });
|
|
53
52
|
registerToolMetadata("ctx_search", { isReadOnly: true });
|
|
54
53
|
registerToolMetadata("ctx_inspect", { isReadOnly: true });
|
|
55
54
|
registerToolMetadata("ctx_expand", { isReadOnly: true });
|
|
@@ -324,7 +323,6 @@ export function registerAllToolMetadata() {
|
|
|
324
323
|
registerToolMetadata("pipeline", { searchHint: "workflow dag graph orchestrate chain multi-step sequential" });
|
|
325
324
|
registerToolMetadata("session_status", { searchHint: "session state alive running progress heartbeat check" });
|
|
326
325
|
registerToolMetadata("session_search", { searchHint: "find session lookup filter match query user channel" });
|
|
327
|
-
registerToolMetadata("agents_list", { searchHint: "bots agents roster fleet inventory configured available" });
|
|
328
326
|
// --- Platform tools ---
|
|
329
327
|
registerToolMetadata("cron", { searchHint: "schedule timer reminder recurring job automation crontab interval" });
|
|
330
328
|
registerToolMetadata("gateway", { searchHint: "config restart patch status settings yaml update system admin" });
|
|
@@ -346,7 +344,7 @@ export function registerAllToolMetadata() {
|
|
|
346
344
|
registerToolMetadata("slack_action", { searchHint: "pin react thread channel topic archive bookmark slack" });
|
|
347
345
|
registerToolMetadata("whatsapp_action", { searchHint: "status group admin label broadcast forward whatsapp" });
|
|
348
346
|
// --- Privileged management tools ---
|
|
349
|
-
registerToolMetadata("agents_manage", { searchHint: "fleet create delete suspend resume agent configure
|
|
347
|
+
registerToolMetadata("agents_manage", { searchHint: "fleet list create delete suspend resume agent configure roster inventory" });
|
|
350
348
|
registerToolMetadata("obs_query", { searchHint: "diagnostics monitoring metrics billing traces logs health" });
|
|
351
349
|
registerToolMetadata("sessions_manage", { searchHint: "delete reset export compact session lifecycle cleanup admin" });
|
|
352
350
|
registerToolMetadata("memory_manage", { searchHint: "delete flush export browse stats storage cleanup purge" });
|
|
@@ -12,6 +12,26 @@
|
|
|
12
12
|
import { tryGetContext } from "@comis/core";
|
|
13
13
|
import { jsonResult, readEnumParam, throwToolError, createTrustGuard, } from "./tool-helpers.js";
|
|
14
14
|
// ---------------------------------------------------------------------------
|
|
15
|
+
// AgentToolResult pass-through guard
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/**
|
|
18
|
+
* Detect when an actionOverride has already produced a fully-formed
|
|
19
|
+
* `AgentToolResult` (multi-block content + typed `details`), so the factory
|
|
20
|
+
* passes it through verbatim instead of re-wrapping via `jsonResult`.
|
|
21
|
+
*
|
|
22
|
+
* Used by `agents_manage.create` (260428-sw2 Layer 1) to emit a 2-text-block
|
|
23
|
+
* tool_result: a high-attention next-step contract first, the JSON-rendered
|
|
24
|
+
* RPC fields second. The 7 sibling admin manage tools (cron/heartbeat/
|
|
25
|
+
* sessions/tokens/etc.) keep returning plain objects from their overrides --
|
|
26
|
+
* they hit the `jsonResult` branch unchanged. Additive, zero-impact change.
|
|
27
|
+
*/
|
|
28
|
+
function isAgentToolResult(value) {
|
|
29
|
+
return (typeof value === "object" &&
|
|
30
|
+
value !== null &&
|
|
31
|
+
Array.isArray(value.content) &&
|
|
32
|
+
"details" in value);
|
|
33
|
+
}
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
15
35
|
// Factory
|
|
16
36
|
// ---------------------------------------------------------------------------
|
|
17
37
|
/**
|
|
@@ -70,7 +90,10 @@ export function createAdminManageTool(descriptor, rpcCall, approvalGate, callbac
|
|
|
70
90
|
if (descriptor.actionOverrides?.[action]) {
|
|
71
91
|
const result = await descriptor.actionOverrides[action](p, rpcCall, { agentId: ctx?.userId, trustLevel: _trustLevel });
|
|
72
92
|
if (result !== undefined) {
|
|
73
|
-
|
|
93
|
+
// Pass through pre-built AgentToolResult shapes (e.g. the
|
|
94
|
+
// multi-text-block contract emitted by agents_manage.create);
|
|
95
|
+
// wrap plain values via jsonResult as before.
|
|
96
|
+
return isAgentToolResult(result) ? result : jsonResult(result);
|
|
74
97
|
}
|
|
75
98
|
// Fall through to default dispatch if override returns undefined
|
|
76
99
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Agent management tool: multi-action tool for fleet management.
|
|
3
3
|
*
|
|
4
|
-
* Supports
|
|
4
|
+
* Supports 7 actions: create, get, update, delete, suspend, resume, list.
|
|
5
5
|
* Destructive actions (create, delete) require approval via the ApprovalGate.
|
|
6
6
|
* All actions enforce admin trust level via createTrustGuard.
|
|
7
7
|
* Delegates to agents.* RPC handlers via rpcCall.
|
|
@@ -10,16 +10,22 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
12
12
|
import type { ApprovalGate } from "@comis/core";
|
|
13
|
+
import type { ComisLogger } from "@comis/infra";
|
|
13
14
|
import type { RpcCall } from "./cron-tool.js";
|
|
14
|
-
declare const AgentsManageToolParams: import("@sinclair/typebox").TObject<{
|
|
15
|
-
action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"create">, import("@sinclair/typebox").TLiteral<"get">, import("@sinclair/typebox").TLiteral<"update">, import("@sinclair/typebox").TLiteral<"delete">, import("@sinclair/typebox").TLiteral<"suspend">, import("@sinclair/typebox").TLiteral<"resume">]>;
|
|
16
|
-
agent_id: import("@sinclair/typebox").TString
|
|
15
|
+
export declare const AgentsManageToolParams: import("@sinclair/typebox").TObject<{
|
|
16
|
+
action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"create">, import("@sinclair/typebox").TLiteral<"get">, import("@sinclair/typebox").TLiteral<"update">, import("@sinclair/typebox").TLiteral<"delete">, import("@sinclair/typebox").TLiteral<"suspend">, import("@sinclair/typebox").TLiteral<"resume">, import("@sinclair/typebox").TLiteral<"list">]>;
|
|
17
|
+
agent_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
17
18
|
config: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
18
19
|
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
19
20
|
model: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
20
21
|
provider: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
21
22
|
maxSteps: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
22
23
|
workspace_profile: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"full">, import("@sinclair/typebox").TLiteral<"specialist">]>>;
|
|
24
|
+
workspace: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
25
|
+
profile: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"full">, import("@sinclair/typebox").TLiteral<"specialist">]>;
|
|
26
|
+
role: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
27
|
+
identity: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
28
|
+
}>>;
|
|
23
29
|
skills: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
24
30
|
builtinTools: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
25
31
|
read: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
@@ -37,8 +43,44 @@ declare const AgentsManageToolParams: import("@sinclair/typebox").TObject<{
|
|
|
37
43
|
}>>;
|
|
38
44
|
}>, import("@sinclair/typebox").TString]>>;
|
|
39
45
|
}>;
|
|
46
|
+
export interface AgentInlineWritesValue {
|
|
47
|
+
roleWritten: boolean;
|
|
48
|
+
identityWritten: boolean;
|
|
49
|
+
bytesWritten: number;
|
|
50
|
+
}
|
|
51
|
+
export interface AgentInlineWritesError {
|
|
52
|
+
ok: false;
|
|
53
|
+
error: {
|
|
54
|
+
kind: "oversize" | "path_traversal" | "io";
|
|
55
|
+
file: "ROLE.md" | "IDENTITY.md";
|
|
56
|
+
[k: string]: unknown;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build the post-create next-step contract emitted as the FIRST text block
|
|
61
|
+
* of the `agents_manage.create` tool_result. The freshest, uncached surface
|
|
62
|
+
* the LLM reads on every turn -- pinned here to fix the silent-termination
|
|
63
|
+
* bug where TOOL_GUIDE prescriptive text gets crowded out under high
|
|
64
|
+
* parallel-tool-call load (production session 1a8b0d91 turn 13: 9 sub-agents
|
|
65
|
+
* created in parallel, then a 0-text 0-thinking 0-tool turn).
|
|
66
|
+
*
|
|
67
|
+
* Pure string composition. No I/O, no Result<T,E> needed (per AGENTS.md
|
|
68
|
+
* §2.1: Result is for fallible paths only; this is infallible).
|
|
69
|
+
*
|
|
70
|
+
* Three branches keyed on `inlineWritesResult` (260428-vyf):
|
|
71
|
+
* - BOTH written → SHORT contract: "No further setup needed — agent is
|
|
72
|
+
* operationally ready". Skips the post-create write() roundtrip.
|
|
73
|
+
* - PARTIAL (only one of role/identity written) → mixed contract pointing
|
|
74
|
+
* only at the still-template file with a single "Next required action".
|
|
75
|
+
* - NEITHER (or write failure / undefined) → existing 260428-sw2 2-step
|
|
76
|
+
* contract verbatim, telling the LLM to call write() for ROLE.md.
|
|
77
|
+
*
|
|
78
|
+
* Case B (workspaceDir absent — defensive fallback): shorter form pinning
|
|
79
|
+
* "Customize {agentId}'s workspace ROLE.md and IDENTITY.md before using."
|
|
80
|
+
*/
|
|
81
|
+
export declare function buildCreateContract(agentId: string, workspaceDir: string | undefined, inlineWritesResult?: AgentInlineWritesValue | AgentInlineWritesError): string;
|
|
40
82
|
/**
|
|
41
|
-
* Create an agent management tool with
|
|
83
|
+
* Create an agent management tool with 7 actions.
|
|
42
84
|
*
|
|
43
85
|
* Actions:
|
|
44
86
|
* - **create** -- Create a new agent (requires approval)
|
|
@@ -47,12 +89,17 @@ declare const AgentsManageToolParams: import("@sinclair/typebox").TObject<{
|
|
|
47
89
|
* - **delete** -- Delete an agent (requires approval)
|
|
48
90
|
* - **suspend** -- Suspend agent execution
|
|
49
91
|
* - **resume** -- Resume a suspended agent
|
|
92
|
+
* - **list** -- List all available agent IDs
|
|
50
93
|
*
|
|
51
94
|
* @param rpcCall - RPC call function for delegating to the daemon backend
|
|
95
|
+
* @param logger - Required structured logger. Used to emit a per-create
|
|
96
|
+
* INFO log pinning the next-step contract emission (260428-sw2 Layer 1).
|
|
97
|
+
* Mirrors the gateway-tool required-logger position; no overload-with-
|
|
98
|
+
* default-logger compat shim (per `feedback_no_backward_compat.md`).
|
|
52
99
|
* @param approvalGate - Optional approval gate for create/delete actions
|
|
53
100
|
* @returns AgentTool implementing the agent management interface
|
|
54
101
|
*/
|
|
55
|
-
export declare function createAgentsManageTool(rpcCall: RpcCall, approvalGate?: ApprovalGate, callbacks?: {
|
|
102
|
+
export declare function createAgentsManageTool(rpcCall: RpcCall, logger: ComisLogger, approvalGate?: ApprovalGate, callbacks?: {
|
|
56
103
|
onMutationStart?: () => void;
|
|
57
104
|
onMutationEnd?: () => void;
|
|
58
105
|
/**
|
|
@@ -66,4 +113,3 @@ export declare function createAgentsManageTool(rpcCall: RpcCall, approvalGate?:
|
|
|
66
113
|
workspaceDir?: string;
|
|
67
114
|
}) => Promise<void> | void;
|
|
68
115
|
}): AgentTool<typeof AgentsManageToolParams>;
|
|
69
|
-
export {};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Agent management tool: multi-action tool for fleet management.
|
|
4
4
|
*
|
|
5
|
-
* Supports
|
|
5
|
+
* Supports 7 actions: create, get, update, delete, suspend, resume, list.
|
|
6
6
|
* Destructive actions (create, delete) require approval via the ApprovalGate.
|
|
7
7
|
* All actions enforce admin trust level via createTrustGuard.
|
|
8
8
|
* Delegates to agents.* RPC handlers via rpcCall.
|
|
@@ -15,7 +15,7 @@ import { createAdminManageTool } from "./admin-manage-factory.js";
|
|
|
15
15
|
// ---------------------------------------------------------------------------
|
|
16
16
|
// Parameter schema
|
|
17
17
|
// ---------------------------------------------------------------------------
|
|
18
|
-
const AgentsManageToolParams = Type.Object({
|
|
18
|
+
export const AgentsManageToolParams = Type.Object({
|
|
19
19
|
action: Type.Union([
|
|
20
20
|
Type.Literal("create"),
|
|
21
21
|
Type.Literal("get"),
|
|
@@ -23,10 +23,11 @@ const AgentsManageToolParams = Type.Object({
|
|
|
23
23
|
Type.Literal("delete"),
|
|
24
24
|
Type.Literal("suspend"),
|
|
25
25
|
Type.Literal("resume"),
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
Type.Literal("list"),
|
|
27
|
+
], { description: "Agent management action. Valid values: create (new agent), get (read config/status), update (modify config), delete (remove agent), suspend (pause execution), resume (restart execution), list (all agent IDs)" }),
|
|
28
|
+
agent_id: Type.Optional(Type.String({
|
|
29
|
+
description: "The agent identifier (required for all actions except list)",
|
|
30
|
+
})),
|
|
30
31
|
config: Type.Optional(
|
|
31
32
|
// Accept EITHER a structured object OR a JSON string. Anthropic's LLM
|
|
32
33
|
// sometimes emits nested free-form objects as stringified JSON; coerceConfig()
|
|
@@ -43,8 +44,41 @@ const AgentsManageToolParams = Type.Object({
|
|
|
43
44
|
workspace_profile: Type.Optional(Type.Union([Type.Literal("full"), Type.Literal("specialist")], {
|
|
44
45
|
description: "Workspace profile controlling platform instruction verbosity. " +
|
|
45
46
|
"Valid values: full (~9K tokens, user-facing agents on channels), " +
|
|
46
|
-
"specialist (~800 tokens, task workers and fleet sub-agents). " +
|
|
47
|
-
"Default: full. Can be changed later via update action."
|
|
47
|
+
"specialist (~800 tokens, task workers and fleet sub-agents) ONLY. NO other values accepted. " +
|
|
48
|
+
"Default: full. Can be changed later via update action. " +
|
|
49
|
+
"Alternative shape: nested workspace.profile (see `workspace` field).",
|
|
50
|
+
})),
|
|
51
|
+
// 260428-oyc: declare nested workspace shape explicitly. The LLM
|
|
52
|
+
// sometimes emits `workspace: {profile: "specialist"}` directly
|
|
53
|
+
// (mirroring the downstream Zod schema-agent.ts:733-738 shape).
|
|
54
|
+
// Without this declaration, the unknown nested object slipped past
|
|
55
|
+
// TypeBox structurally but the enum was never validated -- invalid
|
|
56
|
+
// values would only be caught later at the Zod layer with a less
|
|
57
|
+
// actionable error path. Declaring it here makes both shapes
|
|
58
|
+
// first-class and gates the enum at the tool-validation boundary.
|
|
59
|
+
workspace: Type.Optional(Type.Object({
|
|
60
|
+
profile: Type.Union([Type.Literal("full"), Type.Literal("specialist")], {
|
|
61
|
+
description: "Workspace profile (alternative to flat workspace_profile). Valid: full | specialist ONLY. NO other values accepted.",
|
|
62
|
+
}),
|
|
63
|
+
// 260428-vyf L2: inline ROLE.md / IDENTITY.md content. The tool
|
|
64
|
+
// handler strips these from the config payload BEFORE the RPC
|
|
65
|
+
// and forwards them as a separate top-level `inlineContent`
|
|
66
|
+
// param. The daemon writes them as files (write-once side-
|
|
67
|
+
// effect); they are NEVER persisted to config.yaml. When
|
|
68
|
+
// omitted, the seed templates remain in place and the LLM is
|
|
69
|
+
// instructed via the next-step contract to call write()
|
|
70
|
+
// afterward (the FALLBACK 2-step flow).
|
|
71
|
+
role: Type.Optional(Type.String({
|
|
72
|
+
description: "Inline ROLE.md content. Written to <workspaceDir>/ROLE.md immediately on create. Should describe the agent's purpose, behavioral guidelines, domain conventions. Max 16384 chars. When omitted, ROLE.md is the unmodified seed template — call write() afterward to customize.",
|
|
73
|
+
maxLength: 16384,
|
|
74
|
+
})),
|
|
75
|
+
identity: Type.Optional(Type.String({
|
|
76
|
+
description: "Inline IDENTITY.md content. Written to <workspaceDir>/IDENTITY.md immediately on create. Should set name/creature/vibe/emoji/avatar/ethos for the agent. Max 4096 chars. When omitted, IDENTITY.md is the unmodified seed template.",
|
|
77
|
+
maxLength: 4096,
|
|
78
|
+
})),
|
|
79
|
+
}, {
|
|
80
|
+
description: "Nested workspace configuration. Use this OR the flat workspace_profile field, not both. Optionally inline ROLE.md / IDENTITY.md via role/identity for single-call creation (PREFERRED for batch fleet creation).",
|
|
81
|
+
additionalProperties: false,
|
|
48
82
|
})),
|
|
49
83
|
skills: Type.Optional(Type.Object({
|
|
50
84
|
builtinTools: Type.Optional(Type.Object({
|
|
@@ -68,24 +102,95 @@ const AgentsManageToolParams = Type.Object({
|
|
|
68
102
|
}),
|
|
69
103
|
])),
|
|
70
104
|
});
|
|
71
|
-
const VALID_ACTIONS = ["create", "get", "update", "delete", "suspend", "resume"];
|
|
105
|
+
const VALID_ACTIONS = ["create", "get", "update", "delete", "suspend", "resume", "list"];
|
|
72
106
|
// ---------------------------------------------------------------------------
|
|
73
107
|
// Helpers
|
|
74
108
|
// ---------------------------------------------------------------------------
|
|
75
109
|
/**
|
|
76
110
|
* Map flat workspace_profile param to nested workspace.profile config.
|
|
77
111
|
* Mutates config in place.
|
|
112
|
+
*
|
|
113
|
+
* 260428-oyc: precedence is "flat wins" -- when both flat workspace_profile
|
|
114
|
+
* and nested workspace.profile are present, the flat field overwrites the
|
|
115
|
+
* nested one. This matches the existing spread semantics
|
|
116
|
+
* (`{...existing, profile}`) and keeps a single deterministic rule. When only
|
|
117
|
+
* nested is present (no `workspace_profile` key), this is a no-op and the
|
|
118
|
+
* nested shape flows through unchanged to the downstream Zod validator.
|
|
78
119
|
*/
|
|
79
120
|
function mapWorkspaceProfile(config) {
|
|
80
|
-
if (config
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
121
|
+
if (!config)
|
|
122
|
+
return;
|
|
123
|
+
if (!("workspace_profile" in config)) {
|
|
124
|
+
// Nested-only or no workspace fields -- nothing to map. Downstream Zod
|
|
125
|
+
// (PerAgentConfigSchema.workspace) validates the nested shape directly.
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const profile = config.workspace_profile;
|
|
129
|
+
delete config.workspace_profile;
|
|
130
|
+
if (typeof profile === "string") {
|
|
131
|
+
config.workspace = {
|
|
132
|
+
...(config.workspace ?? {}),
|
|
133
|
+
profile,
|
|
134
|
+
};
|
|
87
135
|
}
|
|
88
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Build the post-create next-step contract emitted as the FIRST text block
|
|
139
|
+
* of the `agents_manage.create` tool_result. The freshest, uncached surface
|
|
140
|
+
* the LLM reads on every turn -- pinned here to fix the silent-termination
|
|
141
|
+
* bug where TOOL_GUIDE prescriptive text gets crowded out under high
|
|
142
|
+
* parallel-tool-call load (production session 1a8b0d91 turn 13: 9 sub-agents
|
|
143
|
+
* created in parallel, then a 0-text 0-thinking 0-tool turn).
|
|
144
|
+
*
|
|
145
|
+
* Pure string composition. No I/O, no Result<T,E> needed (per AGENTS.md
|
|
146
|
+
* §2.1: Result is for fallible paths only; this is infallible).
|
|
147
|
+
*
|
|
148
|
+
* Three branches keyed on `inlineWritesResult` (260428-vyf):
|
|
149
|
+
* - BOTH written → SHORT contract: "No further setup needed — agent is
|
|
150
|
+
* operationally ready". Skips the post-create write() roundtrip.
|
|
151
|
+
* - PARTIAL (only one of role/identity written) → mixed contract pointing
|
|
152
|
+
* only at the still-template file with a single "Next required action".
|
|
153
|
+
* - NEITHER (or write failure / undefined) → existing 260428-sw2 2-step
|
|
154
|
+
* contract verbatim, telling the LLM to call write() for ROLE.md.
|
|
155
|
+
*
|
|
156
|
+
* Case B (workspaceDir absent — defensive fallback): shorter form pinning
|
|
157
|
+
* "Customize {agentId}'s workspace ROLE.md and IDENTITY.md before using."
|
|
158
|
+
*/
|
|
159
|
+
export function buildCreateContract(agentId, workspaceDir, inlineWritesResult) {
|
|
160
|
+
// BOTH written → SHORT operationally-ready contract.
|
|
161
|
+
if (workspaceDir !== undefined
|
|
162
|
+
&& inlineWritesResult !== undefined
|
|
163
|
+
&& "roleWritten" in inlineWritesResult
|
|
164
|
+
&& inlineWritesResult.roleWritten
|
|
165
|
+
&& inlineWritesResult.identityWritten) {
|
|
166
|
+
return `✓ Agent ${agentId} created at ${workspaceDir} with inline ROLE.md and IDENTITY.md (${inlineWritesResult.bytesWritten} bytes total). No further setup needed — agent is operationally ready.`;
|
|
167
|
+
}
|
|
168
|
+
// PARTIAL (exactly one of role/identity written).
|
|
169
|
+
if (workspaceDir !== undefined
|
|
170
|
+
&& inlineWritesResult !== undefined
|
|
171
|
+
&& "roleWritten" in inlineWritesResult
|
|
172
|
+
&& (inlineWritesResult.roleWritten || inlineWritesResult.identityWritten)) {
|
|
173
|
+
const written = inlineWritesResult.roleWritten ? "ROLE.md" : "IDENTITY.md";
|
|
174
|
+
const remaining = inlineWritesResult.roleWritten ? "IDENTITY.md" : "ROLE.md";
|
|
175
|
+
return [
|
|
176
|
+
`✓ Agent ${agentId} created at ${workspaceDir} with inline ${written} (${inlineWritesResult.bytesWritten} bytes).`,
|
|
177
|
+
`⚠ ${remaining} is still the unmodified template.`,
|
|
178
|
+
`Next required action for this agent: call write({path: "${workspaceDir}/${remaining}", content: "..."}). This agent is NOT ready until ${remaining} is customized.`,
|
|
179
|
+
].join("\n");
|
|
180
|
+
}
|
|
181
|
+
// NEITHER (no inlineContent supplied, write failure, or undefined): fall
|
|
182
|
+
// through to the existing 260428-sw2 2-step contract verbatim.
|
|
183
|
+
if (workspaceDir !== undefined) {
|
|
184
|
+
return [
|
|
185
|
+
`✓ Agent ${agentId} created at ${workspaceDir}.`,
|
|
186
|
+
`⚠ Workspace files are TEMPLATES — not yet operationally configured. Customize before use:`,
|
|
187
|
+
` • ${workspaceDir}/ROLE.md — purpose, behavioral guidelines, domain conventions`,
|
|
188
|
+
` • ${workspaceDir}/IDENTITY.md — name, creature, vibe, emoji`,
|
|
189
|
+
`Next required action for this agent: call write({path: "${workspaceDir}/ROLE.md", content: "..."}). This agent is NOT ready until ROLE.md is customized.`,
|
|
190
|
+
].join("\n");
|
|
191
|
+
}
|
|
192
|
+
return `✓ Agent ${agentId} created. Customize ${agentId}'s workspace ROLE.md and IDENTITY.md before using.`;
|
|
193
|
+
}
|
|
89
194
|
/** Coerce config from JSON string to object if LLM double-encoded it. */
|
|
90
195
|
function coerceConfig(p) {
|
|
91
196
|
const raw = p.config;
|
|
@@ -104,7 +209,7 @@ function coerceConfig(p) {
|
|
|
104
209
|
// Factory
|
|
105
210
|
// ---------------------------------------------------------------------------
|
|
106
211
|
/**
|
|
107
|
-
* Create an agent management tool with
|
|
212
|
+
* Create an agent management tool with 7 actions.
|
|
108
213
|
*
|
|
109
214
|
* Actions:
|
|
110
215
|
* - **create** -- Create a new agent (requires approval)
|
|
@@ -113,16 +218,21 @@ function coerceConfig(p) {
|
|
|
113
218
|
* - **delete** -- Delete an agent (requires approval)
|
|
114
219
|
* - **suspend** -- Suspend agent execution
|
|
115
220
|
* - **resume** -- Resume a suspended agent
|
|
221
|
+
* - **list** -- List all available agent IDs
|
|
116
222
|
*
|
|
117
223
|
* @param rpcCall - RPC call function for delegating to the daemon backend
|
|
224
|
+
* @param logger - Required structured logger. Used to emit a per-create
|
|
225
|
+
* INFO log pinning the next-step contract emission (260428-sw2 Layer 1).
|
|
226
|
+
* Mirrors the gateway-tool required-logger position; no overload-with-
|
|
227
|
+
* default-logger compat shim (per `feedback_no_backward_compat.md`).
|
|
118
228
|
* @param approvalGate - Optional approval gate for create/delete actions
|
|
119
229
|
* @returns AgentTool implementing the agent management interface
|
|
120
230
|
*/
|
|
121
|
-
export function createAgentsManageTool(rpcCall, approvalGate, callbacks) {
|
|
231
|
+
export function createAgentsManageTool(rpcCall, logger, approvalGate, callbacks) {
|
|
122
232
|
return createAdminManageTool({
|
|
123
233
|
name: "agents_manage",
|
|
124
234
|
label: "Agent Management",
|
|
125
|
-
description: "Manage agent fleet: create, get, update, delete, suspend, resume. " +
|
|
235
|
+
description: "Manage agent fleet: create, get, update, delete, suspend, resume, list. " +
|
|
126
236
|
"Use update to switch an agent's LLM provider or model (e.g. switch to Gemini, change model). " +
|
|
127
237
|
"Create/delete require approval.",
|
|
128
238
|
parameters: AgentsManageToolParams,
|
|
@@ -134,24 +244,105 @@ export function createAgentsManageTool(rpcCall, approvalGate, callbacks) {
|
|
|
134
244
|
const agentId = readStringParam(p, "agent_id");
|
|
135
245
|
const config = coerceConfig(p);
|
|
136
246
|
mapWorkspaceProfile(config);
|
|
247
|
+
// Map common LLM-hallucinated "system prompt" field names to
|
|
248
|
+
// workspace.role — the correct inline ROLE.md path. Runs after
|
|
249
|
+
// coerceConfig (catches string-form) and before L2 stripping.
|
|
250
|
+
if (config && typeof config === "object") {
|
|
251
|
+
const ROLE_ALIASES = ["systemPrompt", "system", "prompt", "instructions", "systemMessage", "description"];
|
|
252
|
+
const c = config;
|
|
253
|
+
for (const alias of ROLE_ALIASES) {
|
|
254
|
+
if (typeof c[alias] === "string") {
|
|
255
|
+
const ws = (c.workspace ??= {});
|
|
256
|
+
if (typeof ws.role !== "string")
|
|
257
|
+
ws.role = c[alias];
|
|
258
|
+
delete c[alias];
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// 260428-vyf L2 (Path A): strip workspace.role / workspace.identity
|
|
264
|
+
// from the config payload BEFORE the RPC and forward them as a
|
|
265
|
+
// separate top-level `inlineContent` parameter. Rationale: the
|
|
266
|
+
// downstream Zod schema (PerAgentConfigSchema.workspace at
|
|
267
|
+
// packages/core/src/config/schema-agent.ts) is z.strictObject —
|
|
268
|
+
// unknown keys would trigger Zod `unrecognized_keys` rejection.
|
|
269
|
+
// role/identity are write-once side-effects (ROLE.md / IDENTITY.md
|
|
270
|
+
// file writes), NOT durable state — they MUST NOT leak into
|
|
271
|
+
// config.yaml. Path B (extending Zod schema-agent.ts) was
|
|
272
|
+
// rejected because it would persist them.
|
|
273
|
+
let inlineContent;
|
|
274
|
+
if (config && typeof config === "object") {
|
|
275
|
+
const ws = config.workspace;
|
|
276
|
+
if (ws && (typeof ws.role === "string" || typeof ws.identity === "string")) {
|
|
277
|
+
inlineContent = {};
|
|
278
|
+
if (typeof ws.role === "string") {
|
|
279
|
+
inlineContent.role = ws.role;
|
|
280
|
+
delete ws.role;
|
|
281
|
+
}
|
|
282
|
+
if (typeof ws.identity === "string") {
|
|
283
|
+
inlineContent.identity = ws.identity;
|
|
284
|
+
delete ws.identity;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
137
288
|
callbacks?.onMutationStart?.();
|
|
138
289
|
try {
|
|
139
|
-
const
|
|
290
|
+
const rpcParams = { agentId, config, _trustLevel: ctx.trustLevel };
|
|
291
|
+
if (inlineContent !== undefined)
|
|
292
|
+
rpcParams.inlineContent = inlineContent;
|
|
293
|
+
const result = await rpcCall("agents.create", rpcParams);
|
|
294
|
+
// agentId is guaranteed non-undefined by readStringParam(required=true) above.
|
|
295
|
+
const aid = agentId;
|
|
296
|
+
const workspaceDir = result?.workspaceDir;
|
|
297
|
+
const inlineWritesResult = result?.inlineWritesResult;
|
|
298
|
+
// 260428-sw2 Layer 1 + 260428-vyf Layer 2: emit the next-step
|
|
299
|
+
// contract on the freshest, uncached surface the LLM reads each
|
|
300
|
+
// turn (the tool_result text). The contract has 3 branches keyed
|
|
301
|
+
// on inlineWritesResult (see buildCreateContract). One structured
|
|
302
|
+
// INFO log pins this happened.
|
|
303
|
+
const contractText = buildCreateContract(aid, workspaceDir, inlineWritesResult);
|
|
304
|
+
// Distinguish the 3 inline-write outcomes for observability.
|
|
305
|
+
// "none" — caller did not supply inlineContent
|
|
306
|
+
// "written" — helper succeeded (full or partial)
|
|
307
|
+
// "failed" — helper returned err shape (oversize|path_traversal|io)
|
|
308
|
+
const inlineWritesOutcome = inlineWritesResult === undefined
|
|
309
|
+
? "none"
|
|
310
|
+
: "roleWritten" in inlineWritesResult
|
|
311
|
+
? "written"
|
|
312
|
+
: "failed";
|
|
313
|
+
logger.info({
|
|
314
|
+
module: "skill.agents-manage",
|
|
315
|
+
action: "create",
|
|
316
|
+
agentId: aid,
|
|
317
|
+
workspaceDir: workspaceDir ?? null,
|
|
318
|
+
contractEmitted: true,
|
|
319
|
+
inlineWritesOutcome,
|
|
320
|
+
}, "agents_manage.create succeeded — next-step contract emitted");
|
|
140
321
|
// Best-effort seed registration hook. Fires only on successful
|
|
141
322
|
// RPC return. Callback failures are swallowed — the agent was
|
|
142
323
|
// created; tracker registration is an optimization, not a gate.
|
|
143
324
|
if (callbacks?.onAgentCreated) {
|
|
144
325
|
try {
|
|
145
|
-
const workspaceDir = result?.workspaceDir;
|
|
146
|
-
// agentId is guaranteed non-undefined by readStringParam(required=true) above.
|
|
147
|
-
const aid = agentId;
|
|
148
326
|
await callbacks.onAgentCreated(workspaceDir !== undefined ? { agentId: aid, workspaceDir } : { agentId: aid });
|
|
149
327
|
}
|
|
150
328
|
catch {
|
|
151
329
|
/* non-fatal */
|
|
152
330
|
}
|
|
153
331
|
}
|
|
154
|
-
|
|
332
|
+
// Return a 2-text-block AgentToolResult passed through verbatim
|
|
333
|
+
// by admin-manage-factory's isAgentToolResult guard:
|
|
334
|
+
// - block 0: the next-step contract (high-attention text)
|
|
335
|
+
// - block 1: the JSON-rendered RPC fields (preserves the
|
|
336
|
+
// structured view existing pin/regression tests assert)
|
|
337
|
+
// `details` is the raw RPC return so result.details assertions
|
|
338
|
+
// continue to pass unchanged.
|
|
339
|
+
return {
|
|
340
|
+
content: [
|
|
341
|
+
{ type: "text", text: contractText },
|
|
342
|
+
{ type: "text", text: JSON.stringify(result, null, 2) },
|
|
343
|
+
],
|
|
344
|
+
details: result,
|
|
345
|
+
};
|
|
155
346
|
}
|
|
156
347
|
finally {
|
|
157
348
|
callbacks?.onMutationEnd?.();
|
|
@@ -191,6 +382,9 @@ export function createAgentsManageTool(rpcCall, approvalGate, callbacks) {
|
|
|
191
382
|
const agentId = readStringParam(p, "agent_id");
|
|
192
383
|
return rpcCall("agents.resume", { agentId, _trustLevel: ctx.trustLevel });
|
|
193
384
|
},
|
|
385
|
+
async list(_p, rpcCall, ctx) {
|
|
386
|
+
return rpcCall("agents.list", { _trustLevel: ctx.trustLevel });
|
|
387
|
+
},
|
|
194
388
|
},
|
|
195
389
|
}, rpcCall, approvalGate, callbacks);
|
|
196
390
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
12
12
|
import type { RpcCall } from "./cron-tool.js";
|
|
13
|
+
import type { ComisLogger } from "@comis/infra";
|
|
13
14
|
/**
|
|
14
15
|
* Canonical list of gateway tool actions. Single source of truth --
|
|
15
16
|
* the Typebox `action` Union below and the bridge's pre-flight
|
|
@@ -49,7 +50,9 @@ declare const GatewayToolParams: import("@sinclair/typebox").TObject<{
|
|
|
49
50
|
* - **env_list** -- List configured secret NAMES (admin-only, read-only). Use before asking the user for a key to check whether it is already configured. Values are never returned.
|
|
50
51
|
*
|
|
51
52
|
* @param rpcCall - RPC call function for delegating to the daemon backend
|
|
53
|
+
* @param logger - Structured logger for surfacing operator-relevant events
|
|
54
|
+
* (e.g., the Docker restart-policy WARN on the `restart` action)
|
|
52
55
|
* @returns AgentTool implementing the gateway control interface
|
|
53
56
|
*/
|
|
54
|
-
export declare function createGatewayTool(rpcCall: RpcCall): AgentTool<typeof GatewayToolParams>;
|
|
57
|
+
export declare function createGatewayTool(rpcCall: RpcCall, logger: ComisLogger): AgentTool<typeof GatewayToolParams>;
|
|
55
58
|
export {};
|
|
@@ -13,6 +13,7 @@ import { Type } from "@sinclair/typebox";
|
|
|
13
13
|
import { tryGetContext, isImmutableConfigPath, MUTABLE_CONFIG_OVERRIDES, matchesOverridePattern, getMutableOverridesForSection, getManagedSectionRedirect, formatRedirectHint, } from "@comis/core";
|
|
14
14
|
import { readStringParam, throwToolError, createActionGate, } from "./tool-helpers.js";
|
|
15
15
|
import { createMultiActionDispatchTool } from "./messaging-factory.js";
|
|
16
|
+
import { isDocker } from "@comis/infra";
|
|
16
17
|
// ---------------------------------------------------------------------------
|
|
17
18
|
// Canonical action list -- single source of truth
|
|
18
19
|
// ---------------------------------------------------------------------------
|
|
@@ -98,9 +99,11 @@ const GatewayToolParams = Type.Object({
|
|
|
98
99
|
* - **env_list** -- List configured secret NAMES (admin-only, read-only). Use before asking the user for a key to check whether it is already configured. Values are never returned.
|
|
99
100
|
*
|
|
100
101
|
* @param rpcCall - RPC call function for delegating to the daemon backend
|
|
102
|
+
* @param logger - Structured logger for surfacing operator-relevant events
|
|
103
|
+
* (e.g., the Docker restart-policy WARN on the `restart` action)
|
|
101
104
|
* @returns AgentTool implementing the gateway control interface
|
|
102
105
|
*/
|
|
103
|
-
export function createGatewayTool(rpcCall) {
|
|
106
|
+
export function createGatewayTool(rpcCall, logger) {
|
|
104
107
|
const restartGate = createActionGate("gateway.restart");
|
|
105
108
|
const patchGate = createActionGate("config.patch");
|
|
106
109
|
const applyGate = createActionGate("config.apply");
|
|
@@ -162,6 +165,18 @@ export function createGatewayTool(rpcCall) {
|
|
|
162
165
|
hint: "Ask the user to confirm this restart, then call again with _confirmed: true.",
|
|
163
166
|
};
|
|
164
167
|
}
|
|
168
|
+
// 260428-qrn: Inside Docker the restart relies entirely on the
|
|
169
|
+
// container's restart policy to bring the daemon back. Surface
|
|
170
|
+
// a structured WARN so the operator gets a breadcrumb in
|
|
171
|
+
// `docker logs` pointing at `--restart unless-stopped`. Tool
|
|
172
|
+
// result schema unchanged (Pino-only -- no extra content blocks).
|
|
173
|
+
if (isDocker()) {
|
|
174
|
+
logger.warn({
|
|
175
|
+
hint: "Container must have --restart unless-stopped (or compose restart: unless-stopped) for the restart to bring it back. Otherwise run 'docker restart <name>' from your host after the daemon exits.",
|
|
176
|
+
errorKind: "config",
|
|
177
|
+
module: "skill.gateway",
|
|
178
|
+
}, "Daemon restart requested inside Docker container — relies on container restart policy");
|
|
179
|
+
}
|
|
165
180
|
return rpcCall("gateway.restart", { _trustLevel });
|
|
166
181
|
}
|
|
167
182
|
case "schema": {
|
|
@@ -16,7 +16,6 @@ export { createSessionsHistoryTool } from "./sessions-history-tool.js";
|
|
|
16
16
|
export { createSessionsSendTool } from "./sessions-send-tool.js";
|
|
17
17
|
export { createSessionsSpawnTool } from "./sessions-spawn-tool.js";
|
|
18
18
|
export { createSessionSearchTool } from "./session-search-tool.js";
|
|
19
|
-
export { createAgentsListTool } from "./agents-list-tool.js";
|
|
20
19
|
export { createSubagentsTool } from "./subagents-tool.js";
|
|
21
20
|
export { createPipelineTool } from "./pipeline-tool.js";
|
|
22
21
|
export { createRpcDispatchTool, createMultiActionDispatchTool } from "./messaging-factory.js";
|
|
@@ -53,6 +52,7 @@ export { createObsQueryTool } from "./obs-query-tool.js";
|
|
|
53
52
|
export { createMemoryManageTool } from "./memory-manage-tool.js";
|
|
54
53
|
export { createSessionsManageTool } from "./sessions-manage-tool.js";
|
|
55
54
|
export { createModelsManageTool } from "./models-manage-tool.js";
|
|
55
|
+
export { createProvidersManageTool } from "./providers-manage-tool.js";
|
|
56
56
|
export { createTokensManageTool } from "./tokens-manage-tool.js";
|
|
57
57
|
export { createChannelsManageTool } from "./channels-manage-tool.js";
|
|
58
58
|
export { createSkillsManageTool } from "./skills-manage-tool.js";
|
|
@@ -19,7 +19,6 @@ export { createSessionsSendTool } from "./sessions-send-tool.js";
|
|
|
19
19
|
export { createSessionsSpawnTool } from "./sessions-spawn-tool.js";
|
|
20
20
|
export { createSessionSearchTool } from "./session-search-tool.js";
|
|
21
21
|
// Agent tools
|
|
22
|
-
export { createAgentsListTool } from "./agents-list-tool.js";
|
|
23
22
|
export { createSubagentsTool } from "./subagents-tool.js";
|
|
24
23
|
export { createPipelineTool } from "./pipeline-tool.js";
|
|
25
24
|
// Messaging factory
|
|
@@ -66,6 +65,7 @@ export { createObsQueryTool } from "./obs-query-tool.js";
|
|
|
66
65
|
export { createMemoryManageTool } from "./memory-manage-tool.js";
|
|
67
66
|
export { createSessionsManageTool } from "./sessions-manage-tool.js";
|
|
68
67
|
export { createModelsManageTool } from "./models-manage-tool.js";
|
|
68
|
+
export { createProvidersManageTool } from "./providers-manage-tool.js";
|
|
69
69
|
export { createTokensManageTool } from "./tokens-manage-tool.js";
|
|
70
70
|
export { createChannelsManageTool } from "./channels-manage-tool.js";
|
|
71
71
|
export { createSkillsManageTool } from "./skills-manage-tool.js";
|