Skip to content

Commit a259dfa

Browse files
committed
publishing agents requires "publisher" field
1 parent 82f3668 commit a259dfa

File tree

9 files changed

+83
-162
lines changed

9 files changed

+83
-162
lines changed

.agents/types/agent-config.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* const config: AgentConfig = {
1111
* // ... your agent configuration with full type safety ...
1212
* }
13-
*
13+
*
1414
* export default config
1515
*/
1616

@@ -25,6 +25,9 @@ export interface AgentConfig {
2525
/** Version string (if not provided, will default to '0.0.1' and be bumped on each publish) */
2626
version?: string
2727

28+
/** Publisher ID for the agent. Must be provided if you want to publish the agent. */
29+
publisher?: string
30+
2831
/** Human-readable name for the agent */
2932
displayName: string
3033

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { AgentConfig } from '../../util/types/agent-config'
2+
import type { DynamicAgentConfig } from '../dynamic-agent-template'
3+
4+
// Don't remove these lines!
5+
const _typecheck1: AgentConfig extends DynamicAgentConfig ? true : false = true
6+
const _typecheck2: DynamicAgentConfig extends AgentConfig ? true : false = true
7+
const _keyTypecheck1: keyof AgentConfig = {} as keyof DynamicAgentConfig
8+
const _keyTypecheck2: keyof DynamicAgentConfig = {} as keyof AgentConfig

common/src/types/api/agents/publish.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { DynamicAgentTemplateSchema } from '../../../types/dynamic-agent-templat
44

55
export const publishAgentsRequestSchema = z.object({
66
data: DynamicAgentTemplateSchema.array(),
7-
publisherId: z.string().optional(),
87
authToken: z.string(),
98
})
109
export type PublishAgentsRequest = z.infer<typeof publishAgentsRequestSchema>

common/src/types/dynamic-agent-template.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import { z } from 'zod'
33
import { ALLOWED_MODEL_PREFIXES, models } from '../constants'
44
import { toolNames } from '../tools/constants'
55

6-
import type { AgentConfig } from '../util/types/agent-config'
7-
86
// Filter models to only include those that begin with allowed prefixes
97
const filteredModels = Object.values(models).filter((model) =>
108
ALLOWED_MODEL_PREFIXES.some((prefix) => model.startsWith(prefix)),
@@ -91,6 +89,7 @@ export const DynamicAgentConfigSchema = z.object({
9189
'Agent ID must contain only lowercase letters, numbers, and hyphens',
9290
), // The unique identifier for this agent
9391
version: z.string().optional(),
92+
publisher: z.string().optional(),
9493

9594
// Required fields for new agents
9695
displayName: z.string(),
@@ -136,20 +135,13 @@ export const DynamicAgentConfigSchema = z.object({
136135
systemPrompt: z.string().optional(),
137136
instructionsPrompt: z.string().optional(),
138137
stepPrompt: z.string().optional(),
139-
// NOTE: Removed from AgentConfig. If there's a need, can be added back or else removed entirely.
140-
parentInstructions: z.record(z.string(), z.string()).optional(),
141138

142139
// Optional generator function for programmatic agents
143140
handleSteps: HandleStepsSchema,
144141
})
145142
export type DynamicAgentConfig = z.input<typeof DynamicAgentConfigSchema>
146143
export type DynamicAgentConfigParsed = z.infer<typeof DynamicAgentConfigSchema>
147144

148-
// Checks that the AgentConfig and DynamicAgentConfig types are compatible
149-
// NOTE TO LLM: Don't remove these lines!
150-
const _typecheck: AgentConfig = {} as DynamicAgentConfig
151-
const _typecheck2: DynamicAgentConfig = {} as AgentConfig
152-
153145
export const DynamicAgentTemplateSchema = DynamicAgentConfigSchema.extend({
154146
systemPrompt: z.string(),
155147
instructionsPrompt: z.string(),

common/src/util/types/agent-config.d.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* const config: AgentConfig = {
1111
* // ... your agent configuration with full type safety ...
1212
* }
13-
*
13+
*
1414
* export default config
1515
*/
1616

@@ -25,6 +25,9 @@ export interface AgentConfig {
2525
/** Version string (if not provided, will default to '0.0.1' and be bumped on each publish) */
2626
version?: string
2727

28+
/** Publisher ID for the agent. Must be provided if you want to publish the agent. */
29+
publisher?: string
30+
2831
/** Human-readable name for the agent */
2932
displayName: string
3033

@@ -57,18 +60,18 @@ export interface AgentConfig {
5760
}
5861

5962
/** Whether to include conversation history from the parent agent in context.
60-
*
63+
*
6164
* Defaults to false.
6265
* Use this if the agent needs to know all the previous messages in the conversation.
6366
*/
6467
includeMessageHistory?: boolean
6568

6669
/** How the agent should output a response to its parent (defaults to 'last_message')
67-
*
70+
*
6871
* last_message: The last message from the agent, typcically after using tools.
69-
*
72+
*
7073
* all_messages: All messages from the agent, including tool calls and results.
71-
*
74+
*
7275
* json: Make the agent output a JSON object. Can be used with outputSchema or without if you want freeform json output.
7376
*/
7477
outputMode?: 'last_message' | 'all_messages' | 'json'
@@ -81,21 +84,21 @@ export interface AgentConfig {
8184
// ============================================================================
8285

8386
/** Prompt for when to spawn this agent as a subagent. Include the main purpose and use cases.
84-
*
87+
*
8588
* This field is key if the agent is a subagent and intended to be spawned. */
8689
parentPrompt?: string
8790

8891
/** Background information for the agent. Fairly optional. Prefer using instructionsPrompt for agent instructions. */
8992
systemPrompt?: string
9093

9194
/** Instructions for the agent.
92-
*
95+
*
9396
* IMPORTANT: Updating this prompt is the best way to shape the agent's behavior.
9497
* This prompt is inserted after each user input. */
9598
instructionsPrompt?: string
9699

97100
/** Prompt inserted at each agent step.
98-
*
101+
*
99102
* Powerful for changing the agent's behavior, but usually not necessary for smart models.
100103
* Prefer instructionsPrompt for most instructions. */
101104
stepPrompt?: string

npm-app/src/cli-definitions.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,4 @@ export const cliOptions: CliParam[] = [
9393
menuDescription: 'Log subagent messages to trace files',
9494
hidden: false,
9595
},
96-
{
97-
flags: '--publisher <publisher-id>',
98-
description: 'Specify which publisher to use when publishing agents',
99-
menuDescription: 'Specify publisher for agent publishing',
100-
hidden: false,
101-
},
10296
]

npm-app/src/cli-handlers/publish.ts

Lines changed: 11 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ import type { DynamicAgentTemplate } from '@codebuff/common/types/dynamic-agent-
1616
/**
1717
* Handle the publish command to upload agent templates to the backend
1818
* @param agentId The id of the agent to publish (required)
19-
* @param publisherId The id of the publisher to use (optional)
20-
*/ export async function handlePublish(
21-
agentIds: string[],
22-
publisherId?: string,
23-
): Promise<void> {
19+
*/ export async function handlePublish(agentIds: string[]): Promise<void> {
2420
const user = getUserCredentials()
2521

2622
if (!user) {
@@ -95,7 +91,6 @@ import type { DynamicAgentTemplate } from '@codebuff/common/types/dynamic-agent-
9591
const result = await publishAgentTemplates(
9692
Object.values(matchingTemplates),
9793
user.authToken!,
98-
publisherId,
9994
)
10095

10196
if (result.success) {
@@ -111,73 +106,27 @@ import type { DynamicAgentTemplate } from '@codebuff/common/types/dynamic-agent-
111106
}
112107

113108
console.log(red(`❌ Failed to publish agents: ${result.error}`))
114-
if (result.statusCode !== 403) {
115-
return
116-
}
117109

118-
// Check if this is a "no publisher" error vs "multiple publishers" error
119-
if (result.error?.includes('No publisher associated with user')) {
120-
console.log()
121-
console.log(
122-
cyan('Please visit the website to create your publisher profile:'),
123-
)
124-
console.log(yellow(`${websiteUrl}/publishers`))
110+
// Show helpful guidance based on error type
111+
if (result.error?.includes('Publisher field required')) {
125112
console.log()
126-
console.log('A publisher profile allows you to:')
127-
console.log(' • Publish and manage your agents')
128-
console.log(' • Build your reputation in the community')
129-
console.log(' • Organize agents under your name or organization')
113+
console.log(cyan('Add a "publisher" field to your agent templates:'))
114+
console.log(yellow(' "publisher": "<publisher-id>"'))
130115
console.log()
131116
} else if (
132-
result.availablePublishers &&
133-
result.availablePublishers.length > 0
117+
result.error?.includes('Publisher not found or not accessible')
134118
) {
135-
// Show available publishers
119+
console.log()
136120
console.log(
137121
cyan(
138-
'You have access to multiple publishers. Please specify which one to use:',
122+
'Check that the publisher ID is correct and you have access to it.',
139123
),
140124
)
141125
console.log()
142-
console.log(cyan('Available publishers:'))
143-
result.availablePublishers.forEach((publisher) => {
144-
const orgInfo = publisher.organizationName
145-
? ` (${publisher.organizationName})`
146-
: ''
147-
const typeInfo =
148-
publisher.ownershipType === 'organization'
149-
? ' [Organization]'
150-
: ' [Personal]'
151-
console.log(
152-
` • ${yellow(publisher.id)} - ${publisher.name}${orgInfo}${typeInfo}`,
153-
)
154-
})
155-
console.log()
156-
console.log('Run one of these commands:')
157-
result.availablePublishers.forEach((publisher) => {
158-
console.log(
159-
yellow(
160-
` codebuff publish ${agentIds.join(' ')} --publisher ${publisher.id}`,
161-
),
162-
)
163-
})
164-
console.log()
165-
console.log(cyan('Or visit the website to manage your publishers:'))
166-
console.log(yellow(`${websiteUrl}/publishers`))
167-
console.log()
168-
} else {
169-
// Generic 403 error
170-
console.log(cyan('You may need to specify which publisher to use.'))
171-
console.log()
172-
console.log('Try running:')
173-
console.log(
174-
yellow(` publish ${agentIds.join(' ')} --publisher <publisher-id>`),
175-
)
176-
console.log()
177-
console.log(cyan('Visit the website to see your available publishers:'))
178-
console.log(yellow(`${websiteUrl}/publishers`))
179-
console.log()
180126
}
127+
128+
console.log(cyan('Visit the website to manage your publishers:'))
129+
console.log(yellow(`${websiteUrl}/publishers`))
181130
} catch (error) {
182131
console.log(
183132
red(
@@ -204,7 +153,6 @@ import type { DynamicAgentTemplate } from '@codebuff/common/types/dynamic-agent-
204153
async function publishAgentTemplates(
205154
data: DynamicAgentTemplate[],
206155
authToken: string,
207-
publisherId?: string,
208156
): Promise<PublishAgentsResponse & { statusCode?: number }> {
209157
try {
210158
const response = await fetch(`${websiteUrl}/api/agents/publish`, {
@@ -215,7 +163,6 @@ async function publishAgentTemplates(
215163
body: JSON.stringify({
216164
data,
217165
authToken,
218-
...(publisherId && { publisherId }),
219166
}),
220167
})
221168

npm-app/src/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,7 @@ For all commands and options, run 'codebuff' and then type 'help'.
137137
// Handle publish command
138138
if (args[0] === 'publish') {
139139
const agentNames = args.slice(1)
140-
const publisherId = options.publisher
141-
await handlePublish(agentNames, publisherId)
140+
await handlePublish(agentNames)
142141
process.exit(0)
143142
}
144143

0 commit comments

Comments
 (0)