@letta-ai/letta-code 0.11.2-next.2 → 0.11.2-next.4
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/letta.js +7059 -6390
- package/package.json +1 -1
- package/skills/acquiring-skills/SKILL.md +126 -0
- package/skills/creating-skills/SKILL.md +3 -3
- package/skills/finding-agents/SKILL.md +9 -9
- package/skills/migrating-memory/SKILL.md +34 -11
- package/skills/migrating-memory/scripts/attach-block.ts +91 -22
- package/skills/migrating-memory/scripts/copy-block.ts +107 -19
package/package.json
CHANGED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: acquiring-skills
|
|
3
|
+
description: Guide for safely discovering and installing skills from external repositories. Use when a user asks for something where a specialized skill likely exists (browser testing, PDF processing, document generation, etc.) and you want to bootstrap your understanding rather than starting from scratch.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Acquiring New Skills
|
|
7
|
+
|
|
8
|
+
This skill teaches you how to safely discover and install skills from external sources.
|
|
9
|
+
|
|
10
|
+
## SAFETY - READ THIS FIRST
|
|
11
|
+
|
|
12
|
+
Skills can contain:
|
|
13
|
+
- **Markdown files** (.md) - Risk: prompt injection, misleading instructions
|
|
14
|
+
- **Scripts** (Python, TypeScript, Bash) - Risk: malicious code execution
|
|
15
|
+
|
|
16
|
+
### Trusted Sources (no user approval needed for download)
|
|
17
|
+
- `https://github.com/letta-ai/skills` - Letta's community skills
|
|
18
|
+
- `https://github.com/anthropics/skills` - Anthropic's official skills
|
|
19
|
+
|
|
20
|
+
### Untrusted Sources (ALWAYS verify with user)
|
|
21
|
+
For ANY source other than letta-ai or anthropics:
|
|
22
|
+
1. Ask the user before downloading
|
|
23
|
+
2. Explain where the skill comes from
|
|
24
|
+
3. Get explicit approval
|
|
25
|
+
|
|
26
|
+
### Script Safety
|
|
27
|
+
Even for skills from trusted sources, ALWAYS:
|
|
28
|
+
1. Read and inspect any scripts before executing them
|
|
29
|
+
2. Understand what the script does
|
|
30
|
+
3. Be wary of network calls, file operations, or system commands
|
|
31
|
+
|
|
32
|
+
## When to Use This Skill
|
|
33
|
+
|
|
34
|
+
**DO use** when:
|
|
35
|
+
- User asks for something where a skill likely exists (e.g., "help me test this webapp", "generate a PDF report")
|
|
36
|
+
- You think "there's probably a skill that would bootstrap my understanding"
|
|
37
|
+
- User explicitly asks about available skills or extending capabilities
|
|
38
|
+
|
|
39
|
+
**DON'T use** for:
|
|
40
|
+
- General coding tasks you can already handle
|
|
41
|
+
- Simple bug fixes or feature implementations
|
|
42
|
+
- Tasks where you have sufficient knowledge
|
|
43
|
+
|
|
44
|
+
## Ask Before Searching (Interactive Mode)
|
|
45
|
+
|
|
46
|
+
If you recognize a task that might have an associated skill, **ask the user first**:
|
|
47
|
+
|
|
48
|
+
> "This sounds like something where a community skill might help (e.g., webapp testing with Playwright). Would you like me to look for available skills in the Letta or Anthropic repositories? This might take a minute, or I can start coding right away if you prefer."
|
|
49
|
+
|
|
50
|
+
The user may prefer to start immediately rather than wait for skill discovery.
|
|
51
|
+
|
|
52
|
+
Only proceed with skill acquisition if the user agrees.
|
|
53
|
+
|
|
54
|
+
## Skill Repositories
|
|
55
|
+
|
|
56
|
+
| Repository | Description |
|
|
57
|
+
|------------|-------------|
|
|
58
|
+
| https://github.com/letta-ai/skills | Community skills for Letta agents |
|
|
59
|
+
| https://github.com/anthropics/skills | Anthropic's official Agent Skills |
|
|
60
|
+
|
|
61
|
+
Browse these repositories to discover available skills. Check the README for skill listings.
|
|
62
|
+
|
|
63
|
+
## Installation Locations
|
|
64
|
+
|
|
65
|
+
| Location | Path | When to Use |
|
|
66
|
+
|----------|------|-------------|
|
|
67
|
+
| **Global** | `~/.letta/skills/<skill>/` | General-purpose skills useful across projects |
|
|
68
|
+
| **Project** | `.skills/<skill>/` | Project-specific skills |
|
|
69
|
+
|
|
70
|
+
**Rule**: If useful across multiple projects, install globally. If project-specific, install in `.skills/`.
|
|
71
|
+
|
|
72
|
+
## How to Download Skills
|
|
73
|
+
|
|
74
|
+
Skills are directories containing SKILL.md and optionally scripts/, references/, examples/.
|
|
75
|
+
|
|
76
|
+
### Method: Clone to /tmp, then copy
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# 1. Clone the repo (shallow)
|
|
80
|
+
git clone --depth 1 https://github.com/anthropics/skills /tmp/skills-temp
|
|
81
|
+
|
|
82
|
+
# 2. Copy the skill to your skills directory
|
|
83
|
+
# For global:
|
|
84
|
+
cp -r /tmp/skills-temp/skills/webapp-testing ~/.letta/skills/
|
|
85
|
+
# For project:
|
|
86
|
+
cp -r /tmp/skills-temp/skills/webapp-testing .skills/
|
|
87
|
+
|
|
88
|
+
# 3. Cleanup
|
|
89
|
+
rm -rf /tmp/skills-temp
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Alternative: rsync (preserves permissions)
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git clone --depth 1 https://github.com/anthropics/skills /tmp/skills-temp
|
|
96
|
+
rsync -av /tmp/skills-temp/skills/webapp-testing/ ~/.letta/skills/webapp-testing/
|
|
97
|
+
rm -rf /tmp/skills-temp
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Registering New Skills
|
|
101
|
+
|
|
102
|
+
After downloading, refresh the skills list:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
Skill(command: "refresh")
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This scans `~/.letta/skills/` and `.skills/` and updates your `skills` memory block.
|
|
109
|
+
|
|
110
|
+
## Complete Example
|
|
111
|
+
|
|
112
|
+
User asks: "Can you help me test my React app's UI?"
|
|
113
|
+
|
|
114
|
+
1. **Recognize opportunity**: Browser/webapp testing - likely has a skill
|
|
115
|
+
2. **Ask user**: "Would you like me to look for webapp testing skills, or start coding right away?"
|
|
116
|
+
3. **If user agrees, find skill**: Check anthropics/skills for webapp-testing
|
|
117
|
+
4. **Download** (trusted source):
|
|
118
|
+
```bash
|
|
119
|
+
git clone --depth 1 https://github.com/anthropics/skills /tmp/skills-temp
|
|
120
|
+
cp -r /tmp/skills-temp/skills/webapp-testing ~/.letta/skills/
|
|
121
|
+
rm -rf /tmp/skills-temp
|
|
122
|
+
```
|
|
123
|
+
5. **Refresh**: `Skill(command: "refresh")`
|
|
124
|
+
6. **Inspect scripts**: Read any .py or .ts files before using them
|
|
125
|
+
7. **Load**: `Skill(command: "load", skills: ["webapp-testing"])`
|
|
126
|
+
8. **Use**: Follow the skill's instructions for the user's task
|
|
@@ -263,7 +263,7 @@ When creating a new skill from scratch, always run the `init-skill.ts` script. T
|
|
|
263
263
|
Usage:
|
|
264
264
|
|
|
265
265
|
```bash
|
|
266
|
-
npx
|
|
266
|
+
npx tsx <SKILL_DIR>/scripts/init-skill.ts <skill-name> --path <output-directory>
|
|
267
267
|
```
|
|
268
268
|
|
|
269
269
|
The script:
|
|
@@ -335,13 +335,13 @@ Write instructions for using the skill and its bundled resources.
|
|
|
335
335
|
Once development of the skill is complete, it must be packaged into a distributable .skill file that gets shared with the user. The packaging process automatically validates the skill first to ensure it meets all requirements:
|
|
336
336
|
|
|
337
337
|
```bash
|
|
338
|
-
npx
|
|
338
|
+
npx tsx <SKILL_DIR>/scripts/package-skill.ts <path/to/skill-folder>
|
|
339
339
|
```
|
|
340
340
|
|
|
341
341
|
Optional output directory specification:
|
|
342
342
|
|
|
343
343
|
```bash
|
|
344
|
-
npx
|
|
344
|
+
npx tsx <SKILL_DIR>/scripts/package-skill.ts <path/to/skill-folder> ./dist
|
|
345
345
|
```
|
|
346
346
|
|
|
347
347
|
The packaging script will:
|
|
@@ -18,7 +18,7 @@ This skill helps you find other agents on the same Letta server.
|
|
|
18
18
|
## Script Usage
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
npx
|
|
21
|
+
npx tsx <SKILL_DIR>/scripts/find-agents.ts [options]
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
### Options
|
|
@@ -39,7 +39,7 @@ npx ts-node scripts/find-agents.ts [options]
|
|
|
39
39
|
Agents created by Letta Code are tagged with `origin:letta-code`. To find only Letta Code agents:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
npx
|
|
42
|
+
npx tsx <SKILL_DIR>/scripts/find-agents.ts --tags "origin:letta-code"
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
This is useful when the user is looking for agents they've worked with in Letta Code CLI sessions.
|
|
@@ -49,39 +49,39 @@ This is useful when the user is looking for agents they've worked with in Letta
|
|
|
49
49
|
If the user has agents created outside Letta Code (via ADE, SDK, etc.), search without the tag filter:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
npx
|
|
52
|
+
npx tsx <SKILL_DIR>/scripts/find-agents.ts
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
## Examples
|
|
56
56
|
|
|
57
57
|
**List all agents (up to 20):**
|
|
58
58
|
```bash
|
|
59
|
-
npx
|
|
59
|
+
npx tsx <SKILL_DIR>/scripts/find-agents.ts
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
**Find agent by exact name:**
|
|
63
63
|
```bash
|
|
64
|
-
npx
|
|
64
|
+
npx tsx <SKILL_DIR>/scripts/find-agents.ts --name "ProjectX-v1"
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
**Search agents by name (fuzzy):**
|
|
68
68
|
```bash
|
|
69
|
-
npx
|
|
69
|
+
npx tsx <SKILL_DIR>/scripts/find-agents.ts --query "project"
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
**Find only Letta Code agents:**
|
|
73
73
|
```bash
|
|
74
|
-
npx
|
|
74
|
+
npx tsx <SKILL_DIR>/scripts/find-agents.ts --tags "origin:letta-code"
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
**Find agents with multiple tags:**
|
|
78
78
|
```bash
|
|
79
|
-
npx
|
|
79
|
+
npx tsx <SKILL_DIR>/scripts/find-agents.ts --tags "frontend,production" --match-all-tags
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
**Include memory blocks in results:**
|
|
83
83
|
```bash
|
|
84
|
-
npx
|
|
84
|
+
npx tsx <SKILL_DIR>/scripts/find-agents.ts --query "project" --include-blocks
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
## Output
|
|
@@ -29,7 +29,6 @@ Best for: Extracting sections, cleaning up messy content, selective migration.
|
|
|
29
29
|
|
|
30
30
|
Creates new blocks with the same content using `copy-block.ts`. After copying:
|
|
31
31
|
- You own the copy - changes don't sync
|
|
32
|
-
- Use `--label` flag if you already have a block with that label
|
|
33
32
|
- Best for: One-time migration, forking an agent
|
|
34
33
|
|
|
35
34
|
### 3. Share (Linked Blocks)
|
|
@@ -40,7 +39,31 @@ Attaches the same block to multiple agents using `attach-block.ts`. After sharin
|
|
|
40
39
|
- Can be read-only (target can read but not modify)
|
|
41
40
|
- Best for: Shared knowledge bases, synchronized state
|
|
42
41
|
|
|
43
|
-
|
|
42
|
+
## Handling Duplicate Label Errors
|
|
43
|
+
|
|
44
|
+
**You cannot have two blocks with the same label.** If you try to copy/attach a block and you already have one with that label, you'll get a `duplicate key value violates unique constraint` error.
|
|
45
|
+
|
|
46
|
+
**Solutions:**
|
|
47
|
+
|
|
48
|
+
1. **Use `--label` (copy only):** Rename the block when copying:
|
|
49
|
+
```bash
|
|
50
|
+
npx tsx <SKILL_DIR>/scripts/copy-block.ts --block-id <id> --label project-imported
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
2. **Use `--override` (copy or attach):** Automatically detach your existing block first:
|
|
54
|
+
```bash
|
|
55
|
+
npx tsx <SKILL_DIR>/scripts/copy-block.ts --block-id <id> --override
|
|
56
|
+
npx tsx <SKILL_DIR>/scripts/attach-block.ts --block-id <id> --override
|
|
57
|
+
```
|
|
58
|
+
If the operation fails, the original block is automatically reattached.
|
|
59
|
+
|
|
60
|
+
3. **Manual detach first:** Use the `memory` tool to detach your existing block:
|
|
61
|
+
```
|
|
62
|
+
memory(agent_state, "delete", path="/memories/<label>")
|
|
63
|
+
```
|
|
64
|
+
Then run the copy/attach script.
|
|
65
|
+
|
|
66
|
+
**Note:** `attach-block.ts` does NOT support `--label` because attached blocks keep their original label (they're shared, not copied).
|
|
44
67
|
|
|
45
68
|
## Workflow
|
|
46
69
|
|
|
@@ -60,7 +83,7 @@ Example: "What's the ID of the agent you want to migrate memory from?"
|
|
|
60
83
|
Inspect what memory blocks the source agent has:
|
|
61
84
|
|
|
62
85
|
```bash
|
|
63
|
-
npx
|
|
86
|
+
npx tsx <SKILL_DIR>/scripts/get-agent-blocks.ts --agent-id <source-agent-id>
|
|
64
87
|
```
|
|
65
88
|
|
|
66
89
|
This shows each block's ID, label, description, and value.
|
|
@@ -71,14 +94,14 @@ For each block you want to migrate, choose copy or share:
|
|
|
71
94
|
|
|
72
95
|
**To Copy (create independent block):**
|
|
73
96
|
```bash
|
|
74
|
-
npx
|
|
97
|
+
npx tsx <SKILL_DIR>/scripts/copy-block.ts --block-id <block-id> [--label <new-label>]
|
|
75
98
|
```
|
|
76
99
|
|
|
77
100
|
Use `--label` if you already have a block with that label (e.g., `--label project-imported`).
|
|
78
101
|
|
|
79
102
|
**To Share (attach existing block):**
|
|
80
103
|
```bash
|
|
81
|
-
npx
|
|
104
|
+
npx tsx <SKILL_DIR>/scripts/attach-block.ts --block-id <block-id>
|
|
82
105
|
```
|
|
83
106
|
|
|
84
107
|
Add `--read-only` flag to share to make this agent unable to modify the block.
|
|
@@ -92,8 +115,8 @@ All scripts are located in the `scripts/` directory and output raw API responses
|
|
|
92
115
|
| Script | Purpose | Args |
|
|
93
116
|
|--------|---------|------|
|
|
94
117
|
| `get-agent-blocks.ts` | Get blocks from an agent | `--agent-id` |
|
|
95
|
-
| `copy-block.ts` | Copy block to current agent | `--block-id`, optional `--label` |
|
|
96
|
-
| `attach-block.ts` | Attach existing block to current agent | `--block-id`, optional `--read-only` |
|
|
118
|
+
| `copy-block.ts` | Copy block to current agent | `--block-id`, optional `--label`, `--override` |
|
|
119
|
+
| `attach-block.ts` | Attach existing block to current agent | `--block-id`, optional `--read-only`, `--override` |
|
|
97
120
|
|
|
98
121
|
## Authentication
|
|
99
122
|
|
|
@@ -113,20 +136,20 @@ Scenario: You're a new agent and want to inherit memory from an existing agent "
|
|
|
113
136
|
|
|
114
137
|
2. **List its blocks:**
|
|
115
138
|
```bash
|
|
116
|
-
npx
|
|
139
|
+
npx tsx <SKILL_DIR>/scripts/get-agent-blocks.ts --agent-id agent-abc123
|
|
117
140
|
# Shows: project (block-def456), human (block-ghi789), persona (block-jkl012)
|
|
118
141
|
```
|
|
119
142
|
|
|
120
143
|
3. **Copy project knowledge to yourself:**
|
|
121
144
|
```bash
|
|
122
145
|
# If you don't have a 'project' block yet:
|
|
123
|
-
npx
|
|
146
|
+
npx tsx <SKILL_DIR>/scripts/copy-block.ts --block-id block-def456
|
|
124
147
|
|
|
125
148
|
# If you already have 'project', use --label to rename:
|
|
126
|
-
npx
|
|
149
|
+
npx tsx <SKILL_DIR>/scripts/copy-block.ts --block-id block-def456 --label project-v1
|
|
127
150
|
```
|
|
128
151
|
|
|
129
152
|
4. **Optionally share human preferences (read-only):**
|
|
130
153
|
```bash
|
|
131
|
-
npx
|
|
154
|
+
npx tsx <SKILL_DIR>/scripts/attach-block.ts --block-id block-ghi789 --read-only
|
|
132
155
|
```
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* It reads agent ID from LETTA_AGENT_ID env var or --agent-id arg.
|
|
8
8
|
*
|
|
9
9
|
* Usage:
|
|
10
|
-
* npx tsx attach-block.ts --block-id <block-id> [--agent-id <agent-id>] [--read-only]
|
|
10
|
+
* npx tsx attach-block.ts --block-id <block-id> [--agent-id <agent-id>] [--read-only] [--override]
|
|
11
11
|
*
|
|
12
12
|
* This attaches an existing block to another agent, making it shared.
|
|
13
13
|
* Changes to the block will be visible to all agents that have it attached.
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
* Options:
|
|
16
16
|
* --agent-id Target agent ID (overrides LETTA_AGENT_ID env var)
|
|
17
17
|
* --read-only Target agent can read but not modify the block
|
|
18
|
+
* --override If you already have a block with the same label, detach it first
|
|
19
|
+
* (on error, the original block is reattached)
|
|
18
20
|
*
|
|
19
21
|
* Output:
|
|
20
22
|
* Raw API response from the attach operation
|
|
@@ -75,49 +77,109 @@ function createClient(): LettaClient {
|
|
|
75
77
|
return new Letta({ apiKey: getApiKey() });
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
interface AttachBlockResult {
|
|
81
|
+
attachResult: Awaited<ReturnType<LettaClient["agents"]["blocks"]["attach"]>>;
|
|
82
|
+
detachedBlock?: Awaited<ReturnType<LettaClient["blocks"]["retrieve"]>>;
|
|
83
|
+
}
|
|
84
|
+
|
|
78
85
|
/**
|
|
79
86
|
* Attach an existing block to the current agent (sharing it)
|
|
80
87
|
* @param client - Letta client instance
|
|
81
88
|
* @param blockId - The block ID to attach
|
|
82
|
-
* @param
|
|
83
|
-
* @param targetAgentId - Optional target agent ID (defaults to current agent)
|
|
89
|
+
* @param options - readOnly, targetAgentId, override (detach existing block with same label)
|
|
84
90
|
* @returns API response from the attach operation
|
|
85
91
|
*/
|
|
86
92
|
export async function attachBlock(
|
|
87
93
|
client: LettaClient,
|
|
88
94
|
blockId: string,
|
|
89
|
-
readOnly
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
|
|
95
|
+
options?: { readOnly?: boolean; targetAgentId?: string; override?: boolean },
|
|
96
|
+
): Promise<AttachBlockResult> {
|
|
97
|
+
const currentAgentId = getAgentId(options?.targetAgentId);
|
|
98
|
+
let detachedBlock:
|
|
99
|
+
| Awaited<ReturnType<LettaClient["blocks"]["retrieve"]>>
|
|
100
|
+
| undefined;
|
|
101
|
+
|
|
102
|
+
// If override is requested, check for existing block with same label and detach it
|
|
103
|
+
if (options?.override) {
|
|
104
|
+
// Get the block we're trying to attach to find its label
|
|
105
|
+
const sourceBlock = await client.blocks.retrieve(blockId);
|
|
106
|
+
const sourceLabel = sourceBlock.label;
|
|
107
|
+
|
|
108
|
+
// Get current agent's blocks to check for label conflict
|
|
109
|
+
const currentBlocksResponse =
|
|
110
|
+
await client.agents.blocks.list(currentAgentId);
|
|
111
|
+
// The response may be paginated or an array depending on SDK version
|
|
112
|
+
const currentBlocks = Array.isArray(currentBlocksResponse)
|
|
113
|
+
? currentBlocksResponse
|
|
114
|
+
: (currentBlocksResponse as { items?: unknown[] }).items || [];
|
|
115
|
+
const conflictingBlock = currentBlocks.find(
|
|
116
|
+
(b: { label?: string }) => b.label === sourceLabel,
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
if (conflictingBlock) {
|
|
120
|
+
console.error(
|
|
121
|
+
`Detaching existing block with label "${sourceLabel}" (${conflictingBlock.id})...`,
|
|
122
|
+
);
|
|
123
|
+
detachedBlock = conflictingBlock;
|
|
124
|
+
try {
|
|
125
|
+
await client.agents.blocks.detach(conflictingBlock.id, {
|
|
126
|
+
agent_id: currentAgentId,
|
|
127
|
+
});
|
|
128
|
+
} catch (detachError) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`Failed to detach existing block "${sourceLabel}": ${detachError instanceof Error ? detachError.message : String(detachError)}`,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Attempt to attach the new block
|
|
137
|
+
let attachResult: Awaited<ReturnType<typeof client.agents.blocks.attach>>;
|
|
138
|
+
try {
|
|
139
|
+
attachResult = await client.agents.blocks.attach(blockId, {
|
|
140
|
+
agent_id: currentAgentId,
|
|
141
|
+
});
|
|
142
|
+
} catch (attachError) {
|
|
143
|
+
// If attach failed and we detached a block, try to reattach it
|
|
144
|
+
if (detachedBlock) {
|
|
145
|
+
console.error(
|
|
146
|
+
`Attach failed, reattaching original block "${detachedBlock.label}"...`,
|
|
147
|
+
);
|
|
148
|
+
try {
|
|
149
|
+
await client.agents.blocks.attach(detachedBlock.id, {
|
|
150
|
+
agent_id: currentAgentId,
|
|
151
|
+
});
|
|
152
|
+
console.error("Original block reattached successfully.");
|
|
153
|
+
} catch {
|
|
154
|
+
console.error(
|
|
155
|
+
`WARNING: Failed to reattach original block! Block ID: ${detachedBlock.id}`,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
throw attachError;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// If read-only is requested, note the limitation
|
|
163
|
+
if (options?.readOnly) {
|
|
104
164
|
console.warn(
|
|
105
165
|
"Note: read_only flag is set on the block itself, not per-agent. " +
|
|
106
166
|
"Use the block update API to set read_only if needed.",
|
|
107
167
|
);
|
|
108
168
|
}
|
|
109
169
|
|
|
110
|
-
return
|
|
170
|
+
return { attachResult, detachedBlock };
|
|
111
171
|
}
|
|
112
172
|
|
|
113
173
|
function parseArgs(args: string[]): {
|
|
114
174
|
blockId: string;
|
|
115
175
|
readOnly: boolean;
|
|
176
|
+
override: boolean;
|
|
116
177
|
agentId?: string;
|
|
117
178
|
} {
|
|
118
179
|
const blockIdIndex = args.indexOf("--block-id");
|
|
119
180
|
const agentIdIndex = args.indexOf("--agent-id");
|
|
120
181
|
const readOnly = args.includes("--read-only");
|
|
182
|
+
const override = args.includes("--override");
|
|
121
183
|
|
|
122
184
|
if (blockIdIndex === -1 || blockIdIndex + 1 >= args.length) {
|
|
123
185
|
throw new Error("Missing required argument: --block-id <block-id>");
|
|
@@ -126,6 +188,7 @@ function parseArgs(args: string[]): {
|
|
|
126
188
|
return {
|
|
127
189
|
blockId: args[blockIdIndex + 1] as string,
|
|
128
190
|
readOnly,
|
|
191
|
+
override,
|
|
129
192
|
agentId:
|
|
130
193
|
agentIdIndex !== -1 && agentIdIndex + 1 < args.length
|
|
131
194
|
? (args[agentIdIndex + 1] as string)
|
|
@@ -138,9 +201,15 @@ const isMainModule = import.meta.url === `file://${process.argv[1]}`;
|
|
|
138
201
|
if (isMainModule) {
|
|
139
202
|
(async () => {
|
|
140
203
|
try {
|
|
141
|
-
const { blockId, readOnly, agentId } = parseArgs(
|
|
204
|
+
const { blockId, readOnly, override, agentId } = parseArgs(
|
|
205
|
+
process.argv.slice(2),
|
|
206
|
+
);
|
|
142
207
|
const client = createClient();
|
|
143
|
-
const result = await attachBlock(client, blockId,
|
|
208
|
+
const result = await attachBlock(client, blockId, {
|
|
209
|
+
readOnly,
|
|
210
|
+
override,
|
|
211
|
+
targetAgentId: agentId,
|
|
212
|
+
});
|
|
144
213
|
console.log(JSON.stringify(result, null, 2));
|
|
145
214
|
} catch (error) {
|
|
146
215
|
console.error(
|
|
@@ -152,7 +221,7 @@ if (isMainModule) {
|
|
|
152
221
|
error.message.includes("Missing required argument")
|
|
153
222
|
) {
|
|
154
223
|
console.error(
|
|
155
|
-
"\nUsage: npx tsx attach-block.ts --block-id <block-id> [--agent-id <agent-id>] [--read-only]",
|
|
224
|
+
"\nUsage: npx tsx attach-block.ts --block-id <block-id> [--agent-id <agent-id>] [--read-only] [--override]",
|
|
156
225
|
);
|
|
157
226
|
}
|
|
158
227
|
process.exit(1);
|