@openagentpack/sdk 0.7.0 → 0.7.1

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.
@@ -77,11 +77,11 @@ Use this Skill when the user asks to summarize text.
77
77
  the directory is the upload source. Do not put secrets in these files.
78
78
  \`SKILL.md\` \u662F Skill \u6307\u4EE4\uFF0C\u9700\u8981\u7684\u811A\u672C\u548C\u7D20\u6750\u4E5F\u653E\u5728\u6B64\u76EE\u5F55\uFF1B\u6574\u4E2A\u76EE\u5F55\u4F5C\u4E3A\u4E0A\u4F20\u6E90\uFF0C\u8BF7\u52FF\u653E\u5165\u5BC6\u94A5\u3002
79
79
  - This example is ignored by Build/Publish. Copy it from \`skills/_examples/example-skill/\`
80
- to \`skills/example-skill/\`, then add \`"skills": ["example-skill"]\` to \`agent.json\`.
81
- \u6B64\u793A\u4F8B\u4E0D\u53C2\u4E0E\u6784\u5EFA/\u53D1\u5E03\u3002\u590D\u5236\u5230 \`skills/example-skill/\` \u540E\uFF0C\u518D\u5728 Agent \u4E2D\u6DFB\u52A0\u4E0A\u8FF0\u5F15\u7528\u3002
80
+ to \`skills/example-skill/\`, then Build adds \`"example-skill"\` to \`agent.json.skills\` automatically.
81
+ \u6B64\u793A\u4F8B\u4E0D\u53C2\u4E0E\u6784\u5EFA/\u53D1\u5E03\u3002\u590D\u5236\u5230 \`skills/example-skill/\` \u540E\uFF0CBuild \u4F1A\u81EA\u52A8\u8865\u9F50 Agent \u5F15\u7528\u3002
82
82
  - To add another Skill, copy this directory, change the directory name and \`skill.json.id\`,
83
- then add its ID to \`agent.json.skills\`. A new directory with only \`SKILL.md\` is also discovered by Build.
84
- \u65B0\u589E Skill \u65F6\u590D\u5236\u6B64\u76EE\u5F55\u3001\u4FEE\u6539\u76EE\u5F55\u540D\u548C ID\uFF0C\u518D\u5728 Agent \u4E2D\u5F15\u7528\uFF1B\u53EA\u653E \`SKILL.md\` \u7684\u65B0\u76EE\u5F55\u4E5F\u80FD\u7531 Build \u81EA\u52A8\u5173\u8054\u3002
83
+ then run Build to add its ID to \`agent.json.skills\`. A new directory with only \`SKILL.md\` is also discovered by Build.
84
+ \u65B0\u589E Skill \u65F6\u590D\u5236\u6B64\u76EE\u5F55\u3001\u4FEE\u6539\u76EE\u5F55\u540D\u548C ID\uFF0C\u518D\u8FD0\u884C Build \u81EA\u52A8\u5173\u8054\uFF1B\u53EA\u653E \`SKILL.md\` \u7684\u65B0\u76EE\u5F55\u4E5F\u80FD\u7531 Build \u81EA\u52A8\u5173\u8054\u3002
85
85
  - Delete this ignored example directory if not needed. For an enabled Skill, also remove its Agent reference.
86
86
  \u4E0D\u9700\u8981\u65F6\u53EF\u76F4\u63A5\u5220\u9664\u672C\u793A\u4F8B\u76EE\u5F55\uFF1B\u82E5\u5DF2\u7ECF\u542F\u7528\uFF0C\u8FD8\u9700\u5220\u9664 Agent \u5F15\u7528\u3002
87
87
  `,
