Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/workshop-backend/__tests__/agent-catalog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ describe("normalizeAgentCatalog", () => {
// A resource with no catalog gets just its env line, nothing inlined.
expect(message).toContain("- Empty: `env.EMPTY`");
expect(message).not.toContain("- Empty: `env.EMPTY`\n{");
expect(message).toContain("Check the entries listed above before starting a task");
expect(message).toContain('A catalog marked `"truncated":true` is partial');
});

it("describes the catalogs only when a resource published entries", () => {
let message = formatAlwaysAvailableResourcesPrompt([
{title: "Empty", name: "EMPTY", catalog: null},
]);

expect(message).toContain("- Empty: `env.EMPTY`");
expect(message).not.toContain("Check the entries listed above");
});
});

Expand Down
9 changes: 8 additions & 1 deletion packages/workshop-backend/src/agent-catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,16 @@ export function formatAlwaysAvailableResourcesPrompt(resources: Array<{
}>): string {
let lines = resources.map(resource =>
`- ${resource.title}: \`env.${resource.name}\`${formatAgentCatalogPrompt(resource.catalog)}`);
// Only describe the catalogs when a resource actually published entries, so a deployment whose
// resources offer none doesn't get told to consult a list that isn't there.
let catalogs = resources.some(resource => resource.catalog?.entries.length)
? ` Check the entries listed above before starting a task and use a relevant one even when the ` +
`user did not name it. A catalog marked \`"truncated":true\` is partial, so reach what it ` +
`omits through the binding's own search or listing methods.`
: ``;
return `The following resources are always available as bindings in your env for use with the ` +
`executeCode tool (you don't need to request them):\n${lines.join("\n")}\n` +
`When one is relevant, use describeBinding with the binding's name to learn its API before ` +
`using it. If a Gadget's persistent code needs one, wire it into that gadget with ` +
`using it.${catalogs} If a Gadget's persistent code needs one, wire it into that gadget with ` +
`setGadgetBinding.`;
}
5 changes: 5 additions & 0 deletions packages/workshop-backend/src/overseer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5834,6 +5834,11 @@ class OverseerImpl implements AgentHooks {
`them rather than for an existing one to be repurposed. If the Gadget they are talking ` +
`about already *is* one of these, work on that one instead: asking to change an existing ` +
`output is not a request for a second one.\n\n` +
`An instruction that names a file path for the result ("save it to notes.md") names the ` +
`output to produce, not a file to write: there is no path to write to. Use the matching ` +
`format below, creating it when the workspace has none, then fill it in through its RPC ` +
`methods, reusing any ready-made layout its code documents rather than positioning ` +
`content yourself.\n\n` +
formats.map(format =>
`* ${format.output.noun} (plural: ${format.output.plural}) — blueprintId: ` +
`${format.blueprintId}` + (format.agentHint ? `; ${format.agentHint}` : ``)).join("\n");
Expand Down
Loading