Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ This project _loosely_ adheres to [Semantic Versioning](https://semver.org/spec/
- Full CRUD systems for choosing AI models, remote models through API calls and UI in ADAM Launcher for setup and managing of models [PR#504](https://github.com/coasys/ad4m/pull/504)
- Add remote AI API model picking, to enable Ollama use-case [PR#547](https://github.com/coasys/ad4m/pull/547)
- ad4m CLI: wildcards (underscore: "_") in query-links command [PR#551](https://github.com/coasys/ad4m/pull/551)

- Add `author` and `timestamp` to SubjectEntity objects [PR#557](https://github.com/coasys/ad4m/pull/557)
- Make `SubjectEntity.#perspective` protected to enable subclasses to implement complex fields and methods [PR#557](https://github.com/coasys/ad4m/pull/557)
-
### Changed
- Partially migrated the Runtime service to Rust. (DM language installation for agents is pending.) [PR#466](https://github.com/coasys/ad4m/pull/466)
- Improved performance of SDNA / SubjectClass functions by moving code from client into executor and saving a lot of client <-> executor roundtrips [PR#480](https://github.com/coasys/ad4m/pull/480)
Expand Down
8 changes: 8 additions & 0 deletions core/src/subject/SubjectEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ export class SubjectEntity {
return this.#baseExpression
}

/**
* Protected getter for the perspective.
* Allows subclasses to access the perspective while keeping it private from external code.
*/
protected get perspective(): PerspectiveProxy {
return this.#perspective;
}

private async getData(id?: string) {
const tempId = id ?? this.#baseExpression;
let data = await this.#perspective.getSubjectData(this.#subjectClass, tempId)
Expand Down
16 changes: 16 additions & 0 deletions rust-executor/src/perspectives/perspective_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1552,6 +1552,22 @@ impl PerspectiveInstance {
) -> Result<String, AnyError> {
let mut object: HashMap<String, String> = HashMap::new();

// Get author and timestamp from the first link mentioning base as source
let mut base_query = LinkQuery::default();
base_query.source = Some(base_expression.clone());
let base_links = self.get_links(&base_query).await?;
let first_link = base_links
.first()
.ok_or_else(|| anyhow!("No links found for base expression: {}", base_expression))?;
object.insert(
String::from("author"),
format!("\"{}\"", first_link.author.clone()),
);
object.insert(
String::from("timestamp"),
format!("\"{}\"", first_link.timestamp.clone()),
);

let class_name = self
.subject_class_option_to_class_name(subject_class)
.await?;
Expand Down
17 changes: 17 additions & 0 deletions tests/js/tests/prolog-and-literals.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,23 @@ describe("Prolog + Literals", () => {
expect(recipe2.resolve.length).to.equal(longName.length)
expect(recipe2.resolve).to.equal(longName)
})

it("should have author and timestamp properties", async () => {
let root = Literal.from("Author and timestamp test").toUrl()
const recipe = new Recipe(perspective!, root)

recipe.name = "recipe://test";
await recipe.save();

const recipe2 = new Recipe(perspective!, root);
await recipe2.get();

const me = await ad4m!.agent.me();
// @ts-ignore - author and timestamp are added by the system
expect(recipe2.author).to.equal(me!.did)
// @ts-ignore
expect(recipe2.timestamp).to.not.be.undefined;
})
})
})
})
Expand Down