@@ -106,8 +106,8 @@ at \`/mnt/example.md\` in agent.json.
106
106
  - \`source\` is relative to this resource directory. Keep \`id\` equal to the directory name.
107
107
  \`source\` \u76F8\u5BF9\u6B64\u8D44\u6E90\u76EE\u5F55\u89E3\u6790\uFF0C\`id\` \u5E94\u4E0E\u76EE\u5F55\u540D\u4E00\u81F4\u3002
108
108
  - Build/Publish ignore this example. Copy \`files/_examples/example-file/\` to \`files/example-file/\`
109
- to enable its declaration; add \`"files": [{"file": "example-file", "mount_path": "/mnt/example.md"}]\` to \`agent.json\`.
110
- \u6B64\u793A\u4F8B\u4E0D\u53C2\u4E0E\u6784\u5EFA/\u53D1\u5E03\u3002\u590D\u5236\u5230 \`files/example-file/\` \u540E\u542F\u7528\u58F0\u660E\uFF0C\u518D\u6DFB\u52A0\u4E0A\u8FF0\u6302\u8F7D\u5F15\u7528\uFF1B\u6302\u8F7D\u8DEF\u5F84\u5FC5\u987B\u5728 \`/mnt/\` \u4E0B\u3002
109
+ to enable its declaration; Build adds \`{"file": "example-file", "mount_path": "/mnt/example.md"}\` to \`agent.json.files\`.
110
+ \u6B64\u793A\u4F8B\u4E0D\u53C2\u4E0E\u6784\u5EFA/\u53D1\u5E03\u3002\u590D\u5236\u5230 \`files/example-file/\` \u540E\uFF0CBuild \u81EA\u52A8\u6DFB\u52A0\u4E0A\u8FF0\u6302\u8F7D\u5F15\u7528\uFF1B\u5DF2\u6709\u81EA\u5B9A\u4E49\u6302\u8F7D\u8DEF\u5F84\u4F1A\u4FDD\u7559\uFF0C\u6302\u8F7D\u8DEF\u5F84\u5FC5\u987B\u5728 \`/mnt/\` \u4E0B\u3002
111
111
  - Uploading a File does not permanently attach it to the remote Agent. These declarations
112
112
  supply default mounts for new Sessions; existing Sessions are unchanged.
113
113
  \u4E0A\u4F20 File \u4E0D\u7B49\u4E8E\u6C38\u4E45\u7ED1\u5B9A\u5230\u8FDC\u7AEF Agent\uFF1B\u8FD9\u91CC\u58F0\u660E\u7684\u662F\u65B0 Session \u7684\u9ED8\u8BA4\u6302\u8F7D\uFF0C\u4E0D\u4FEE\u6539\u5DF2\u6709 Session\u3002
@@ -133,9 +133,10 @@ at \`/mnt/example.md\` in agent.json.
133
133
 
134
134
  Build/Publish ignore this directory; no example secret is required to open Workbench.
135
135
  Copy \`vaults/_examples/example-vault/\` to \`vaults/example-vault/\` to enable the declaration,
136
- then add \`"vault": "example-vault"\` to \`agent.json\` and supply the secret.
136
+ then supply the secret and run Build. If \`agent.json.vault\` is unset, Build selects the sole local Vault automatically.
137
+ With multiple local Vaults, set \`"vault": "example-vault"\` explicitly; Build never overwrites an existing selection.
137
138
  \u6B64\u793A\u4F8B\u4E0D\u53C2\u4E0E\u6784\u5EFA/\u53D1\u5E03\uFF0C\u4E0D\u9700\u8981\u914D\u7F6E\u5BC6\u94A5\u5373\u53EF\u6253\u5F00 Workbench\u3002
138
- \u542F\u7528\u65F6\uFF0C\u590D\u5236\u5230 \`vaults/example-vault/\`\uFF0C\u5728 Agent \u4E2D\u6DFB\u52A0\u4E0A\u8FF0\u5F15\u7528\uFF0C\u5E76\u914D\u7F6E\u5BC6\u94A5\u3002
139
+ \u542F\u7528\u65F6\uFF0C\u590D\u5236\u5230 \`vaults/example-vault/\`\uFF0C\u914D\u7F6E\u5BC6\u94A5\u540E\u8FD0\u884C Build\u3002\u672A\u6307\u5B9A Vault \u65F6\u81EA\u52A8\u5173\u8054\u552F\u4E00\u5019\u9009\uFF1B\u591A\u4E2A\u5019\u9009\u9700\u663E\u5F0F\u9009\u62E9\uFF0C\u5DF2\u6709\u5F15\u7528\u4E0D\u8986\u76D6\u3002
139
140
 
140
141
  The example \`vault.json\` contains:
141
142
  \u793A\u4F8B \`vault.json\` \u7684\u5B8C\u6574\u914D\u7F6E\u5982\u4E0B\uFF1A
@@ -184,8 +185,9 @@ ${JSON.stringify(
184
185
  [`${agentRoot}/environments/${RESOURCE_EXAMPLES_DIRECTORY}/example-env/README.md`]: `# Environment example / Environment \u914D\u7F6E\u793A\u4F8B
185
186
 
