@cjhyy/code-shell-pet 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -0
- package/dist/capability.d.ts +15 -0
- package/dist/capability.js +251 -0
- package/dist/current-time.d.ts +5 -0
- package/dist/current-time.js +43 -0
- package/dist/delegate-work.d.ts +7 -0
- package/dist/delegate-work.js +142 -0
- package/dist/delegation.d.ts +33 -0
- package/dist/delegation.js +6 -0
- package/dist/disclosure/catalog.d.ts +22 -0
- package/dist/disclosure/catalog.js +104 -0
- package/dist/disclosure/constants.d.ts +7 -0
- package/dist/disclosure/constants.js +7 -0
- package/dist/disclosure/jsonl.d.ts +9 -0
- package/dist/disclosure/jsonl.js +61 -0
- package/dist/disclosure/latest-result.d.ts +8 -0
- package/dist/disclosure/latest-result.js +35 -0
- package/dist/disclosure/search.d.ts +21 -0
- package/dist/disclosure/search.js +124 -0
- package/dist/disclosure/selector.d.ts +2 -0
- package/dist/disclosure/selector.js +5 -0
- package/dist/disclosure/todo-snapshot.d.ts +8 -0
- package/dist/disclosure/todo-snapshot.js +54 -0
- package/dist/follow-ups.d.ts +21 -0
- package/dist/follow-ups.js +102 -0
- package/dist/gateway.d.ts +41 -0
- package/dist/gateway.js +263 -0
- package/dist/host-actions.d.ts +51 -0
- package/dist/host-actions.js +405 -0
- package/dist/index.capability.d.ts +7 -0
- package/dist/index.capability.js +7 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.disclosure.d.ts +13 -0
- package/dist/index.disclosure.js +13 -0
- package/dist/index.js +32 -0
- package/dist/index.protocol.d.ts +8 -0
- package/dist/index.protocol.js +8 -0
- package/dist/index.team.d.ts +2 -0
- package/dist/index.team.js +2 -0
- package/dist/long-task.d.ts +251 -0
- package/dist/long-task.js +795 -0
- package/dist/mobile-remote.d.ts +14 -0
- package/dist/mobile-remote.js +39 -0
- package/dist/outbound-message.d.ts +15 -0
- package/dist/outbound-message.js +127 -0
- package/dist/pending-decision-index.d.ts +24 -0
- package/dist/pending-decision-index.js +110 -0
- package/dist/profile.d.ts +27 -0
- package/dist/profile.js +120 -0
- package/dist/projection-extension.d.ts +8 -0
- package/dist/projection-extension.js +238 -0
- package/dist/protocol.d.ts +58 -0
- package/dist/protocol.js +15 -0
- package/dist/report-to-mimi.d.ts +7 -0
- package/dist/report-to-mimi.js +87 -0
- package/dist/run-params.d.ts +34 -0
- package/dist/run-params.js +387 -0
- package/dist/segment-closure.d.ts +52 -0
- package/dist/segment-closure.js +130 -0
- package/dist/session-control.d.ts +5 -0
- package/dist/session-control.js +46 -0
- package/dist/session-index.d.ts +22 -0
- package/dist/session-index.js +324 -0
- package/dist/sessions-tool.d.ts +21 -0
- package/dist/sessions-tool.js +145 -0
- package/dist/team.d.ts +13 -0
- package/dist/team.js +38 -0
- package/dist/tool-arguments.d.ts +1 -0
- package/dist/tool-arguments.js +10 -0
- package/dist/topic-segment.d.ts +55 -0
- package/dist/topic-segment.js +37 -0
- package/dist/types.d.ts +95 -0
- package/dist/types.js +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { isAbsolute } from "node:path";
|
|
2
|
+
export const PET_HOST_ACTION_KINDS = [
|
|
3
|
+
"mobileRemote",
|
|
4
|
+
"longTaskControl",
|
|
5
|
+
"memory",
|
|
6
|
+
"gatewayReply",
|
|
7
|
+
"followUpMutation",
|
|
8
|
+
"sessionArchive",
|
|
9
|
+
"outboundMessage",
|
|
10
|
+
];
|
|
11
|
+
export function isPetHostActionKind(value) {
|
|
12
|
+
return PET_HOST_ACTION_KINDS.includes(value);
|
|
13
|
+
}
|
|
14
|
+
const MAX_MEMORY_TEXT_LENGTH = 2_000;
|
|
15
|
+
const MAX_HOST_ACTION_ID_LENGTH = 128;
|
|
16
|
+
const MAX_GATEWAY_REPLY_TEXT_LENGTH = 8_000;
|
|
17
|
+
const MAX_GATEWAY_BUTTON_TEXT_LENGTH = 80;
|
|
18
|
+
const MAX_GATEWAY_BUTTON_URL_LENGTH = 2_048;
|
|
19
|
+
const MAX_GATEWAY_ATTACHMENT_PATH_LENGTH = 4_096;
|
|
20
|
+
const MAX_GATEWAY_ATTACHMENTS = 4;
|
|
21
|
+
const CONTROL_CHARACTER_RE = /[\u0000-\u001f\u007f]/u;
|
|
22
|
+
function isRecord(value) {
|
|
23
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
24
|
+
}
|
|
25
|
+
function hasExactKeys(record, keys) {
|
|
26
|
+
const actual = Object.keys(record).sort();
|
|
27
|
+
const expected = [...keys].sort();
|
|
28
|
+
return actual.length === expected.length && actual.every((key, index) => key === expected[index]);
|
|
29
|
+
}
|
|
30
|
+
function isOpaqueId(value) {
|
|
31
|
+
return (typeof value === "string" &&
|
|
32
|
+
value.length > 0 &&
|
|
33
|
+
value.length <= MAX_HOST_ACTION_ID_LENGTH &&
|
|
34
|
+
value === value.trim() &&
|
|
35
|
+
!CONTROL_CHARACTER_RE.test(value));
|
|
36
|
+
}
|
|
37
|
+
function isGatewayAttachmentPath(value) {
|
|
38
|
+
return (typeof value === "string" &&
|
|
39
|
+
isAbsolute(value) &&
|
|
40
|
+
value.length > 0 &&
|
|
41
|
+
value.length <= MAX_GATEWAY_ATTACHMENT_PATH_LENGTH &&
|
|
42
|
+
value === value.trim() &&
|
|
43
|
+
!CONTROL_CHARACTER_RE.test(value));
|
|
44
|
+
}
|
|
45
|
+
function isGatewayButton(value) {
|
|
46
|
+
if (!isRecord(value) || !hasExactKeys(value, ["text", "url"]))
|
|
47
|
+
return false;
|
|
48
|
+
if (typeof value.text !== "string" ||
|
|
49
|
+
!value.text.trim() ||
|
|
50
|
+
value.text.length > MAX_GATEWAY_BUTTON_TEXT_LENGTH ||
|
|
51
|
+
CONTROL_CHARACTER_RE.test(value.text) ||
|
|
52
|
+
typeof value.url !== "string" ||
|
|
53
|
+
value.url.length > MAX_GATEWAY_BUTTON_URL_LENGTH ||
|
|
54
|
+
value.url !== value.url.trim() ||
|
|
55
|
+
CONTROL_CHARACTER_RE.test(value.url)) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const url = new URL(value.url);
|
|
60
|
+
return url.protocol === "https:" || url.protocol === "http:";
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function isGatewayReplyPayload(value) {
|
|
67
|
+
const keys = Object.keys(value);
|
|
68
|
+
if (keys.length < 1 ||
|
|
69
|
+
keys.some((key) => key !== "text" && key !== "button" && key !== "attachmentPaths") ||
|
|
70
|
+
typeof value.text !== "string" ||
|
|
71
|
+
!value.text.trim() ||
|
|
72
|
+
value.text.length > MAX_GATEWAY_REPLY_TEXT_LENGTH ||
|
|
73
|
+
CONTROL_CHARACTER_RE.test(value.text.replaceAll("\n", "").replaceAll("\t", "")) ||
|
|
74
|
+
(value.button !== undefined && !isGatewayButton(value.button))) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
if (value.attachmentPaths === undefined)
|
|
78
|
+
return true;
|
|
79
|
+
return (Array.isArray(value.attachmentPaths) &&
|
|
80
|
+
value.attachmentPaths.length > 0 &&
|
|
81
|
+
value.attachmentPaths.length <= MAX_GATEWAY_ATTACHMENTS &&
|
|
82
|
+
value.attachmentPaths.every(isGatewayAttachmentPath) &&
|
|
83
|
+
new Set(value.attachmentPaths).size === value.attachmentPaths.length);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Validate the full worker-to-host envelope, including each kind's payload.
|
|
87
|
+
* Tool input schemas are not a trust boundary: the worker response still
|
|
88
|
+
* crosses a process boundary and must fail closed before a host side effect.
|
|
89
|
+
*/
|
|
90
|
+
export function isPetHostActionRequest(value) {
|
|
91
|
+
if (!isRecord(value) || !hasExactKeys(value, ["kind", "payload"]))
|
|
92
|
+
return false;
|
|
93
|
+
if (!isPetHostActionKind(value.kind) || !isRecord(value.payload))
|
|
94
|
+
return false;
|
|
95
|
+
const payload = value.payload;
|
|
96
|
+
if (value.kind === "mobileRemote") {
|
|
97
|
+
return (hasExactKeys(payload, ["action"]) && (payload.action === "open" || payload.action === "close"));
|
|
98
|
+
}
|
|
99
|
+
if (value.kind === "longTaskControl") {
|
|
100
|
+
return (hasExactKeys(payload, ["taskId", "action"]) &&
|
|
101
|
+
isOpaqueId(payload.taskId) &&
|
|
102
|
+
LONG_TASK_ACTIONS.includes(payload.action));
|
|
103
|
+
}
|
|
104
|
+
if (value.kind === "gatewayReply")
|
|
105
|
+
return isGatewayReplyPayload(payload);
|
|
106
|
+
if (value.kind === "followUpMutation") {
|
|
107
|
+
return (hasExactKeys(payload, ["action", "followUpId"]) &&
|
|
108
|
+
(payload.action === "complete" || payload.action === "dismiss") &&
|
|
109
|
+
isOpaqueId(payload.followUpId));
|
|
110
|
+
}
|
|
111
|
+
if (value.kind === "sessionArchive") {
|
|
112
|
+
return (payload.action === "archive" &&
|
|
113
|
+
hasExactKeys(payload, ["action", "sessionIds"]) &&
|
|
114
|
+
Array.isArray(payload.sessionIds) &&
|
|
115
|
+
payload.sessionIds.length > 0 &&
|
|
116
|
+
payload.sessionIds.length <= 20 &&
|
|
117
|
+
payload.sessionIds.every((id) => typeof id === "string" && /^[A-Za-z0-9_-]{1,128}$/u.test(id)) &&
|
|
118
|
+
new Set(payload.sessionIds).size === payload.sessionIds.length);
|
|
119
|
+
}
|
|
120
|
+
if (value.kind === "outboundMessage") {
|
|
121
|
+
const attachmentPaths = payload.attachmentPaths;
|
|
122
|
+
return (Object.keys(payload).every((key) => ["targetId", "text", "attachmentPaths"].includes(key)) &&
|
|
123
|
+
Object.keys(payload).length === (attachmentPaths === undefined ? 2 : 3) &&
|
|
124
|
+
isOpaqueId(payload.targetId) &&
|
|
125
|
+
typeof payload.text === "string" &&
|
|
126
|
+
payload.text.trim().length > 0 &&
|
|
127
|
+
payload.text.length <= MAX_GATEWAY_REPLY_TEXT_LENGTH &&
|
|
128
|
+
!CONTROL_CHARACTER_RE.test(payload.text.replaceAll("\n", "").replaceAll("\t", "")) &&
|
|
129
|
+
(attachmentPaths === undefined ||
|
|
130
|
+
(Array.isArray(attachmentPaths) &&
|
|
131
|
+
attachmentPaths.length > 0 &&
|
|
132
|
+
attachmentPaths.length <= MAX_GATEWAY_ATTACHMENTS &&
|
|
133
|
+
attachmentPaths.every(isGatewayAttachmentPath) &&
|
|
134
|
+
new Set(attachmentPaths).size === attachmentPaths.length)));
|
|
135
|
+
}
|
|
136
|
+
if (payload.action === "remember") {
|
|
137
|
+
return (hasExactKeys(payload, ["action", "text"]) &&
|
|
138
|
+
typeof payload.text === "string" &&
|
|
139
|
+
payload.text.trim().length > 0 &&
|
|
140
|
+
payload.text.length <= MAX_MEMORY_TEXT_LENGTH);
|
|
141
|
+
}
|
|
142
|
+
if (payload.action === "update") {
|
|
143
|
+
return (hasExactKeys(payload, ["action", "memoryId", "text"]) &&
|
|
144
|
+
isOpaqueId(payload.memoryId) &&
|
|
145
|
+
typeof payload.text === "string" &&
|
|
146
|
+
payload.text.trim().length > 0 &&
|
|
147
|
+
payload.text.length <= MAX_MEMORY_TEXT_LENGTH);
|
|
148
|
+
}
|
|
149
|
+
return (payload.action === "forget" &&
|
|
150
|
+
hasExactKeys(payload, ["action", "memoryId"]) &&
|
|
151
|
+
isOpaqueId(payload.memoryId));
|
|
152
|
+
}
|
|
153
|
+
export function hostActionAvailability(kind) {
|
|
154
|
+
return (ctx) => {
|
|
155
|
+
const kinds = ctx.profileMeta?.petHostActionKinds;
|
|
156
|
+
return ctx.behaviorProfile === "pet" && Array.isArray(kinds) && kinds.includes(kind);
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
export function hostActionService(ctx) {
|
|
160
|
+
const services = ctx?.runScopedServices;
|
|
161
|
+
return typeof services?.requestPetHostAction === "function"
|
|
162
|
+
? services.requestPetHostAction
|
|
163
|
+
: undefined;
|
|
164
|
+
}
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// GatewayReply
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
export const GATEWAY_REPLY_TOOL_NAME = "GatewayReply";
|
|
169
|
+
export const gatewayReplyToolDef = {
|
|
170
|
+
name: GATEWAY_REPLY_TOOL_NAME,
|
|
171
|
+
description: "Deliver the current reply through the originating Chat Gateway route. This is the only tool " +
|
|
172
|
+
"that owns IM reply text, optional URL buttons, and optional existing local image/file/audio/video " +
|
|
173
|
+
"attachments. The host and Gateway validate the exact route capability after the turn. " +
|
|
174
|
+
"Use only attachment paths supplied by the user or trusted runtime context; never invent one. " +
|
|
175
|
+
"Tool acceptance is pending, not delivery, so do not repeat the reply in assistant text or " +
|
|
176
|
+
"claim that it was sent.",
|
|
177
|
+
inputSchema: {
|
|
178
|
+
type: "object",
|
|
179
|
+
additionalProperties: false,
|
|
180
|
+
properties: {
|
|
181
|
+
text: {
|
|
182
|
+
type: "string",
|
|
183
|
+
minLength: 1,
|
|
184
|
+
maxLength: MAX_GATEWAY_REPLY_TEXT_LENGTH,
|
|
185
|
+
description: "The complete user-facing reply to deliver to the current IM conversation.",
|
|
186
|
+
},
|
|
187
|
+
button: {
|
|
188
|
+
type: "object",
|
|
189
|
+
additionalProperties: false,
|
|
190
|
+
properties: {
|
|
191
|
+
text: { type: "string", minLength: 1, maxLength: MAX_GATEWAY_BUTTON_TEXT_LENGTH },
|
|
192
|
+
url: {
|
|
193
|
+
type: "string",
|
|
194
|
+
minLength: 1,
|
|
195
|
+
maxLength: MAX_GATEWAY_BUTTON_URL_LENGTH,
|
|
196
|
+
description: "An absolute http(s) URL.",
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
required: ["text", "url"],
|
|
200
|
+
},
|
|
201
|
+
attachment_paths: {
|
|
202
|
+
type: "array",
|
|
203
|
+
minItems: 1,
|
|
204
|
+
maxItems: MAX_GATEWAY_ATTACHMENTS,
|
|
205
|
+
uniqueItems: true,
|
|
206
|
+
items: {
|
|
207
|
+
type: "string",
|
|
208
|
+
minLength: 1,
|
|
209
|
+
maxLength: MAX_GATEWAY_ATTACHMENT_PATH_LENGTH,
|
|
210
|
+
description: "Exact absolute local path from trusted context or the user's message.",
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
required: ["text"],
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
export const gatewayReplyAvailability = hostActionAvailability("gatewayReply");
|
|
218
|
+
function gatewayReplyCapability(ctx) {
|
|
219
|
+
const services = ctx?.runScopedServices;
|
|
220
|
+
return services?.petGatewayReply;
|
|
221
|
+
}
|
|
222
|
+
function gatewayReplyCapabilityFromVisibility(ctx) {
|
|
223
|
+
const value = ctx.profileMeta?.petGatewayReply;
|
|
224
|
+
if (!isRecord(value))
|
|
225
|
+
return undefined;
|
|
226
|
+
return value;
|
|
227
|
+
}
|
|
228
|
+
export function rewriteGatewayReplyDef(def, ctx) {
|
|
229
|
+
const capability = gatewayReplyCapabilityFromVisibility(ctx);
|
|
230
|
+
if (!capability)
|
|
231
|
+
return def;
|
|
232
|
+
const properties = gatewayReplyToolDef.inputSchema.properties;
|
|
233
|
+
const { attachment_paths: attachmentPaths, ...textAndButton } = properties;
|
|
234
|
+
const textProperty = textAndButton.text;
|
|
235
|
+
const attachmentDescription = capability.attachments.length
|
|
236
|
+
? ` This route also accepts ${capability.attachments.join("/")} attachments (maximum ${capability.maxAttachments}, ${capability.maxAttachmentBytes} bytes each).`
|
|
237
|
+
: " This route does not accept outgoing attachments.";
|
|
238
|
+
return {
|
|
239
|
+
...def,
|
|
240
|
+
description: `${gatewayReplyToolDef.description} The button is rendered as a ${capability.button === "native" ? "native channel button" : "labelled text link"}.` +
|
|
241
|
+
attachmentDescription,
|
|
242
|
+
inputSchema: {
|
|
243
|
+
...gatewayReplyToolDef.inputSchema,
|
|
244
|
+
properties: {
|
|
245
|
+
...textAndButton,
|
|
246
|
+
text: { ...textProperty, maxLength: capability.maxTextLength },
|
|
247
|
+
...(capability.attachments.length > 0 && attachmentPaths
|
|
248
|
+
? {
|
|
249
|
+
attachment_paths: {
|
|
250
|
+
...attachmentPaths,
|
|
251
|
+
maxItems: capability.maxAttachments,
|
|
252
|
+
},
|
|
253
|
+
}
|
|
254
|
+
: {}),
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
export async function gatewayReplyTool(args, ctx) {
|
|
260
|
+
const request = hostActionService(ctx);
|
|
261
|
+
const capability = gatewayReplyCapability(ctx);
|
|
262
|
+
if (!request || !capability) {
|
|
263
|
+
return "Error: GatewayReply is available only in a Mimi turn originating from Chat Gateway.";
|
|
264
|
+
}
|
|
265
|
+
const text = typeof args.text === "string" ? args.text.trim() : "";
|
|
266
|
+
const button = args.button;
|
|
267
|
+
const attachmentPaths = args.attachment_paths;
|
|
268
|
+
const payload = {
|
|
269
|
+
text,
|
|
270
|
+
...(button === undefined ? {} : { button }),
|
|
271
|
+
...(attachmentPaths === undefined ? {} : { attachmentPaths }),
|
|
272
|
+
};
|
|
273
|
+
if (!isGatewayReplyPayload(payload)) {
|
|
274
|
+
return "Error: GatewayReply requires bounded text, an optional valid http(s) button, and optional unique absolute attachment_paths.";
|
|
275
|
+
}
|
|
276
|
+
if (text.length > capability.maxTextLength) {
|
|
277
|
+
return `Error: the current Gateway route accepts at most ${capability.maxTextLength} text characters.`;
|
|
278
|
+
}
|
|
279
|
+
if (Array.isArray(attachmentPaths)) {
|
|
280
|
+
if (capability.attachments.length === 0) {
|
|
281
|
+
return "Error: the current Gateway route cannot send attachments.";
|
|
282
|
+
}
|
|
283
|
+
if (attachmentPaths.length > capability.maxAttachments) {
|
|
284
|
+
return `Error: the current Gateway route accepts at most ${capability.maxAttachments} attachments.`;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const decision = request({ kind: "gatewayReply", payload });
|
|
288
|
+
if (!decision.ok)
|
|
289
|
+
return `Error: ${decision.error ?? "Gateway reply was rejected"}`;
|
|
290
|
+
return ("ACCEPTED EXACTLY ONCE — NOT SENT YET. The Gateway reply was recorded for host validation " +
|
|
291
|
+
"after this turn. End the turn now with only a short internal acknowledgement; do not call " +
|
|
292
|
+
"GatewayReply again, repeat the user-facing reply, or claim sent, attached, or delivered.");
|
|
293
|
+
}
|
|
294
|
+
// ---------------------------------------------------------------------------
|
|
295
|
+
// ControlLongTask
|
|
296
|
+
// ---------------------------------------------------------------------------
|
|
297
|
+
export const CONTROL_LONG_TASK_TOOL_NAME = "ControlLongTask";
|
|
298
|
+
const LONG_TASK_ACTIONS = ["pause", "resume", "retry", "cancel"];
|
|
299
|
+
export const controlLongTaskToolDef = {
|
|
300
|
+
name: CONTROL_LONG_TASK_TOOL_NAME,
|
|
301
|
+
description: "Request the host to pause, resume, retry, or cancel one long-running task from the " +
|
|
302
|
+
"longTasks ledger in the runtime context. task_id must be copied exactly from that ledger. " +
|
|
303
|
+
"The host performs the operation after this turn and appends the real outcome to your " +
|
|
304
|
+
"reply; acceptance is not success.",
|
|
305
|
+
inputSchema: {
|
|
306
|
+
type: "object",
|
|
307
|
+
additionalProperties: false,
|
|
308
|
+
properties: {
|
|
309
|
+
task_id: {
|
|
310
|
+
type: "string",
|
|
311
|
+
description: "Exact taskId from the longTasks ledger in the runtime context.",
|
|
312
|
+
},
|
|
313
|
+
action: {
|
|
314
|
+
type: "string",
|
|
315
|
+
enum: [...LONG_TASK_ACTIONS],
|
|
316
|
+
description: "Lifecycle operation the host should apply to the task.",
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
required: ["task_id", "action"],
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
export const controlLongTaskAvailability = hostActionAvailability("longTaskControl");
|
|
323
|
+
export async function controlLongTaskTool(args, ctx) {
|
|
324
|
+
const request = hostActionService(ctx);
|
|
325
|
+
if (!request)
|
|
326
|
+
return "Error: ControlLongTask is available only in a Mimi manager turn.";
|
|
327
|
+
const taskId = typeof args.task_id === "string" ? args.task_id.trim() : "";
|
|
328
|
+
const action = args.action;
|
|
329
|
+
if (!taskId)
|
|
330
|
+
return "Error: task_id is required; copy it exactly from the longTasks ledger.";
|
|
331
|
+
if (!LONG_TASK_ACTIONS.includes(action)) {
|
|
332
|
+
return `Error: unknown action ${JSON.stringify(action)}. Use ${LONG_TASK_ACTIONS.map((entry) => JSON.stringify(entry)).join(", ")}.`;
|
|
333
|
+
}
|
|
334
|
+
const decision = request({ kind: "longTaskControl", payload: { taskId, action } });
|
|
335
|
+
if (!decision.ok)
|
|
336
|
+
return `Error: ${decision.error ?? "long-task control was rejected"}`;
|
|
337
|
+
return (`Long-task ${String(action)} request accepted. The host will apply it after this turn and ` +
|
|
338
|
+
"append the real outcome to your reply; do not claim the task state changed yet.");
|
|
339
|
+
}
|
|
340
|
+
// ---------------------------------------------------------------------------
|
|
341
|
+
// Memory
|
|
342
|
+
// ---------------------------------------------------------------------------
|
|
343
|
+
export const MEMORY_TOOL_NAME = "Memory";
|
|
344
|
+
const MEMORY_ACTIONS = ["remember", "update", "forget"];
|
|
345
|
+
export const memoryToolDef = {
|
|
346
|
+
name: MEMORY_TOOL_NAME,
|
|
347
|
+
description: "Maintain Mimi's durable memory of the user: stable preferences, facts, and standing " +
|
|
348
|
+
"instructions worth keeping across conversations. The newest bounded memory window appears " +
|
|
349
|
+
"in runtime context with ids; memoryWindow reports whether older entries are omitted. " +
|
|
350
|
+
"remember adds a new entry; update rewrites one visible existing entry by " +
|
|
351
|
+
"memory_id; forget removes one entry by memory_id. Never store secrets, passwords, or " +
|
|
352
|
+
"one-off conversational details. Do not invent an id for an omitted older entry; ask the user " +
|
|
353
|
+
"to manage it in Memory settings. The host applies the change after this turn.",
|
|
354
|
+
inputSchema: {
|
|
355
|
+
type: "object",
|
|
356
|
+
additionalProperties: false,
|
|
357
|
+
properties: {
|
|
358
|
+
action: {
|
|
359
|
+
type: "string",
|
|
360
|
+
enum: [...MEMORY_ACTIONS],
|
|
361
|
+
description: "remember adds; update rewrites by memory_id; forget removes by memory_id.",
|
|
362
|
+
},
|
|
363
|
+
memory_id: {
|
|
364
|
+
type: "string",
|
|
365
|
+
description: "Exact id from the visible memories window in runtime context (update/forget).",
|
|
366
|
+
},
|
|
367
|
+
text: {
|
|
368
|
+
type: "string",
|
|
369
|
+
description: "Full replacement text of the memory, at most 2000 characters (remember/update).",
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
required: ["action"],
|
|
373
|
+
},
|
|
374
|
+
};
|
|
375
|
+
export const memoryAvailability = hostActionAvailability("memory");
|
|
376
|
+
export async function memoryTool(args, ctx) {
|
|
377
|
+
const request = hostActionService(ctx);
|
|
378
|
+
if (!request)
|
|
379
|
+
return "Error: Memory is available only in a Mimi manager turn.";
|
|
380
|
+
const action = args.action;
|
|
381
|
+
if (!MEMORY_ACTIONS.includes(action)) {
|
|
382
|
+
return `Error: unknown action ${JSON.stringify(action)}. Use ${MEMORY_ACTIONS.map((entry) => JSON.stringify(entry)).join(", ")}.`;
|
|
383
|
+
}
|
|
384
|
+
const memoryId = typeof args.memory_id === "string" ? args.memory_id.trim() : "";
|
|
385
|
+
const text = typeof args.text === "string" ? args.text.replace(/\s+/gu, " ").trim() : "";
|
|
386
|
+
if ((action === "remember" || action === "update") && !text) {
|
|
387
|
+
return "Error: text is required for remember/update.";
|
|
388
|
+
}
|
|
389
|
+
if (text.length > MAX_MEMORY_TEXT_LENGTH) {
|
|
390
|
+
return `Error: text is too long (maximum ${MAX_MEMORY_TEXT_LENGTH} characters).`;
|
|
391
|
+
}
|
|
392
|
+
if ((action === "update" || action === "forget") && !memoryId) {
|
|
393
|
+
return "Error: memory_id is required for update/forget; copy it from the memories list.";
|
|
394
|
+
}
|
|
395
|
+
const payload = {
|
|
396
|
+
action,
|
|
397
|
+
...(action === "update" || action === "forget" ? { memoryId } : {}),
|
|
398
|
+
...(action === "remember" || action === "update" ? { text } : {}),
|
|
399
|
+
};
|
|
400
|
+
const decision = request({ kind: "memory", payload });
|
|
401
|
+
if (!decision.ok)
|
|
402
|
+
return `Error: ${decision.error ?? "memory change was rejected"}`;
|
|
403
|
+
return ("Memory change request accepted. The host will apply it after this turn; " +
|
|
404
|
+
"do not claim it is stored until the host confirms.");
|
|
405
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @cjhyy/code-shell-pet — Pet (top-level personal assistant) capability.
|
|
3
|
+
*
|
|
4
|
+
* Owns the Pet domain that used to live inside core: projection domain model,
|
|
5
|
+
* owner-scoped session/pending-decision read models, and the DelegateWork
|
|
6
|
+
* delegation contract. Composed by hosts (desktop worker via
|
|
7
|
+
* CODE_SHELL_CAPABILITY_MODULES, future packages/server) — core stays
|
|
8
|
+
* pet-free and only provides the generic extension seams.
|
|
9
|
+
*/
|
|
10
|
+
export * from "./types.js";
|
|
11
|
+
export * from "./delegation.js";
|
|
12
|
+
export * from "./team.js";
|
|
13
|
+
export * from "./protocol.js";
|
|
14
|
+
export { REPORT_TO_MIMI_TOOL_NAME, reportToMimiToolDef, reportToMimiTool, reportToMimiAvailability, type PetReportToMimiSink, } from "./report-to-mimi.js";
|
|
15
|
+
export { petRunOptionsFrom, validatePetRunParams, type PetRunOptions } from "./run-params.js";
|
|
16
|
+
export { SessionIndex } from "./session-index.js";
|
|
17
|
+
export { PendingDecisionIndex, safePendingTitle } from "./pending-decision-index.js";
|
|
18
|
+
export { PET_BEHAVIOR_PROFILE, PET_SYSTEM_PROMPT, PET_ALLOWED_TOOL_NAMES, type PetRunScopedServices, } from "./profile.js";
|
|
19
|
+
export { createPetProjectionObserver, PET_HIDDEN_SESSION_KINDS } from "./projection-extension.js";
|
|
20
|
+
export { delegateWorkToolDef, delegateWorkToolDefFor, delegateWorkTool, delegateWorkAvailability, rewriteDelegateWorkDef, } from "./delegate-work.js";
|
|
21
|
+
export { MOBILE_REMOTE_TOOL_NAME, mobileRemoteToolDef, mobileRemoteTool, mobileRemoteAvailability, type PetMobileRemoteAction, type PetMobileRemoteRequest, type PetMobileRemoteDecision, } from "./mobile-remote.js";
|
|
22
|
+
export { GATEWAY_TOOL_NAME, gatewayToolDef, gatewayTool, gatewayAvailability, parsePetGatewayCatalog, type PetGatewayAttachmentKind, type PetGatewayChannelCapabilities, type PetGatewayChannel, type PetGatewayCatalog, } from "./gateway.js";
|
|
23
|
+
export { SESSIONS_TOOL_NAME, sessionsToolDef, sessionsTool, sessionsAvailability, } from "./sessions-tool.js";
|
|
24
|
+
export { CURRENT_TIME_TOOL_NAME, currentTimeToolDef, currentTimeTool, currentTimeAvailability, } from "./current-time.js";
|
|
25
|
+
export { MANAGE_SESSIONS_TOOL_NAME, manageSessionsToolDef, manageSessionsTool, manageSessionsAvailability, } from "./session-control.js";
|
|
26
|
+
export { FOLLOW_UPS_TOOL_NAME, MANAGE_FOLLOW_UP_TOOL_NAME, followUpsToolDef, followUpsTool, followUpsAvailability, manageFollowUpToolDef, manageFollowUpTool, manageFollowUpAvailability, type PetFollowUpItem, } from "./follow-ups.js";
|
|
27
|
+
export { SEND_MESSAGE_TOOL_NAME, sendMessageToolDef, sendMessageTool, sendMessageAvailability, rewriteSendMessageDef, type PetOutboundTargetOption, } from "./outbound-message.js";
|
|
28
|
+
export { PET_HOST_ACTION_KINDS, isPetHostActionKind, isPetHostActionRequest, CONTROL_LONG_TASK_TOOL_NAME, GATEWAY_REPLY_TOOL_NAME, MEMORY_TOOL_NAME, controlLongTaskToolDef, controlLongTaskTool, controlLongTaskAvailability, memoryToolDef, memoryTool, memoryAvailability, gatewayReplyToolDef, gatewayReplyTool, gatewayReplyAvailability, rewriteGatewayReplyDef, type PetGatewayReplyAttachmentKind, type PetGatewayReplyCapability, type PetHostActionKind, type PetHostActionRequest, type PetHostActionDecision, } from "./host-actions.js";
|
|
29
|
+
export { createPetCapability } from "./capability.js";
|
|
30
|
+
export * from "./topic-segment.js";
|
|
31
|
+
export * from "./segment-closure.js";
|
|
32
|
+
export * from "./long-task.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node-only disclosure entry, kept out of the browser-safe main entry because
|
|
3
|
+
* it imports node:fs. Pure disk readers over on-disk sessions
|
|
4
|
+
* (~/.code-shell/sessions/<id>/{state.json,transcript.jsonl}) for progressive
|
|
5
|
+
* disclosure surfaces (Mimi tool, desktop UI) built on top of this package.
|
|
6
|
+
*/
|
|
7
|
+
export * from "./disclosure/constants.js";
|
|
8
|
+
export * from "./disclosure/jsonl.js";
|
|
9
|
+
export * from "./disclosure/latest-result.js";
|
|
10
|
+
export * from "./disclosure/todo-snapshot.js";
|
|
11
|
+
export * from "./disclosure/catalog.js";
|
|
12
|
+
export * from "./disclosure/selector.js";
|
|
13
|
+
export * from "./disclosure/search.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node-only disclosure entry, kept out of the browser-safe main entry because
|
|
3
|
+
* it imports node:fs. Pure disk readers over on-disk sessions
|
|
4
|
+
* (~/.code-shell/sessions/<id>/{state.json,transcript.jsonl}) for progressive
|
|
5
|
+
* disclosure surfaces (Mimi tool, desktop UI) built on top of this package.
|
|
6
|
+
*/
|
|
7
|
+
export * from "./disclosure/constants.js";
|
|
8
|
+
export * from "./disclosure/jsonl.js";
|
|
9
|
+
export * from "./disclosure/latest-result.js";
|
|
10
|
+
export * from "./disclosure/todo-snapshot.js";
|
|
11
|
+
export * from "./disclosure/catalog.js";
|
|
12
|
+
export * from "./disclosure/selector.js";
|
|
13
|
+
export * from "./disclosure/search.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @cjhyy/code-shell-pet — Pet (top-level personal assistant) capability.
|
|
3
|
+
*
|
|
4
|
+
* Owns the Pet domain that used to live inside core: projection domain model,
|
|
5
|
+
* owner-scoped session/pending-decision read models, and the DelegateWork
|
|
6
|
+
* delegation contract. Composed by hosts (desktop worker via
|
|
7
|
+
* CODE_SHELL_CAPABILITY_MODULES, future packages/server) — core stays
|
|
8
|
+
* pet-free and only provides the generic extension seams.
|
|
9
|
+
*/
|
|
10
|
+
export * from "./types.js";
|
|
11
|
+
export * from "./delegation.js";
|
|
12
|
+
export * from "./team.js";
|
|
13
|
+
export * from "./protocol.js";
|
|
14
|
+
export { REPORT_TO_MIMI_TOOL_NAME, reportToMimiToolDef, reportToMimiTool, reportToMimiAvailability, } from "./report-to-mimi.js";
|
|
15
|
+
export { petRunOptionsFrom, validatePetRunParams } from "./run-params.js";
|
|
16
|
+
export { SessionIndex } from "./session-index.js";
|
|
17
|
+
export { PendingDecisionIndex, safePendingTitle } from "./pending-decision-index.js";
|
|
18
|
+
export { PET_BEHAVIOR_PROFILE, PET_SYSTEM_PROMPT, PET_ALLOWED_TOOL_NAMES, } from "./profile.js";
|
|
19
|
+
export { createPetProjectionObserver, PET_HIDDEN_SESSION_KINDS } from "./projection-extension.js";
|
|
20
|
+
export { delegateWorkToolDef, delegateWorkToolDefFor, delegateWorkTool, delegateWorkAvailability, rewriteDelegateWorkDef, } from "./delegate-work.js";
|
|
21
|
+
export { MOBILE_REMOTE_TOOL_NAME, mobileRemoteToolDef, mobileRemoteTool, mobileRemoteAvailability, } from "./mobile-remote.js";
|
|
22
|
+
export { GATEWAY_TOOL_NAME, gatewayToolDef, gatewayTool, gatewayAvailability, parsePetGatewayCatalog, } from "./gateway.js";
|
|
23
|
+
export { SESSIONS_TOOL_NAME, sessionsToolDef, sessionsTool, sessionsAvailability, } from "./sessions-tool.js";
|
|
24
|
+
export { CURRENT_TIME_TOOL_NAME, currentTimeToolDef, currentTimeTool, currentTimeAvailability, } from "./current-time.js";
|
|
25
|
+
export { MANAGE_SESSIONS_TOOL_NAME, manageSessionsToolDef, manageSessionsTool, manageSessionsAvailability, } from "./session-control.js";
|
|
26
|
+
export { FOLLOW_UPS_TOOL_NAME, MANAGE_FOLLOW_UP_TOOL_NAME, followUpsToolDef, followUpsTool, followUpsAvailability, manageFollowUpToolDef, manageFollowUpTool, manageFollowUpAvailability, } from "./follow-ups.js";
|
|
27
|
+
export { SEND_MESSAGE_TOOL_NAME, sendMessageToolDef, sendMessageTool, sendMessageAvailability, rewriteSendMessageDef, } from "./outbound-message.js";
|
|
28
|
+
export { PET_HOST_ACTION_KINDS, isPetHostActionKind, isPetHostActionRequest, CONTROL_LONG_TASK_TOOL_NAME, GATEWAY_REPLY_TOOL_NAME, MEMORY_TOOL_NAME, controlLongTaskToolDef, controlLongTaskTool, controlLongTaskAvailability, memoryToolDef, memoryTool, memoryAvailability, gatewayReplyToolDef, gatewayReplyTool, gatewayReplyAvailability, rewriteGatewayReplyDef, } from "./host-actions.js";
|
|
29
|
+
export { createPetCapability } from "./capability.js";
|
|
30
|
+
export * from "./topic-segment.js";
|
|
31
|
+
export * from "./segment-closure.js";
|
|
32
|
+
export * from "./long-task.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable Pet projection wire contract for host bridges and UI clients.
|
|
3
|
+
*
|
|
4
|
+
* State-machine implementations remain package-private; this entry contains
|
|
5
|
+
* only method names and the shapes crossing the host boundary.
|
|
6
|
+
*/
|
|
7
|
+
export { GET_PET_PROJECTION_SNAPSHOT_METHOD, PET_PROJECTION_DELTA_METHOD, PET_REPORT_TO_MIMI_METHOD, type PetProjectionDelta, type PetProjectionSnapshotResult, type PetReportToMimiEvent, } from "./protocol.js";
|
|
8
|
+
export { LOCAL_PET_OWNER, type PendingDecisionKind, type PendingDecisionProjection, type PendingDecisionStatus, type PetOwnerId, type PetProjectionCursor, type PetProjectionFreshness, type PetProjectionSnapshot, type PetSessionPhase, type PetSessionProjection, type PetSessionRunState, type PetTerminalStatus, type PetWorkerState, } from "./types.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable Pet projection wire contract for host bridges and UI clients.
|
|
3
|
+
*
|
|
4
|
+
* State-machine implementations remain package-private; this entry contains
|
|
5
|
+
* only method names and the shapes crossing the host boundary.
|
|
6
|
+
*/
|
|
7
|
+
export { GET_PET_PROJECTION_SNAPSHOT_METHOD, PET_PROJECTION_DELTA_METHOD, PET_REPORT_TO_MIMI_METHOD, } from "./protocol.js";
|
|
8
|
+
export { LOCAL_PET_OWNER, } from "./types.js";
|