agentic-lang 0.2.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/COMMUNITY.md +220 -0
- package/CONTRIBUTING.md +194 -0
- package/FINAL_REPORT.md +398 -0
- package/FOR_OTHER_LLMS.md +286 -0
- package/IMPROVEMENTS.md +319 -0
- package/LAUNCH_GUIDE.md +388 -0
- package/LICENSE +21 -0
- package/NPM_PUBLISH.md +257 -0
- package/PROJECT_COMPLETE.md +414 -0
- package/PROJECT_OVERVIEW.md +265 -0
- package/PROJECT_TREE.txt +228 -0
- package/PUBLISHING_GUIDE.md +426 -0
- package/PUBLISH_NOW.md +337 -0
- package/QUICKSTART.md +207 -0
- package/README.md +195 -0
- package/README_ENHANCED.md +329 -0
- package/READY_TO_LAUNCH.txt +56 -0
- package/REFACTOR_PLAN.md +179 -0
- package/ROADMAP.md +201 -0
- package/SUMMARY.md +315 -0
- package/bin/agentic.js +3 -0
- package/blog/001-introducing-agentic.md +382 -0
- package/blog/002-confidence-driven-development.md +490 -0
- package/blog/003-formal-verification.md +427 -0
- package/blog/004-multi-agent-production.md +436 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +151 -0
- package/dist/cli.js.map +1 -0
- package/dist/diagnostics/diagnostic.d.ts +115 -0
- package/dist/diagnostics/diagnostic.d.ts.map +1 -0
- package/dist/diagnostics/diagnostic.js +101 -0
- package/dist/diagnostics/diagnostic.js.map +1 -0
- package/dist/diagnostics/formatter.d.ts +36 -0
- package/dist/diagnostics/formatter.d.ts.map +1 -0
- package/dist/diagnostics/formatter.js +263 -0
- package/dist/diagnostics/formatter.js.map +1 -0
- package/dist/effects/effect-system.d.ts +64 -0
- package/dist/effects/effect-system.d.ts.map +1 -0
- package/dist/effects/effect-system.js +197 -0
- package/dist/effects/effect-system.js.map +1 -0
- package/dist/generator/typescript-generator.d.ts +31 -0
- package/dist/generator/typescript-generator.d.ts.map +1 -0
- package/dist/generator/typescript-generator.js +308 -0
- package/dist/generator/typescript-generator.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/lean4/exporter.d.ts +24 -0
- package/dist/lean4/exporter.d.ts.map +1 -0
- package/dist/lean4/exporter.js +142 -0
- package/dist/lean4/exporter.js.map +1 -0
- package/dist/lsp/server.d.ts +6 -0
- package/dist/lsp/server.d.ts.map +1 -0
- package/dist/lsp/server.js +131 -0
- package/dist/lsp/server.js.map +1 -0
- package/dist/parser/lexer.d.ts +79 -0
- package/dist/parser/lexer.d.ts.map +1 -0
- package/dist/parser/lexer.js +296 -0
- package/dist/parser/lexer.js.map +1 -0
- package/dist/parser/parser-enhanced.d.ts +12 -0
- package/dist/parser/parser-enhanced.d.ts.map +1 -0
- package/dist/parser/parser-enhanced.js +206 -0
- package/dist/parser/parser-enhanced.js.map +1 -0
- package/dist/parser/parser.d.ts +34 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/parser/parser.js +507 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/property-tests/generator-enhanced.d.ts +27 -0
- package/dist/property-tests/generator-enhanced.d.ts.map +1 -0
- package/dist/property-tests/generator-enhanced.js +209 -0
- package/dist/property-tests/generator-enhanced.js.map +1 -0
- package/dist/property-tests/generator-fixed.d.ts +2 -0
- package/dist/property-tests/generator-fixed.d.ts.map +1 -0
- package/dist/property-tests/generator-fixed.js +7 -0
- package/dist/property-tests/generator-fixed.js.map +1 -0
- package/dist/property-tests/generator.d.ts +28 -0
- package/dist/property-tests/generator.d.ts.map +1 -0
- package/dist/property-tests/generator.js +284 -0
- package/dist/property-tests/generator.js.map +1 -0
- package/dist/refinements/refinement-types.d.ts +96 -0
- package/dist/refinements/refinement-types.d.ts.map +1 -0
- package/dist/refinements/refinement-types.js +234 -0
- package/dist/refinements/refinement-types.js.map +1 -0
- package/dist/repl.d.ts +21 -0
- package/dist/repl.d.ts.map +1 -0
- package/dist/repl.js +317 -0
- package/dist/repl.js.map +1 -0
- package/dist/runtime/agents.d.ts +97 -0
- package/dist/runtime/agents.d.ts.map +1 -0
- package/dist/runtime/agents.js +258 -0
- package/dist/runtime/agents.js.map +1 -0
- package/dist/runtime/index.d.ts +98 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +253 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/types-extended.d.ts +197 -0
- package/dist/types-extended.d.ts.map +1 -0
- package/dist/types-extended.js +7 -0
- package/dist/types-extended.js.map +1 -0
- package/dist/types.d.ts +129 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/verification/z3-engine.d.ts +75 -0
- package/dist/verification/z3-engine.d.ts.map +1 -0
- package/dist/verification/z3-engine.js +234 -0
- package/dist/verification/z3-engine.js.map +1 -0
- package/examples/advanced-features.agentic +98 -0
- package/examples/annotations.agentic +37 -0
- package/examples/auth.agentic +53 -0
- package/examples/enterprise-example.agentic +360 -0
- package/examples/minimal.agentic +3 -0
- package/examples/minimal.ts +7 -0
- package/examples/ml-pipeline.agentic +350 -0
- package/examples/multi-agent-example.agentic +212 -0
- package/examples/onboarding-tutorial.agentic +263 -0
- package/examples/production-api.agentic +304 -0
- package/examples/real-world-chatbot.agentic +351 -0
- package/examples/result-handling.agentic +34 -0
- package/examples/runtime.ts +24 -0
- package/examples/showcase.agentic +22 -0
- package/examples/showcase.ts +28 -0
- package/examples/simple-test.agentic +4 -0
- package/examples/simple-test.ts +7 -0
- package/examples/simple.agentic +20 -0
- package/examples/test2.agentic +4 -0
- package/examples/test2.ts +9 -0
- package/examples/test3.agentic +4 -0
- package/examples/test3.ts +9 -0
- package/package.json +70 -0
- package/playground/index.html +221 -0
- package/playground/playground.js +291 -0
- package/registry/package-registry.ts +319 -0
- package/scripts/build.js +50 -0
- package/scripts/validate-confidence-mutation.ts +112 -0
- package/stdlib/async/promise.agentic +216 -0
- package/stdlib/database/pool.agentic +235 -0
- package/stdlib/file/io.agentic +194 -0
- package/stdlib/http/client.agentic +168 -0
- package/video-scripts/001-agentic-in-100-seconds.md +175 -0
- package/vscode-extension/README.md +67 -0
- package/vscode-extension/language-configuration.json +31 -0
- package/vscode-extension/package.json +46 -0
- package/vscode-extension/syntaxes/agentic.tmLanguage.json +134 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// Multi-Agent Coordination Example
|
|
2
|
+
// Demonstrates session types, message passing, and handoffs
|
|
3
|
+
|
|
4
|
+
@agent(role: "coordinator", capabilities: ["task_planning", "delegation"])
|
|
5
|
+
agent CoordinatorAgent {
|
|
6
|
+
inbox: Channel<TaskRequest>
|
|
7
|
+
outbox: Channel<TaskAssignment>
|
|
8
|
+
|
|
9
|
+
@handler("task_request")
|
|
10
|
+
@confidence(0.90)
|
|
11
|
+
func handleRequest(request: TaskRequest) -> TaskAssignment {
|
|
12
|
+
// Analyze task complexity
|
|
13
|
+
complexity = analyzeComplexity(request)
|
|
14
|
+
|
|
15
|
+
assignment = complexity match {
|
|
16
|
+
"simple" -> assignToWorker(request),
|
|
17
|
+
"complex" -> assignToSpecialist(request),
|
|
18
|
+
"uncertain" -> requestHumanReview(request)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return assignment
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@agent(role: "worker", capabilities: ["task_execution"])
|
|
26
|
+
agent WorkerAgent {
|
|
27
|
+
inbox: Channel<TaskAssignment>
|
|
28
|
+
outbox: Channel<TaskResult>
|
|
29
|
+
|
|
30
|
+
@handler("task_assignment")
|
|
31
|
+
@confidence(0.85)
|
|
32
|
+
@session_aware
|
|
33
|
+
func executeTask(assignment: TaskAssignment) -> TaskResult {
|
|
34
|
+
@checkpoint("start")
|
|
35
|
+
session.save({ assignmentId: assignment.id, status: "started" })
|
|
36
|
+
|
|
37
|
+
@confidence(0.80)
|
|
38
|
+
result = processTask(assignment.task)
|
|
39
|
+
|
|
40
|
+
@checkpoint("complete")
|
|
41
|
+
session.save({ assignmentId: assignment.id, status: "complete", result: result })
|
|
42
|
+
|
|
43
|
+
return TaskResult {
|
|
44
|
+
assignmentId: assignment.id,
|
|
45
|
+
output: result,
|
|
46
|
+
confidence: 0.85
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Main workflow orchestration
|
|
52
|
+
@workflow(persistent: true, resumable: true)
|
|
53
|
+
workflow TaskProcessingPipeline {
|
|
54
|
+
states: [Idle, Processing, Review, Complete, Failed]
|
|
55
|
+
|
|
56
|
+
Idle -> Processing on TaskReceived {
|
|
57
|
+
@confidence(0.92)
|
|
58
|
+
coordinator.send(TaskRequest { task: event.task })
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
Processing -> Review on LowConfidence {
|
|
62
|
+
@handoff {
|
|
63
|
+
to: "human_reviewer",
|
|
64
|
+
reason: "Task confidence below threshold",
|
|
65
|
+
context: {
|
|
66
|
+
task: current_task,
|
|
67
|
+
confidence: 0.65,
|
|
68
|
+
attempted_approaches: ["approach_a", "approach_b"]
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
Processing -> Complete on HighConfidence {
|
|
74
|
+
@confidence(0.90)
|
|
75
|
+
finalizeTask(result)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
Review -> Processing on ReviewComplete {
|
|
79
|
+
// Resume after human review
|
|
80
|
+
@resume_from_checkpoint("processing_start")
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
* -> Failed on Error @max_attempts(3)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Human-in-the-Loop approval example
|
|
87
|
+
@requires_approval(
|
|
88
|
+
channel: "slack",
|
|
89
|
+
approvers: ["team_lead"],
|
|
90
|
+
timeout: 1h,
|
|
91
|
+
fallback: "reject"
|
|
92
|
+
)
|
|
93
|
+
@confidence(0.75)
|
|
94
|
+
func deployToProduction(artifact: Artifact) -> Result<Deployment, Error> {
|
|
95
|
+
// This code won't execute until approved
|
|
96
|
+
@trace_decision("deployment_approved", {
|
|
97
|
+
artifact: artifact.id,
|
|
98
|
+
version: artifact.version,
|
|
99
|
+
approver: approval.approver
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
deployment = deploy(artifact)
|
|
103
|
+
|
|
104
|
+
return Ok(deployment)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Session persistence and resumption
|
|
108
|
+
@session(id: "user_onboarding", storage: "database")
|
|
109
|
+
@resumable
|
|
110
|
+
@checkpoint_interval(5m)
|
|
111
|
+
func onboardUser(userId: string) -> Result<User, OnboardingError> {
|
|
112
|
+
// Step 1: Create account
|
|
113
|
+
@checkpoint("account_created")
|
|
114
|
+
account = createAccount(userId)
|
|
115
|
+
session.save({ step: 1, accountId: account.id })
|
|
116
|
+
|
|
117
|
+
// Step 2: Send verification email
|
|
118
|
+
@checkpoint("email_sent")
|
|
119
|
+
email = sendVerificationEmail(account.email)
|
|
120
|
+
session.save({ step: 2, emailId: email.id })
|
|
121
|
+
|
|
122
|
+
// Step 3: Wait for verification (resumable)
|
|
123
|
+
@checkpoint("awaiting_verification")
|
|
124
|
+
@resumable_point
|
|
125
|
+
verification = awaitVerification(account.id, timeout: 24h)
|
|
126
|
+
|
|
127
|
+
// If timeout, session can be resumed when user verifies
|
|
128
|
+
if verification.timedOut {
|
|
129
|
+
@pause_session({
|
|
130
|
+
reason: "Awaiting user email verification",
|
|
131
|
+
resumeOn: "email_verified_event",
|
|
132
|
+
state: { accountId: account.id, emailSent: true }
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Step 4: Complete onboarding
|
|
137
|
+
@checkpoint("complete")
|
|
138
|
+
user = completeOnboarding(account, verification)
|
|
139
|
+
|
|
140
|
+
return Ok(user)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Cost-aware LLM usage
|
|
144
|
+
@budget_limit(user_daily: 10.00, action: "throttle")
|
|
145
|
+
@cost_optimized(
|
|
146
|
+
models: {
|
|
147
|
+
cheap: "gpt-4.5-turbo",
|
|
148
|
+
standard: "gpt-4.5",
|
|
149
|
+
premium: "o3"
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
func generateSummary(document: string, userId: string) -> Result<Summary, Error> {
|
|
153
|
+
// Check budget first
|
|
154
|
+
budget = costRuntime.checkBudget(userId)
|
|
155
|
+
|
|
156
|
+
if budget.remaining < 0.50 {
|
|
157
|
+
return Err(BudgetError {
|
|
158
|
+
message: "Insufficient budget",
|
|
159
|
+
remaining: budget.remaining
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Start with cheapest model
|
|
164
|
+
@llm_call(model: "gpt-4.5-turbo", max_tokens: 500)
|
|
165
|
+
@cost_tracked(userId: userId, feature: "summarization")
|
|
166
|
+
summary = llm.summarize(document)
|
|
167
|
+
|
|
168
|
+
if summary.confidence < 0.85 {
|
|
169
|
+
// Escalate to better model if needed and budget allows
|
|
170
|
+
if budget.remaining > 2.00 {
|
|
171
|
+
@llm_call(model: "gpt-4.5", max_tokens: 500)
|
|
172
|
+
summary = llm.summarize(document)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return Ok(summary)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Safety guardrails example
|
|
180
|
+
@input_guardrails(
|
|
181
|
+
pii_detection: true,
|
|
182
|
+
prompt_injection: true,
|
|
183
|
+
toxicity_threshold: 0.8
|
|
184
|
+
)
|
|
185
|
+
@output_guardrails(
|
|
186
|
+
checks: ["toxicity", "bias", "pii"],
|
|
187
|
+
enforcement: "block"
|
|
188
|
+
)
|
|
189
|
+
@confidence(0.92)
|
|
190
|
+
func moderateContent(content: UserContent) -> Result<ModerationDecision, Error> {
|
|
191
|
+
// Input validation happens automatically via @input_guardrails
|
|
192
|
+
|
|
193
|
+
@llm_call(model: "gpt-4.5")
|
|
194
|
+
analysis = llm.analyzeContent(content.text)
|
|
195
|
+
|
|
196
|
+
// Output validation happens automatically via @output_guardrails
|
|
197
|
+
|
|
198
|
+
decision = analysis.toxicity match {
|
|
199
|
+
score if score > 0.8 -> Reject("High toxicity detected"),
|
|
200
|
+
score if score > 0.5 -> Flag("Moderate toxicity, needs review"),
|
|
201
|
+
_ -> Approve()
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
@audit_trail({
|
|
205
|
+
action: "content_moderation",
|
|
206
|
+
decision: decision,
|
|
207
|
+
scores: analysis,
|
|
208
|
+
confidence: 0.92
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
return Ok(decision)
|
|
212
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// Agentic Onboarding Tutorial
|
|
2
|
+
// Complete guide for AI agents learning the language
|
|
3
|
+
|
|
4
|
+
// LESSON 1: Confidence Tracking
|
|
5
|
+
// Always tell humans how confident you are in your code
|
|
6
|
+
@confidence(0.99, "Simple addition, mathematically proven")
|
|
7
|
+
@complete
|
|
8
|
+
func add(a: number, b: number) -> number {
|
|
9
|
+
return a + b
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@confidence(0.75, "Regex might miss edge cases")
|
|
13
|
+
@partial
|
|
14
|
+
func validateEmail(email: string) -> Result<boolean, string> {
|
|
15
|
+
if email.contains("@") {
|
|
16
|
+
return Ok(true)
|
|
17
|
+
}
|
|
18
|
+
return Err("Invalid email format")
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// LESSON 2: Incremental Development
|
|
22
|
+
// Start with @stub, improve to @partial, finish with @complete
|
|
23
|
+
|
|
24
|
+
@stub
|
|
25
|
+
@needs(database, email_service)
|
|
26
|
+
func sendWelcomeEmail(userId: string) -> Result<boolean, string> {
|
|
27
|
+
// Not implemented yet - will throw error if called
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@partial
|
|
31
|
+
@confidence(0.60, "Only handles happy path")
|
|
32
|
+
func processPayment(amount: number) -> Result<boolean, string> {
|
|
33
|
+
if amount > 0 {
|
|
34
|
+
return Ok(true)
|
|
35
|
+
}
|
|
36
|
+
return Err("Invalid amount")
|
|
37
|
+
// TODO: Add actual payment processing
|
|
38
|
+
// TODO: Handle refunds
|
|
39
|
+
// TODO: Add fraud detection
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@complete
|
|
43
|
+
@confidence(0.95, "Production tested with 1000+ transactions")
|
|
44
|
+
func calculateTotal(items: number[]) -> number {
|
|
45
|
+
total = 0
|
|
46
|
+
// Sum all items
|
|
47
|
+
return total
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// LESSON 3: Result Types & Pattern Matching
|
|
51
|
+
// Use Result<Success, Error> instead of throwing exceptions
|
|
52
|
+
|
|
53
|
+
@confidence(0.90, "Standard division logic")
|
|
54
|
+
@complete
|
|
55
|
+
func safeDivide(a: number, b: number) -> Result<number, string> {
|
|
56
|
+
if b == 0 {
|
|
57
|
+
return Err("Division by zero")
|
|
58
|
+
}
|
|
59
|
+
if a == 0 {
|
|
60
|
+
return Ok(0)
|
|
61
|
+
}
|
|
62
|
+
return Ok(a / b)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Pattern match on results
|
|
66
|
+
@confidence(0.92, "Handles all error cases")
|
|
67
|
+
@complete
|
|
68
|
+
func divideAndFormat(a: number, b: number) -> string {
|
|
69
|
+
safeDivide(a, b) match {
|
|
70
|
+
Ok(result) -> return "Result: " + result,
|
|
71
|
+
Err(error) -> return "Error: " + error
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// LESSON 4: Nested Pattern Matching
|
|
76
|
+
// You can match within matches for complex logic
|
|
77
|
+
|
|
78
|
+
@confidence(0.85, "Tested with various inputs")
|
|
79
|
+
@complete
|
|
80
|
+
func complexCalculation(x: number, y: number) -> string {
|
|
81
|
+
safeDivide(x, 2) match {
|
|
82
|
+
Ok(half) -> {
|
|
83
|
+
safeDivide(half, y) match {
|
|
84
|
+
Ok(final) -> return "Final result: " + final,
|
|
85
|
+
Err(e) -> return "Second division failed: " + e
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
Err(e) -> return "First division failed: " + e
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// LESSON 5: Error Recovery Blocks
|
|
93
|
+
// Provide structured error context for debugging
|
|
94
|
+
|
|
95
|
+
@confidence(0.80, "Has fallback mechanism")
|
|
96
|
+
@partial
|
|
97
|
+
func fetchUserData(userId: string) -> Result<string, string> {
|
|
98
|
+
result = database.query(userId) or error {
|
|
99
|
+
@context {
|
|
100
|
+
what_failed: "Database query",
|
|
101
|
+
what_i_tried: "SELECT * FROM users WHERE id = " + userId,
|
|
102
|
+
current_state: { userId: userId, connected: true },
|
|
103
|
+
likely_cause: "User not found or database timeout",
|
|
104
|
+
suggestions: [
|
|
105
|
+
"Check if userId exists",
|
|
106
|
+
"Verify database connection",
|
|
107
|
+
"Check query syntax"
|
|
108
|
+
],
|
|
109
|
+
recovery: {
|
|
110
|
+
action: "try_cache",
|
|
111
|
+
command: "redis-cli GET user:" + userId
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return getCachedUser(userId)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return Ok(result)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// LESSON 6: Explicit Dependencies
|
|
121
|
+
// Use @needs to declare what your function requires
|
|
122
|
+
|
|
123
|
+
@needs(database, api_key, logger)
|
|
124
|
+
@confidence(0.88, "Dependencies properly validated")
|
|
125
|
+
@complete
|
|
126
|
+
func authenticateUser(token: string) -> Result<string, string> {
|
|
127
|
+
// Compiler ensures database, api_key, logger are available
|
|
128
|
+
// This prevents "undefined variable" bugs
|
|
129
|
+
|
|
130
|
+
if !token {
|
|
131
|
+
return Err("Missing token")
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return Ok("authenticated")
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// LESSON 7: Marking Uncertainty
|
|
138
|
+
// Flag specific areas you're uncertain about
|
|
139
|
+
|
|
140
|
+
@confidence(0.65, "Timezone handling unverified")
|
|
141
|
+
@uncertain("Leap year calculation", "Daylight saving time", "Non-Gregorian calendars")
|
|
142
|
+
@partial
|
|
143
|
+
func parseDate(dateStr: string) -> Result<string, string> {
|
|
144
|
+
// Basic date parsing
|
|
145
|
+
if dateStr.contains("-") {
|
|
146
|
+
return Ok(dateStr)
|
|
147
|
+
}
|
|
148
|
+
return Err("Invalid date format")
|
|
149
|
+
|
|
150
|
+
// TODO: Handle timezones properly
|
|
151
|
+
// TODO: Validate leap years
|
|
152
|
+
// TODO: Support multiple date formats
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// LESSON 8: Confidence-Based Fallback Chains
|
|
156
|
+
// Try high-confidence methods first, fall back to lower confidence
|
|
157
|
+
|
|
158
|
+
@confidence(0.92, "Multiple fallback strategies")
|
|
159
|
+
@complete
|
|
160
|
+
func robustFetch(url: string) -> Result<string, string> {
|
|
161
|
+
// Try primary method (confidence: 0.95)
|
|
162
|
+
primaryFetch(url) match {
|
|
163
|
+
Ok(data) -> return Ok(data),
|
|
164
|
+
Err(e) -> {
|
|
165
|
+
// Try secondary method (confidence: 0.85)
|
|
166
|
+
secondaryFetch(url) match {
|
|
167
|
+
Ok(data) -> return Ok(data),
|
|
168
|
+
Err(e2) -> {
|
|
169
|
+
// Try cache (confidence: 0.70)
|
|
170
|
+
return getCachedData(url)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// LESSON 9: Best Practices for AI Agents
|
|
178
|
+
|
|
179
|
+
// DO: Start with @stub to get it compiling
|
|
180
|
+
@stub
|
|
181
|
+
func newFeature() { }
|
|
182
|
+
|
|
183
|
+
// DO: Gradually improve to @partial
|
|
184
|
+
@partial
|
|
185
|
+
@confidence(0.60, "Basic implementation only")
|
|
186
|
+
func newFeatureImproved() {
|
|
187
|
+
// Basic logic here
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// DO: Mark areas you're uncertain about
|
|
191
|
+
@uncertain("edge cases for empty arrays")
|
|
192
|
+
func processArray(arr: number[]) -> number {
|
|
193
|
+
if arr.length == 0 {
|
|
194
|
+
return 0
|
|
195
|
+
}
|
|
196
|
+
return arr.length
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// DO: Use pattern matching for clarity
|
|
200
|
+
@complete
|
|
201
|
+
func handleResult(r: Result<number, string>) -> string {
|
|
202
|
+
r match {
|
|
203
|
+
Ok(value) -> return "Success: " + value,
|
|
204
|
+
Err(error) -> return "Failed: " + error
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// DON'T: Throw exceptions - use Result types
|
|
209
|
+
// BAD (in other languages):
|
|
210
|
+
// throw new Error("Something failed")
|
|
211
|
+
// GOOD (in Agentic):
|
|
212
|
+
// return Err("Something failed")
|
|
213
|
+
|
|
214
|
+
// DON'T: Mark everything @complete if you're unsure
|
|
215
|
+
// Better to be honest with @partial and low confidence
|
|
216
|
+
|
|
217
|
+
// DON'T: Skip @confidence annotations
|
|
218
|
+
// Always include them so humans know what to review
|
|
219
|
+
|
|
220
|
+
// LESSON 10: Real-World Example - User Authentication
|
|
221
|
+
|
|
222
|
+
@needs(database, jwt_secret, rate_limiter)
|
|
223
|
+
@confidence(0.87, "Production tested, needs 2FA")
|
|
224
|
+
@partial
|
|
225
|
+
func fullAuthenticate(email: string, password: string) -> Result<string, string> {
|
|
226
|
+
// Validate inputs
|
|
227
|
+
if !email || !password {
|
|
228
|
+
return Err("Missing credentials")
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Check rate limiting
|
|
232
|
+
checkRateLimit(email) match {
|
|
233
|
+
Ok(allowed) -> {
|
|
234
|
+
// Continue
|
|
235
|
+
},
|
|
236
|
+
Err(e) -> return Err("Rate limited: " + e)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Query database
|
|
240
|
+
findUser(email) match {
|
|
241
|
+
Ok(user) -> {
|
|
242
|
+
// Verify password
|
|
243
|
+
verifyPassword(password, user.hash) match {
|
|
244
|
+
Ok(valid) -> {
|
|
245
|
+
// Generate JWT
|
|
246
|
+
return Ok(generateJWT(user, jwt_secret))
|
|
247
|
+
},
|
|
248
|
+
Err(e) -> return Err("Invalid password")
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
Err(e) -> return Err("User not found")
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// SUMMARY:
|
|
256
|
+
// - Use @confidence to grade your work
|
|
257
|
+
// - Use @stub/@partial/@complete to track progress
|
|
258
|
+
// - Use Result<T, E> instead of exceptions
|
|
259
|
+
// - Use pattern matching for elegant error handling
|
|
260
|
+
// - Use @needs to declare dependencies
|
|
261
|
+
// - Use @uncertain to flag risky code
|
|
262
|
+
// - Use error recovery blocks for debugging context
|
|
263
|
+
// - Be honest about limitations!
|