@oyasmi/pipiclaw 0.6.6-beta.2 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/channel-runner.d.ts +9 -4
- package/dist/agent/channel-runner.js +126 -74
- package/dist/agent/command-extension.js +15 -7
- package/dist/agent/session-events.js +0 -2
- package/dist/agent/types.d.ts +0 -1
- package/dist/memory/lifecycle.d.ts +1 -1
- package/dist/memory/lifecycle.js +3 -3
- package/dist/runtime/bootstrap.js +17 -17
- package/dist/runtime/delivery.js +4 -22
- package/dist/runtime/dingtalk.d.ts +7 -1
- package/dist/runtime/dingtalk.js +12 -11
- package/dist/subagents/tool.d.ts +16 -15
- package/dist/subagents/tool.js +1 -1
- package/dist/tools/attach.d.ts +5 -4
- package/dist/tools/attach.js +1 -1
- package/dist/tools/bash.d.ts +5 -4
- package/dist/tools/bash.js +1 -1
- package/dist/tools/edit.d.ts +6 -5
- package/dist/tools/edit.js +1 -1
- package/dist/tools/read.d.ts +6 -5
- package/dist/tools/read.js +1 -1
- package/dist/tools/session-search.d.ts +6 -5
- package/dist/tools/session-search.js +1 -1
- package/dist/tools/skill-list.d.ts +3 -2
- package/dist/tools/skill-list.js +1 -1
- package/dist/tools/skill-manage.d.ts +9 -8
- package/dist/tools/skill-manage.js +1 -1
- package/dist/tools/skill-view.d.ts +5 -4
- package/dist/tools/skill-view.js +1 -1
- package/dist/tools/web-fetch.d.ts +6 -5
- package/dist/tools/web-fetch.js +1 -1
- package/dist/tools/web-search.d.ts +5 -4
- package/dist/tools/web-search.js +1 -1
- package/dist/tools/write.d.ts +5 -4
- package/dist/tools/write.js +1 -1
- package/package.json +6 -6
|
@@ -11,15 +11,17 @@ export declare class ChannelRunner implements AgentRunner {
|
|
|
11
11
|
private readonly channelDir;
|
|
12
12
|
private readonly workspacePath;
|
|
13
13
|
private readonly workspaceDir;
|
|
14
|
-
private
|
|
15
|
-
private
|
|
16
|
-
private
|
|
14
|
+
private session;
|
|
15
|
+
private agent;
|
|
16
|
+
private sessionManager;
|
|
17
17
|
private readonly settingsManager;
|
|
18
18
|
private readonly modelRegistry;
|
|
19
19
|
private readonly memoryLifecycle;
|
|
20
20
|
private readonly memoryCandidateStore;
|
|
21
21
|
private readonly sessionResourceGate;
|
|
22
22
|
private readonly sessionReady;
|
|
23
|
+
private readonly sessionRuntime;
|
|
24
|
+
private sessionUnsubscribe?;
|
|
23
25
|
private subAgentDiscovery;
|
|
24
26
|
private activeModel;
|
|
25
27
|
private currentSkills;
|
|
@@ -34,7 +36,6 @@ export declare class ChannelRunner implements AgentRunner {
|
|
|
34
36
|
}>;
|
|
35
37
|
handleBuiltinCommand(ctx: DingTalkContext, command: BuiltInCommand): Promise<void>;
|
|
36
38
|
queueSteer(text: string, userName?: string): Promise<void>;
|
|
37
|
-
queueFollowUp(text: string, userName?: string): Promise<void>;
|
|
38
39
|
flushMemoryForShutdown(): Promise<void>;
|
|
39
40
|
getMemoryMaintenanceContext(): Promise<MemoryMaintenanceRuntimeContext>;
|
|
40
41
|
abort(): Promise<void>;
|
|
@@ -54,6 +55,10 @@ export declare class ChannelRunner implements AgentRunner {
|
|
|
54
55
|
private refreshSubAgentDiscovery;
|
|
55
56
|
private reportSettingsDiagnostics;
|
|
56
57
|
private reportConfigDiagnostics;
|
|
58
|
+
private createResourceLoader;
|
|
59
|
+
private createAgentSessionServices;
|
|
60
|
+
private createEmptyExtensionsResult;
|
|
61
|
+
private createSessionRuntime;
|
|
57
62
|
private buildRuntimeTools;
|
|
58
63
|
private rebuildSessionTools;
|
|
59
64
|
private subscribeToSessionEvents;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Agent } from "@mariozechner/pi-agent-core";
|
|
2
|
-
import { AgentSession, AuthStorage, convertToLlm, DefaultResourceLoader, ModelRegistry, SessionManager, } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import { AgentSession, AgentSessionRuntime, AuthStorage, convertToLlm, createExtensionRuntime, DefaultResourceLoader, ModelRegistry, SessionManager, } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
4
4
|
import { dirname, join, resolve } from "path";
|
|
5
5
|
import * as log from "../log.js";
|
|
@@ -80,15 +80,14 @@ export class ChannelRunner {
|
|
|
80
80
|
this.activeModel = resolveInitialModel(this.modelRegistry, this.settingsManager);
|
|
81
81
|
log.logInfo(`Using model: ${this.activeModel.provider}/${this.activeModel.id} (${this.activeModel.name})`);
|
|
82
82
|
this.subAgentDiscovery = this.refreshSubAgentDiscovery();
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
// Create agent
|
|
83
|
+
const initialSessionManager = this.sessionManager;
|
|
84
|
+
const initialTools = this.buildRuntimeTools();
|
|
86
85
|
this.agent = new Agent({
|
|
87
86
|
initialState: {
|
|
88
87
|
systemPrompt: "",
|
|
89
88
|
model: this.activeModel,
|
|
90
89
|
thinkingLevel: "off",
|
|
91
|
-
tools,
|
|
90
|
+
tools: initialTools,
|
|
92
91
|
},
|
|
93
92
|
convertToLlm,
|
|
94
93
|
getApiKey: async () => getApiKeyForModel(this.modelRegistry, this.activeModel),
|
|
@@ -105,62 +104,33 @@ export class ChannelRunner {
|
|
|
105
104
|
void this.recordMemoryActivity(event);
|
|
106
105
|
},
|
|
107
106
|
});
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
agentDir: APP_HOME_DIR,
|
|
111
|
-
settingsManager: asSdkSettingsManager(this.settingsManager),
|
|
112
|
-
extensionFactories: [
|
|
113
|
-
this.memoryLifecycle.createExtensionFactory(),
|
|
114
|
-
createCommandExtension({
|
|
115
|
-
getCurrentModel: () => this.session.model ?? this.activeModel,
|
|
116
|
-
getAvailableModels: async () => {
|
|
117
|
-
this.modelRegistry.refresh();
|
|
118
|
-
return await this.modelRegistry.getAvailable();
|
|
119
|
-
},
|
|
120
|
-
getSessionStats: () => this.session.getSessionStats(),
|
|
121
|
-
getThinkingLevel: () => this.session.thinkingLevel,
|
|
122
|
-
switchModel: async (model) => {
|
|
123
|
-
await this.session.setModel(model);
|
|
124
|
-
this.activeModel = model;
|
|
125
|
-
},
|
|
126
|
-
refreshSessionResources: async () => {
|
|
127
|
-
await this.refreshSessionResources();
|
|
128
|
-
},
|
|
129
|
-
}),
|
|
130
|
-
],
|
|
131
|
-
appendSystemPromptOverride: (base) => {
|
|
132
|
-
const soul = getSoul(this.workspaceDir);
|
|
133
|
-
const sections = [...base];
|
|
134
|
-
if (soul) {
|
|
135
|
-
sections.unshift(soul);
|
|
136
|
-
}
|
|
137
|
-
sections.push(buildAppendSystemPrompt(this.workspacePath, this.channelId, this.sandboxConfig, {
|
|
138
|
-
subAgentList: formatSubAgentList(this.subAgentDiscovery.agents),
|
|
139
|
-
}));
|
|
140
|
-
return sections;
|
|
141
|
-
},
|
|
142
|
-
agentsFilesOverride: () => {
|
|
143
|
-
const agentConfig = getAgentConfig(this.channelDir);
|
|
144
|
-
return {
|
|
145
|
-
agentsFiles: agentConfig ? [{ path: `${this.workspacePath}/AGENTS.md`, content: agentConfig }] : [],
|
|
146
|
-
};
|
|
147
|
-
},
|
|
148
|
-
skillsOverride: (base) => ({
|
|
149
|
-
skills: [...base.skills, ...this.currentSkills],
|
|
150
|
-
diagnostics: base.diagnostics,
|
|
151
|
-
}),
|
|
152
|
-
});
|
|
153
|
-
const baseToolsOverride = Object.fromEntries(tools.map((tool) => [tool.name, tool]));
|
|
154
|
-
// Create AgentSession
|
|
107
|
+
const initialResourceLoader = this.createResourceLoader();
|
|
108
|
+
const baseToolsOverride = Object.fromEntries(initialTools.map((tool) => [tool.name, tool]));
|
|
155
109
|
this.session = new AgentSession({
|
|
156
110
|
agent: this.agent,
|
|
157
|
-
sessionManager:
|
|
111
|
+
sessionManager: initialSessionManager,
|
|
158
112
|
settingsManager: asSdkSettingsManager(this.settingsManager),
|
|
159
113
|
cwd: process.cwd(),
|
|
160
114
|
modelRegistry: this.modelRegistry,
|
|
161
|
-
resourceLoader,
|
|
115
|
+
resourceLoader: initialResourceLoader,
|
|
162
116
|
baseToolsOverride,
|
|
163
117
|
});
|
|
118
|
+
this.sessionRuntime = new AgentSessionRuntime(this.session, this.createAgentSessionServices(initialResourceLoader), async ({ sessionManager, sessionStartEvent }) => {
|
|
119
|
+
const next = this.createSessionRuntime(sessionManager, sessionStartEvent);
|
|
120
|
+
return {
|
|
121
|
+
session: next.session,
|
|
122
|
+
extensionsResult: this.createEmptyExtensionsResult(),
|
|
123
|
+
services: this.createAgentSessionServices(next.resourceLoader),
|
|
124
|
+
diagnostics: [],
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
this.sessionRuntime.setRebindSession(async (session) => {
|
|
128
|
+
this.session = session;
|
|
129
|
+
this.agent = session.agent;
|
|
130
|
+
this.sessionManager = session.sessionManager;
|
|
131
|
+
await this.bindSessionExtensions();
|
|
132
|
+
this.subscribeToSessionEvents();
|
|
133
|
+
});
|
|
164
134
|
this.sessionResourceGate = new SessionResourceGate(async () => {
|
|
165
135
|
await this.reloadSessionResources();
|
|
166
136
|
});
|
|
@@ -356,10 +326,7 @@ export class ChannelRunner {
|
|
|
356
326
|
}
|
|
357
327
|
}
|
|
358
328
|
async queueSteer(text, userName) {
|
|
359
|
-
await this.queueBusyMessage(
|
|
360
|
-
}
|
|
361
|
-
async queueFollowUp(text, userName) {
|
|
362
|
-
await this.queueBusyMessage("followUp", this.requireQueuedMessage(text, "followup"), userName);
|
|
329
|
+
await this.queueBusyMessage(this.requireQueuedMessage(text, "steer"), userName);
|
|
363
330
|
}
|
|
364
331
|
async flushMemoryForShutdown() {
|
|
365
332
|
await this.memoryLifecycle.flushForShutdown();
|
|
@@ -437,7 +404,7 @@ export class ChannelRunner {
|
|
|
437
404
|
const timestamp = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}${offsetSign}${offsetHours}:${offsetMins}`;
|
|
438
405
|
return `[${timestamp}] [${userName || "unknown"}]: ${text}`;
|
|
439
406
|
}
|
|
440
|
-
async queueBusyMessage(
|
|
407
|
+
async queueBusyMessage(text, userName) {
|
|
441
408
|
if (!this.acceptingBusyMessages) {
|
|
442
409
|
throw new Error("No task is currently running.");
|
|
443
410
|
}
|
|
@@ -461,12 +428,7 @@ export class ChannelRunner {
|
|
|
461
428
|
if (this.agentLoopStarted && !this.session.isStreaming) {
|
|
462
429
|
throw new Error("No task is currently running.");
|
|
463
430
|
}
|
|
464
|
-
|
|
465
|
-
await this.session.followUp(queuedMessage);
|
|
466
|
-
}
|
|
467
|
-
else {
|
|
468
|
-
await this.session.steer(queuedMessage);
|
|
469
|
-
}
|
|
431
|
+
await this.session.steer(queuedMessage);
|
|
470
432
|
};
|
|
471
433
|
await this.sessionResourceGate.runPrompt(queueMessage);
|
|
472
434
|
}
|
|
@@ -502,20 +464,18 @@ export class ChannelRunner {
|
|
|
502
464
|
commandContextActions: {
|
|
503
465
|
waitForIdle: () => this.session.agent.waitForIdle(),
|
|
504
466
|
newSession: async (options) => {
|
|
505
|
-
|
|
506
|
-
return { cancelled: !success };
|
|
467
|
+
return await this.sessionRuntime.newSession(options);
|
|
507
468
|
},
|
|
508
|
-
fork: async (entryId) => {
|
|
509
|
-
const result = await this.
|
|
469
|
+
fork: async (entryId, options) => {
|
|
470
|
+
const result = await this.sessionRuntime.fork(entryId, options);
|
|
510
471
|
return { cancelled: result.cancelled };
|
|
511
472
|
},
|
|
512
473
|
navigateTree: async (targetId, options) => {
|
|
513
474
|
const result = await this.session.navigateTree(targetId, options);
|
|
514
475
|
return { cancelled: result.cancelled };
|
|
515
476
|
},
|
|
516
|
-
switchSession: async (sessionPath) => {
|
|
517
|
-
|
|
518
|
-
return { cancelled: !success };
|
|
477
|
+
switchSession: async (sessionPath, options) => {
|
|
478
|
+
return await this.sessionRuntime.switchSession(sessionPath, options);
|
|
519
479
|
},
|
|
520
480
|
reload: async () => {
|
|
521
481
|
await this.refreshSessionResources();
|
|
@@ -565,6 +525,96 @@ export class ChannelRunner {
|
|
|
565
525
|
log.logWarning(`[${this.channelId}] ${formatConfigDiagnostic(diagnostic)}`, diagnostic.path);
|
|
566
526
|
}
|
|
567
527
|
}
|
|
528
|
+
createResourceLoader() {
|
|
529
|
+
return new DefaultResourceLoader({
|
|
530
|
+
cwd: process.cwd(),
|
|
531
|
+
agentDir: APP_HOME_DIR,
|
|
532
|
+
settingsManager: asSdkSettingsManager(this.settingsManager),
|
|
533
|
+
extensionFactories: [
|
|
534
|
+
this.memoryLifecycle.createExtensionFactory(),
|
|
535
|
+
createCommandExtension({
|
|
536
|
+
getCurrentModel: () => this.session.model ?? this.activeModel,
|
|
537
|
+
getAvailableModels: async () => {
|
|
538
|
+
this.modelRegistry.refresh();
|
|
539
|
+
return await this.modelRegistry.getAvailable();
|
|
540
|
+
},
|
|
541
|
+
getSessionStats: () => this.session.getSessionStats(),
|
|
542
|
+
getThinkingLevel: () => this.session.thinkingLevel,
|
|
543
|
+
switchModel: async (model) => {
|
|
544
|
+
await this.session.setModel(model);
|
|
545
|
+
this.activeModel = model;
|
|
546
|
+
},
|
|
547
|
+
refreshSessionResources: async () => {
|
|
548
|
+
await this.refreshSessionResources();
|
|
549
|
+
},
|
|
550
|
+
}),
|
|
551
|
+
],
|
|
552
|
+
appendSystemPromptOverride: (base) => {
|
|
553
|
+
const soul = getSoul(this.workspaceDir);
|
|
554
|
+
const sections = [...base];
|
|
555
|
+
if (soul) {
|
|
556
|
+
sections.unshift(soul);
|
|
557
|
+
}
|
|
558
|
+
sections.push(buildAppendSystemPrompt(this.workspacePath, this.channelId, this.sandboxConfig, {
|
|
559
|
+
subAgentList: formatSubAgentList(this.subAgentDiscovery.agents),
|
|
560
|
+
}));
|
|
561
|
+
return sections;
|
|
562
|
+
},
|
|
563
|
+
agentsFilesOverride: () => {
|
|
564
|
+
const agentConfig = getAgentConfig(this.channelDir);
|
|
565
|
+
return {
|
|
566
|
+
agentsFiles: agentConfig ? [{ path: `${this.workspacePath}/AGENTS.md`, content: agentConfig }] : [],
|
|
567
|
+
};
|
|
568
|
+
},
|
|
569
|
+
skillsOverride: (base) => ({
|
|
570
|
+
skills: [...base.skills, ...this.currentSkills],
|
|
571
|
+
diagnostics: base.diagnostics,
|
|
572
|
+
}),
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
createAgentSessionServices(resourceLoader) {
|
|
576
|
+
return {
|
|
577
|
+
cwd: process.cwd(),
|
|
578
|
+
agentDir: APP_HOME_DIR,
|
|
579
|
+
authStorage: AuthStorage.create(AUTH_CONFIG_PATH),
|
|
580
|
+
settingsManager: asSdkSettingsManager(this.settingsManager),
|
|
581
|
+
modelRegistry: this.modelRegistry,
|
|
582
|
+
resourceLoader,
|
|
583
|
+
diagnostics: [],
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
createEmptyExtensionsResult() {
|
|
587
|
+
return {
|
|
588
|
+
extensions: [],
|
|
589
|
+
errors: [],
|
|
590
|
+
runtime: createExtensionRuntime(),
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
createSessionRuntime(sessionManager, sessionStartEvent) {
|
|
594
|
+
const tools = this.buildRuntimeTools();
|
|
595
|
+
const agent = new Agent({
|
|
596
|
+
initialState: {
|
|
597
|
+
systemPrompt: "",
|
|
598
|
+
model: this.activeModel,
|
|
599
|
+
thinkingLevel: "off",
|
|
600
|
+
tools,
|
|
601
|
+
},
|
|
602
|
+
convertToLlm,
|
|
603
|
+
getApiKey: async () => getApiKeyForModel(this.modelRegistry, this.activeModel),
|
|
604
|
+
});
|
|
605
|
+
const resourceLoader = this.createResourceLoader();
|
|
606
|
+
const session = new AgentSession({
|
|
607
|
+
agent,
|
|
608
|
+
sessionManager,
|
|
609
|
+
settingsManager: asSdkSettingsManager(this.settingsManager),
|
|
610
|
+
cwd: process.cwd(),
|
|
611
|
+
modelRegistry: this.modelRegistry,
|
|
612
|
+
resourceLoader,
|
|
613
|
+
baseToolsOverride: Object.fromEntries(tools.map((tool) => [tool.name, tool])),
|
|
614
|
+
sessionStartEvent,
|
|
615
|
+
});
|
|
616
|
+
return { agent, session, resourceLoader };
|
|
617
|
+
}
|
|
568
618
|
buildRuntimeTools() {
|
|
569
619
|
const securityLoad = loadSecurityConfigWithDiagnostics(APP_HOME_DIR);
|
|
570
620
|
const toolsLoad = loadToolsConfigWithDiagnostics(APP_HOME_DIR);
|
|
@@ -589,13 +639,15 @@ export class ChannelRunner {
|
|
|
589
639
|
}
|
|
590
640
|
rebuildSessionTools() {
|
|
591
641
|
const tools = this.buildRuntimeTools();
|
|
592
|
-
this.agent.setTools(tools);
|
|
593
642
|
this.session._baseToolsOverride =
|
|
594
643
|
Object.fromEntries(tools.map((tool) => [tool.name, tool]));
|
|
644
|
+
this.agent.state.tools = tools;
|
|
645
|
+
this.session.setActiveToolsByName(tools.map((tool) => tool.name));
|
|
595
646
|
}
|
|
596
647
|
// === Session event subscription ===
|
|
597
648
|
subscribeToSessionEvents() {
|
|
598
|
-
this.
|
|
649
|
+
this.sessionUnsubscribe?.();
|
|
650
|
+
this.sessionUnsubscribe = this.session.subscribe(async (event) => {
|
|
599
651
|
if (isRecord(event) && event.type === "message_start") {
|
|
600
652
|
this.agentLoopStarted = true;
|
|
601
653
|
}
|
|
@@ -27,8 +27,8 @@ async function runCompact(ctx, customInstructions) {
|
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
|
-
function sendCommandResult(
|
|
31
|
-
|
|
30
|
+
function sendCommandResult(sender, text) {
|
|
31
|
+
return sender.sendMessage({
|
|
32
32
|
customType: COMMAND_RESULT_CUSTOM_TYPE,
|
|
33
33
|
content: text,
|
|
34
34
|
display: true,
|
|
@@ -83,13 +83,21 @@ ${available}`);
|
|
|
83
83
|
pi.registerCommand("new", {
|
|
84
84
|
description: "Start a new session",
|
|
85
85
|
handler: async (_args, ctx) => {
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
let sentFromReplacement = false;
|
|
87
|
+
const result = await ctx.newSession({
|
|
88
|
+
withSession: async (nextCtx) => {
|
|
89
|
+
sentFromReplacement = true;
|
|
90
|
+
await options.refreshSessionResources();
|
|
91
|
+
await sendCommandResult(nextCtx, `已开启新会话。\n\nSession ID: \`${nextCtx.sessionManager.getSessionId()}\``);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
if (result.cancelled) {
|
|
95
|
+
sendCommandResult(pi, "新会话已取消。");
|
|
96
|
+
}
|
|
97
|
+
else if (!sentFromReplacement) {
|
|
88
98
|
await options.refreshSessionResources();
|
|
99
|
+
sendCommandResult(pi, `已开启新会话。\n\nSession ID: \`${ctx.sessionManager.getSessionId()}\``);
|
|
89
100
|
}
|
|
90
|
-
sendCommandResult(pi, result.cancelled
|
|
91
|
-
? "新会话已取消。"
|
|
92
|
-
: `已开启新会话。\n\nSession ID: \`${ctx.sessionManager.getSessionId()}\``);
|
|
93
101
|
},
|
|
94
102
|
});
|
|
95
103
|
pi.registerCommand("compact", {
|
|
@@ -127,7 +127,6 @@ export async function handleSessionEvent(event, context) {
|
|
|
127
127
|
const commandResultText = extractCustomCommandResultText(event.message);
|
|
128
128
|
if (commandResultText) {
|
|
129
129
|
runState.finalOutcome = { kind: "final", text: commandResultText };
|
|
130
|
-
runState.finalResponseDelivered = false;
|
|
131
130
|
log.logResponse(logCtx, commandResultText);
|
|
132
131
|
queue.enqueue(async () => {
|
|
133
132
|
const delivered = await ctx.respondPlain(commandResultText);
|
|
@@ -196,7 +195,6 @@ export async function handleSessionEvent(event, context) {
|
|
|
196
195
|
return;
|
|
197
196
|
}
|
|
198
197
|
runState.finalOutcome = { kind: "final", text: finalText };
|
|
199
|
-
runState.finalResponseDelivered = false;
|
|
200
198
|
memoryLifecycle.noteCompletedAssistantTurn();
|
|
201
199
|
log.logResponse(logCtx, finalText);
|
|
202
200
|
queue.enqueue(async () => {
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -10,7 +10,6 @@ export interface AgentRunner {
|
|
|
10
10
|
}>;
|
|
11
11
|
handleBuiltinCommand(ctx: DingTalkContext, command: BuiltInCommand): Promise<void>;
|
|
12
12
|
queueSteer(text: string, userName?: string): Promise<void>;
|
|
13
|
-
queueFollowUp(text: string, userName?: string): Promise<void>;
|
|
14
13
|
flushMemoryForShutdown(): Promise<void>;
|
|
15
14
|
getMemoryMaintenanceContext(): Promise<MemoryMaintenanceRuntimeContext>;
|
|
16
15
|
abort(): Promise<void>;
|
package/dist/memory/lifecycle.js
CHANGED
|
@@ -33,8 +33,8 @@ export class MemoryLifecycle {
|
|
|
33
33
|
pi.on("session_before_switch", async (event) => {
|
|
34
34
|
await this.handleSessionBeforeSwitch(event);
|
|
35
35
|
});
|
|
36
|
-
pi.on("
|
|
37
|
-
this.
|
|
36
|
+
pi.on("session_start", async (event) => {
|
|
37
|
+
this.handleSessionStart(event);
|
|
38
38
|
});
|
|
39
39
|
};
|
|
40
40
|
}
|
|
@@ -204,7 +204,7 @@ export class MemoryLifecycle {
|
|
|
204
204
|
}
|
|
205
205
|
await this.runPreflightConsolidation("new-session");
|
|
206
206
|
}
|
|
207
|
-
|
|
207
|
+
handleSessionStart(event) {
|
|
208
208
|
if (event.reason !== "new") {
|
|
209
209
|
return;
|
|
210
210
|
}
|
|
@@ -393,17 +393,21 @@ export function createRuntimeContext(options) {
|
|
|
393
393
|
},
|
|
394
394
|
async handleBusyMessage(event, bot, mode, queueText) {
|
|
395
395
|
if (shuttingDown) {
|
|
396
|
-
return
|
|
396
|
+
return { kind: "handled" };
|
|
397
397
|
}
|
|
398
398
|
const state = getState(event.channelId);
|
|
399
399
|
const trimmedQueueText = queueText.trim();
|
|
400
|
+
if (!trimmedQueueText) {
|
|
401
|
+
const commandName = mode === "followUp" ? "followup" : "steer";
|
|
402
|
+
await bot.sendPlain(event.channelId, `Could not queue this message: /${commandName} requires a message.`);
|
|
403
|
+
return { kind: "handled" };
|
|
404
|
+
}
|
|
405
|
+
if (mode === "followUp") {
|
|
406
|
+
log.logInfo(`[${event.channelId}] Queued followUp as next task: ${trimmedQueueText.substring(0, 80)}`);
|
|
407
|
+
return { kind: "requeue", text: trimmedQueueText };
|
|
408
|
+
}
|
|
400
409
|
try {
|
|
401
|
-
|
|
402
|
-
await state.runner.queueFollowUp(trimmedQueueText, event.userName);
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
405
|
-
await state.runner.queueSteer(trimmedQueueText, event.userName);
|
|
406
|
-
}
|
|
410
|
+
await state.runner.queueSteer(trimmedQueueText, event.userName);
|
|
407
411
|
await archiveIncomingMessage(event.channelId, {
|
|
408
412
|
date: new Date().toISOString(),
|
|
409
413
|
ts: event.ts,
|
|
@@ -414,26 +418,22 @@ export function createRuntimeContext(options) {
|
|
|
414
418
|
deliveryMode: mode,
|
|
415
419
|
skipContextSync: true,
|
|
416
420
|
}, `${mode} message`);
|
|
417
|
-
const confirmation =
|
|
418
|
-
?
|
|
419
|
-
|
|
420
|
-
: "Queued as follow-up. I’ll handle it after the current task completes. Use `/steer <message>` to apply it after the current tool step finishes."
|
|
421
|
-
: event.text.trim().startsWith("/")
|
|
422
|
-
? "Queued as steer. I’ll apply it after the current tool step finishes."
|
|
423
|
-
: "Queued as steer. I’ll apply this after the current tool step finishes. Use `/followup <message>` to queue it after completion.";
|
|
421
|
+
const confirmation = event.text.trim().startsWith("/")
|
|
422
|
+
? "Queued as steer. I’ll apply it after the current tool step finishes."
|
|
423
|
+
: "Queued as steer. I’ll apply this after the current tool step finishes. Use `/followup <message>` to queue it after completion.";
|
|
424
424
|
await bot.sendPlain(event.channelId, confirmation);
|
|
425
425
|
log.logInfo(`[${event.channelId}] Queued ${mode}: ${trimmedQueueText.substring(0, 80)}`);
|
|
426
|
-
return
|
|
426
|
+
return { kind: "handled" };
|
|
427
427
|
}
|
|
428
428
|
catch (err) {
|
|
429
429
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
430
430
|
if (isNoRunningTaskQueueError(err)) {
|
|
431
431
|
log.logInfo(`[${event.channelId}] Busy ${mode} window closed; requeueing as a normal message`);
|
|
432
|
-
return
|
|
432
|
+
return { kind: "requeue", text: trimmedQueueText };
|
|
433
433
|
}
|
|
434
434
|
log.logWarning(`[${event.channelId}] Failed to queue ${mode}`, errMsg);
|
|
435
435
|
await bot.sendPlain(event.channelId, `Could not queue this message: ${errMsg}`);
|
|
436
|
-
return
|
|
436
|
+
return { kind: "handled" };
|
|
437
437
|
}
|
|
438
438
|
},
|
|
439
439
|
async handleEvent(event, bot, _isEvent) {
|
package/dist/runtime/delivery.js
CHANGED
|
@@ -96,28 +96,10 @@ class ChannelDeliveryController {
|
|
|
96
96
|
log.logWarning(`[${this.event.channelId}] Failed to archive bot response`, err instanceof Error ? err.message : String(err));
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
|
-
resetProgressAfterFinal() {
|
|
100
|
-
if (!this.finalResponseDelivered) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
this.progressSegments = [];
|
|
104
|
-
this.cachedProgressText = "";
|
|
105
|
-
this.progressTextDirty = false;
|
|
106
|
-
this.mode = "progress";
|
|
107
|
-
this.progressStartedAt = 0;
|
|
108
|
-
this.progressWindowStartedAt = 0;
|
|
109
|
-
this.toolCallCount = 0;
|
|
110
|
-
this.sentProgressChars = 0;
|
|
111
|
-
this.replayRequired = false;
|
|
112
|
-
this.finalReplacementText = "";
|
|
113
|
-
this.cardWarmupTriggered = false;
|
|
114
|
-
this.finalResponseDelivered = false;
|
|
115
|
-
}
|
|
116
99
|
async appendProgress(text, shouldLog) {
|
|
117
|
-
if (this.closed || !text.trim())
|
|
100
|
+
if (this.closed || this.finalResponseDelivered || !text.trim())
|
|
118
101
|
return;
|
|
119
102
|
this.clearCardWarmup();
|
|
120
|
-
this.resetProgressAfterFinal();
|
|
121
103
|
if (this.progressStartedAt === 0) {
|
|
122
104
|
this.progressStartedAt = Date.now();
|
|
123
105
|
}
|
|
@@ -142,8 +124,8 @@ class ChannelDeliveryController {
|
|
|
142
124
|
this.bumpRevision(false);
|
|
143
125
|
}
|
|
144
126
|
async sendFinal(text, shouldLog) {
|
|
145
|
-
if (this.closed)
|
|
146
|
-
return
|
|
127
|
+
if (this.closed || this.finalResponseDelivered)
|
|
128
|
+
return this.finalResponseDelivered;
|
|
147
129
|
this.clearCardWarmup();
|
|
148
130
|
if (shouldLog) {
|
|
149
131
|
this.archiveBotResponse(text);
|
|
@@ -158,7 +140,7 @@ class ChannelDeliveryController {
|
|
|
158
140
|
return true;
|
|
159
141
|
}
|
|
160
142
|
async replaceWithFinal(text) {
|
|
161
|
-
if (this.closed)
|
|
143
|
+
if (this.closed || this.finalResponseDelivered)
|
|
162
144
|
return;
|
|
163
145
|
this.clearCardWarmup();
|
|
164
146
|
this.finalReplacementText = text;
|
|
@@ -47,11 +47,17 @@ export interface DingTalkContext {
|
|
|
47
47
|
flush: () => Promise<void>;
|
|
48
48
|
close: () => Promise<void>;
|
|
49
49
|
}
|
|
50
|
+
export type BusyMessageResult = {
|
|
51
|
+
kind: "handled";
|
|
52
|
+
} | {
|
|
53
|
+
kind: "requeue";
|
|
54
|
+
text: string;
|
|
55
|
+
};
|
|
50
56
|
export interface DingTalkHandler {
|
|
51
57
|
isRunning(channelId: string): boolean;
|
|
52
58
|
handleEvent(event: DingTalkEvent, bot: DingTalkBot, isEvent?: boolean): Promise<void>;
|
|
53
59
|
handleStop(channelId: string, bot: DingTalkBot): Promise<void>;
|
|
54
|
-
handleBusyMessage(event: DingTalkEvent, bot: DingTalkBot, mode: BusyMessageMode, queueText: string): Promise<
|
|
60
|
+
handleBusyMessage(event: DingTalkEvent, bot: DingTalkBot, mode: BusyMessageMode, queueText: string): Promise<BusyMessageResult>;
|
|
55
61
|
}
|
|
56
62
|
export declare class DingTalkBot {
|
|
57
63
|
private handler;
|
package/dist/runtime/dingtalk.js
CHANGED
|
@@ -481,11 +481,12 @@ export class DingTalkBot {
|
|
|
481
481
|
});
|
|
482
482
|
return true;
|
|
483
483
|
}
|
|
484
|
-
enqueueStreamMessage(event) {
|
|
484
|
+
enqueueStreamMessage(event, textOverride) {
|
|
485
|
+
const queuedEvent = textOverride === undefined ? event : { ...event, text: textOverride };
|
|
485
486
|
this.getQueue(event.channelId).enqueue(async () => {
|
|
486
487
|
this.activeMessageProcessing = true;
|
|
487
488
|
try {
|
|
488
|
-
await this.handler.handleEvent(
|
|
489
|
+
await this.handler.handleEvent(queuedEvent, this);
|
|
489
490
|
}
|
|
490
491
|
finally {
|
|
491
492
|
this.activeMessageProcessing = false;
|
|
@@ -870,16 +871,16 @@ export class DingTalkBot {
|
|
|
870
871
|
return;
|
|
871
872
|
}
|
|
872
873
|
if (builtInCommand?.name === "steer") {
|
|
873
|
-
const
|
|
874
|
-
if (
|
|
875
|
-
this.enqueueStreamMessage(event);
|
|
874
|
+
const result = await this.handler.handleBusyMessage(event, this, "steer", builtInCommand.args);
|
|
875
|
+
if (result.kind === "requeue") {
|
|
876
|
+
this.enqueueStreamMessage(event, result.text);
|
|
876
877
|
}
|
|
877
878
|
return;
|
|
878
879
|
}
|
|
879
880
|
if (builtInCommand?.name === "followup") {
|
|
880
|
-
const
|
|
881
|
-
if (
|
|
882
|
-
this.enqueueStreamMessage(event);
|
|
881
|
+
const result = await this.handler.handleBusyMessage(event, this, "followUp", builtInCommand.args);
|
|
882
|
+
if (result.kind === "requeue") {
|
|
883
|
+
this.enqueueStreamMessage(event, result.text);
|
|
883
884
|
}
|
|
884
885
|
return;
|
|
885
886
|
}
|
|
@@ -891,9 +892,9 @@ export class DingTalkBot {
|
|
|
891
892
|
await this.sendPlain(channelId, "A task is already running. Only `/stop`, `/steer <message>`, and `/followup <message>` are available while streaming.");
|
|
892
893
|
return;
|
|
893
894
|
}
|
|
894
|
-
const
|
|
895
|
-
if (
|
|
896
|
-
this.enqueueStreamMessage(event);
|
|
895
|
+
const result = await this.handler.handleBusyMessage(event, this, this.busyMessageDefault, content);
|
|
896
|
+
if (result.kind === "requeue") {
|
|
897
|
+
this.enqueueStreamMessage(event, result.text);
|
|
897
898
|
}
|
|
898
899
|
return;
|
|
899
900
|
}
|
package/dist/subagents/tool.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type AgentEvent, type AgentMessage, type AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
2
|
import type { Api, Model } from "@mariozechner/pi-ai";
|
|
3
|
+
import { Type } from "typebox";
|
|
3
4
|
import type { MemoryCandidateStore } from "../memory/candidates.js";
|
|
4
5
|
import type { Executor } from "../sandbox.js";
|
|
5
6
|
import type { SecurityConfig } from "../security/types.js";
|
|
@@ -7,21 +8,21 @@ import type { PipiclawMemoryRecallSettings } from "../settings.js";
|
|
|
7
8
|
import type { UsageTotals } from "../shared/types.js";
|
|
8
9
|
import type { PipiclawWebToolsConfig } from "../tools/config.js";
|
|
9
10
|
import { type ResolvedSubAgentConfig, type SubAgentDiscoveryResult } from "./discovery.js";
|
|
10
|
-
declare const subagentSchema:
|
|
11
|
-
label:
|
|
12
|
-
agent:
|
|
13
|
-
name:
|
|
14
|
-
task:
|
|
15
|
-
systemPrompt:
|
|
16
|
-
tools:
|
|
17
|
-
model:
|
|
18
|
-
maxTurns:
|
|
19
|
-
maxToolCalls:
|
|
20
|
-
maxWallTimeSec:
|
|
21
|
-
bashTimeoutSec:
|
|
22
|
-
contextMode:
|
|
23
|
-
memory:
|
|
24
|
-
paths:
|
|
11
|
+
declare const subagentSchema: Type.TObject<{
|
|
12
|
+
label: Type.TString;
|
|
13
|
+
agent: Type.TOptional<Type.TString>;
|
|
14
|
+
name: Type.TOptional<Type.TString>;
|
|
15
|
+
task: Type.TString;
|
|
16
|
+
systemPrompt: Type.TOptional<Type.TString>;
|
|
17
|
+
tools: Type.TOptional<Type.TArray<Type.TString>>;
|
|
18
|
+
model: Type.TOptional<Type.TString>;
|
|
19
|
+
maxTurns: Type.TOptional<Type.TNumber>;
|
|
20
|
+
maxToolCalls: Type.TOptional<Type.TNumber>;
|
|
21
|
+
maxWallTimeSec: Type.TOptional<Type.TNumber>;
|
|
22
|
+
bashTimeoutSec: Type.TOptional<Type.TNumber>;
|
|
23
|
+
contextMode: Type.TOptional<Type.TString>;
|
|
24
|
+
memory: Type.TOptional<Type.TString>;
|
|
25
|
+
paths: Type.TOptional<Type.TArray<Type.TString>>;
|
|
25
26
|
}>;
|
|
26
27
|
export interface SubAgentToolDetails {
|
|
27
28
|
kind: "subagent";
|
package/dist/subagents/tool.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Agent } from "@mariozechner/pi-agent-core";
|
|
2
2
|
import { convertToLlm } from "@mariozechner/pi-coding-agent";
|
|
3
|
-
import { Type } from "
|
|
3
|
+
import { Type } from "typebox";
|
|
4
4
|
import { readChannelSession } from "../memory/files.js";
|
|
5
5
|
import { recallRelevantMemory } from "../memory/recall.js";
|
|
6
6
|
import { formatModelReference } from "../models/utils.js";
|
package/dist/tools/attach.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { Type } from "typebox";
|
|
2
3
|
import type { SecurityConfig, SecurityRuntimeContext } from "../security/types.js";
|
|
3
|
-
declare const attachSchema:
|
|
4
|
-
label:
|
|
5
|
-
path:
|
|
6
|
-
title:
|
|
4
|
+
declare const attachSchema: Type.TObject<{
|
|
5
|
+
label: Type.TString;
|
|
6
|
+
path: Type.TString;
|
|
7
|
+
title: Type.TOptional<Type.TString>;
|
|
7
8
|
}>;
|
|
8
9
|
export type UploadFunction = (filePath: string, title?: string) => Promise<void>;
|
|
9
10
|
export interface AttachToolOptions {
|
package/dist/tools/attach.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Type } from "@sinclair/typebox";
|
|
2
1
|
import { basename, resolve as resolvePath } from "path";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
3
|
import { DEFAULT_SECURITY_CONFIG } from "../security/config.js";
|
|
4
4
|
import { logSecurityEvent } from "../security/logger.js";
|
|
5
5
|
import { guardPath } from "../security/path-guard.js";
|
package/dist/tools/bash.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { Type } from "typebox";
|
|
2
3
|
import type { Executor } from "../sandbox.js";
|
|
3
4
|
import type { SecurityConfig, SecurityRuntimeContext } from "../security/types.js";
|
|
4
|
-
declare const bashSchema:
|
|
5
|
-
label:
|
|
6
|
-
command:
|
|
7
|
-
timeout:
|
|
5
|
+
declare const bashSchema: Type.TObject<{
|
|
6
|
+
label: Type.TString;
|
|
7
|
+
command: Type.TString;
|
|
8
|
+
timeout: Type.TOptional<Type.TNumber>;
|
|
8
9
|
}>;
|
|
9
10
|
export interface BashToolOptions {
|
|
10
11
|
defaultTimeoutSeconds?: number;
|
package/dist/tools/bash.js
CHANGED
|
@@ -2,7 +2,7 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { createWriteStream } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import { Type } from "
|
|
5
|
+
import { Type } from "typebox";
|
|
6
6
|
import { guardCommand } from "../security/command-guard.js";
|
|
7
7
|
import { DEFAULT_SECURITY_CONFIG } from "../security/config.js";
|
|
8
8
|
import { logSecurityEvent } from "../security/logger.js";
|
package/dist/tools/edit.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { Type } from "typebox";
|
|
2
3
|
import type { Executor } from "../sandbox.js";
|
|
3
4
|
import type { SecurityConfig, SecurityRuntimeContext } from "../security/types.js";
|
|
4
|
-
declare const editSchema:
|
|
5
|
-
label:
|
|
6
|
-
path:
|
|
7
|
-
oldText:
|
|
8
|
-
newText:
|
|
5
|
+
declare const editSchema: Type.TObject<{
|
|
6
|
+
label: Type.TString;
|
|
7
|
+
path: Type.TString;
|
|
8
|
+
oldText: Type.TString;
|
|
9
|
+
newText: Type.TString;
|
|
9
10
|
}>;
|
|
10
11
|
export interface EditToolOptions {
|
|
11
12
|
securityConfig?: SecurityConfig;
|
package/dist/tools/edit.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Type } from "@sinclair/typebox";
|
|
2
1
|
import * as Diff from "diff";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
3
|
import { DEFAULT_SECURITY_CONFIG } from "../security/config.js";
|
|
4
4
|
import { logSecurityEvent } from "../security/logger.js";
|
|
5
5
|
import { guardPath } from "../security/path-guard.js";
|
package/dist/tools/read.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { Type } from "typebox";
|
|
2
3
|
import type { Executor } from "../sandbox.js";
|
|
3
4
|
import type { SecurityConfig, SecurityRuntimeContext } from "../security/types.js";
|
|
4
|
-
declare const readSchema:
|
|
5
|
-
label:
|
|
6
|
-
path:
|
|
7
|
-
offset:
|
|
8
|
-
limit:
|
|
5
|
+
declare const readSchema: Type.TObject<{
|
|
6
|
+
label: Type.TString;
|
|
7
|
+
path: Type.TString;
|
|
8
|
+
offset: Type.TOptional<Type.TNumber>;
|
|
9
|
+
limit: Type.TOptional<Type.TNumber>;
|
|
9
10
|
}>;
|
|
10
11
|
export interface ReadToolOptions {
|
|
11
12
|
securityConfig?: SecurityConfig;
|
package/dist/tools/read.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Type } from "@sinclair/typebox";
|
|
2
1
|
import { extname } from "path";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
3
|
import { DEFAULT_SECURITY_CONFIG } from "../security/config.js";
|
|
4
4
|
import { logSecurityEvent } from "../security/logger.js";
|
|
5
5
|
import { guardPath } from "../security/path-guard.js";
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
2
|
import type { Api, Model } from "@mariozechner/pi-ai";
|
|
3
|
+
import { Type } from "typebox";
|
|
3
4
|
import type { PipiclawSessionSearchSettings } from "../settings.js";
|
|
4
|
-
declare const sessionSearchSchema:
|
|
5
|
-
label:
|
|
6
|
-
query:
|
|
7
|
-
limit:
|
|
8
|
-
roleFilter:
|
|
5
|
+
declare const sessionSearchSchema: Type.TObject<{
|
|
6
|
+
label: Type.TString;
|
|
7
|
+
query: Type.TOptional<Type.TString>;
|
|
8
|
+
limit: Type.TOptional<Type.TNumber>;
|
|
9
|
+
roleFilter: Type.TOptional<Type.TArray<Type.TString>>;
|
|
9
10
|
}>;
|
|
10
11
|
export interface SessionSearchToolOptions {
|
|
11
12
|
channelDir: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Type } from "
|
|
1
|
+
import { Type } from "typebox";
|
|
2
2
|
import { searchChannelSessions } from "../memory/session-search.js";
|
|
3
3
|
const sessionSearchSchema = Type.Object({
|
|
4
4
|
label: Type.String({ description: "Brief description of what you're searching for and why (shown to user)" }),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
declare const skillListSchema: Type.TObject<{
|
|
4
|
+
label: Type.TString;
|
|
4
5
|
}>;
|
|
5
6
|
export interface WorkspaceSkillSummary {
|
|
6
7
|
name: string;
|
package/dist/tools/skill-list.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readdir, readFile, stat } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { Type } from "
|
|
3
|
+
import { Type } from "typebox";
|
|
4
4
|
import { validateSkillFrontmatter, validateSkillName } from "./skill-security.js";
|
|
5
5
|
const skillListSchema = Type.Object({
|
|
6
6
|
label: Type.String({ description: "Brief description of why you're listing workspace skills (shown to user)" }),
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
declare const skillManageSchema: Type.TObject<{
|
|
4
|
+
label: Type.TString;
|
|
5
|
+
action: Type.TString;
|
|
6
|
+
name: Type.TString;
|
|
7
|
+
content: Type.TOptional<Type.TString>;
|
|
8
|
+
filePath: Type.TOptional<Type.TString>;
|
|
9
|
+
find: Type.TOptional<Type.TString>;
|
|
10
|
+
replace: Type.TOptional<Type.TString>;
|
|
10
11
|
}>;
|
|
11
12
|
export type SkillManageAction = "create" | "patch" | "write_file";
|
|
12
13
|
export interface SkillManageResult {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { Type } from "
|
|
4
|
+
import { Type } from "typebox";
|
|
5
5
|
import { createAtomicTempPath, writeFileAtomically } from "../shared/atomic-file.js";
|
|
6
6
|
import { resolveSkillPath, resolveSkillSupportingFile, scanSkillContent, validateSkillMarkdown, } from "./skill-security.js";
|
|
7
7
|
const skillManageSchema = Type.Object({
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
declare const skillViewSchema: Type.TObject<{
|
|
4
|
+
label: Type.TString;
|
|
5
|
+
name: Type.TString;
|
|
6
|
+
filePath: Type.TOptional<Type.TString>;
|
|
6
7
|
}>;
|
|
7
8
|
export interface SkillViewToolOptions {
|
|
8
9
|
workspaceDir: string;
|
package/dist/tools/skill-view.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { Type } from "
|
|
3
|
+
import { Type } from "typebox";
|
|
4
4
|
import { resolveSkillPath, resolveSkillSupportingFile } from "./skill-security.js";
|
|
5
5
|
const skillViewSchema = Type.Object({
|
|
6
6
|
label: Type.String({ description: "Brief description of why you're viewing this skill (shown to user)" }),
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { Type } from "typebox";
|
|
2
3
|
import type { SecurityConfig } from "../security/types.js";
|
|
3
4
|
import type { PipiclawWebToolsConfig } from "./config.js";
|
|
4
|
-
declare const webFetchSchema:
|
|
5
|
-
label:
|
|
6
|
-
url:
|
|
7
|
-
extractMode:
|
|
8
|
-
maxChars:
|
|
5
|
+
declare const webFetchSchema: Type.TObject<{
|
|
6
|
+
label: Type.TString;
|
|
7
|
+
url: Type.TString;
|
|
8
|
+
extractMode: Type.TOptional<Type.TUnion<[Type.TLiteral<"markdown">, Type.TLiteral<"text">]>>;
|
|
9
|
+
maxChars: Type.TOptional<Type.TNumber>;
|
|
9
10
|
}>;
|
|
10
11
|
export interface WebFetchToolOptions {
|
|
11
12
|
webConfig: PipiclawWebToolsConfig;
|
package/dist/tools/web-fetch.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { Type } from "typebox";
|
|
2
3
|
import type { SecurityConfig } from "../security/types.js";
|
|
3
4
|
import type { PipiclawWebToolsConfig } from "./config.js";
|
|
4
|
-
declare const webSearchSchema:
|
|
5
|
-
label:
|
|
6
|
-
query:
|
|
7
|
-
count:
|
|
5
|
+
declare const webSearchSchema: Type.TObject<{
|
|
6
|
+
label: Type.TString;
|
|
7
|
+
query: Type.TString;
|
|
8
|
+
count: Type.TOptional<Type.TNumber>;
|
|
8
9
|
}>;
|
|
9
10
|
export interface WebSearchToolOptions {
|
|
10
11
|
webConfig: PipiclawWebToolsConfig;
|
package/dist/tools/web-search.js
CHANGED
package/dist/tools/write.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { Type } from "typebox";
|
|
2
3
|
import type { Executor } from "../sandbox.js";
|
|
3
4
|
import type { SecurityConfig, SecurityRuntimeContext } from "../security/types.js";
|
|
4
|
-
declare const writeSchema:
|
|
5
|
-
label:
|
|
6
|
-
path:
|
|
7
|
-
content:
|
|
5
|
+
declare const writeSchema: Type.TObject<{
|
|
6
|
+
label: Type.TString;
|
|
7
|
+
path: Type.TString;
|
|
8
|
+
content: Type.TString;
|
|
8
9
|
}>;
|
|
9
10
|
export interface WriteToolOptions {
|
|
10
11
|
securityConfig?: SecurityConfig;
|
package/dist/tools/write.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oyasmi/pipiclaw",
|
|
3
|
-
"version": "0.6.6
|
|
3
|
+
"version": "0.6.6",
|
|
4
4
|
"description": "An AI assistant runtime for coding and team workflows, with DingTalk AI Cards, sub-agents, memory, and scheduled events.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,11 +33,10 @@
|
|
|
33
33
|
"prepublishOnly": "npm run clean && npm run build && npm run check"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@mariozechner/pi-agent-core": "^0.
|
|
37
|
-
"@mariozechner/pi-ai": "^0.
|
|
38
|
-
"@mariozechner/pi-coding-agent": "^0.
|
|
36
|
+
"@mariozechner/pi-agent-core": "^0.70.2",
|
|
37
|
+
"@mariozechner/pi-ai": "^0.70.2",
|
|
38
|
+
"@mariozechner/pi-coding-agent": "^0.70.2",
|
|
39
39
|
"@mozilla/readability": "^0.6.0",
|
|
40
|
-
"@sinclair/typebox": "^0.34.0",
|
|
41
40
|
"axios": "^1.7.0",
|
|
42
41
|
"croner": "^9.1.0",
|
|
43
42
|
"diff": "^8.0.2",
|
|
@@ -46,7 +45,8 @@
|
|
|
46
45
|
"https-proxy-agent": "^7.0.6",
|
|
47
46
|
"jsdom": "^26.1.0",
|
|
48
47
|
"proxy-from-env": "^1.1.0",
|
|
49
|
-
"socks-proxy-agent": "^8.0.5"
|
|
48
|
+
"socks-proxy-agent": "^8.0.5",
|
|
49
|
+
"typebox": "^1.1.34"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@biomejs/biome": "2.3.5",
|