import { defineSkill } from '@cognest/sdk'
export default defineSkill({
name: 'weather-lookup',
description: 'Get current weather for a location',
version: '1.0.0',
// Input schema (used by Think Engine for function calling)
input: {
location: { type: 'string', description: 'City name or coordinates', required: true },
units: { type: 'string', description: 'celsius or fahrenheit', default: 'celsius' },
},
async execute(context, input) {
const weather = await fetch(
`https://api.weather.com/v1/current?q=${input.location}&units=${input.units}`
).then(r => r.json())
return {
text: `It's ${weather.temp}° and ${weather.condition} in ${input.location}.`,
data: weather,
}
},
})The context object gives skills access to integrations, state, the Think Engine, and other skills:
context(integration(name): (name: string) => Integration, think(prompt): (prompt: string) => Promise<string>, state: StateManager, event: CognestEvent, skill(name): (name: string) => Skill, log: Logger): SkillContextThe execution context passed to every skill.
Parameters
integration(name)(name: string) => IntegrationGet an integration instance by namethink(prompt)(prompt: string) => Promise<string>Invoke the Think Engine from within a skillstateStateManagerRead/write persistent state scoped to the current usereventCognestEventThe triggering eventskill(name)(name: string) => SkillCall another skilllogLoggerStructured logger for the skill# cognest.config.yaml
skills:
installed:
- weather-lookup # from NestHub
- email-triage # from NestHub
custom_dir: ./skills # Local skills auto-loadedimport { defineSkill } from '@cognest/sdk'
export default defineSkill({
name: 'meeting-scheduler',
description: 'Schedule a meeting based on participants availability',
// Declare required integrations
integrations: ['google-calendar', 'slack'],
permissions: ['calendar.read', 'calendar.write', 'slack.send'],
input: {
participants: { type: 'string[]', description: 'Email addresses', required: true },
duration: { type: 'number', description: 'Duration in minutes', default: 30 },
title: { type: 'string', description: 'Meeting title', required: true },
},
async execute(context, input) {
const calendar = context.integration('google-calendar')
const slack = context.integration('slack')
// Find available time
const availability = await calendar.checkAvailability(
input.participants,
{ duration: input.duration }
)
// Create event
const event = await calendar.createEvent({
title: input.title,
start: availability.suggestedSlot.start,
end: availability.suggestedSlot.end,
attendees: input.participants,
})
// Notify via Slack
await slack.send('#meetings', {
text: `Meeting scheduled: ${input.title} at ${event.start}`,
})
return { text: `Meeting "${input.title}" scheduled for ${event.start}`, data: event }
},
})export default defineSkill({
name: 'my-skill',
description: 'Skill with lifecycle hooks',
// Called once when the skill is loaded
async onLoad(context) {
context.log.info('Skill loaded')
await context.state.set('initialized', true)
},
// Called before each execution
async beforeExecute(context, input) {
context.log.debug('Starting execution', { input })
},
async execute(context, input) {
return { text: 'Done' }
},
// Called after each execution
async afterExecute(context, result) {
context.log.debug('Execution complete', { result })
},
// Called on errors
async onError(context, error) {
context.log.error('Skill failed', { error: error.message })
return { text: 'Sorry, something went wrong.' }
},
})# List installed skills
cognest skills list
# Install from NestHub
cognest install skill email-triage
# Uninstall a skill
cognest uninstall skill email-triage
# View skill info
cognest skills info weather-lookup