186
187
  - This is an ignored managed cloud environment example. Copy \`environments/_examples/example-env/\`
187
- to \`environments/example-env/\` to enable it, then add \`"environment": "example-env"\` to \`agent.json\`.
188
- \u8FD9\u662F\u4E0D\u53C2\u4E0E\u6784\u5EFA/\u53D1\u5E03\u7684\u6258\u7BA1\u4E91\u73AF\u5883\u793A\u4F8B\u3002\u590D\u5236\u5230 \`environments/example-env/\` \u540E\u542F\u7528\uFF0C\u518D\u5728 Agent \u4E2D\u6DFB\u52A0\u4E0A\u8FF0\u5F15\u7528\u3002
188
+ to \`environments/example-env/\`, then run Build. An unset \`agent.json.environment\` is linked to the sole local Environment.
189
+ With multiple local Environments, set \`"environment": "example-env"\` explicitly; existing selections are preserved.
190
+ \u8FD9\u662F\u4E0D\u53C2\u4E0E\u6784\u5EFA/\u53D1\u5E03\u7684\u6258\u7BA1\u4E91\u73AF\u5883\u793A\u4F8B\u3002\u590D\u5236\u5230 \`environments/example-env/\` \u540E\u8FD0\u884C Build\uFF1B\u672A\u6307\u5B9A\u73AF\u5883\u65F6\u81EA\u52A8\u5173\u8054\u552F\u4E00\u5019\u9009\uFF0C\u591A\u4E2A\u5019\u9009\u9700\u663E\u5F0F\u9009\u62E9\uFF0C\u5DF2\u6709\u5F15\u7528\u4E0D\u8986\u76D6\u3002
189
191
  Keep \`id\` equal to the directory name. / ID \u5E94\u4E0E\u76EE\u5F55\u540D\u4E00\u81F4\u3002
190
192
  - Optional \`config\` fields include \`networking\`, \`packages\`, and \`setup_script\`.
191
193
  \`config\` \u53EF\u6309\u9700\u589E\u52A0\u7F51\u7EDC\u7B56\u7565\u3001\u4F9D\u8D56\u5305\u548C\u521D\u59CB\u5316\u811A\u672C\uFF0C\u4F8B\u5982\uFF1A
@@ -198,8 +200,8 @@ ${JSON.stringify({ type: "cloud", packages: { pip: ["requests"] }, setup_script:
198
200
  packages/scripts take effect on the remote platform, not on your computer during Init/Build.
199
201
  \u4E0A\u9762\u7684\u7247\u6BB5\u53EA\u66FF\u6362 \`config\`\u3002Init/Build \u4E0D\u4F1A\u5728\u672C\u673A\u5B89\u88C5\u4F9D\u8D56\u6216\u6267\u884C\u811A\u672C\uFF1B\u8FDC\u7AEF\u662F\u5426\u652F\u6301\u4EE5 Provider \u4E3A\u51C6\u3002
200
202
  - Init leaves \`agent.json\` unchanged and only creates ignored resource examples.
201
- Moving a declaration outside \`_examples/\` enables it for Build/Publish, even without an Agent reference.
202
- Init \u4E0D\u6DFB\u52A0 Agent \u8D44\u6E90\u5F15\u7528\u3002\u5C06\u58F0\u660E\u79FB\u5230 \`_examples/\` \u5916\u5373\u4F1A\u8FDB\u5165\u6784\u5EFA/\u53D1\u5E03\u8303\u56F4\uFF0C\u5373\u4F7F\u5C1A\u672A\u914D\u7F6E Agent \u5F15\u7528\u3002
203
+ Moving a declaration outside \`_examples/\` enables it for Build/Publish; Build also fills in the owning Agent's missing reference.
204
+ Init \u4E0D\u6DFB\u52A0 Agent \u8D44\u6E90\u5F15\u7528\u3002\u5C06\u58F0\u660E\u79FB\u5230 \`_examples/\` \u5916\u540E\uFF0CBuild \u4F1A\u8865\u9F50\u6240\u5C5E Agent \u7684\u5F15\u7528\u5E76\u7EB3\u5165\u6784\u5EFA/\u53D1\u5E03\u3002
203
205
  - Delete this ignored example directory if not needed. For an enabled Environment, also remove its Agent reference.
204
206
  \u4E0D\u9700\u8981\u65F6\u53EF\u76F4\u63A5\u5220\u9664\u672C\u793A\u4F8B\u76EE\u5F55\uFF1B\u82E5\u5DF2\u7ECF\u542F\u7528\uFF0C\u8FD8\u9700\u5220\u9664 Agent \u7684 Environment \u5F15\u7528\u3002
205
207
  `
@@ -438,6 +440,23 @@ async function resolveDirectoryProjectRoot(input = ".") {
438
440
  const root = resolve2(input);
439
441
  const details = await stat(root).catch(() => null);
440
442
  if (!details?.isDirectory()) throw new UserError(`Project directory does not exist: ${root}`);
443
+ if (!await pathExists(resolve2(root, PROJECT_METADATA_FILE))) {
444
+ let ancestor = dirname(root);
445
+ while (ancestor !== root) {
446
+ if (await pathExists(resolve2(ancestor, PROJECT_METADATA_FILE))) {
447
+ const quotedRoot = `'${ancestor.replaceAll("'", "'\\''")}'`;
448
+ throw new UserError(
449
+ `Not a project root: ${root} (${PROJECT_METADATA_FILE} is missing).
450
+ Project root: ${ancestor}
451
+ Run from the project root: cd ${quotedRoot}
452
+ Or specify the project directory: --project ${quotedRoot}`
453
+ );
454
+ }
455
+ const parent = dirname(ancestor);
456
+ if (parent === ancestor) break;
457
+ ancestor = parent;
458
+ }
459
+ }
441
460
  return root;
442
461
  }
