@oyasmi/pipiclaw 0.5.3 → 0.5.5
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 +3 -2
- package/dist/agent/channel-runner.d.ts +1 -1
- package/dist/agent/channel-runner.js +7 -6
- package/dist/{command-extension.js → agent/command-extension.js} +1 -1
- package/dist/{prompt-builder.d.ts → agent/prompt-builder.d.ts} +1 -1
- package/dist/{prompt-builder.js → agent/prompt-builder.js} +13 -11
- package/dist/agent/type-guards.js +1 -1
- package/dist/agent/types.d.ts +1 -1
- package/dist/agent/workspace-resources.d.ts +19 -0
- package/dist/{config-loader.js → agent/workspace-resources.js} +7 -32
- package/dist/index.d.ts +10 -8
- package/dist/index.js +10 -8
- package/dist/memory/consolidation.js +1 -1
- package/dist/memory/lifecycle.d.ts +1 -1
- package/dist/memory/recall.js +1 -1
- package/dist/memory/session.js +1 -1
- package/dist/{sidecar-worker.js → memory/sidecar-worker.js} +1 -1
- package/dist/models/api-keys.d.ts +7 -0
- package/dist/models/api-keys.js +16 -0
- package/dist/{model-utils.d.ts → models/utils.d.ts} +1 -1
- package/dist/runtime/bootstrap.js +25 -3
- package/dist/runtime/channel-paths.d.ts +3 -0
- package/dist/runtime/channel-paths.js +13 -0
- package/dist/runtime/dingtalk.js +3 -2
- package/dist/runtime/store.js +3 -6
- package/dist/{context.d.ts → settings.d.ts} +1 -1
- package/dist/{context.js → settings.js} +1 -1
- package/dist/subagents/discovery.js +1 -1
- package/dist/subagents/tool.d.ts +1 -1
- package/dist/subagents/tool.js +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/agent.d.ts +0 -2
- package/dist/agent.js +0 -1
- package/dist/config-loader.d.ts +0 -26
- /package/dist/{command-extension.d.ts → agent/command-extension.d.ts} +0 -0
- /package/dist/{commands.d.ts → agent/commands.d.ts} +0 -0
- /package/dist/{commands.js → agent/commands.js} +0 -0
- /package/dist/{sidecar-worker.d.ts → memory/sidecar-worker.d.ts} +0 -0
- /package/dist/{model-utils.js → models/utils.js} +0 -0
package/README.md
CHANGED
|
@@ -140,6 +140,7 @@ pipiclaw
|
|
|
140
140
|
├── SOUL.md
|
|
141
141
|
├── AGENTS.md
|
|
142
142
|
├── MEMORY.md
|
|
143
|
+
├── ENVIRONMENT.md
|
|
143
144
|
├── events/
|
|
144
145
|
├── skills/
|
|
145
146
|
└── sub-agents/
|
|
@@ -385,6 +386,7 @@ Pipiclaw 的核心不是一个临时机器人实例,而是一组长期存在
|
|
|
385
386
|
├── SOUL.md
|
|
386
387
|
├── AGENTS.md
|
|
387
388
|
├── MEMORY.md
|
|
389
|
+
├── ENVIRONMENT.md
|
|
388
390
|
├── events/
|
|
389
391
|
├── skills/
|
|
390
392
|
├── sub-agents/
|
|
@@ -395,8 +397,7 @@ Pipiclaw 的核心不是一个临时机器人实例,而是一组长期存在
|
|
|
395
397
|
│ ├── .channel-meta.json
|
|
396
398
|
│ ├── context.jsonl
|
|
397
399
|
│ ├── log.jsonl
|
|
398
|
-
│
|
|
399
|
-
│ └── skills/
|
|
400
|
+
│ └── subagent-runs.jsonl
|
|
400
401
|
└── group_{conversationId}/
|
|
401
402
|
└── ...
|
|
402
403
|
```
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type BuiltInCommand } from "../commands.js";
|
|
2
1
|
import type { DingTalkContext } from "../runtime/dingtalk.js";
|
|
3
2
|
import type { ChannelStore } from "../runtime/store.js";
|
|
4
3
|
import { type SandboxConfig } from "../sandbox.js";
|
|
4
|
+
import { type BuiltInCommand } from "./commands.js";
|
|
5
5
|
import { type AgentRunner } from "./types.js";
|
|
6
6
|
export declare class ChannelRunner implements AgentRunner {
|
|
7
7
|
private readonly sandboxConfig;
|
|
@@ -2,30 +2,31 @@ import { Agent } from "@mariozechner/pi-agent-core";
|
|
|
2
2
|
import { AgentSession, AuthStorage, convertToLlm, 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
|
-
import { createCommandExtension } from "../command-extension.js";
|
|
6
|
-
import { renderBuiltInHelp } from "../commands.js";
|
|
7
|
-
import { getAgentConfig, getApiKeyForModel, getSoul, loadPipiclawSkills } from "../config-loader.js";
|
|
8
|
-
import { PipiclawSettingsManager } from "../context.js";
|
|
9
5
|
import * as log from "../log.js";
|
|
10
6
|
import { buildFirstTurnMemoryBootstrap as renderFirstTurnMemoryBootstrap } from "../memory/bootstrap.js";
|
|
11
7
|
import { createMemoryCandidateCache } from "../memory/candidates.js";
|
|
12
8
|
import { getChannelMemoryPath } from "../memory/files.js";
|
|
13
9
|
import { MemoryLifecycle } from "../memory/lifecycle.js";
|
|
14
10
|
import { recallRelevantMemory } from "../memory/recall.js";
|
|
15
|
-
import {
|
|
11
|
+
import { getApiKeyForModel } from "../models/api-keys.js";
|
|
12
|
+
import { resolveInitialModel } from "../models/utils.js";
|
|
16
13
|
import { APP_HOME_DIR, AUTH_CONFIG_PATH, MODELS_CONFIG_PATH } from "../paths.js";
|
|
17
|
-
import { buildAppendSystemPrompt } from "../prompt-builder.js";
|
|
18
14
|
import { createExecutor } from "../sandbox.js";
|
|
15
|
+
import { PipiclawSettingsManager } from "../settings.js";
|
|
19
16
|
import { HAN_REGEX } from "../shared/text-utils.js";
|
|
20
17
|
import { isRecord } from "../shared/type-guards.js";
|
|
21
18
|
import { discoverSubAgents, formatSubAgentList } from "../subagents/discovery.js";
|
|
22
19
|
import { createPipiclawTools } from "../tools/index.js";
|
|
20
|
+
import { createCommandExtension } from "./command-extension.js";
|
|
21
|
+
import { renderBuiltInHelp } from "./commands.js";
|
|
23
22
|
import { clipUserInput } from "./progress-formatter.js";
|
|
23
|
+
import { buildAppendSystemPrompt } from "./prompt-builder.js";
|
|
24
24
|
import { createRunQueue } from "./run-queue.js";
|
|
25
25
|
import { handleSessionEvent } from "./session-events.js";
|
|
26
26
|
import { SessionResourceGate } from "./session-resource-gate.js";
|
|
27
27
|
import { getLastAssistantUsage } from "./type-guards.js";
|
|
28
28
|
import { createEmptyRunState, MAX_USER_MESSAGE_CHARS, } from "./types.js";
|
|
29
|
+
import { getAgentConfig, getSoul, loadPipiclawSkills } from "./workspace-resources.js";
|
|
29
30
|
function isSilentOutcome(outcome) {
|
|
30
31
|
return outcome.kind === "silent";
|
|
31
32
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { basename } from "path";
|
|
2
|
-
import { findExactModelReferenceMatch, formatModelList, formatModelReference } from "
|
|
2
|
+
import { findExactModelReferenceMatch, formatModelList, formatModelReference } from "../models/utils.js";
|
|
3
3
|
export const COMMAND_RESULT_CUSTOM_TYPE = "pipiclaw.command_result";
|
|
4
4
|
function buildSessionText(stats, currentModel, thinkingLevel) {
|
|
5
5
|
const modelText = currentModel ? `\`${formatModelReference(currentModel)}\`` : "(none)";
|
|
@@ -31,6 +31,7 @@ ${workspacePath}/
|
|
|
31
31
|
├── SOUL.md # Your identity/personality (read-only)
|
|
32
32
|
├── AGENTS.md # Custom behavior instructions (read-only)
|
|
33
33
|
├── MEMORY.md # Stable workspace memory (admin-managed, read on demand)
|
|
34
|
+
├── ENVIRONMENT.md # Environment facts and notable machine-level changes (read on demand)
|
|
34
35
|
├── sub-agents/ # Predefined sub-agent definitions
|
|
35
36
|
├── skills/ # Global CLI tools you create
|
|
36
37
|
├── events/ # Scheduled events
|
|
@@ -39,9 +40,7 @@ ${workspacePath}/
|
|
|
39
40
|
├── MEMORY.md # Channel durable memory (read on demand, runtime-managed)
|
|
40
41
|
├── HISTORY.md # Channel summarized history (read on demand, runtime-managed)
|
|
41
42
|
├── log.jsonl # Raw message archive (cold storage)
|
|
42
|
-
|
|
43
|
-
├── scratch/ # Your working directory
|
|
44
|
-
└── skills/ # Channel-specific tools`);
|
|
43
|
+
└── context.jsonl # Raw session archive (cold storage)`);
|
|
45
44
|
sections.push(`## Events
|
|
46
45
|
You can schedule events that wake you up at specific times or when external things happen. Events are JSON files in \`${workspacePath}/events/\`.
|
|
47
46
|
|
|
@@ -80,6 +79,8 @@ Memory files are not preloaded into session context. Read them explicitly when m
|
|
|
80
79
|
### Files
|
|
81
80
|
- Workspace memory: ${workspacePath}/MEMORY.md
|
|
82
81
|
Stable shared background memory. Admin-managed. Read on demand.
|
|
82
|
+
- Workspace environment: ${workspacePath}/ENVIRONMENT.md
|
|
83
|
+
Durable environment facts and notable machine-level changes. Read on demand when environment state or prior machine changes matter.
|
|
83
84
|
- Channel session memory: ${channelPath}/SESSION.md
|
|
84
85
|
Current working state for this channel. Runtime-managed. Read on demand. Prefer this when current task state matters.
|
|
85
86
|
- Channel memory: ${channelPath}/MEMORY.md
|
|
@@ -92,20 +93,21 @@ Memory files are not preloaded into session context. Read them explicitly when m
|
|
|
92
93
|
- SESSION.md is the primary runtime-managed working-state artifact for current active work.
|
|
93
94
|
- The runtime automatically consolidates channel MEMORY.md and HISTORY.md before compaction or session trimming.
|
|
94
95
|
- Workspace MEMORY.md is not updated by normal runtime consolidation.
|
|
96
|
+
- ENVIRONMENT.md is not normal conversational memory. Read it only when environment history or machine state matters.
|
|
95
97
|
|
|
96
98
|
### Cold Storage
|
|
97
99
|
- ${channelPath}/log.jsonl is a raw archive. It is not normal memory and is not proactively loaded.
|
|
98
100
|
- ${channelPath}/context.jsonl is a raw session archive. It is not normal memory and is not proactively loaded.
|
|
99
101
|
|
|
100
102
|
When a task depends on prior decisions, preferences, or long-running work, prefer SESSION.md first for current state, then MEMORY.md, then HISTORY.md.`);
|
|
101
|
-
sections.push(`##
|
|
102
|
-
Maintain ${workspacePath}/
|
|
103
|
-
- Installed packages
|
|
104
|
-
-
|
|
105
|
-
- Config files modified
|
|
106
|
-
-
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
sections.push(`## Environment Log
|
|
104
|
+
Maintain ${workspacePath}/ENVIRONMENT.md to record durable environment changes when they matter:
|
|
105
|
+
- Installed packages or tools that future work depends on
|
|
106
|
+
- Important environment variables or credential sources
|
|
107
|
+
- Config files modified outside normal project code
|
|
108
|
+
- Runtime prerequisites that affect future sessions
|
|
109
|
+
|
|
110
|
+
Keep it factual and concise. Do not use it for task progress or conversation summaries.`);
|
|
109
111
|
sections.push(`## Tools
|
|
110
112
|
- read: Read files
|
|
111
113
|
- edit: Surgical file edits
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { COMMAND_RESULT_CUSTOM_TYPE } from "../command-extension.js";
|
|
2
1
|
import { isRecord } from "../shared/type-guards.js";
|
|
2
|
+
import { COMMAND_RESULT_CUSTOM_TYPE } from "./command-extension.js";
|
|
3
3
|
function isMessageWithRole(value) {
|
|
4
4
|
return isRecord(value) && typeof value.role === "string";
|
|
5
5
|
}
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { BuiltInCommand } from "../commands.js";
|
|
2
1
|
import type { DingTalkContext } from "../runtime/dingtalk.js";
|
|
3
2
|
import type { ChannelStore } from "../runtime/store.js";
|
|
4
3
|
import type { UsageTotals } from "../shared/types.js";
|
|
4
|
+
import type { BuiltInCommand } from "./commands.js";
|
|
5
5
|
export interface AgentRunner {
|
|
6
6
|
run(ctx: DingTalkContext, store: ChannelStore): Promise<{
|
|
7
7
|
stopReason: string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace resource loaders for pipiclaw:
|
|
3
|
+
* SOUL.md, AGENTS.md, and workspace-level skills.
|
|
4
|
+
*/
|
|
5
|
+
import { type Skill } from "@mariozechner/pi-coding-agent";
|
|
6
|
+
/**
|
|
7
|
+
* Load SOUL.md — defines the agent's identity, personality, and communication style.
|
|
8
|
+
* Only loaded from workspace root (global).
|
|
9
|
+
*/
|
|
10
|
+
export declare function getSoul(workspaceDir: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Load AGENTS.md — defines the agent's behavior instructions, capabilities, and constraints.
|
|
13
|
+
* Only loaded from workspace root (global).
|
|
14
|
+
*/
|
|
15
|
+
export declare function getAgentConfig(channelDir: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Load skills from the workspace-level skill directory only.
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadPipiclawSkills(channelDir: string, workspacePath: string): Skill[];
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* SOUL.md, AGENTS.md,
|
|
2
|
+
* Workspace resource loaders for pipiclaw:
|
|
3
|
+
* SOUL.md, AGENTS.md, and workspace-level skills.
|
|
4
4
|
*/
|
|
5
5
|
import { loadSkillsFromDir } from "@mariozechner/pi-coding-agent";
|
|
6
6
|
import { existsSync, readFileSync } from "fs";
|
|
7
7
|
import { join } from "path";
|
|
8
|
-
import * as log from "
|
|
8
|
+
import * as log from "../log.js";
|
|
9
9
|
/**
|
|
10
10
|
* Load SOUL.md — defines the agent's identity, personality, and communication style.
|
|
11
11
|
* Only loaded from workspace root (global).
|
|
@@ -44,11 +44,9 @@ export function getAgentConfig(channelDir) {
|
|
|
44
44
|
return "";
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
* Load skills from
|
|
48
|
-
* Channel-level skills override global skills with the same name.
|
|
47
|
+
* Load skills from the workspace-level skill directory only.
|
|
49
48
|
*/
|
|
50
49
|
export function loadPipiclawSkills(channelDir, workspacePath) {
|
|
51
|
-
const skillMap = new Map();
|
|
52
50
|
const hostWorkspacePath = join(channelDir, "..");
|
|
53
51
|
const translatePath = (hostPath) => {
|
|
54
52
|
if (hostPath.startsWith(hostWorkspacePath)) {
|
|
@@ -56,34 +54,11 @@ export function loadPipiclawSkills(channelDir, workspacePath) {
|
|
|
56
54
|
}
|
|
57
55
|
return hostPath;
|
|
58
56
|
};
|
|
59
|
-
// Load workspace-level skills (global)
|
|
60
57
|
const workspaceSkillsDir = join(hostWorkspacePath, "skills");
|
|
61
|
-
|
|
58
|
+
const skills = loadSkillsFromDir({ dir: workspaceSkillsDir, source: "workspace" }).skills;
|
|
59
|
+
for (const skill of skills) {
|
|
62
60
|
skill.filePath = translatePath(skill.filePath);
|
|
63
61
|
skill.baseDir = translatePath(skill.baseDir);
|
|
64
|
-
skillMap.set(skill.name, skill);
|
|
65
62
|
}
|
|
66
|
-
|
|
67
|
-
const channelSkillsDir = join(channelDir, "skills");
|
|
68
|
-
for (const skill of loadSkillsFromDir({ dir: channelSkillsDir, source: "channel" }).skills) {
|
|
69
|
-
skill.filePath = translatePath(skill.filePath);
|
|
70
|
-
skill.baseDir = translatePath(skill.baseDir);
|
|
71
|
-
skillMap.set(skill.name, skill);
|
|
72
|
-
}
|
|
73
|
-
return Array.from(skillMap.values());
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Resolve an API key for the given model's provider.
|
|
77
|
-
* Checks ModelRegistry first, then falls back to ANTHROPIC_API_KEY env var.
|
|
78
|
-
*/
|
|
79
|
-
export async function getApiKeyForModel(modelRegistry, model) {
|
|
80
|
-
const key = await modelRegistry.getApiKeyForProvider(model.provider);
|
|
81
|
-
if (key)
|
|
82
|
-
return key;
|
|
83
|
-
// Fallback: try anthropic env var
|
|
84
|
-
const envKey = process.env.ANTHROPIC_API_KEY;
|
|
85
|
-
if (envKey)
|
|
86
|
-
return envKey;
|
|
87
|
-
throw new Error(`No API key found for provider: ${model.provider}.\n\n` +
|
|
88
|
-
"Configure credentials in ~/.pi/pipiclaw/auth.json or ~/.pi/pipiclaw/models.json, or set the matching provider environment variable.");
|
|
63
|
+
return skills;
|
|
89
64
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
export { type
|
|
2
|
-
export {
|
|
3
|
-
export { type
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
1
|
+
export { COMMAND_RESULT_CUSTOM_TYPE, createCommandExtension, type PipiclawCommandExtensionOptions, } from "./agent/command-extension.js";
|
|
2
|
+
export { type BuiltInCommand, type BuiltInCommandName, parseBuiltInCommand, renderBuiltInHelp, } from "./agent/commands.js";
|
|
3
|
+
export { type AgentRunner, getOrCreateRunner } from "./agent/index.js";
|
|
4
|
+
export { type AppendSystemPromptOptions, buildAppendSystemPrompt } from "./agent/prompt-builder.js";
|
|
5
|
+
export { getAgentConfig, getSoul, loadPipiclawSkills, } from "./agent/workspace-resources.js";
|
|
6
6
|
export { type BuildMemoryCandidatesOptions, buildMemoryCandidates, type MemoryCandidate, } from "./memory/candidates.js";
|
|
7
7
|
export { type BackgroundMaintenanceResult, type ConsolidationRunOptions, type InlineConsolidationResult, runBackgroundMaintenance, runInlineConsolidation, } from "./memory/consolidation.js";
|
|
8
8
|
export { ensureChannelMemoryFiles, ensureChannelMemoryFilesSync, getChannelSessionPath, readChannelSession, rewriteChannelSession, } from "./memory/files.js";
|
|
9
9
|
export { type ConsolidationReason, MemoryLifecycle, type MemoryLifecycleOptions } from "./memory/lifecycle.js";
|
|
10
10
|
export { type RecalledMemory, type RecallRequest, type RecallResult, recallRelevantMemory, } from "./memory/recall.js";
|
|
11
11
|
export { renderSessionMemory, type SessionMemoryState, type SessionMemoryUpdateOptions, updateChannelSessionMemory, } from "./memory/session.js";
|
|
12
|
-
export {
|
|
12
|
+
export { runSidecarTask, type SidecarResult, type SidecarTask, } from "./memory/sidecar-worker.js";
|
|
13
|
+
export { getApiKeyForModel } from "./models/api-keys.js";
|
|
14
|
+
export { findExactModelReferenceMatch, formatModelList, formatModelReference, resolveInitialModel, } from "./models/utils.js";
|
|
13
15
|
export { APP_HOME_DIR, APP_NAME, AUTH_CONFIG_PATH, CHANNEL_CONFIG_PATH, MODELS_CONFIG_PATH, SETTINGS_CONFIG_PATH, SUB_AGENTS_DIR, SUB_AGENTS_DIR_NAME, WORKSPACE_DIR, } from "./paths.js";
|
|
14
|
-
export {
|
|
16
|
+
export { ensureChannelDir, getChannelDir, getChannelDirName, } from "./runtime/channel-paths.js";
|
|
15
17
|
export { createDingTalkContext } from "./runtime/delivery.js";
|
|
16
18
|
export { type BusyMessageMode, DingTalkBot, type DingTalkConfig, type DingTalkContext, type DingTalkEvent, type DingTalkHandler, } from "./runtime/dingtalk.js";
|
|
17
19
|
export { createEventsWatcher, EventsWatcher, type ImmediateEvent, type OneShotEvent, type PeriodicEvent, type ScheduledEvent, } from "./runtime/events.js";
|
|
18
20
|
export { ChannelStore, type LoggedMessage, type LoggedSubAgentRun } from "./runtime/store.js";
|
|
19
21
|
export { createExecutor, type ExecOptions, type ExecResult, type Executor, parseSandboxArg, type SandboxConfig, validateSandbox, } from "./sandbox.js";
|
|
20
|
-
export {
|
|
22
|
+
export { type PipiclawMemoryRecallSettings, type PipiclawSessionMemorySettings, type PipiclawSettings, PipiclawSettingsManager, } from "./settings.js";
|
|
21
23
|
export { discoverSubAgents, formatSubAgentList, getSubAgentsDir, type ResolvedSubAgentConfig, resolveSubAgentConfig, type SubAgentConfig, type SubAgentContextMode, type SubAgentDiscoveryResult, type SubAgentInvocationOverrides, type SubAgentMemoryMode, type SubAgentToolName, } from "./subagents/discovery.js";
|
|
22
24
|
export { createSubAgentTool, type SubAgentToolDetails, type SubAgentToolOptions, } from "./subagents/tool.js";
|
|
23
25
|
export { type CreatePipiclawToolsOptions, createPipiclawBaseTools, createPipiclawTools, } from "./tools/index.js";
|
package/dist/index.js
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
1
|
+
export { COMMAND_RESULT_CUSTOM_TYPE, createCommandExtension, } from "./agent/command-extension.js";
|
|
2
|
+
export { parseBuiltInCommand, renderBuiltInHelp, } from "./agent/commands.js";
|
|
3
|
+
export { getOrCreateRunner } from "./agent/index.js";
|
|
4
|
+
export { buildAppendSystemPrompt } from "./agent/prompt-builder.js";
|
|
5
|
+
export { getAgentConfig, getSoul, loadPipiclawSkills, } from "./agent/workspace-resources.js";
|
|
6
6
|
export { buildMemoryCandidates, } from "./memory/candidates.js";
|
|
7
7
|
export { runBackgroundMaintenance, runInlineConsolidation, } from "./memory/consolidation.js";
|
|
8
8
|
export { ensureChannelMemoryFiles, ensureChannelMemoryFilesSync, getChannelSessionPath, readChannelSession, rewriteChannelSession, } from "./memory/files.js";
|
|
9
9
|
export { MemoryLifecycle } from "./memory/lifecycle.js";
|
|
10
10
|
export { recallRelevantMemory, } from "./memory/recall.js";
|
|
11
11
|
export { renderSessionMemory, updateChannelSessionMemory, } from "./memory/session.js";
|
|
12
|
-
export {
|
|
12
|
+
export { runSidecarTask, } from "./memory/sidecar-worker.js";
|
|
13
|
+
export { getApiKeyForModel } from "./models/api-keys.js";
|
|
14
|
+
export { findExactModelReferenceMatch, formatModelList, formatModelReference, resolveInitialModel, } from "./models/utils.js";
|
|
13
15
|
export { APP_HOME_DIR, APP_NAME, AUTH_CONFIG_PATH, CHANNEL_CONFIG_PATH, MODELS_CONFIG_PATH, SETTINGS_CONFIG_PATH, SUB_AGENTS_DIR, SUB_AGENTS_DIR_NAME, WORKSPACE_DIR, } from "./paths.js";
|
|
14
|
-
export {
|
|
16
|
+
export { ensureChannelDir, getChannelDir, getChannelDirName, } from "./runtime/channel-paths.js";
|
|
15
17
|
export { createDingTalkContext } from "./runtime/delivery.js";
|
|
16
18
|
export { DingTalkBot, } from "./runtime/dingtalk.js";
|
|
17
19
|
export { createEventsWatcher, EventsWatcher, } from "./runtime/events.js";
|
|
18
20
|
export { ChannelStore } from "./runtime/store.js";
|
|
19
21
|
export { createExecutor, parseSandboxArg, validateSandbox, } from "./sandbox.js";
|
|
20
|
-
export {
|
|
22
|
+
export { PipiclawSettingsManager, } from "./settings.js";
|
|
21
23
|
export { discoverSubAgents, formatSubAgentList, getSubAgentsDir, resolveSubAgentConfig, } from "./subagents/discovery.js";
|
|
22
24
|
export { createSubAgentTool, } from "./subagents/tool.js";
|
|
23
25
|
export { createPipiclawBaseTools, createPipiclawTools, } from "./tools/index.js";
|
|
@@ -3,8 +3,8 @@ import { parseJsonObject } from "../shared/llm-json.js";
|
|
|
3
3
|
import { splitH2Sections } from "../shared/markdown-sections.js";
|
|
4
4
|
import { clipText } from "../shared/text-utils.js";
|
|
5
5
|
import { buildStandardMessages } from "../shared/type-guards.js";
|
|
6
|
-
import { runSidecarTask } from "../sidecar-worker.js";
|
|
7
6
|
import { appendChannelHistoryBlock, appendChannelMemoryUpdate, readChannelHistory, readChannelMemory, readChannelSession, rewriteChannelHistory, rewriteChannelMemory, } from "./files.js";
|
|
7
|
+
import { runSidecarTask } from "./sidecar-worker.js";
|
|
8
8
|
const INLINE_TRANSCRIPT_MAX_CHARS = 28_000;
|
|
9
9
|
const MEMORY_CLEANUP_LENGTH_THRESHOLD = 5_000;
|
|
10
10
|
const MEMORY_UPDATE_BLOCK_THRESHOLD = 4;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
|
2
2
|
import type { Api, Model } from "@mariozechner/pi-ai";
|
|
3
3
|
import type { ExtensionFactory, SessionEntry } from "@mariozechner/pi-coding-agent";
|
|
4
|
-
import type { PipiclawSessionMemorySettings } from "../
|
|
4
|
+
import type { PipiclawSessionMemorySettings } from "../settings.js";
|
|
5
5
|
export type ConsolidationReason = "compaction" | "new-session" | "idle";
|
|
6
6
|
export interface MemoryLifecycleOptions {
|
|
7
7
|
channelId: string;
|
package/dist/memory/recall.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { parseJsonObject } from "../shared/llm-json.js";
|
|
2
2
|
import { HAN_REGEX } from "../shared/text-utils.js";
|
|
3
|
-
import { runSidecarTask } from "../sidecar-worker.js";
|
|
4
3
|
import { buildMemoryCandidates } from "./candidates.js";
|
|
5
4
|
import { COMMON_CHINESE_WORDS } from "./chinese-words.js";
|
|
5
|
+
import { runSidecarTask } from "./sidecar-worker.js";
|
|
6
6
|
const RERANK_SYSTEM_PROMPT = `You are selecting which memory snippets are most relevant to the current user turn.
|
|
7
7
|
|
|
8
8
|
Return strict JSON only:
|
package/dist/memory/session.js
CHANGED
|
@@ -5,8 +5,8 @@ import { parseJsonObject } from "../shared/llm-json.js";
|
|
|
5
5
|
import { splitH1Sections } from "../shared/markdown-sections.js";
|
|
6
6
|
import { clipText } from "../shared/text-utils.js";
|
|
7
7
|
import { buildStandardMessages, isRecord } from "../shared/type-guards.js";
|
|
8
|
-
import { runSidecarTask, SidecarParseError } from "../sidecar-worker.js";
|
|
9
8
|
import { readChannelMemory, readChannelSession, rewriteChannelSession } from "./files.js";
|
|
9
|
+
import { runSidecarTask, SidecarParseError } from "./sidecar-worker.js";
|
|
10
10
|
const SESSION_TRANSCRIPT_MAX_CHARS = 20_000;
|
|
11
11
|
const SESSION_MEMORY_MAX_CHARS = 4_000;
|
|
12
12
|
const SESSION_ITEM_LIMIT = 12;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Agent } from "@mariozechner/pi-agent-core";
|
|
2
2
|
import { convertToLlm } from "@mariozechner/pi-coding-agent";
|
|
3
|
-
import { extractAssistantText } from "
|
|
3
|
+
import { extractAssistantText } from "../shared/text-utils.js";
|
|
4
4
|
export class SidecarTimeoutError extends Error {
|
|
5
5
|
constructor(taskName, timeoutMs) {
|
|
6
6
|
super(`Sidecar task "${taskName}" timed out after ${timeoutMs}ms`);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Api, Model } from "@mariozechner/pi-ai";
|
|
2
|
+
import type { ModelRegistry } from "@mariozechner/pi-coding-agent";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve an API key for the given model's provider.
|
|
5
|
+
* Checks ModelRegistry first, then falls back to ANTHROPIC_API_KEY.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getApiKeyForModel(modelRegistry: ModelRegistry, model: Model<Api>): Promise<string>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve an API key for the given model's provider.
|
|
3
|
+
* Checks ModelRegistry first, then falls back to ANTHROPIC_API_KEY.
|
|
4
|
+
*/
|
|
5
|
+
export async function getApiKeyForModel(modelRegistry, model) {
|
|
6
|
+
const key = await modelRegistry.getApiKeyForProvider(model.provider);
|
|
7
|
+
if (key) {
|
|
8
|
+
return key;
|
|
9
|
+
}
|
|
10
|
+
const envKey = process.env.ANTHROPIC_API_KEY;
|
|
11
|
+
if (envKey) {
|
|
12
|
+
return envKey;
|
|
13
|
+
}
|
|
14
|
+
throw new Error(`No API key found for provider: ${model.provider}.\n\n` +
|
|
15
|
+
"Configure credentials in ~/.pi/pipiclaw/auth.json or ~/.pi/pipiclaw/models.json, or set the matching provider environment variable.");
|
|
16
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Api, type Model } from "@mariozechner/pi-ai";
|
|
2
2
|
import type { ModelRegistry } from "@mariozechner/pi-coding-agent";
|
|
3
|
-
import type { PipiclawSettingsManager } from "
|
|
3
|
+
import type { PipiclawSettingsManager } from "../settings.js";
|
|
4
4
|
export declare function formatModelReference(model: Model<Api>): string;
|
|
5
5
|
export declare function findExactModelReferenceMatch(modelReference: string, availableModels: Model<Api>[]): {
|
|
6
6
|
match?: Model<Api>;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
2
2
|
import { join } from "path";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { parseBuiltInCommand } from "../agent/commands.js";
|
|
4
|
+
import { getOrCreateRunner } from "../agent/index.js";
|
|
5
5
|
import * as log from "../log.js";
|
|
6
6
|
import { ensureChannelMemoryFilesSync } from "../memory/files.js";
|
|
7
7
|
import { APP_HOME_DIR, APP_NAME, AUTH_CONFIG_PATH, CHANNEL_CONFIG_PATH, MODELS_CONFIG_PATH, SETTINGS_CONFIG_PATH, WORKSPACE_DIR, } from "../paths.js";
|
|
8
8
|
import { parseSandboxArg, validateSandbox } from "../sandbox.js";
|
|
9
|
+
import { ensureChannelDir } from "./channel-paths.js";
|
|
9
10
|
import { createDingTalkContext } from "./delivery.js";
|
|
10
11
|
import { DingTalkBot, } from "./dingtalk.js";
|
|
11
12
|
import { createEventsWatcher } from "./events.js";
|
|
@@ -68,6 +69,26 @@ This file stores stable workspace-level memory.
|
|
|
68
69
|
|
|
69
70
|
<!-- Put long-lived project facts here. -->
|
|
70
71
|
`;
|
|
72
|
+
const DEFAULT_ENVIRONMENT = `# Environment
|
|
73
|
+
|
|
74
|
+
This file records durable environment facts and notable machine-level changes.
|
|
75
|
+
|
|
76
|
+
- Record installed tools, runtime prerequisites, and important config changes here.
|
|
77
|
+
- Keep entries concise and factual.
|
|
78
|
+
- Do not use this file for task progress, conversation summaries, or project-specific decisions.
|
|
79
|
+
|
|
80
|
+
## Environment Facts
|
|
81
|
+
|
|
82
|
+
<!-- Put stable machine or runtime facts here. -->
|
|
83
|
+
|
|
84
|
+
## Installed Tools
|
|
85
|
+
|
|
86
|
+
<!-- Record durable tools or dependencies that were installed for this workspace. -->
|
|
87
|
+
|
|
88
|
+
## Config Changes
|
|
89
|
+
|
|
90
|
+
<!-- Record important config or environment changes that affect future work. -->
|
|
91
|
+
`;
|
|
71
92
|
const CHANNEL_CONFIG_TEMPLATE = {
|
|
72
93
|
clientId: "your-dingtalk-client-id",
|
|
73
94
|
clientSecret: "your-dingtalk-client-secret",
|
|
@@ -139,6 +160,7 @@ export function bootstrapAppHome(paths = DEFAULT_BOOTSTRAP_PATHS) {
|
|
|
139
160
|
writeTextFileIfMissing(join(paths.workspaceDir, "SOUL.md"), DEFAULT_SOUL, "workspace/SOUL.md", created);
|
|
140
161
|
writeTextFileIfMissing(join(paths.workspaceDir, "AGENTS.md"), DEFAULT_AGENT, "workspace/AGENTS.md", created);
|
|
141
162
|
writeTextFileIfMissing(join(paths.workspaceDir, "MEMORY.md"), DEFAULT_MEMORY, "workspace/MEMORY.md", created);
|
|
163
|
+
writeTextFileIfMissing(join(paths.workspaceDir, "ENVIRONMENT.md"), DEFAULT_ENVIRONMENT, "workspace/ENVIRONMENT.md", created);
|
|
142
164
|
const channelTemplateCreated = writeJsonFileIfMissing(paths.channelConfigPath, CHANNEL_CONFIG_TEMPLATE, "channel.json", created);
|
|
143
165
|
writeJsonFileIfMissing(paths.authConfigPath, {}, "auth.json", created);
|
|
144
166
|
writeJsonFileIfMissing(paths.modelsConfigPath, MODELS_CONFIG_TEMPLATE, "models.json", created);
|
|
@@ -273,7 +295,7 @@ export async function bootstrap(argv, options = {}) {
|
|
|
273
295
|
const getState = (channelId) => {
|
|
274
296
|
let state = channelStates.get(channelId);
|
|
275
297
|
if (!state) {
|
|
276
|
-
const channelDir =
|
|
298
|
+
const channelDir = ensureChannelDir(paths.workspaceDir, channelId);
|
|
277
299
|
ensureChannelMemoryFilesSync(channelDir);
|
|
278
300
|
state = {
|
|
279
301
|
running: false,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { mkdirSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
export function getChannelDirName(channelId) {
|
|
4
|
+
return channelId.replaceAll("/", "__");
|
|
5
|
+
}
|
|
6
|
+
export function getChannelDir(baseDir, channelId) {
|
|
7
|
+
return join(baseDir, getChannelDirName(channelId));
|
|
8
|
+
}
|
|
9
|
+
export function ensureChannelDir(baseDir, channelId) {
|
|
10
|
+
const channelDir = getChannelDir(baseDir, channelId);
|
|
11
|
+
mkdirSync(channelDir, { recursive: true });
|
|
12
|
+
return channelDir;
|
|
13
|
+
}
|
package/dist/runtime/dingtalk.js
CHANGED
|
@@ -11,9 +11,10 @@ import axios from "axios";
|
|
|
11
11
|
import { DWClient, TOPIC_ROBOT } from "dingtalk-stream";
|
|
12
12
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
13
13
|
import { dirname, join } from "path";
|
|
14
|
-
import { parseBuiltInCommand, renderBuiltInHelp } from "../commands.js";
|
|
14
|
+
import { parseBuiltInCommand, renderBuiltInHelp } from "../agent/commands.js";
|
|
15
15
|
import * as log from "../log.js";
|
|
16
16
|
import { isRecord } from "../shared/type-guards.js";
|
|
17
|
+
import { getChannelDir } from "./channel-paths.js";
|
|
17
18
|
class ChannelQueue {
|
|
18
19
|
constructor() {
|
|
19
20
|
this.queue = [];
|
|
@@ -761,6 +762,6 @@ export class DingTalkBot {
|
|
|
761
762
|
getConversationMetaPath(channelId) {
|
|
762
763
|
if (!this.config.stateDir)
|
|
763
764
|
return null;
|
|
764
|
-
return join(this.config.stateDir, channelId, ".channel-meta.json");
|
|
765
|
+
return join(getChannelDir(this.config.stateDir, channelId), ".channel-meta.json");
|
|
765
766
|
}
|
|
766
767
|
}
|
package/dist/runtime/store.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { closeSync, existsSync, mkdirSync, openSync, readSync, renameSync, statSync } from "fs";
|
|
2
2
|
import { appendFile, writeFile } from "fs/promises";
|
|
3
3
|
import { dirname, join } from "path";
|
|
4
|
+
import { ensureChannelDir, getChannelDir } from "./channel-paths.js";
|
|
4
5
|
const MAX_LOG_SIZE_BYTES = 1_000_000;
|
|
5
6
|
const DEDUPE_TTL_MS = 60_000;
|
|
6
7
|
const DEDUPE_CLEANUP_INTERVAL_MS = 30_000;
|
|
@@ -19,11 +20,7 @@ export class ChannelStore {
|
|
|
19
20
|
* Get or create the directory for a channel/DM
|
|
20
21
|
*/
|
|
21
22
|
getChannelDir(channelId) {
|
|
22
|
-
|
|
23
|
-
if (!existsSync(dir)) {
|
|
24
|
-
mkdirSync(dir, { recursive: true });
|
|
25
|
-
}
|
|
26
|
-
return dir;
|
|
23
|
+
return ensureChannelDir(this.workingDir, channelId);
|
|
27
24
|
}
|
|
28
25
|
/**
|
|
29
26
|
* Log a message to the channel's log.jsonl raw archive.
|
|
@@ -102,7 +99,7 @@ export class ChannelStore {
|
|
|
102
99
|
* Returns null if no log exists
|
|
103
100
|
*/
|
|
104
101
|
getLastTimestamp(channelId) {
|
|
105
|
-
const logPath = join(this.workingDir, channelId, "log.jsonl");
|
|
102
|
+
const logPath = join(getChannelDir(this.workingDir, channelId), "log.jsonl");
|
|
106
103
|
if (!existsSync(logPath)) {
|
|
107
104
|
return null;
|
|
108
105
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parseFrontmatter } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
3
3
|
import { join } from "path";
|
|
4
|
-
import { findExactModelReferenceMatch, formatModelReference } from "../
|
|
4
|
+
import { findExactModelReferenceMatch, formatModelReference } from "../models/utils.js";
|
|
5
5
|
import { SUB_AGENTS_DIR_NAME } from "../paths.js";
|
|
6
6
|
const ALLOWED_SUB_AGENT_TOOLS = ["read", "bash", "edit", "write"];
|
|
7
7
|
const DEFAULT_SUB_AGENT_TOOLS = ["read", "bash"];
|
package/dist/subagents/tool.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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 { PipiclawMemoryRecallSettings } from "../context.js";
|
|
4
3
|
import type { Executor } from "../sandbox.js";
|
|
4
|
+
import type { PipiclawMemoryRecallSettings } from "../settings.js";
|
|
5
5
|
import type { UsageTotals } from "../shared/types.js";
|
|
6
6
|
import { type ResolvedSubAgentConfig, type SubAgentDiscoveryResult } from "./discovery.js";
|
|
7
7
|
declare const subagentSchema: import("@sinclair/typebox").TObject<{
|
package/dist/subagents/tool.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Type } from "@sinclair/typebox";
|
|
|
4
4
|
import { createMemoryCandidateCache } from "../memory/candidates.js";
|
|
5
5
|
import { readChannelSession } from "../memory/files.js";
|
|
6
6
|
import { recallRelevantMemory } from "../memory/recall.js";
|
|
7
|
-
import { formatModelReference } from "../
|
|
7
|
+
import { formatModelReference } from "../models/utils.js";
|
|
8
8
|
import { splitH1Sections } from "../shared/markdown-sections.js";
|
|
9
9
|
import { clipText, extractAssistantText, extractLabelFromArgs, HAN_REGEX } from "../shared/text-utils.js";
|
|
10
10
|
import { createBashTool } from "../tools/bash.js";
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
2
|
import type { Api, Model } from "@mariozechner/pi-ai";
|
|
3
|
-
import type { PipiclawMemoryRecallSettings } from "../context.js";
|
|
4
3
|
import type { Executor, SandboxConfig } from "../sandbox.js";
|
|
4
|
+
import type { PipiclawMemoryRecallSettings } from "../settings.js";
|
|
5
5
|
import type { SubAgentDiscoveryResult } from "../subagents/discovery.js";
|
|
6
6
|
export interface CreatePipiclawToolsOptions {
|
|
7
7
|
executor: Executor;
|
package/package.json
CHANGED
package/dist/agent.d.ts
DELETED
package/dist/agent.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ChannelRunner, getOrCreateRunner } from "./agent/index.js";
|
package/dist/config-loader.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Configuration file loaders for pipiclaw workspace files:
|
|
3
|
-
* SOUL.md, AGENTS.md, skills/, and API key resolution.
|
|
4
|
-
*/
|
|
5
|
-
import type { Api, Model } from "@mariozechner/pi-ai";
|
|
6
|
-
import { type ModelRegistry, type Skill } from "@mariozechner/pi-coding-agent";
|
|
7
|
-
/**
|
|
8
|
-
* Load SOUL.md — defines the agent's identity, personality, and communication style.
|
|
9
|
-
* Only loaded from workspace root (global).
|
|
10
|
-
*/
|
|
11
|
-
export declare function getSoul(workspaceDir: string): string;
|
|
12
|
-
/**
|
|
13
|
-
* Load AGENTS.md — defines the agent's behavior instructions, capabilities, and constraints.
|
|
14
|
-
* Only loaded from workspace root (global).
|
|
15
|
-
*/
|
|
16
|
-
export declare function getAgentConfig(channelDir: string): string;
|
|
17
|
-
/**
|
|
18
|
-
* Load skills from both workspace-level and channel-level skill directories.
|
|
19
|
-
* Channel-level skills override global skills with the same name.
|
|
20
|
-
*/
|
|
21
|
-
export declare function loadPipiclawSkills(channelDir: string, workspacePath: string): Skill[];
|
|
22
|
-
/**
|
|
23
|
-
* Resolve an API key for the given model's provider.
|
|
24
|
-
* Checks ModelRegistry first, then falls back to ANTHROPIC_API_KEY env var.
|
|
25
|
-
*/
|
|
26
|
-
export declare function getApiKeyForModel(modelRegistry: ModelRegistry, model: Model<Api>): Promise<string>;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|