@alexkroman1/aai-cli 0.9.0
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/LICENSE +21 -0
- package/dist/_build-p1HHkdon.mjs +132 -0
- package/dist/_discover-BzlCDVZ6.mjs +161 -0
- package/dist/_init-l_uoyFCN.mjs +82 -0
- package/dist/_link-BGXGFYWa.mjs +47 -0
- package/dist/_server-common-qLA1QU2C.mjs +36 -0
- package/dist/_ui-kJIua5L9.mjs +44 -0
- package/dist/cli.mjs +318 -0
- package/dist/deploy-KyNJaoP5.mjs +86 -0
- package/dist/dev-DBFvKyzk.mjs +39 -0
- package/dist/init-BWG5OrQa.mjs +65 -0
- package/dist/rag-BnCMnccf.mjs +173 -0
- package/dist/secret-CzeHIGzE.mjs +50 -0
- package/dist/start-C1qkhU4O.mjs +23 -0
- package/package.json +39 -0
- package/templates/_shared/.env.example +5 -0
- package/templates/_shared/CLAUDE.md +1051 -0
- package/templates/_shared/biome.json +32 -0
- package/templates/_shared/global.d.ts +1 -0
- package/templates/_shared/index.html +16 -0
- package/templates/_shared/package.json +23 -0
- package/templates/_shared/tsconfig.json +15 -0
- package/templates/code-interpreter/agent.ts +27 -0
- package/templates/code-interpreter/client.tsx +3 -0
- package/templates/css.d.ts +1 -0
- package/templates/dispatch-center/agent.ts +1227 -0
- package/templates/dispatch-center/client.tsx +505 -0
- package/templates/embedded-assets/agent.ts +48 -0
- package/templates/embedded-assets/client.tsx +3 -0
- package/templates/embedded-assets/knowledge.json +20 -0
- package/templates/health-assistant/agent.ts +160 -0
- package/templates/health-assistant/client.tsx +3 -0
- package/templates/infocom-adventure/agent.ts +164 -0
- package/templates/infocom-adventure/client.tsx +300 -0
- package/templates/math-buddy/agent.ts +21 -0
- package/templates/math-buddy/client.tsx +3 -0
- package/templates/memory-agent/agent.ts +20 -0
- package/templates/memory-agent/client.tsx +3 -0
- package/templates/night-owl/agent.ts +98 -0
- package/templates/night-owl/client.tsx +12 -0
- package/templates/personal-finance/agent.ts +26 -0
- package/templates/personal-finance/client.tsx +3 -0
- package/templates/pizza-ordering/agent.ts +218 -0
- package/templates/pizza-ordering/client.tsx +264 -0
- package/templates/simple/agent.ts +6 -0
- package/templates/simple/client.tsx +3 -0
- package/templates/smart-research/agent.ts +164 -0
- package/templates/smart-research/client.tsx +3 -0
- package/templates/solo-rpg/agent.ts +1244 -0
- package/templates/solo-rpg/client.tsx +698 -0
- package/templates/support/README.md +62 -0
- package/templates/support/agent.ts +19 -0
- package/templates/support/client.tsx +3 -0
- package/templates/travel-concierge/agent.ts +29 -0
- package/templates/travel-concierge/client.tsx +3 -0
- package/templates/tsconfig.json +1 -0
- package/templates/web-researcher/agent.ts +17 -0
- package/templates/web-researcher/client.tsx +3 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { defineAgent, tool } from "@alexkroman1/aai";
|
|
2
|
+
import type { HookContext, StepInfo } from "@alexkroman1/aai";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Smart Research Agent — demonstrates all 5 advanced features:
|
|
7
|
+
* 1. toolChoice: "required" — forces the LLM to use tools every step
|
|
8
|
+
* 2. ctx.messages — tools can read conversation history
|
|
9
|
+
* 3. onStep — logs each step's tool calls
|
|
10
|
+
* 4. onBeforeStep — restricts available tools based on research phase
|
|
11
|
+
* 5. maxSteps as function — adapts max steps based on session complexity
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
type ResearchState = {
|
|
15
|
+
phase: "gather" | "analyze" | "respond";
|
|
16
|
+
sources: string[];
|
|
17
|
+
stepCount: number;
|
|
18
|
+
complexity: "simple" | "deep";
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default defineAgent({
|
|
22
|
+
name: "Smart Research Agent",
|
|
23
|
+
instructions: `You are a research assistant that gathers information, \
|
|
24
|
+
analyzes it, then responds. You work in three phases:
|
|
25
|
+
1. Gather: Use search and fetch tools to collect information.
|
|
26
|
+
2. Analyze: Use the analyze tool to synthesize your findings.
|
|
27
|
+
3. Respond: Deliver your final answer.
|
|
28
|
+
|
|
29
|
+
Always search first, then analyze, then answer. Be thorough but concise.`,
|
|
30
|
+
greeting:
|
|
31
|
+
"I'm your research assistant. Ask me anything and I'll dig into it.",
|
|
32
|
+
builtinTools: ["web_search"],
|
|
33
|
+
|
|
34
|
+
// Feature 1: toolChoice — force the LLM to always use a tool
|
|
35
|
+
toolChoice: "required",
|
|
36
|
+
|
|
37
|
+
// Feature 5: maxSteps as function — more steps for complex research
|
|
38
|
+
maxSteps: (ctx: HookContext<ResearchState>) => {
|
|
39
|
+
const state = ctx.state;
|
|
40
|
+
return state.complexity === "deep" ? 10 : 5;
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
state: (): ResearchState => ({
|
|
44
|
+
phase: "gather",
|
|
45
|
+
sources: [],
|
|
46
|
+
stepCount: 0,
|
|
47
|
+
complexity: "simple",
|
|
48
|
+
}),
|
|
49
|
+
|
|
50
|
+
// Feature 3: onStep — track what tools were called each step
|
|
51
|
+
onStep: (step: StepInfo, ctx: HookContext<ResearchState>) => {
|
|
52
|
+
const state = ctx.state;
|
|
53
|
+
state.stepCount++;
|
|
54
|
+
for (const tc of step.toolCalls) {
|
|
55
|
+
console.log(
|
|
56
|
+
`[step ${step.stepNumber}] ${tc.toolName} (phase: ${state.phase})`,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// Feature 4: onBeforeStep — restrict tools per research phase
|
|
62
|
+
onBeforeStep: (
|
|
63
|
+
_stepNumber: number,
|
|
64
|
+
ctx: HookContext<ResearchState>,
|
|
65
|
+
) => {
|
|
66
|
+
const state = ctx.state;
|
|
67
|
+
if (state.phase === "gather") {
|
|
68
|
+
return {
|
|
69
|
+
activeTools: [
|
|
70
|
+
"web_search",
|
|
71
|
+
"save_source",
|
|
72
|
+
"mark_complex",
|
|
73
|
+
"advance_phase",
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (state.phase === "analyze") {
|
|
78
|
+
return {
|
|
79
|
+
activeTools: [
|
|
80
|
+
"analyze",
|
|
81
|
+
"conversation_summary",
|
|
82
|
+
"advance_phase",
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// respond phase: no tools needed, LLM responds with text directly
|
|
87
|
+
return { activeTools: [] };
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
tools: {
|
|
91
|
+
save_source: tool<z.ZodObject<{ url: z.ZodString; title: z.ZodString }>, ResearchState>({
|
|
92
|
+
description: "Save a source URL found during research for later analysis",
|
|
93
|
+
parameters: z.object({
|
|
94
|
+
url: z.string().describe("The source URL"),
|
|
95
|
+
title: z.string().describe("Brief title or description"),
|
|
96
|
+
}),
|
|
97
|
+
execute: ({ url, title }, ctx) => {
|
|
98
|
+
const state = ctx.state;
|
|
99
|
+
state.sources.push(`${title}: ${url}`);
|
|
100
|
+
return { saved: true, totalSources: state.sources.length };
|
|
101
|
+
},
|
|
102
|
+
}),
|
|
103
|
+
|
|
104
|
+
mark_complex: {
|
|
105
|
+
description:
|
|
106
|
+
"Mark this research query as complex, allowing more search steps",
|
|
107
|
+
execute: (_args, ctx) => {
|
|
108
|
+
const state = ctx.state;
|
|
109
|
+
state.complexity = "deep";
|
|
110
|
+
return { complexity: "deep", maxSteps: 10 };
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
advance_phase: {
|
|
115
|
+
description:
|
|
116
|
+
"Move to the next research phase (gather -> analyze -> respond)",
|
|
117
|
+
execute: (_args, ctx) => {
|
|
118
|
+
const state = ctx.state;
|
|
119
|
+
if (state.phase === "gather") {
|
|
120
|
+
state.phase = "analyze";
|
|
121
|
+
} else if (state.phase === "analyze") {
|
|
122
|
+
state.phase = "respond";
|
|
123
|
+
}
|
|
124
|
+
return { phase: state.phase };
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
// Feature 2: ctx.messages — access conversation history in tools
|
|
129
|
+
analyze: tool<z.ZodObject<{ focus: z.ZodString }>, ResearchState>({
|
|
130
|
+
description:
|
|
131
|
+
"Analyze all gathered sources and conversation context to form a conclusion",
|
|
132
|
+
parameters: z.object({
|
|
133
|
+
focus: z.string().describe("What aspect to focus the analysis on"),
|
|
134
|
+
}),
|
|
135
|
+
execute: ({ focus }, ctx) => {
|
|
136
|
+
const state = ctx.state;
|
|
137
|
+
// Use ctx.messages to see what's been discussed
|
|
138
|
+
const userMessages = ctx.messages.filter((m) => m.role === "user");
|
|
139
|
+
return {
|
|
140
|
+
focus,
|
|
141
|
+
sources: state.sources,
|
|
142
|
+
conversationTurns: userMessages.length,
|
|
143
|
+
totalMessages: ctx.messages.length,
|
|
144
|
+
phase: state.phase,
|
|
145
|
+
};
|
|
146
|
+
},
|
|
147
|
+
}),
|
|
148
|
+
|
|
149
|
+
conversation_summary: {
|
|
150
|
+
description: "Get a summary of the conversation so far",
|
|
151
|
+
execute: (_args, ctx) => {
|
|
152
|
+
const msgs = ctx.messages;
|
|
153
|
+
return {
|
|
154
|
+
totalMessages: msgs.length,
|
|
155
|
+
byRole: {
|
|
156
|
+
user: msgs.filter((m) => m.role === "user").length,
|
|
157
|
+
assistant: msgs.filter((m) => m.role === "assistant").length,
|
|
158
|
+
tool: msgs.filter((m) => m.role === "tool").length,
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
});
|