Skip to content

Commit 5060052

Browse files
authored
AMPR-165 #489: Finish declarative spark migration (#491)
* AMPR-165 #489: Finish declarative spark migration Authored by Codex. * AMPR-165 #489: Fix Android spark resource fallback Authored by Codex.
1 parent bfdd76c commit 5060052

38 files changed

Lines changed: 1441 additions & 774 deletions

ampere-core/src/androidMain/kotlin/link/socket/ampere/agents/domain/cognition/sparks/DefaultPhaseSparkLibrary.android.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package link.socket.ampere.agents.domain.cognition.sparks
22

3+
import java.io.File
4+
35
internal actual suspend fun loadBundledSparkFallback(
46
resourcePath: String,
57
fallbackPath: String,
@@ -26,5 +28,40 @@ internal actual suspend fun loadBundledSparkFallback(
2628
}
2729
}
2830

31+
for (file in candidateFiles(resourcePath = resourcePath, fallbackPath = fallbackPath)) {
32+
if (file.isFile) {
33+
return file.readText()
34+
}
35+
}
36+
2937
return null
3038
}
39+
40+
private fun candidateFiles(
41+
resourcePath: String,
42+
fallbackPath: String,
43+
): List<File> {
44+
val userDir = File(System.getProperty("user.dir") ?: ".").absoluteFile
45+
val roots = listOf(
46+
userDir,
47+
File(userDir, "ampere-core"),
48+
).distinctBy { it.path }
49+
50+
val generatedAssetPaths = listOf(
51+
"build/generated/assets/copyDebugComposeResourcesToAndroidAssets/$resourcePath",
52+
"build/generated/assets/copyReleaseComposeResourcesToAndroidAssets/$resourcePath",
53+
)
54+
55+
val sourcePaths = listOf(
56+
"src/commonMain/composeResources/$fallbackPath",
57+
"build/generated/compose/resourceGenerator/preparedResources/commonMain/composeResources/$fallbackPath",
58+
)
59+
60+
return roots
61+
.flatMap { root ->
62+
(generatedAssetPaths + sourcePaths).map { relativePath ->
63+
File(root, relativePath)
64+
}
65+
}
66+
.distinctBy { it.path }
67+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---json
2+
{
3+
"type": "language",
4+
"id": "java",
5+
"name": "Language:Java",
6+
"fileAccessScope": {
7+
"read": ["**/*.java", "**/*.xml", "**/*.gradle*", "**/pom.xml"],
8+
"write": ["**/*.java"]
9+
}
10+
}
11+
---
12+
13+
## Language: Java
14+
15+
You are working with **Java** code. Follow these idioms and best practices:
16+
17+
### Core Principles
18+
19+
- Use modern Java features (records, sealed classes, pattern matching)
20+
- Prefer composition over inheritance
21+
- Follow SOLID principles
22+
- Use meaningful, descriptive names
23+
24+
### Java-Specific Patterns
25+
26+
- Use Optional for nullable return types
27+
- Prefer streams for collection processing
28+
- Use records for immutable data carriers
29+
- Leverage sealed classes for restricted hierarchies
30+
- Use interfaces for abstraction
31+
32+
### Code Style
33+
34+
- Follow standard Java conventions
35+
- Keep classes focused and cohesive
36+
- Document public APIs with Javadoc
37+
- Handle exceptions appropriately
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---json
2+
{
3+
"type": "language",
4+
"id": "kotlin",
5+
"name": "Language:Kotlin",
6+
"fileAccessScope": {
7+
"read": ["**/*.kt", "**/*.kts", "**/*.xml", "**/*.gradle*"],
8+
"write": ["**/*.kt", "**/*.kts"]
9+
}
10+
}
11+
---
12+
13+
## Language: Kotlin
14+
15+
You are working with **Kotlin** code. Follow these idioms and best practices:
16+
17+
### Core Principles
18+
19+
- **Prefer immutability**: Use `val` over `var`, immutable collections over mutable
20+
- **Leverage null safety**: Use nullable types explicitly, prefer safe calls (`?.`) over `!!`
21+
- **Use scope functions appropriately**: `let` for null checks, `apply` for configuration, `run` for transformations
22+
- **Prefer expressions over statements**: `when` expressions, `if` expressions, `try` expressions
23+
24+
### Kotlin-Specific Patterns
25+
26+
- Use data classes for DTOs and value objects
27+
- Prefer sealed classes/interfaces for restricted hierarchies
28+
- Use object declarations for singletons
29+
- Leverage extension functions for clean APIs
30+
- Use inline classes (value classes) for type safety without overhead
31+
32+
### Coroutines
33+
34+
- Use structured concurrency with appropriate scope
35+
- Prefer `suspend` functions over callbacks
36+
- Use `Flow` for reactive streams
37+
- Handle cancellation properly
38+
39+
### Multiplatform Considerations
40+
41+
- Keep platform-specific code in `expect`/`actual` declarations
42+
- Use common abstractions from kotlinx libraries
43+
- Test on all target platforms when possible
44+
45+
### Code Style
46+
47+
- Follow Kotlin coding conventions
48+
- Use meaningful names that express intent
49+
- Keep functions small and focused
50+
- Document public APIs with KDoc
51+
52+
### File and Package Conventions
53+
54+
- Source roots: `src/commonMain/kotlin/`, `src/jvmMain/kotlin/`,
55+
`src/main/kotlin/`. The `package` declaration mirrors the path under the
56+
source root.
57+
- `src/commonMain/kotlin/link/socket/ampere/User.kt``package link.socket.ampere`
58+
- `src/main/kotlin/com/example/Foo.kt``package com.example`
59+
- Every generated `.kt` file starts with its `package` declaration followed
60+
by its imports.
61+
- Prefer one top-level declaration per file when the file is named after
62+
the declaration; multi-declaration files are fine when the declarations
63+
are tightly related (e.g. a sealed class and its `data` subclasses).
64+
65+
### When Generating Code
66+
67+
- Generate **complete, compilable** code — no `TODO`s, no placeholders, no
68+
partial implementations.
69+
- Include every necessary import; rely on the package convention above for
70+
the `package` line.
71+
- Add KDoc on public APIs.
72+
73+
## When Planning
74+
75+
### Kotlin planning notes
76+
77+
- When a step will produce new files, name them with `.kt` (or `.kts` for
78+
Gradle scripts) and place them under the appropriate source root
79+
(`commonMain`, `jvmMain`, `androidMain`, etc.) so the `package` line
80+
follows from the path.
81+
- Group related declarations into the same step when they belong in the
82+
same file (a sealed class plus its subclasses, an interface plus its
83+
default implementations).
84+
85+
## When Executing
86+
87+
### Kotlin execution notes
88+
89+
- Compilation-equivalent failure modes you should surface as critical:
90+
missing `package` declaration, unresolved imports, signature mismatch
91+
against `expect`/`actual` declarations.
92+
- Treat warnings about unsafe casts (`as`), `!!`, or platform-typed
93+
values as something to fix in the same step rather than defer.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---json
2+
{
3+
"type": "language",
4+
"id": "python",
5+
"name": "Language:Python",
6+
"fileAccessScope": {
7+
"read": ["**/*.py", "**/requirements*.txt", "**/pyproject.toml", "**/setup.py"],
8+
"write": ["**/*.py"],
9+
"forbidden": ["**/__pycache__/**", "**/*.pyc", "**/venv/**", "**/.venv/**"]
10+
}
11+
}
12+
---
13+
14+
## Language: Python
15+
16+
You are working with **Python** code. Follow these idioms and best practices:
17+
18+
### Core Principles
19+
20+
- Follow PEP 8 style guide
21+
- Use type hints for better tooling and documentation
22+
- Prefer explicit over implicit
23+
- Keep it simple and readable
24+
25+
### Python-Specific Patterns
26+
27+
- Use dataclasses or Pydantic for data structures
28+
- Leverage list/dict comprehensions appropriately
29+
- Use context managers for resource management
30+
- Prefer generators for large sequences
31+
- Use descriptive variable names
32+
33+
### Code Style
34+
35+
- Follow PEP 8 naming conventions
36+
- Document with docstrings
37+
- Keep functions focused
38+
- Handle exceptions explicitly
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---json
2+
{
3+
"type": "language",
4+
"id": "typescript",
5+
"name": "Language:TypeScript",
6+
"fileAccessScope": {
7+
"read": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.json", "**/package.json"],
8+
"write": ["**/*.ts", "**/*.tsx"],
9+
"forbidden": ["**/node_modules/**"]
10+
}
11+
}
12+
---
13+
14+
## Language: TypeScript
15+
16+
You are working with **TypeScript** code. Follow these idioms and best practices:
17+
18+
### Core Principles
19+
20+
- Leverage the type system for safety and documentation
21+
- Prefer strict type checking settings
22+
- Use union types and discriminated unions effectively
23+
- Avoid `any` - use `unknown` when type is truly unknown
24+
25+
### TypeScript-Specific Patterns
26+
27+
- Use interfaces for object shapes
28+
- Use type aliases for complex types
29+
- Leverage generics for reusable abstractions
30+
- Use const assertions for literal types
31+
- Prefer functional patterns with proper typing
32+
33+
### Code Style
34+
35+
- Follow project ESLint/Prettier configuration
36+
- Export types alongside implementations
37+
- Document complex types with JSDoc
38+
- Keep type definitions close to usage
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---json
2+
{
3+
"type": "project",
4+
"id": "ampere",
5+
"name": "Project:ampere",
6+
"projectId": "ampere",
7+
"repositoryRoot": "${env:AMPERE_ROOT:-${env:PWD:-.}}"
8+
}
9+
---
10+
11+
## Project Description
12+
13+
AMPERE is a Kotlin Multiplatform framework for building autonomous AI agent systems.
14+
15+
## Purpose
16+
AMPERE enables the creation of collaborative AI agent teams that can:
17+
- Communicate through typed events and messages
18+
- Maintain long-term memory and learn from experiences
19+
- Execute tasks autonomously with appropriate tool access
20+
- Coordinate through meetings and tickets
21+
22+
## Key Components
23+
- **Agents**: Autonomous entities with cognitive cycles (PERCEIVE → PLAN → EXECUTE → LEARN)
24+
- **Events**: Typed messages for agent communication (MessagePosted, TicketAssigned, etc.)
25+
- **Sparks**: Cognitive differentiation layers that specialize agent behavior
26+
- **Memory**: Knowledge persistence and recall for experiential learning
27+
28+
## Architecture
29+
- `ampere-core`: Multiplatform core library with agent infrastructure
30+
- `ampere-cli`: JVM command-line interface for running agents
31+
- Kotlin Multiplatform targeting JVM and Android
32+
33+
## The Spark System
34+
Agents use a "cellular differentiation" model where a single SparkBasedAgent class
35+
specializes through accumulated Spark layers:
36+
1. CognitiveAffinity: Base thinking approach (ANALYTICAL, EXPLORATORY, OPERATIONAL, INTEGRATIVE)
37+
2. ProjectSpark: Project context and conventions
38+
3. Declarative role spark: Capability focus (Code, Research, Operations, Planning)
39+
4. CoordinationSpark: Handoff and coordination focus (optional, when needed)
40+
5. TaskSpark: Current task context (applied/removed with task lifecycle)
41+
42+
## Project Conventions
43+
44+
## Kotlin Style
45+
- Follow Kotlin official coding conventions
46+
- Use data classes for immutable value types
47+
- Prefer sealed classes/interfaces for domain modeling
48+
- Use kotlinx.serialization for JSON handling
49+
- Use kotlinx.coroutines for async operations
50+
51+
## Package Structure
52+
- `agents.definition`: Agent class implementations
53+
- `agents.domain.cognition`: Spark system and cognitive types
54+
- `agents.domain.event`: Event types for agent communication
55+
- `agents.domain.memory`: Knowledge and memory persistence
56+
- `agents.events`: Event bus and subscription infrastructure
57+
- `agents.execution`: Tool execution and task running
58+
59+
## Testing
60+
- Write tests in `commonTest` for platform-independent logic
61+
- Use `jvmTest` for JVM-specific tests
62+
- Follow existing test patterns with `@Test` annotation
63+
- Use descriptive test names that explain what's being tested
64+
65+
## Documentation
66+
- Use KDoc for public APIs
67+
- Include examples in documentation where helpful
68+
- Keep comments focused on "why" rather than "what"
69+
70+
## Event Handling
71+
- All agent events should be serializable with kotlinx.serialization
72+
- Use EventSource to track event origin
73+
- Include timestamp in all events
74+
- Prefer immutable event data classes

ampere-core/src/commonMain/composeResources/files/sparks/role-code.spark.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,9 @@
3636
"**/build/**",
3737
"**/.gradle/**",
3838
"**/node_modules/**",
39-
"**/.git/**",
40-
"**/.env",
41-
"**/.env.*",
42-
"**/credentials.json",
43-
"**/secrets.json",
44-
"**/*.pem",
45-
"**/*.key",
46-
"**/id_rsa*",
47-
"**/.git/config"
48-
]
39+
"**/.git/**"
40+
],
41+
"forbiddenRefs": ["sensitive-files"]
4942
}
5043
}
5144
---

0 commit comments

Comments
 (0)