443
462
  async function inspectDirectoryProject(projectDirectory = ".") {
@@ -804,7 +823,7 @@ async function assembleProject(projectRoot, sourceFiles, metadataOverrides) {
804
823
  for (const skill of skills) {
805
824
  if (skillById.has(skill.id)) throw new UserError(`Duplicate local skill id: ${skill.id}`);
806
825
  skillById.set(skill.id, skill);
807
- if (skill.ownerAgent && skill.inferred) {
826
+ if (skill.ownerAgent) {
808
827
  autoAssociateSkill(skill, projectRoot, agents, agentSources, autoAssociations);
809
828
  }
810
829
  }
@@ -850,9 +869,7 @@ async function assembleProject(projectRoot, sourceFiles, metadataOverrides) {
850
869
  const key = `${resource.type}:${resource.id}`;
851
870
  if (resourceKeys.has(key)) throw new UserError(`Duplicate ${resource.type} id: ${resource.id}`);
852
871
  resourceKeys.add(key);
853
- if (resource.type === "file" && resource.owner_agent && resource.inferred) {
854
- autoAssociateFile(resource, projectRoot, agents, agentSources, autoAssociations);
855
- }
872
+ autoAssociateDirectoryResource(resource, resources, projectRoot, agents, agentSources, autoAssociations);
856
873
  if (resource.owner_agent && isDirectoryResourceShared(resource.type, resource.id, resource.owner_agent, agents, project)) {
857
874
  const spec = DIRECTORY_RESOURCE_SPECS[resource.type];
858
875
  moves.push({
@@ -1120,6 +1137,43 @@ function autoAssociateSkill(skill, projectRoot, agents, agentSources, autoAssoci
1120
1137
  message: `Skill '${skill.id}' will be added to agents/${ownerAgent}/agent.json.`
1121
1138
  });
1122
1139
  }
1140
+ function autoAssociateDirectoryResource(resource, resources, projectRoot, agents, agentSources, autoAssociations) {
1141
+ if (resource.type === "file") {
1142
+ autoAssociateFile(resource, projectRoot, agents, agentSources, autoAssociations);
1143
+ return;
1144
+ }
1145
+ const ownerAgent = resource.owner_agent;
1146
+ if (!ownerAgent) return;
1147
+ const agent = agents[ownerAgent];
1148
+ const agentSource = agentSources.get(ownerAgent);
1149
+ if (!agent || !agentSource) return;
1150
+ const agentPath = `agents/${ownerAgent}/agent.json`;
1151
+ if (resource.type === "memory_store") {
1152
+ if (agent.memory_stores !== void 0 && !Array.isArray(agent.memory_stores)) return;
1153
+ const references = Array.isArray(agent.memory_stores) ? agent.memory_stores : [];
1154
+ if (references.includes(resource.id)) return;
1155
+ agent.memory_stores = [...references, resource.id];
1156
+ agentSource.memory_stores = structuredClone(agent.memory_stores);
1157
+ } else {
1158
+ if (agent[resource.type] !== void 0) return;
1159
+ const candidates = resources.filter(
1160
+ (candidate) => candidate.owner_agent === ownerAgent && candidate.type === resource.type
1161
+ );
1162
+ if (candidates.length > 1) {
1163
+ throw new UserError(
1164
+ `${agentPath}: multiple local ${resource.type} resources (${candidates.map((candidate) => candidate.id).join(", ")}). Set '${resource.type}' explicitly to choose one.`
1165
+ );
1166
+ }
1167
+ agent[resource.type] = resource.id;
1168
+ agentSource[resource.type] = resource.id;
1169
+ }
1170
+ planJsonWrite(autoAssociations, projectRoot, resolve2(projectRoot, agentPath), agentSource);
1171
+ autoAssociations.warnings.push({
1172
+ severity: "warning",
1173
+ code: `project.${resource.type}.agent_link.inferred`,
1174
+ message: `${resource.type} '${resource.id}' will be added to ${agentPath}.`
1175
+ });
1176
+ }
1123
1177
  function autoAssociateFile(resource, projectRoot, agents, agentSources, autoAssociations) {
1124
1178
  const ownerAgent = resource.owner_agent;
1125
1179
  if (!ownerAgent) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openagentpack/sdk",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "OpenAgentPack SDK (Node-compatible runtime)",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [